430800c8
Improve glyph positioning
a73x 2026-04-08 11:58
diff --git a/src/font.zig b/src/font.zig index ed0f60d..6be6a1f 100644 --- a/src/font.zig +++ b/src/font.zig @@ -138,6 +138,11 @@ pub const Face = struct { const metrics = self.face.*.size.*.metrics; return @intCast((metrics.ascender - metrics.descender) >> 6); } pub fn baseline(self: *Face) u32 { const metrics = self.face.*.size.*.metrics; return @intCast(metrics.ascender >> 6); } }; pub const GlyphUV = struct { diff --git a/src/main.zig b/src/main.zig index 591cb85..1060bb3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -56,6 +56,7 @@ fn runTerminal(alloc: std.mem.Allocator) !void { const cell_w = face.cellWidth(); const cell_h = face.cellHeight(); const baseline = face.baseline(); // === grid size === const initial_grid: GridSize = .{ .cols = 80, .rows = 24 }; @@ -218,6 +219,7 @@ fn runTerminal(alloc: std.mem.Allocator) !void { col_idx, cell_w, cell_h, baseline, glyph_uv, bg_uv, colors, @@ -286,6 +288,7 @@ fn appendCellInstances( col_idx: u32, cell_w: u32, cell_h: u32, baseline: u32, glyph_uv: ?font.GlyphUV, bg_uv: font.GlyphUV, colors: vt.CellColors, @@ -308,7 +311,7 @@ fn appendCellInstances( .glyph_size = .{ @floatFromInt(uv.width), @floatFromInt(uv.height) }, .glyph_bearing = .{ @floatFromInt(uv.bearing_x), @as(f32, @floatFromInt(cell_h)) - @as(f32, @floatFromInt(uv.bearing_y)), glyphTopOffset(baseline, uv.bearing_y), }, .uv_rect = .{ uv.u0, uv.v0, uv.u1, uv.v1 }, .fg = colors.fg, @@ -316,6 +319,10 @@ fn appendCellInstances( }); } fn glyphTopOffset(baseline: u32, bearing_y: i32) f32 { return @as(f32, @floatFromInt(baseline)) - @as(f32, @floatFromInt(bearing_y)); } fn encodeKeyboardEvent( term: *const vt.Terminal, ev: wayland_client.KeyboardEvent, @@ -416,6 +423,7 @@ fn runDrawSmokeTest(alloc: std.mem.Allocator) !void { // Cell size from font metrics const cell_w: f32 = @floatFromInt(face.cellWidth()); const cell_h: f32 = @floatFromInt(face.cellHeight()); const baseline = face.baseline(); std.debug.print("cell size: {d}x{d}\n", .{ cell_w, cell_h }); // One Instance: 'M' at cell position (40, 12) — near center of 80x24 grid @@ -425,7 +433,7 @@ fn runDrawSmokeTest(alloc: std.mem.Allocator) !void { .glyph_size = .{ @floatFromInt(glyph_uv.width), @floatFromInt(glyph_uv.height) }, .glyph_bearing = .{ @floatFromInt(glyph_uv.bearing_x), @as(f32, @floatFromInt(face.cellHeight())) - @as(f32, @floatFromInt(glyph_uv.bearing_y)), glyphTopOffset(baseline, glyph_uv.bearing_y), }, .uv_rect = .{ glyph_uv.u0, glyph_uv.v0, glyph_uv.u1, glyph_uv.v1 }, .fg = .{ 1.0, 1.0, 1.0, 1.0 }, @@ -503,6 +511,7 @@ test "appendCellInstances emits a background quad for colored space" { 3, 8, 16, 12, null, bg_uv, .{ @@ -552,6 +561,7 @@ test "appendCellInstances emits background before glyph" { 1, 8, 16, 12, glyph_uv, bg_uv, .{ @@ -566,6 +576,11 @@ test "appendCellInstances emits background before glyph" { try std.testing.expectEqualDeep([2]f32{ 7.0, 11.0 }, instances.items[1].glyph_size); try std.testing.expectEqualDeep([4]f32{ 0.1, 0.2, 0.3, 1.0 }, instances.items[0].fg); try std.testing.expectEqualDeep([4]f32{ 0.9, 0.8, 0.7, 1.0 }, instances.items[1].fg); try std.testing.expectEqualDeep([2]f32{ 1.0, -1.0 }, instances.items[1].glyph_bearing); } test "glyphTopOffset uses baseline rather than cell height" { try std.testing.expectEqual(@as(f32, -3.0), glyphTopOffset(9, 12)); } fn runRenderSmokeTest(alloc: std.mem.Allocator) !void {