diff --git a/pkg/freetype/Library.zig b/pkg/freetype/Library.zig index 202025839..df99d2b94 100644 --- a/pkg/freetype/Library.zig +++ b/pkg/freetype/Library.zig @@ -32,6 +32,18 @@ pub fn version(self: Library) Version { return v; } +/// Call FT_New_Face to open a font from a file. +pub fn initFace(self: Library, path: [:0]const u8, index: i32) Error!Face { + var face: Face = undefined; + try intToError(c.FT_New_Face( + self.handle, + path.ptr, + index, + &face.handle, + )); + return face; +} + /// Call FT_Open_Face to open a font that has been loaded into memory. pub fn initMemoryFace(self: Library, data: []const u8, index: i32) Error!Face { var face: Face = undefined; diff --git a/src/font/DeferredFace.zig b/src/font/DeferredFace.zig index 8a4eb9939..7c82cb5de 100644 --- a/src/font/DeferredFace.zig +++ b/src/font/DeferredFace.zig @@ -61,6 +61,31 @@ pub inline fn loaded(self: DeferredFace) bool { return self.face != null; } +pub fn load(self: *DeferredFace) !void { + // No-op if we already loaded + if (self.face != null) return; + + if (options.fontconfig) { + try self.loadFontconfig(); + return; + } + + unreachable; +} + +fn loadFontconfig(self: *DeferredFace) !void { + assert(self.face == null); + const fc = self.fc.?; + + // Filename and index for our face so we can load it + const filename = (try fc.pattern.get(.file, 0)).string; + const face_index = (try fc.pattern.get(.index, 0)).integer; + + self.face = try Face.initFile(filename, face_index, .{ + .points = fc.req_size, + }); +} + /// Returns true if this face can satisfy the given codepoint and /// presentation. If presentation is null, then it just checks if the /// codepoint is present at all. diff --git a/src/font/Face.zig b/src/font/Face.zig index 9777567e7..3068b8cbc 100644 --- a/src/font/Face.zig +++ b/src/font/Face.zig @@ -50,6 +50,23 @@ pub const DesiredSize = struct { } }; +/// Initialize a new font face with the given source in-memory. +pub fn initFile(lib: Library, path: [:0]const u8, index: i32, size: DesiredSize) !Face { + const face = try lib.lib.initFace(path, index); + errdefer face.deinit(); + try face.selectCharmap(.unicode); + try setSize_(face, size); + + const hb_font = try harfbuzz.freetype.createFont(face.handle); + errdefer hb_font.destroy(); + + return Face{ + .face = face, + .hb_font = hb_font, + .presentation = if (face.hasColor()) .emoji else .text, + }; +} + /// Initialize a new font face with the given source in-memory. pub fn init(lib: Library, source: [:0]const u8, size: DesiredSize) !Face { const face = try lib.lib.initMemoryFace(source, 0);