more accurately compute font metrics

This commit is contained in:
Mitchell Hashimoto
2022-10-06 11:07:49 -07:00
parent 3d4aacd51d
commit 3b549e0709

View File

@ -328,28 +328,28 @@ fn calcMetrics(face: freetype.Face) Metrics {
// underline should go.
const underline_position = underline_pos: {
// We use the declared underline position if its available
const declared = freetype.mulFix(
@intCast(i32, size_metrics.descender) + face.handle.*.underline_position,
@intCast(i32, size_metrics.x_scale),
) >> 6;
const declared = fontUnitsToPxY(
face,
@intCast(i32, size_metrics.ascender) - face.handle.*.underline_position,
);
if (declared > 0)
break :underline_pos @intToFloat(f32, declared);
break :underline_pos declared;
// If we have no declared underline position, we go slightly under the
// cell height (mainly: non-scalable fonts, i.e. emoji)
break :underline_pos cell_height - 1;
};
const underline_thickness = @intToFloat(f32, @maximum(1, freetype.mulFix(
const underline_thickness = @maximum(1, fontUnitsToPxY(
face,
face.handle.*.underline_thickness,
@intCast(i32, size_metrics.x_scale),
) >> 6));
));
// log.warn("METRICS={} width={} height={} baseline={} underline_pos={} underline_thickness={}", .{
// log.warn("METRICS={} width={d} height={d} baseline={d} underline_pos={d} underline_thickness={d}", .{
// size_metrics,
// cell_width,
// cell_height,
// cell_baseline,
// cell_height - underline_position,
// cell_height - cell_baseline,
// underline_position,
// underline_thickness,
// });
@ -362,6 +362,13 @@ fn calcMetrics(face: freetype.Face) Metrics {
};
}
/// Convert freetype "font units" to pixels using the Y scale.
fn fontUnitsToPxY(face: freetype.Face, x: i32) f32 {
const mul = freetype.mulFix(x, @intCast(i32, face.handle.*.size.*.metrics.y_scale));
const div = @intToFloat(f32, mul) / 64;
return @ceil(div);
}
test {
const testFont = @import("test.zig").fontRegular;
const alloc = testing.allocator;