Read kerning table (untested cause there ain't one)

This commit is contained in:
2026-09-20 15:43:30 +02:00
parent 183e825827
commit ff72311979
6 changed files with 34 additions and 6 deletions

BIN
assets/fonts/EBGaramond-Regular.ttf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/fonts/FiraGO-Regular.ttf (Stored with Git LFS) Normal file

Binary file not shown.

2
castle

Submodule castle updated: af8d725e0c...af5f035830

View File

@@ -449,7 +449,7 @@ pub fn init() !Game {
.codepoint_ranges = &.{
.{ .start = 32, .end = 127 },
},
.name = "EB Garamond Regular",
.name = "Fira Mono",
});
// VOLATILE Load all assets before this point

View File

@@ -197,6 +197,9 @@ pub fn init(ttf_buffer: []const u8, init_info: InitInfo) !Font {
errdefer codepoint_glyph_id.deinit(allocator_general);
try codepoint_glyph_id.ensureTotalCapacity(allocator_general, glyph_count);
var external_glyph_id_to_cpu_glyph_id: std.hash_map.AutoHashMapUnmanaged(u16, u16) = .empty;
try external_glyph_id_to_cpu_glyph_id.ensureTotalCapacity(allocator_frame, glyph_count);
var kerning_em: std.hash_map.AutoHashMapUnmanaged([2]u16, f32) = .empty;
errdefer kerning_em.deinit(allocator_general);
@@ -227,8 +230,15 @@ pub fn init(ttf_buffer: []const u8, init_info: InitInfo) !Font {
while (codepoint < range.end) : (codepoint += 1) {
// std.debug.print("Processing codepoint 0x{X} '{u}'\n", .{ codepoint, codepoint });
if (ttf_font.findGlyphIndex(codepoint)) |external_glyph_id| {
const cpu_glyph_id = @as(u16, @intCast(cpu_glyph_data.items.len));
codepoint_glyph_id.putAssumeCapacityNoClobber(codepoint, cpu_glyph_id);
const external_glyph_id_to_cpu_glyph_id_get_or_put_result = external_glyph_id_to_cpu_glyph_id.getOrPutAssumeCapacity(external_glyph_id);
if (external_glyph_id_to_cpu_glyph_id_get_or_put_result.found_existing) {
codepoint_glyph_id.putAssumeCapacityNoClobber(codepoint, external_glyph_id_to_cpu_glyph_id_get_or_put_result.value_ptr.*);
continue;
} else {
const cpu_glyph_id = @as(u16, @intCast(cpu_glyph_data.items.len));
external_glyph_id_to_cpu_glyph_id_get_or_put_result.value_ptr.* = cpu_glyph_id;
codepoint_glyph_id.putAssumeCapacityNoClobber(codepoint, cpu_glyph_id);
}
const glyph_metrics = ttf_font.getGlyphMetrics(external_glyph_id);
// std.debug.print(" Advance: {d} U\n", .{glyph_metrics.advance_width});
@@ -374,6 +384,16 @@ pub fn init(ttf_buffer: []const u8, init_info: InitInfo) !Font {
}
}
var kerning_it = ttf_font.kerningTableIterator();
while (kerning_it.next()) |entry| {
if (external_glyph_id_to_cpu_glyph_id.contains(entry.glyph_prev) and external_glyph_id_to_cpu_glyph_id.contains(entry.glyph_next)) {
const advance_em = @as(f32, @floatFromInt(entry.advance)) * em_per_unit;
try kerning_em.put(allocator_general, .{ entry.glyph_prev, entry.glyph_next }, advance_em);
}
}
// std.debug.print("Kerning table size: {d}\n", .{kerning_em.size});
var glyph_data: GenericBuffer(void, shaders.GlyphData) = try .init(.{
.usage = .storage,
.target_queue = .graphics,

View File

@@ -605,11 +605,13 @@ pub fn printLine(self: *Gui, comptime fmt: []const u8, fmt_args: anytype, print_
var cursor_offset_em = glyph_data.bottom_left_em;
cursor_offset_em.y = -cursor_offset_em.y;
cursor_offset_em.x += glyph_data.left_side_bearing_em;
if (maybe_prev_glyph == null) {
cursor_offset_em.x += glyph_data.left_side_bearing_em;
}
if (maybe_prev_glyph) |prev_glyph| {
const kerning_em = font.kerning_em.get(.{ prev_glyph, glyph_id }) orelse 0;
cursor_offset_em.x += kerning_em;
cursor_sspx.x += kerning_em;
}
if (glyph_data.gpu_glyph_id) |gpu_glyph_id| {