mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-07 02:16:34 +00:00
Merge pull request #811 from mitchellh/ct-score-style
font/coretext: discovery scoring should take into account symb. traits
This commit is contained in:
@@ -47,6 +47,10 @@ pub const Font = opaque {
|
||||
return @ptrCast(@constCast(c.CTFontCopyFontDescriptor(@ptrCast(self))));
|
||||
}
|
||||
|
||||
pub fn getGlyphCount(self: *Font) usize {
|
||||
return @intCast(c.CTFontGetGlyphCount(@ptrCast(self)));
|
||||
}
|
||||
|
||||
pub fn getGlyphsForCharacters(self: *Font, chars: []const u16, glyphs: []graphics.Glyph) bool {
|
||||
assert(chars.len == glyphs.len);
|
||||
return c.CTFontGetGlyphsForCharacters(
|
||||
|
@@ -397,10 +397,13 @@ pub const CoreText = struct {
|
||||
const Score = packed struct {
|
||||
const Backing = @typeInfo(@This()).Struct.backing_integer.?;
|
||||
|
||||
glyph_count: u16 = 0, // clamped if > intmax
|
||||
traits: Traits = .unmatched,
|
||||
style: Style = .unmatched,
|
||||
monospace: bool = false,
|
||||
codepoint: bool = false,
|
||||
|
||||
const Traits = enum(u8) { unmatched = 0, _ };
|
||||
const Style = enum(u8) { unmatched = 0, match = 0xFF, _ };
|
||||
|
||||
pub fn int(self: Score) Backing {
|
||||
@@ -411,12 +414,27 @@ pub const CoreText = struct {
|
||||
fn score(desc: *const Descriptor, ct_desc: *const macos.text.FontDescriptor) Score {
|
||||
var score_acc: Score = .{};
|
||||
|
||||
// We always load the font if we can since some things can only be
|
||||
// inspected on the font itself.
|
||||
const font_: ?*macos.text.Font = macos.text.Font.createWithFontDescriptor(
|
||||
ct_desc,
|
||||
12,
|
||||
) catch null;
|
||||
defer if (font_) |font| font.release();
|
||||
|
||||
// If we have a font, prefer the font with more glyphs.
|
||||
if (font_) |font| {
|
||||
const Type = @TypeOf(score_acc.glyph_count);
|
||||
score_acc.glyph_count = std.math.cast(
|
||||
Type,
|
||||
font.getGlyphCount(),
|
||||
) orelse std.math.maxInt(Type);
|
||||
}
|
||||
|
||||
// If we're searching for a codepoint, prioritize fonts that
|
||||
// have that codepoint.
|
||||
if (desc.codepoint > 0) codepoint: {
|
||||
const font = macos.text.Font.createWithFontDescriptor(ct_desc, 12) catch
|
||||
break :codepoint;
|
||||
defer font.release();
|
||||
const font = font_ orelse break :codepoint;
|
||||
|
||||
// Turn UTF-32 into UTF-16 for CT API
|
||||
var unichars: [2]u16 = undefined;
|
||||
@@ -446,9 +464,12 @@ pub const CoreText = struct {
|
||||
|
||||
score_acc.monospace = symbolic_traits.monospace;
|
||||
|
||||
score_acc.style = if (desc.style) |desired_style| style: {
|
||||
score_acc.style = style: {
|
||||
const style = ct_desc.copyAttribute(.style_name);
|
||||
defer style.release();
|
||||
|
||||
// If we have a specific desired style, attempt to search for that.
|
||||
if (desc.style) |desired_style| {
|
||||
var buf: [128]u8 = undefined;
|
||||
const style_str = style.cstring(&buf, .utf8) orelse break :style .unmatched;
|
||||
|
||||
@@ -458,7 +479,27 @@ pub const CoreText = struct {
|
||||
// Otherwise the score is based on the length of the style string.
|
||||
// Shorter styles are scored higher.
|
||||
break :style @enumFromInt(100 -| style_str.len);
|
||||
} else .unmatched;
|
||||
}
|
||||
|
||||
// If we do not, and we have no symbolic traits, then we try
|
||||
// to find "regular" (or no style). If we have symbolic traits
|
||||
// we do nothing but we can improve scoring by taking that into
|
||||
// account, too.
|
||||
if (!desc.bold and !desc.italic) {
|
||||
var buf: [128]u8 = undefined;
|
||||
const style_str = style.cstring(&buf, .utf8) orelse break :style .unmatched;
|
||||
if (std.mem.eql(u8, "Regular", style_str)) break :style .match;
|
||||
}
|
||||
|
||||
break :style .unmatched;
|
||||
};
|
||||
|
||||
score_acc.traits = traits: {
|
||||
var count: u8 = 0;
|
||||
if (desc.bold == symbolic_traits.bold) count += 1;
|
||||
if (desc.italic == symbolic_traits.italic) count += 1;
|
||||
break :traits @enumFromInt(count);
|
||||
};
|
||||
|
||||
return score_acc;
|
||||
}
|
||||
|
Reference in New Issue
Block a user