coretext: improve strikethrough position calculation

This commit is contained in:
Qwerasd
2024-09-23 19:01:15 -06:00
parent ecb3c543b3
commit 3ec36e4d23
2 changed files with 20 additions and 8 deletions

View File

@ -188,6 +188,14 @@ pub const Font = opaque {
return c.CTFontGetUnderlineThickness(@ptrCast(self)); return c.CTFontGetUnderlineThickness(@ptrCast(self));
} }
pub fn getCapHeight(self: *Font) f64 {
return c.CTFontGetCapHeight(@ptrCast(self));
}
pub fn getXHeight(self: *Font) f64 {
return c.CTFontGetXHeight(@ptrCast(self));
}
pub fn getUnitsPerEm(self: *Font) u32 { pub fn getUnitsPerEm(self: *Font) u32 {
return c.CTFontGetUnitsPerEm(@ptrCast(self)); return c.CTFontGetUnitsPerEm(@ptrCast(self));
} }

View File

@ -596,15 +596,19 @@ pub const Face = struct {
const cell_baseline = @ceil(layout_metrics.height - layout_metrics.ascent); const cell_baseline = @ceil(layout_metrics.height - layout_metrics.ascent);
const underline_thickness = @ceil(@as(f32, @floatCast(ct_font.getUnderlineThickness()))); const underline_thickness = @ceil(@as(f32, @floatCast(ct_font.getUnderlineThickness())));
const strikethrough_position = strikethrough_position: { const strikethrough_position = strikethrough_position: {
// This is the height above baseline consumed by text. We must take // This is the height of lower case letters in our font.
// into account that our cell height splits the leading between two const ex_height = ct_font.getXHeight();
// rows so we subtract leading space (blank space).
const above_baseline = layout_metrics.ascent - (layout_metrics.leading / 2);
// We want to position the strikethrough at 65% of the height. // We want to position the strikethrough so that it's
// This generally gives a nice visual appearance. The number 65% // vertically centered on any lower case text. This is
// is somewhat arbitrary but is a common value across terminals. // a fairly standard choice for strikethrough positioning.
const pos = above_baseline * 0.65; //
// Because our `strikethrough_position` is relative to the
// top of the cell we start with the ascent metric, which
// is the distance from the top down to the baseline, then
// we subtract half of the ex height to go back up to the
// correct height that should evenly split lowercase text.
const pos = layout_metrics.ascent - ex_height * 0.5 + 1;
break :strikethrough_position @ceil(pos); break :strikethrough_position @ceil(pos);
}; };