font/coretext: hasColor/isColored

This commit is contained in:
Mitchell Hashimoto
2024-05-28 13:20:37 -07:00
parent d22c645a02
commit dc6b1b0b7a
3 changed files with 30 additions and 17 deletions

View File

@ -291,7 +291,10 @@ fn getIndexCodepointOverride(
/// Returns the presentation for a specific font index. This is useful for /// Returns the presentation for a specific font index. This is useful for
/// determining what atlas is needed. /// determining what atlas is needed.
pub fn getPresentation(self: *CodepointResolver, index: Collection.Index) !Presentation { pub fn getPresentation(
self: *CodepointResolver,
index: Collection.Index,
) !Presentation {
if (index.special()) |sp| return switch (sp) { if (index.special()) |sp| return switch (sp) {
.sprite => .text, .sprite => .text,
}; };

View File

@ -242,9 +242,22 @@ pub const Face = struct {
self.* = face; self.* = face;
} }
/// Returns true if the face has any glyphs that are colorized.
/// To determine if an individual glyph is colorized you must use
/// isColored.
pub fn hasColor(self: *const Face) bool {
return self.color != null;
}
/// Returns true if the given glyph ID is colorized.
pub fn isColored(self: *const Face, glyph_id: u16) bool {
const c = self.color orelse return false;
return c.isColored(glyph_id);
}
/// Returns the glyph index for the given Unicode code point. If this /// Returns the glyph index for the given Unicode code point. If this
/// face doesn't support this glyph, null is returned. /// face doesn't support this glyph, null is returned.
pub fn glyphIndex(self: Face, cp: u32) ?GlyphIndex { pub fn glyphIndex(self: Face, cp: u32) ?u16 {
// Turn UTF-32 into UTF-16 for CT API // Turn UTF-32 into UTF-16 for CT API
var unichars: [2]u16 = undefined; var unichars: [2]u16 = undefined;
const pair = macos.foundation.stringGetSurrogatePairForLongCharacter(cp, &unichars); const pair = macos.foundation.stringGetSurrogatePairForLongCharacter(cp, &unichars);
@ -262,10 +275,7 @@ pub const Face = struct {
// If we have colorization information, then check if this // If we have colorization information, then check if this
// glyph is colorized. // glyph is colorized.
return .{ return @intCast(glyphs[0]);
.index = @intCast(glyphs[0]),
.color = if (self.color) |v| v.isColored(glyphs[0]) else false,
};
} }
pub fn renderGlyph( pub fn renderGlyph(
@ -695,7 +705,7 @@ test {
var i: u8 = 32; var i: u8 = 32;
while (i < 127) : (i += 1) { while (i < 127) : (i += 1) {
try testing.expect(face.glyphIndex(i) != null); try testing.expect(face.glyphIndex(i) != null);
_ = try face.renderGlyph(alloc, &atlas, face.glyphIndex(i).?.index, .{}); _ = try face.renderGlyph(alloc, &atlas, face.glyphIndex(i).?, .{});
} }
} }
@ -737,8 +747,8 @@ test "emoji" {
// Glyph index check // Glyph index check
{ {
const glyph = face.glyphIndex('🥸').?; const id = face.glyphIndex('🥸').?;
try testing.expect(glyph.color); try testing.expect(face.isColored(id));
} }
} }
@ -762,7 +772,7 @@ test "in-memory" {
var i: u8 = 32; var i: u8 = 32;
while (i < 127) : (i += 1) { while (i < 127) : (i += 1) {
try testing.expect(face.glyphIndex(i) != null); try testing.expect(face.glyphIndex(i) != null);
_ = try face.renderGlyph(alloc, &atlas, face.glyphIndex(i).?.index, .{}); _ = try face.renderGlyph(alloc, &atlas, face.glyphIndex(i).?, .{});
} }
} }
@ -786,7 +796,7 @@ test "variable" {
var i: u8 = 32; var i: u8 = 32;
while (i < 127) : (i += 1) { while (i < 127) : (i += 1) {
try testing.expect(face.glyphIndex(i) != null); try testing.expect(face.glyphIndex(i) != null);
_ = try face.renderGlyph(alloc, &atlas, face.glyphIndex(i).?.index, .{}); _ = try face.renderGlyph(alloc, &atlas, face.glyphIndex(i).?, .{});
} }
} }
@ -814,7 +824,7 @@ test "variable set variation" {
var i: u8 = 32; var i: u8 = 32;
while (i < 127) : (i += 1) { while (i < 127) : (i += 1) {
try testing.expect(face.glyphIndex(i) != null); try testing.expect(face.glyphIndex(i) != null);
_ = try face.renderGlyph(alloc, &atlas, face.glyphIndex(i).?.index, .{}); _ = try face.renderGlyph(alloc, &atlas, face.glyphIndex(i).?, .{});
} }
} }
@ -860,13 +870,13 @@ test "glyphIndex colored vs text" {
{ {
const glyph = face.glyphIndex('A').?; const glyph = face.glyphIndex('A').?;
try testing.expectEqual(4, glyph.index); try testing.expectEqual(4, glyph);
try testing.expectEqual(false, glyph.color); try testing.expect(!face.isColored(glyph));
} }
{ {
const glyph = face.glyphIndex(0xE800).?; const glyph = face.glyphIndex(0xE800).?;
try testing.expectEqual(11482, glyph.index); try testing.expectEqual(11482, glyph);
try testing.expectEqual(true, glyph.color); try testing.expect(face.isColored(glyph));
} }
} }

View File

@ -160,7 +160,7 @@ pub const Style = enum(u3) {
bold_italic = 3, bold_italic = 3,
}; };
/// The presentation for a an emoji. /// The presentation for an emoji.
pub const Presentation = enum(u1) { pub const Presentation = enum(u1) {
text = 0, // U+FE0E text = 0, // U+FE0E
emoji = 1, // U+FEOF emoji = 1, // U+FEOF