diff --git a/pkg/freetype/face.zig b/pkg/freetype/face.zig index f4eaf24f0..e7dc7b0fa 100644 --- a/pkg/freetype/face.zig +++ b/pkg/freetype/face.zig @@ -135,6 +135,15 @@ pub const Face = struct { return buf; } + /// Check whether a given SFNT table is available in a face. + pub fn hasSfntTable(self: Face, tag: Tag) bool { + const tag_u64: u64 = @intCast(@as(u32, @bitCast(tag))); + var len: c_ulong = 0; + const res = c.FT_Load_Sfnt_Table(self.handle, tag_u64, 0, null, &len); + _ = intToError(res) catch return false; + return len != 0; + } + /// Retrieve the font variation descriptor for a font. pub fn getMMVar(self: Face) Error!*c.FT_MM_Var { var result: *c.FT_MM_Var = undefined; diff --git a/src/font/face/freetype.zig b/src/font/face/freetype.zig index 6037f6c0c..346d8aa8d 100644 --- a/src/font/face/freetype.zig +++ b/src/font/face/freetype.zig @@ -216,6 +216,11 @@ pub const Face = struct { // sbix table is always true for now if (self.face.hasSBIX()) return true; + // CBDT/CBLC tables always imply colorized glyphs. + // These are used by Noto. + if (self.face.hasSfntTable(freetype.Tag.init("CBDT"))) return true; + if (self.face.hasSfntTable(freetype.Tag.init("CBLC"))) return true; + // Otherwise, load the glyph and see what format it is in. self.face.loadGlyph(glyph_id, .{ .render = true, @@ -698,6 +703,13 @@ test "color emoji" { _ = try ft_font.renderGlyph(alloc, &atlas, ft_font.glyphIndex('🥸').?, .{}); + // Make sure this glyph has color + { + try testing.expect(ft_font.hasColor()); + const glyph_id = ft_font.glyphIndex('🥸').?; + try testing.expect(ft_font.isColorGlyph(glyph_id)); + } + // resize { const glyph = try ft_font.renderGlyph(alloc, &atlas, ft_font.glyphIndex('🥸').?, .{