mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-24 12:46:10 +03:00
Merge pull request #670 from mitchellh/font-fallbakc
font: fallback search should search full discovery chain
This commit is contained in:
@ -7,7 +7,7 @@ const text = @import("../text.zig");
|
||||
const c = @import("c.zig");
|
||||
|
||||
pub const Font = opaque {
|
||||
pub fn createWithFontDescriptor(desc: *text.FontDescriptor, size: f32) Allocator.Error!*Font {
|
||||
pub fn createWithFontDescriptor(desc: *const text.FontDescriptor, size: f32) Allocator.Error!*Font {
|
||||
return @as(
|
||||
?*Font,
|
||||
@ptrFromInt(@intFromPtr(c.CTFontCreateWithFontDescriptor(
|
||||
|
@ -327,6 +327,7 @@ pub fn indexForCodepoint(
|
||||
|
||||
// If we are regular, try looking for a fallback using discovery.
|
||||
if (style == .regular and font.Discover != void) {
|
||||
log.debug("searching for a fallback font for cp={x}", .{cp});
|
||||
if (self.discover) |disco| discover: {
|
||||
var disco_it = disco.discover(self.alloc, .{
|
||||
.codepoint = cp,
|
||||
@ -337,19 +338,27 @@ pub fn indexForCodepoint(
|
||||
}) catch break :discover;
|
||||
defer disco_it.deinit();
|
||||
|
||||
if (disco_it.next() catch break :discover) |face| {
|
||||
while (true) {
|
||||
const face_ = disco_it.next() catch |err| {
|
||||
log.warn("fallback search failed with error err={}", .{err});
|
||||
break;
|
||||
};
|
||||
const face = face_ orelse break;
|
||||
|
||||
// Discovery is supposed to only return faces that have our
|
||||
// codepoint but we can't search presentation in discovery so
|
||||
// we have to check it here.
|
||||
if (face.hasCodepoint(cp, p)) {
|
||||
var buf: [256]u8 = undefined;
|
||||
log.info("found codepoint 0x{x} in fallback face={s}", .{
|
||||
cp,
|
||||
face.name(&buf) catch "<error>",
|
||||
});
|
||||
return self.addFace(style, .{ .deferred = face }) catch break :discover;
|
||||
}
|
||||
if (!face.hasCodepoint(cp, p)) continue;
|
||||
|
||||
var buf: [256]u8 = undefined;
|
||||
log.info("found codepoint 0x{x} in fallback face={s}", .{
|
||||
cp,
|
||||
face.name(&buf) catch "<error>",
|
||||
});
|
||||
return self.addFace(style, .{ .deferred = face }) catch break :discover;
|
||||
}
|
||||
|
||||
log.debug("no fallback face found for cp={x}", .{cp});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,6 +399,7 @@ pub const CoreText = struct {
|
||||
|
||||
style: Style = .unmatched,
|
||||
monospace: bool = false,
|
||||
codepoint: bool = false,
|
||||
|
||||
const Style = enum(u8) { unmatched = 0, match = 0xFF, _ };
|
||||
|
||||
@ -410,6 +411,26 @@ pub const CoreText = struct {
|
||||
fn score(desc: *const Descriptor, ct_desc: *const macos.text.FontDescriptor) Score {
|
||||
var score_acc: Score = .{};
|
||||
|
||||
// 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();
|
||||
|
||||
// Turn UTF-32 into UTF-16 for CT API
|
||||
var unichars: [2]u16 = undefined;
|
||||
const pair = macos.foundation.stringGetSurrogatePairForLongCharacter(
|
||||
desc.codepoint,
|
||||
&unichars,
|
||||
);
|
||||
const len: usize = if (pair) 2 else 1;
|
||||
|
||||
// Get our glyphs
|
||||
var glyphs = [2]macos.graphics.Glyph{ 0, 0 };
|
||||
score_acc.codepoint = font.getGlyphsForCharacters(unichars[0..len], glyphs[0..len]);
|
||||
}
|
||||
|
||||
// Get our symbolic traits for the descriptor so we can compare
|
||||
// boolean attributes like bold, monospace, etc.
|
||||
const symbolic_traits: macos.text.FontSymbolicTraits = traits: {
|
||||
|
Reference in New Issue
Block a user