font/freetype: update to new presentation APIs

This commit is contained in:
Mitchell Hashimoto
2024-05-28 20:25:49 -07:00
parent 326659c522
commit 4daa49fe27
2 changed files with 26 additions and 17 deletions

View File

@ -26,6 +26,12 @@ pub const Face = struct {
return c.FT_HAS_COLOR(self.handle); return c.FT_HAS_COLOR(self.handle);
} }
/// A macro that returns true whenever a face object contains an sbix
/// OpenType table and outline glyphs.
pub fn hasSBIX(self: Face) bool {
return c.FT_HAS_SBIX(self.handle);
}
/// A macro that returns true whenever a face object contains some /// A macro that returns true whenever a face object contains some
/// multiple masters. /// multiple masters.
pub fn hasMultipleMasters(self: Face) bool { pub fn hasMultipleMasters(self: Face) bool {

View File

@ -15,7 +15,6 @@ const Allocator = std.mem.Allocator;
const font = @import("../main.zig"); const font = @import("../main.zig");
const Glyph = font.Glyph; const Glyph = font.Glyph;
const Library = font.Library; const Library = font.Library;
const Presentation = font.Presentation;
const convert = @import("freetype_convert.zig"); const convert = @import("freetype_convert.zig");
const fastmem = @import("../../fastmem.zig"); const fastmem = @import("../../fastmem.zig");
const quirks = @import("../../quirks.zig"); const quirks = @import("../../quirks.zig");
@ -32,10 +31,6 @@ pub const Face = struct {
/// Harfbuzz font corresponding to this face. /// Harfbuzz font corresponding to this face.
hb_font: harfbuzz.Font, hb_font: harfbuzz.Font,
/// The presentation for this font. This is a heuristic since fonts don't have
/// a way to declare this. We just assume a font with color is an emoji font.
presentation: Presentation,
/// Metrics for this font face. These are useful for renderers. /// Metrics for this font face. These are useful for renderers.
metrics: font.face.Metrics, metrics: font.face.Metrics,
@ -67,17 +62,10 @@ pub const Face = struct {
.lib = lib.lib, .lib = lib.lib,
.face = face, .face = face,
.hb_font = hb_font, .hb_font = hb_font,
.presentation = if (face.hasColor()) .emoji else .text,
.metrics = calcMetrics(face, opts.metric_modifiers), .metrics = calcMetrics(face, opts.metric_modifiers),
}; };
result.quirks_disable_default_font_features = quirks.disableDefaultFontFeatures(&result); result.quirks_disable_default_font_features = quirks.disableDefaultFontFeatures(&result);
// See coretext.zig which has a similar check for this.
if (result.presentation == .emoji and result.glyphIndex('🥸') == null) {
log.warn("font has colorized glyphs but isn't emoji, treating as text", .{});
result.presentation = .text;
}
// In debug mode, we output information about available variation axes, // In debug mode, we output information about available variation axes,
// if they exist. // if they exist.
if (comptime builtin.mode == .Debug) mm: { if (comptime builtin.mode == .Debug) mm: {
@ -219,10 +207,29 @@ pub const Face = struct {
/// Returns true if this font is colored. This can be used by callers to /// Returns true if this font is colored. This can be used by callers to
/// determine what kind of atlas to pass in. /// determine what kind of atlas to pass in.
fn hasColor(self: Face) bool { pub fn hasColor(self: Face) bool {
return self.face.hasColor(); return self.face.hasColor();
} }
/// Returns true if the given glyph ID is colorized.
pub fn isColorGlyph(self: *const Face, glyph_id: u32) bool {
// sbix table is always true for now
if (self.face.hasSBIX()) return true;
// Otherwise, load the glyph and see what format it is in.
self.face.loadGlyph(glyph_id, .{
.render = true,
.color = self.face.hasColor(),
.no_bitmap = !self.face.hasColor(),
}) catch return false;
// If the glyph is SVG we assume colorized
const glyph = self.face.handle.*.glyph;
if (glyph.*.format == freetype.c.FT_GLYPH_FORMAT_SVG) return true;
return false;
}
/// Render a glyph using the glyph index. The rendered glyph is stored in the /// Render a glyph using the glyph index. The rendered glyph is stored in the
/// given texture atlas. /// given texture atlas.
pub fn renderGlyph( pub fn renderGlyph(
@ -655,8 +662,6 @@ test {
); );
defer ft_font.deinit(); defer ft_font.deinit();
try testing.expectEqual(Presentation.text, ft_font.presentation);
// Generate all visible ASCII // Generate all visible ASCII
var i: u8 = 32; var i: u8 = 32;
while (i < 127) : (i += 1) { while (i < 127) : (i += 1) {
@ -691,8 +696,6 @@ test "color emoji" {
); );
defer ft_font.deinit(); defer ft_font.deinit();
try testing.expectEqual(Presentation.emoji, ft_font.presentation);
_ = try ft_font.renderGlyph(alloc, &atlas, ft_font.glyphIndex('🥸').?, .{}); _ = try ft_font.renderGlyph(alloc, &atlas, ft_font.glyphIndex('🥸').?, .{});
// resize // resize