font: allow fractional pixel sizes

pull/7953/head
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, ydpi: u16 = default_dpi,
// Converts points to pixels // Converts points to pixels
pub fn pixels(self: DesiredSize) u16 { pub fn pixels(self: DesiredSize) f32 {
// 1 point = 1/72 inch // 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 // but we need to scale the points by the DPI and to do that we use our
// function called "pixels". // function called "pixels".
const ct_font = try base.copyWithAttributes( const ct_font = try base.copyWithAttributes(
@floatFromInt(opts.size.pixels()), opts.size.pixels(),
null, null,
null, null,
); );
@ -94,7 +94,8 @@ pub const Face = struct {
var hb_font = if (comptime harfbuzz_shaper) font: { var hb_font = if (comptime harfbuzz_shaper) font: {
var hb_font = try harfbuzz.coretext.createFont(ct_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; break :font hb_font;
} else {}; } else {};
errdefer if (comptime harfbuzz_shaper) hb_font.destroy(); errdefer if (comptime harfbuzz_shaper) hb_font.destroy();

View File

@ -217,7 +217,7 @@ pub const Face = struct {
if (face.isScalable()) { if (face.isScalable()) {
const size_26dot6: i32 = @intFromFloat(@round(size.points * 64)); const size_26dot6: i32 = @intFromFloat(@round(size.points * 64));
try face.setCharSize(0, size_26dot6, size.xdpi, size.ydpi); 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 /// 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, .glyph_index = info_v.codepoint,
}); });
if (font.options.backend.hasFreetype()) { // Under both FreeType and CoreText the harfbuzz scale is
// Freetype returns 26.6 fixed point values, so we need to // in 26.6 fixed point units, so we round to the nearest
// divide by 64 to get the actual value. I can't find any // whole value here.
// HB API to stop this. cell_offset.x += (pos_v.x_advance + 0b100_000) >> 6;
cell_offset.x += pos_v.x_advance >> 6; cell_offset.y += (pos_v.y_advance + 0b100_000) >> 6;
cell_offset.y += pos_v.y_advance >> 6;
} else {
cell_offset.x += pos_v.x_advance;
cell_offset.y += pos_v.y_advance;
}
// const i = self.cell_buf.items.len - 1; // const i = self.cell_buf.items.len - 1;
// log.warn("i={} info={} pos={} cell={}", .{ i, info_v, pos_v, self.cell_buf.items[i] }); // log.warn("i={} info={} pos={} cell={}", .{ i, info_v, pos_v, self.cell_buf.items[i] });