diff --git a/src/Grid.zig b/src/Grid.zig index fb41064aa..9630cfc6e 100644 --- a/src/Grid.zig +++ b/src/Grid.zig @@ -167,24 +167,24 @@ pub fn init( try group.addFace( alloc, .regular, - try font.Face.init(font_lib, face_ttf, font_size), + font.DeferredFace.initLoaded(try font.Face.init(font_lib, face_ttf, font_size)), ); try group.addFace( alloc, .bold, - try font.Face.init(font_lib, face_bold_ttf, font_size), + font.DeferredFace.initLoaded(try font.Face.init(font_lib, face_bold_ttf, font_size)), ); // Emoji try group.addFace( alloc, .regular, - try font.Face.init(font_lib, face_emoji_ttf, font_size), + font.DeferredFace.initLoaded(try font.Face.init(font_lib, face_emoji_ttf, font_size)), ); try group.addFace( alloc, .regular, - try font.Face.init(font_lib, face_emoji_text_ttf, font_size), + font.DeferredFace.initLoaded(try font.Face.init(font_lib, face_emoji_text_ttf, font_size)), ); break :group group; diff --git a/src/font/DeferredFace.zig b/src/font/DeferredFace.zig index e5e4cc135..43efbcb72 100644 --- a/src/font/DeferredFace.zig +++ b/src/font/DeferredFace.zig @@ -13,6 +13,8 @@ const options = @import("main.zig").options; const Face = @import("main.zig").Face; const Presentation = @import("main.zig").Presentation; +const Library = @import("main.zig").Library; + /// The loaded face (once loaded). face: ?Face = null, @@ -31,6 +33,12 @@ pub const Fontconfig = struct { } }; +/// Initialize a deferred face that is already pre-loaded. The deferred face +/// takes ownership over the loaded face, deinit will deinit the loaded face. +pub fn initLoaded(face: Face) DeferredFace { + return .{ .face = face }; +} + pub fn deinit(self: *DeferredFace) void { if (self.face) |*face| face.deinit(); if (options.fontconfig) if (self.fc) |*fc| fc.deinit(); @@ -82,3 +90,19 @@ pub fn hasCodepoint(self: DeferredFace, cp: u32, p: ?Presentation) bool { // if we're not using a discovery mechanism, the face MUST be loaded. unreachable; } + +test { + const testing = std.testing; + const testFont = @import("test.zig").fontRegular; + + var lib = try Library.init(); + defer lib.deinit(); + + var face = try Face.init(lib, testFont, .{ .points = 12 }); + errdefer face.deinit(); + + var def = initLoaded(face); + defer def.deinit(); + + try testing.expect(def.hasCodepoint(' ', null)); +} diff --git a/src/font/Group.zig b/src/font/Group.zig index 27ef4545d..b49ef0c58 100644 --- a/src/font/Group.zig +++ b/src/font/Group.zig @@ -58,8 +58,8 @@ pub fn deinit(self: *Group, alloc: Allocator) void { /// /// The group takes ownership of the face. The face will be deallocated when /// the group is deallocated. -pub fn addFace(self: *Group, alloc: Allocator, style: Style, face: Face) !void { - try self.faces.getPtr(style).append(alloc, .{ .face = face }); +pub fn addFace(self: *Group, alloc: Allocator, style: Style, face: DeferredFace) !void { + try self.faces.getPtr(style).append(alloc, face); } /// This represents a specific font in the group. @@ -169,9 +169,9 @@ test { var group = try init(alloc); defer group.deinit(alloc); - try group.addFace(alloc, .regular, try Face.init(lib, testFont, .{ .points = 12 })); - try group.addFace(alloc, .regular, try Face.init(lib, testEmoji, .{ .points = 12 })); - try group.addFace(alloc, .regular, try Face.init(lib, testEmojiText, .{ .points = 12 })); + try group.addFace(alloc, .regular, DeferredFace.initLoaded(try Face.init(lib, testFont, .{ .points = 12 }))); + try group.addFace(alloc, .regular, DeferredFace.initLoaded(try Face.init(lib, testEmoji, .{ .points = 12 }))); + try group.addFace(alloc, .regular, DeferredFace.initLoaded(try Face.init(lib, testEmojiText, .{ .points = 12 }))); // Should find all visible ASCII var i: u32 = 32; diff --git a/src/font/GroupCache.zig b/src/font/GroupCache.zig index 90f33da5a..c81ea42e8 100644 --- a/src/font/GroupCache.zig +++ b/src/font/GroupCache.zig @@ -7,6 +7,7 @@ const Allocator = std.mem.Allocator; const Atlas = @import("../Atlas.zig"); const Face = @import("main.zig").Face; +const DeferredFace = @import("main.zig").DeferredFace; const Library = @import("main.zig").Library; const Glyph = @import("main.zig").Glyph; const Style = @import("main.zig").Style; @@ -221,7 +222,11 @@ test { defer cache.deinit(alloc); // Setup group - try cache.group.addFace(alloc, .regular, try Face.init(lib, testFont, .{ .points = 12 })); + try cache.group.addFace( + alloc, + .regular, + DeferredFace.initLoaded(try Face.init(lib, testFont, .{ .points = 12 })), + ); const group = cache.group; // Visible ASCII. Do it twice to verify cache. diff --git a/src/font/Shaper.zig b/src/font/Shaper.zig index 9063ae45b..4c901bd06 100644 --- a/src/font/Shaper.zig +++ b/src/font/Shaper.zig @@ -8,6 +8,7 @@ const harfbuzz = @import("harfbuzz"); const trace = @import("tracy").trace; const Atlas = @import("../Atlas.zig"); const Face = @import("main.zig").Face; +const DeferredFace = @import("main.zig").DeferredFace; const Group = @import("main.zig").Group; const GroupCache = @import("main.zig").GroupCache; const Library = @import("main.zig").Library; @@ -599,9 +600,9 @@ fn testShaper(alloc: Allocator) !TestShaper { errdefer cache_ptr.*.deinit(alloc); // Setup group - try cache_ptr.group.addFace(alloc, .regular, try Face.init(lib, testFont, .{ .points = 12 })); - try cache_ptr.group.addFace(alloc, .regular, try Face.init(lib, testEmoji, .{ .points = 12 })); - try cache_ptr.group.addFace(alloc, .regular, try Face.init(lib, testEmojiText, .{ .points = 12 })); + try cache_ptr.group.addFace(alloc, .regular, DeferredFace.initLoaded(try Face.init(lib, testFont, .{ .points = 12 }))); + try cache_ptr.group.addFace(alloc, .regular, DeferredFace.initLoaded(try Face.init(lib, testEmoji, .{ .points = 12 }))); + try cache_ptr.group.addFace(alloc, .regular, DeferredFace.initLoaded(try Face.init(lib, testEmojiText, .{ .points = 12 }))); var cell_buf = try alloc.alloc(Cell, 80); errdefer alloc.free(cell_buf);