Merge pull request #2605 from ghostty-org/push-zymoylrqolxx

coretext: set variations on deferred face load
This commit is contained in:
Mitchell Hashimoto
2024-11-05 16:23:56 -08:00
committed by GitHub
3 changed files with 22 additions and 40 deletions

View File

@ -57,6 +57,11 @@ pub const CoreText = struct {
/// The initialized font
font: *macos.text.Font,
/// Variations to apply to this font. We apply the variations to the
/// search descriptor but sometimes when the font collection is
/// made the variation axes are reset so we have to reapply them.
variations: []const font.face.Variation,
pub fn deinit(self: *CoreText) void {
self.font.release();
self.* = undefined;
@ -194,7 +199,10 @@ fn loadCoreText(
) !Face {
_ = lib;
const ct = self.ct.?;
return try Face.initFontCopy(ct.font, opts);
var face = try Face.initFontCopy(ct.font, opts);
errdefer face.deinit();
try face.setVariations(ct.variations, opts);
return face;
}
fn loadCoreTextFreetype(
@ -236,43 +244,7 @@ fn loadCoreTextFreetype(
//std.log.warn("path={s}", .{path_slice});
var face = try Face.initFile(lib, buf[0..path_slice.len :0], 0, opts);
errdefer face.deinit();
// If our ct font has variations, apply them to the face.
if (ct.font.copyAttribute(.variation)) |variations| vars: {
defer variations.release();
if (variations.getCount() == 0) break :vars;
// This configuration is just used for testing so we don't want to
// have to pass a full allocator through so use the stack. We
// shouldn't have a lot of variations and if we do we should use
// another mechanism.
//
// On macOS the default stack size for a thread is 512KB and the main
// thread gets megabytes so 16KB is a safe stack allocation.
var data: [1024 * 16]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&data);
const alloc = fba.allocator();
var face_vars = std.ArrayList(font.face.Variation).init(alloc);
const kav = try variations.getKeysAndValues(alloc);
for (kav.keys, kav.values) |key, value| {
const num: *const macos.foundation.Number = @ptrCast(key.?);
const val: *const macos.foundation.Number = @ptrCast(value.?);
var num_i32: i32 = undefined;
if (!num.getValue(.sint32, &num_i32)) continue;
var val_f64: f64 = undefined;
if (!val.getValue(.float64, &val_f64)) continue;
try face_vars.append(.{
.id = @bitCast(num_i32),
.value = val_f64,
});
}
try face.setVariations(face_vars.items, opts);
}
try face.setVariations(ct.variations, opts);
return face;
}

View File

@ -79,7 +79,7 @@ pub const Descriptor = struct {
// This is not correct, but we don't currently depend on the
// hash value being different based on decimal values of variations.
autoHash(hasher, @as(u64, @intFromFloat(variation.value)));
autoHash(hasher, @as(i64, @intFromFloat(variation.value)));
}
}
@ -384,6 +384,7 @@ pub const CoreText = struct {
return DiscoverIterator{
.alloc = alloc,
.list = zig_list,
.variations = desc.variations,
.i = 0,
};
}
@ -420,6 +421,7 @@ pub const CoreText = struct {
return DiscoverIterator{
.alloc = alloc,
.list = list,
.variations = desc.variations,
.i = 0,
};
}
@ -443,6 +445,7 @@ pub const CoreText = struct {
return DiscoverIterator{
.alloc = alloc,
.list = list,
.variations = desc.variations,
.i = 0,
};
}
@ -721,6 +724,7 @@ pub const CoreText = struct {
pub const DiscoverIterator = struct {
alloc: Allocator,
list: []const *macos.text.FontDescriptor,
variations: []const Variation,
i: usize,
pub fn deinit(self: *DiscoverIterator) void {
@ -756,7 +760,10 @@ pub const CoreText = struct {
defer self.i += 1;
return DeferredFace{
.ct = .{ .font = font },
.ct = .{
.font = font,
.variations = self.variations,
},
};
}
};

View File

@ -229,6 +229,9 @@ pub const Face = struct {
vs: []const font.face.Variation,
opts: font.face.Options,
) !void {
// If we have no variations, we don't need to do anything.
if (vs.len == 0) return;
// Create a new font descriptor with all the variations set.
var desc = self.font.copyDescriptor();
defer desc.release();