fontconfig: object sets and patterns

This commit is contained in:
Mitchell Hashimoto
2022-09-14 09:54:48 -07:00
parent b4d571e018
commit 382f569d65
3 changed files with 146 additions and 0 deletions

View File

@ -1,6 +1,8 @@
pub const c = @import("c.zig"); pub const c = @import("c.zig");
pub usingnamespace @import("init.zig"); pub usingnamespace @import("init.zig");
pub usingnamespace @import("config.zig"); pub usingnamespace @import("config.zig");
pub usingnamespace @import("object_set.zig");
pub usingnamespace @import("pattern.zig");
test { test {
@import("std").testing.refAllDecls(@This()); @import("std").testing.refAllDecls(@This());

View File

@ -0,0 +1,115 @@
const std = @import("std");
const c = @import("c.zig");
pub const ObjectSet = opaque {
pub fn create() *ObjectSet {
return @ptrCast(*ObjectSet, c.FcObjectSetCreate());
}
pub fn destroy(self: *ObjectSet) void {
c.FcObjectSetDestroy(self.cval());
}
pub fn add(self: *ObjectSet, p: Property) bool {
return c.FcObjectSetAdd(self.cval(), p.cval().ptr) == c.FcTrue;
}
fn cval(self: *ObjectSet) *c.struct__FcObjectSet {
return @ptrCast(
*c.struct__FcObjectSet,
@alignCast(@alignOf(c.struct__FcObjectSet), self),
);
}
};
pub const Property = enum {
family,
style,
slant,
weight,
size,
aspect,
pixel_size,
spacing,
foundry,
antialias,
hinting,
hint_style,
vertical_layout,
autohint,
global_advance,
width,
file,
index,
ft_face,
rasterizer,
outline,
scalable,
color,
variable,
scale,
symbol,
dpi,
rgba,
minspace,
source,
charset,
lang,
fontversion,
fullname,
familylang,
stylelang,
fullnamelang,
capability,
embolden,
embedded_bitmap,
decorative,
lcd_filter,
font_features,
font_variations,
namelang,
prgname,
hash,
postscript_name,
font_has_hint,
order,
fn cval(self: Property) [:0]const u8 {
@setEvalBranchQuota(10_000);
inline for (@typeInfo(Property).Enum.fields) |field| {
if (self == @field(Property, field.name)) {
// Build our string in a comptime context so it is a binary
// constant and not stack allocated.
return comptime name: {
// Replace _ with ""
var buf: [field.name.len]u8 = undefined;
const count = std.mem.replace(u8, field.name, "_", "", &buf);
const replaced = buf[0 .. field.name.len - count];
// Build our string
var name: [replaced.len:0]u8 = undefined;
std.mem.copy(u8, &name, replaced);
name[replaced.len] = 0;
break :name &name;
};
}
}
unreachable;
}
test "cval" {
const testing = std.testing;
try testing.expectEqualStrings("family", Property.family.cval());
try testing.expectEqualStrings("pixelsize", Property.pixel_size.cval());
}
};
test "create" {
const testing = std.testing;
var os = ObjectSet.create();
defer os.destroy();
try testing.expect(os.add(.family));
}

View File

@ -0,0 +1,29 @@
const std = @import("std");
const c = @import("c.zig");
pub const Pattern = opaque {
pub fn create() *Pattern {
return @ptrCast(*Pattern, c.FcPatternCreate());
}
pub fn parse(str: [:0]const u8) *Pattern {
return @ptrCast(*Pattern, c.FcNameParse(str.ptr));
}
pub fn destroy(self: *Pattern) void {
c.FcPatternDestroy(@ptrCast(
*c.struct__FcPattern,
self,
));
}
};
test "create" {
var pat = Pattern.create();
defer pat.destroy();
}
test "name parse" {
var pat = Pattern.parse(":monospace");
defer pat.destroy();
}