mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
coretext: exclude bitmap fonts from discovery (#3550)
We do not currently support bitmap fonts in a real capacity, and they often are missing some tables which we currently rely on for metrics, and we don't handle the metrics calculations failing gracefully right now. This needs to be fixed for the fontconfig discovery mechanism as well, so this does NOT close issue #2168 (it fixes the problem on macOS but not linux). This greatly alleviates the effect of #2991 since most cases I've seen that be a problem have been the accidental loading of a bitmap font; but the underlying issue still exists.
This commit is contained in:
@ -362,9 +362,16 @@ pub const CoreText = struct {
|
|||||||
const list = set.createMatchingFontDescriptors();
|
const list = set.createMatchingFontDescriptors();
|
||||||
defer list.release();
|
defer list.release();
|
||||||
|
|
||||||
// Sort our descriptors
|
// Bring the list of descriptors in to zig land
|
||||||
const zig_list = try copyMatchingDescriptors(alloc, list);
|
var zig_list = try copyMatchingDescriptors(alloc, list);
|
||||||
errdefer alloc.free(zig_list);
|
errdefer alloc.free(zig_list);
|
||||||
|
|
||||||
|
// Filter them. We don't use `CTFontCollectionSetExclusionDescriptors`
|
||||||
|
// to do this because that requires a mutable collection. This way is
|
||||||
|
// much more straight forward.
|
||||||
|
zig_list = try alloc.realloc(zig_list, filterDescriptors(zig_list));
|
||||||
|
|
||||||
|
// Sort our descriptors
|
||||||
sortMatchingDescriptors(&desc, zig_list);
|
sortMatchingDescriptors(&desc, zig_list);
|
||||||
|
|
||||||
return DiscoverIterator{
|
return DiscoverIterator{
|
||||||
@ -551,13 +558,47 @@ pub const CoreText = struct {
|
|||||||
for (0..result.len) |i| {
|
for (0..result.len) |i| {
|
||||||
result[i] = list.getValueAtIndex(macos.text.FontDescriptor, i);
|
result[i] = list.getValueAtIndex(macos.text.FontDescriptor, i);
|
||||||
|
|
||||||
// We need to retain becauseonce the list is freed it will
|
// We need to retain because once the list
|
||||||
// release all its members.
|
// is freed it will release all its members.
|
||||||
result[i].retain();
|
result[i].retain();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Filter any descriptors out of the list that aren't acceptable for
|
||||||
|
/// some reason or another (e.g. the font isn't in a format we can handle).
|
||||||
|
///
|
||||||
|
/// Invalid descriptors are filled in from the end of
|
||||||
|
/// the list and the new length for the list is returned.
|
||||||
|
fn filterDescriptors(list: []*macos.text.FontDescriptor) usize {
|
||||||
|
var end = list.len;
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < end) {
|
||||||
|
if (validDescriptor(list[i])) {
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
list[i].release();
|
||||||
|
end -= 1;
|
||||||
|
list[i] = list[end];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used by `filterDescriptors` to decide whether a descriptor is valid.
|
||||||
|
fn validDescriptor(desc: *macos.text.FontDescriptor) bool {
|
||||||
|
if (desc.copyAttribute(macos.text.FontAttribute.format)) |format| {
|
||||||
|
defer format.release();
|
||||||
|
var value: c_int = undefined;
|
||||||
|
assert(format.getValue(.int, &value));
|
||||||
|
|
||||||
|
// Bitmap fonts are not currently supported.
|
||||||
|
if (value == macos.text.c.kCTFontFormatBitmap) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
fn sortMatchingDescriptors(
|
fn sortMatchingDescriptors(
|
||||||
desc: *const Descriptor,
|
desc: *const Descriptor,
|
||||||
list: []*macos.text.FontDescriptor,
|
list: []*macos.text.FontDescriptor,
|
||||||
|
Reference in New Issue
Block a user