mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-08-24 08:01:45 +00:00
font: look up Apple Color Emoji by exact name on macOS
The Apple Color Emoji fallback font was discovered with the generic discovery path, which builds a CTFontCollection and runs system-wide font matching. Since we know the exact font we want, we can look it up directly with CTFontCreateWithName instead.
This commit is contained in:
@@ -18,6 +18,17 @@ pub const Font = opaque {
|
||||
) orelse Allocator.Error.OutOfMemory;
|
||||
}
|
||||
|
||||
pub fn createWithName(name: *foundation.String, size: f32) Allocator.Error!*Font {
|
||||
return @as(
|
||||
?*Font,
|
||||
@ptrFromInt(@intFromPtr(c.CTFontCreateWithName(
|
||||
@ptrCast(name),
|
||||
size,
|
||||
null,
|
||||
))),
|
||||
) orelse Allocator.Error.OutOfMemory;
|
||||
}
|
||||
|
||||
pub fn createForString(
|
||||
self: *Font,
|
||||
str: *foundation.String,
|
||||
|
||||
@@ -340,6 +340,24 @@ fn collection(
|
||||
// specifying a font-family for emoji.
|
||||
if (comptime builtin.target.os.tag.isDarwin() and Discover != void) apple_emoji: {
|
||||
const disco = try self.discover() orelse break :apple_emoji;
|
||||
|
||||
// Fast path: we know the exact name of the font we want so we
|
||||
// can look it up directly, which is sometimes significantly faster than
|
||||
// full discovery (e.g. CoreText).
|
||||
if (@hasDecl(Discover, "discoverExactFamily")) {
|
||||
if (try disco.discoverExactFamily(
|
||||
"Apple Color Emoji",
|
||||
)) |face| {
|
||||
_ = try c.addDeferred(self.alloc, face, .{
|
||||
.style = .regular,
|
||||
.fallback = true,
|
||||
// No size adjustment for emojis.
|
||||
.size_adjustment = .none,
|
||||
});
|
||||
break :apple_emoji;
|
||||
}
|
||||
}
|
||||
|
||||
var disco_it = try disco.discover(self.alloc, .{
|
||||
.family = "Apple Color Emoji",
|
||||
});
|
||||
|
||||
@@ -383,6 +383,54 @@ pub const CoreText = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Discover a font by its exact name (family, full, or PostScript
|
||||
/// name). This is significantly faster than `discover` because it
|
||||
/// avoids the system-wide font matching that CTFontCollection does
|
||||
/// (which takes multiple milliseconds). This should be preferred
|
||||
/// when the desired font is known exactly, e.g. system fonts such
|
||||
/// as Apple Color Emoji.
|
||||
///
|
||||
/// Returns null if no font with this exact family name exists;
|
||||
/// CoreText fallback fonts are never returned.
|
||||
pub fn discoverExactFamily(
|
||||
self: *const CoreText,
|
||||
family: []const u8,
|
||||
) !?DeferredFace {
|
||||
_ = self;
|
||||
|
||||
const family_str = try macos.foundation.String.createWithBytes(
|
||||
family,
|
||||
.utf8,
|
||||
false,
|
||||
);
|
||||
defer family_str.release();
|
||||
|
||||
// Create our font. We need a size to initialize it so we use size
|
||||
// 12 but we will alter the size later (same as DiscoverIterator).
|
||||
const ct_font = try macos.text.Font.createWithName(family_str, 12);
|
||||
|
||||
// CTFontCreateWithName never returns null: if the requested font
|
||||
// isn't installed it returns a substitute font. Verify we got
|
||||
// the family we asked for, otherwise report not found.
|
||||
const found: bool = found: {
|
||||
const actual = ct_font.copyFamilyName();
|
||||
defer actual.release();
|
||||
var buf: [256]u8 = undefined;
|
||||
const actual_slice = actual.cstring(&buf, .utf8) orelse
|
||||
break :found false;
|
||||
break :found std.mem.eql(u8, actual_slice, family);
|
||||
};
|
||||
if (!found) {
|
||||
ct_font.release();
|
||||
return null;
|
||||
}
|
||||
|
||||
return .{ .ct = .{
|
||||
.font = ct_font,
|
||||
.variations = &.{},
|
||||
} };
|
||||
}
|
||||
|
||||
pub fn discoverFallback(
|
||||
self: *const CoreText,
|
||||
alloc: Allocator,
|
||||
|
||||
Reference in New Issue
Block a user