font: allow fractional pixel sizes

This commit is contained in:
Qwerasd
2025-07-25 11:22:25 -06:00
parent c0ee4a252a
commit 9405522dd5
4 changed files with 11 additions and 15 deletions

View File

@ -51,9 +51,9 @@ pub const DesiredSize = struct {
ydpi: u16 = default_dpi,
// Converts points to pixels
pub fn pixels(self: DesiredSize) u16 {
pub fn pixels(self: DesiredSize) f32 {
// 1 point = 1/72 inch
return @intFromFloat(@round((self.points * @as(f32, @floatFromInt(self.ydpi))) / 72));
return (self.points * @as(f32, @floatFromInt(self.ydpi))) / 72;
}
};

View File

@ -78,7 +78,7 @@ pub const Face = struct {
// but we need to scale the points by the DPI and to do that we use our
// function called "pixels".
const ct_font = try base.copyWithAttributes(
@floatFromInt(opts.size.pixels()),
opts.size.pixels(),
null,
null,
);
@ -94,7 +94,8 @@ pub const Face = struct {
var hb_font = if (comptime harfbuzz_shaper) font: {
var hb_font = try harfbuzz.coretext.createFont(ct_font);
hb_font.setScale(opts.size.pixels(), opts.size.pixels());
const pixels: opentype.sfnt.F26Dot6 = .from(opts.size.pixels());
hb_font.setScale(@bitCast(pixels), @bitCast(pixels));
break :font hb_font;
} else {};
errdefer if (comptime harfbuzz_shaper) hb_font.destroy();

View File

@ -217,7 +217,7 @@ pub const Face = struct {
if (face.isScalable()) {
const size_26dot6: i32 = @intFromFloat(@round(size.points * 64));
try face.setCharSize(0, size_26dot6, size.xdpi, size.ydpi);
} else try selectSizeNearest(face, size.pixels());
} else try selectSizeNearest(face, @intFromFloat(@round(size.pixels())));
}
/// Selects the fixed size in the loaded face that is closest to the

View File

@ -158,16 +158,11 @@ pub const Shaper = struct {
.glyph_index = info_v.codepoint,
});
if (font.options.backend.hasFreetype()) {
// Freetype returns 26.6 fixed point values, so we need to
// divide by 64 to get the actual value. I can't find any
// HB API to stop this.
cell_offset.x += pos_v.x_advance >> 6;
cell_offset.y += pos_v.y_advance >> 6;
} else {
cell_offset.x += pos_v.x_advance;
cell_offset.y += pos_v.y_advance;
}
// Under both FreeType and CoreText the harfbuzz scale is
// in 26.6 fixed point units, so we round to the nearest
// whole value here.
cell_offset.x += (pos_v.x_advance + 0b100_000) >> 6;
cell_offset.y += (pos_v.y_advance + 0b100_000) >> 6;
// const i = self.cell_buf.items.len - 1;
// log.warn("i={} info={} pos={} cell={}", .{ i, info_v, pos_v, self.cell_buf.items[i] });