mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
Merge pull request #2501 from ghostty-org/push-zzksspuskpmx
font/coretext: use CTFontCreateForString for final codepoint fallback
This commit is contained in:
@ -160,6 +160,10 @@ pub const Font = opaque {
|
|||||||
return @ptrFromInt(@intFromPtr(c.CTFontCopyDisplayName(@ptrCast(self))));
|
return @ptrFromInt(@intFromPtr(c.CTFontCopyDisplayName(@ptrCast(self))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn copyPostScriptName(self: *Font) *foundation.String {
|
||||||
|
return @ptrFromInt(@intFromPtr(c.CTFontCopyPostScriptName(@ptrCast(self))));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn getSymbolicTraits(self: *Font) text.FontSymbolicTraits {
|
pub fn getSymbolicTraits(self: *Font) text.FontSymbolicTraits {
|
||||||
return @bitCast(c.CTFontGetSymbolicTraits(@ptrCast(self)));
|
return @bitCast(c.CTFontGetSymbolicTraits(@ptrCast(self)));
|
||||||
}
|
}
|
||||||
|
@ -424,7 +424,30 @@ pub const CoreText = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return try self.discover(alloc, desc);
|
const it = try self.discover(alloc, desc);
|
||||||
|
|
||||||
|
// If our normal discovery doesn't find anything and we have a specific
|
||||||
|
// codepoint, then fallback to using CTFontCreateForString to find a
|
||||||
|
// matching font CoreText wants to use. See:
|
||||||
|
// https://github.com/ghostty-org/ghostty/issues/2499
|
||||||
|
if (it.list.len == 0 and desc.codepoint > 0) codepoint: {
|
||||||
|
const ct_desc = try self.discoverCodepoint(
|
||||||
|
collection,
|
||||||
|
desc,
|
||||||
|
) orelse break :codepoint;
|
||||||
|
|
||||||
|
const list = try alloc.alloc(*macos.text.FontDescriptor, 1);
|
||||||
|
errdefer alloc.free(list);
|
||||||
|
list[0] = ct_desc;
|
||||||
|
|
||||||
|
return DiscoverIterator{
|
||||||
|
.alloc = alloc,
|
||||||
|
.list = list,
|
||||||
|
.i = 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Discover a font for a specific codepoint using the CoreText
|
/// Discover a font for a specific codepoint using the CoreText
|
||||||
@ -491,16 +514,45 @@ pub const CoreText = struct {
|
|||||||
);
|
);
|
||||||
defer str.release();
|
defer str.release();
|
||||||
|
|
||||||
|
// Get our range length for CTFontCreateForString. It looks like
|
||||||
|
// the range uses UTF-16 codepoints and not UTF-32 codepoints.
|
||||||
|
const range_len: usize = range_len: {
|
||||||
|
var unichars: [2]u16 = undefined;
|
||||||
|
const pair = macos.foundation.stringGetSurrogatePairForLongCharacter(
|
||||||
|
desc.codepoint,
|
||||||
|
&unichars,
|
||||||
|
);
|
||||||
|
break :range_len if (pair) 2 else 1;
|
||||||
|
};
|
||||||
|
|
||||||
// Get our font
|
// Get our font
|
||||||
const font = original.font.createForString(
|
const font = original.font.createForString(
|
||||||
str,
|
str,
|
||||||
macos.foundation.Range.init(0, 1),
|
macos.foundation.Range.init(0, range_len),
|
||||||
) orelse return null;
|
) orelse return null;
|
||||||
defer font.release();
|
defer font.release();
|
||||||
|
|
||||||
|
// Do not allow the last resort font to go through. This is the
|
||||||
|
// last font used by CoreText if it can't find anything else and
|
||||||
|
// only contains replacement characters.
|
||||||
|
last_resort: {
|
||||||
|
const name_str = font.copyPostScriptName();
|
||||||
|
defer name_str.release();
|
||||||
|
|
||||||
|
// If the name doesn't fit in our buffer, then it can't
|
||||||
|
// be the last resort font so we break out.
|
||||||
|
var name_buf: [64]u8 = undefined;
|
||||||
|
const name: []const u8 = name_str.cstring(&name_buf, .utf8) orelse
|
||||||
|
break :last_resort;
|
||||||
|
|
||||||
|
// If the name is "LastResort" then we don't want to use it.
|
||||||
|
if (std.mem.eql(u8, "LastResort", name)) return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the descriptor
|
// Get the descriptor
|
||||||
return font.copyDescriptor();
|
return font.copyDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copyMatchingDescriptors(
|
fn copyMatchingDescriptors(
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
list: *macos.foundation.Array,
|
list: *macos.foundation.Array,
|
||||||
|
Reference in New Issue
Block a user