diff --git a/assets/fonts/EBGaramond-Regular.ttf b/assets/fonts/EBGaramond-Regular.ttf new file mode 100644 index 0000000..6fe494a --- /dev/null +++ b/assets/fonts/EBGaramond-Regular.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5baed6e48bf4c99a770e6edc86ddaf67942bb1850491ed54f94d5c2c213531e +size 489640 diff --git a/assets/fonts/FiraGO-Regular.ttf b/assets/fonts/FiraGO-Regular.ttf new file mode 100644 index 0000000..e8a5496 --- /dev/null +++ b/assets/fonts/FiraGO-Regular.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:495901c0c608ea265f4c31aa2a4c7a313e5cc2a3dd610da78a447fe8e07454a2 +size 804888 diff --git a/castle b/castle index af8d725..af5f035 160000 --- a/castle +++ b/castle @@ -1 +1 @@ -Subproject commit af8d725e0c0b16f89f569fcb0d42b238f94736d5 +Subproject commit af5f035830394d083fab9c6da4445e048bbc7808 diff --git a/src/Game.zig b/src/Game.zig index 91f3061..81ced9f 100644 --- a/src/Game.zig +++ b/src/Game.zig @@ -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 diff --git a/src/engine/Font.zig b/src/engine/Font.zig index 3533da5..bffe552 100644 --- a/src/engine/Font.zig +++ b/src/engine/Font.zig @@ -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, diff --git a/src/engine/Gui.zig b/src/engine/Gui.zig index 3837243..6d6dac1 100644 --- a/src/engine/Gui.zig +++ b/src/engine/Gui.zig @@ -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| {