mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
font: coretext cell width calculation
This commit is contained in:
@ -14,6 +14,9 @@ pub const Face = struct {
|
||||
/// The presentation for this font.
|
||||
presentation: font.Presentation,
|
||||
|
||||
/// Metrics for this font face. These are useful for renderers.
|
||||
metrics: font.face.Metrics,
|
||||
|
||||
/// Initialize a CoreText-based font from a TTF/TTC in memory.
|
||||
pub fn init(lib: font.Library, source: [:0]const u8, size: font.face.DesiredSize) !Face {
|
||||
_ = lib;
|
||||
@ -50,6 +53,7 @@ pub const Face = struct {
|
||||
.font = ct_font,
|
||||
.hb_font = hb_font,
|
||||
.presentation = if (traits.color_glyphs) .emoji else .text,
|
||||
.metrics = calcMetrics(ct_font),
|
||||
};
|
||||
}
|
||||
|
||||
@ -78,6 +82,45 @@ pub const Face = struct {
|
||||
|
||||
return @intCast(u32, glyphs[0]);
|
||||
}
|
||||
|
||||
fn calcMetrics(ct_font: *macos.text.Font) font.face.Metrics {
|
||||
// Cell width is calculated by calculating the widest width of the
|
||||
// visible ASCII characters. Usually 'M' is widest but we just take
|
||||
// whatever is widest.
|
||||
const cell_width: f32 = cell_width: {
|
||||
// Build a comptime array of all the ASCII chars
|
||||
const unichars = comptime unichars: {
|
||||
const len = 127 - 32;
|
||||
var result: [len]u16 = undefined;
|
||||
var i: u16 = 32;
|
||||
while (i < 127) : (i += 1) {
|
||||
result[i - 32] = i;
|
||||
}
|
||||
|
||||
break :unichars result;
|
||||
};
|
||||
|
||||
// Get our glyph IDs for the ASCII chars
|
||||
var glyphs: [unichars.len]macos.graphics.Glyph = undefined;
|
||||
_ = ct_font.getGlyphsForCharacters(&unichars, &glyphs);
|
||||
|
||||
// Get all our advances
|
||||
var advances: [unichars.len]macos.graphics.Size = undefined;
|
||||
_ = ct_font.getAdvancesForGlyphs(.horizontal, &glyphs, &advances);
|
||||
|
||||
// Find the maximum advance
|
||||
var max: f64 = 0;
|
||||
var i: usize = 0;
|
||||
while (i < advances.len) : (i += 1) {
|
||||
max = @maximum(advances[i].width, max);
|
||||
}
|
||||
|
||||
break :cell_width @floatCast(f32, max);
|
||||
};
|
||||
|
||||
std.log.warn("width={}", .{cell_width});
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
test {
|
||||
|
@ -389,6 +389,7 @@ test {
|
||||
|
||||
var ft_font = try Face.init(lib, testFont, .{ .points = 12 });
|
||||
defer ft_font.deinit();
|
||||
//log.warn("FT WIDTH={}", .{ft_font.metrics.cell_width});
|
||||
|
||||
try testing.expectEqual(Presentation.text, ft_font.presentation);
|
||||
|
||||
|
Reference in New Issue
Block a user