From 382f569d653cf90924b3445285625b995d3c503f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 14 Sep 2022 09:54:48 -0700 Subject: [PATCH] fontconfig: object sets and patterns --- pkg/fontconfig/main.zig | 2 + pkg/fontconfig/object_set.zig | 115 ++++++++++++++++++++++++++++++++++ pkg/fontconfig/pattern.zig | 29 +++++++++ 3 files changed, 146 insertions(+) create mode 100644 pkg/fontconfig/object_set.zig create mode 100644 pkg/fontconfig/pattern.zig diff --git a/pkg/fontconfig/main.zig b/pkg/fontconfig/main.zig index 67ec9f57b..2fa857db3 100644 --- a/pkg/fontconfig/main.zig +++ b/pkg/fontconfig/main.zig @@ -1,6 +1,8 @@ pub const c = @import("c.zig"); pub usingnamespace @import("init.zig"); pub usingnamespace @import("config.zig"); +pub usingnamespace @import("object_set.zig"); +pub usingnamespace @import("pattern.zig"); test { @import("std").testing.refAllDecls(@This()); diff --git a/pkg/fontconfig/object_set.zig b/pkg/fontconfig/object_set.zig new file mode 100644 index 000000000..7d79f95e2 --- /dev/null +++ b/pkg/fontconfig/object_set.zig @@ -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)); +} diff --git a/pkg/fontconfig/pattern.zig b/pkg/fontconfig/pattern.zig new file mode 100644 index 000000000..d5073ea37 --- /dev/null +++ b/pkg/fontconfig/pattern.zig @@ -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(); +}