diff --git a/src/gfx/font/native/Font.zig b/src/gfx/font/native/Font.zig index efe12582..994e7385 100644 --- a/src/gfx/font/native/Font.zig +++ b/src/gfx/font/native/Font.zig @@ -36,16 +36,18 @@ pub fn shape(f: *const Font, r: *TextRun) anyerror!void { // Guess text segment properties. r.buffer.guessSegmentProps(); // TODO: Optionally override specific text segment properties? - // buffer.setDirection(.ltr); - // buffer.setScript(.latin); - // buffer.setLanguage(harfbuzz.Language.fromString("en")); + // r.buffer.setDirection(.ltr); + // r.buffer.setScript(.latin); + // r.buffer.setLanguage(harfbuzz.Language.fromString("en")); + + const font_size_pt = r.font_size_px / px_per_pt; + const font_size_pt_frac: i32 = @intFromFloat(font_size_pt * 64.0); + f.face.setCharSize(font_size_pt_frac, font_size_pt_frac, 0, 0) catch return error.RenderError; const hb_face = harfbuzz.Face.fromFreetypeFace(f.face); const hb_font = harfbuzz.Font.init(hb_face); defer hb_font.deinit(); - const font_size_pt = r.font_size_px / px_per_pt; - const font_size_pt_frac: i32 = @intFromFloat(font_size_pt * 256.0); hb_font.setScale(font_size_pt_frac, font_size_pt_frac); hb_font.setPTEM(font_size_pt); @@ -55,14 +57,20 @@ pub fn shape(f: *const Font, r: *TextRun) anyerror!void { r.index = 0; r.infos = r.buffer.getGlyphInfos(); r.positions = r.buffer.getGlyphPositions() orelse return error.OutOfMemory; + + for (r.positions, r.infos) |*pos, info| { + const glyph_index = info.codepoint; + f.face.loadGlyph(glyph_index, .{ .render = false }) catch return error.RenderError; + const glyph = f.face.glyph(); + const metrics = glyph.metrics(); + pos.*.x_offset += @intCast(metrics.horiBearingX); + pos.*.y_offset += @intCast(metrics.horiBearingY); + // TODO: use vertBearingX / vertBearingY for vertical layouts + } } pub fn render(f: *Font, allocator: std.mem.Allocator, glyph_index: u32, opt: RenderOptions) anyerror!RenderedGlyph { - // TODO: DPI configuration - const dpi = 72; - const font_size_pt = opt.font_size_px / px_per_pt; - const font_size_pt_frac: i32 = @intFromFloat(font_size_pt * 64.0); - f.face.setCharSize(font_size_pt_frac, font_size_pt_frac, dpi, dpi) catch return error.RenderError; + _ = opt; f.face.loadGlyph(glyph_index, .{ .render = true }) catch return error.RenderError; const glyph = f.face.glyph(); diff --git a/src/gfx/font/native/TextRun.zig b/src/gfx/font/native/TextRun.zig index e624dec3..40a69dc5 100644 --- a/src/gfx/font/native/TextRun.zig +++ b/src/gfx/font/native/TextRun.zig @@ -14,7 +14,7 @@ px_density: u8 = 1, buffer: harfbuzz.Buffer, index: usize = 0, infos: []harfbuzz.GlyphInfo = undefined, -positions: []harfbuzz.Position = undefined, +positions: []harfbuzz.GlyphPosition = undefined, pub fn init() anyerror!TextRun { return TextRun{ @@ -37,8 +37,8 @@ pub fn next(s: *TextRun) ?Glyph { // .var1 = @intCast(info.var1), // .var2 = @intCast(info.var2), .cluster = info.cluster, - .advance = vec2(@floatFromInt(pos.x_advance), @floatFromInt(pos.y_advance)).div(&Vec2.splat(256.0)), - .offset = vec2(@floatFromInt(pos.x_offset), @floatFromInt(pos.y_offset)).div(&Vec2.splat(256.0)), + .advance = vec2(@floatFromInt(pos.x_advance), @floatFromInt(pos.y_advance)).div(&Vec2.splat(64.0)), + .offset = vec2(@floatFromInt(pos.x_offset), @floatFromInt(pos.y_offset)).div(&Vec2.splat(64.0)), }; }