From 9b4e362a338d90d8c0563f516cfe9819b9a5c9f0 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 30 Apr 2024 10:07:02 -0700 Subject: [PATCH] font/coretext: shaping ligatures adds padding cells for replaced cells Fixes #1708 Harfbuzz does this automatically. Our tests for harfbuzz test this. We had a todo in CoreText to mimic this but wasn't sure if it was useful. Turns out, it is important (see bug!) --- src/font/res/GeistMono-Regular.ttf | Bin 0 -> 112160 bytes src/font/shaper/coretext.zig | 135 +++++++++++++++++++++++++---- src/font/test.zig | 1 + 3 files changed, 117 insertions(+), 19 deletions(-) create mode 100644 src/font/res/GeistMono-Regular.ttf diff --git a/src/font/res/GeistMono-Regular.ttf b/src/font/res/GeistMono-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a909c5d618162902debdbc09463d905c7c54cd61 GIT binary patch literal 112160 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 aaO$9>`obiGh9}g68fa+XGY78l`TqgAA$u_Z literal 0 HcmV?d00001 diff --git a/src/font/shaper/coretext.zig b/src/font/shaper/coretext.zig index 831062208..76d0cdb9a 100644 --- a/src/font/shaper/coretext.zig +++ b/src/font/shaper/coretext.zig @@ -325,9 +325,20 @@ pub const Shaper = struct { // Our cluster is also our cell X position. If the cluster changes // then we need to reset our current cell offsets. const cluster = state.codepoints.items[index].cluster; - if (cell_offset.cluster != cluster) cell_offset = .{ - .cluster = cluster, - }; + if (cell_offset.cluster != cluster) { + assert(cell_offset.cluster < cluster); + + // If we have a gap between clusters then we need to + // add empty cells to the buffer. + for (cell_offset.cluster + 1..cluster) |x| { + self.cell_buf.appendAssumeCapacity(.{ + .x = @intCast(x), + .glyph_index = null, + }); + } + + cell_offset = .{ .cluster = cluster }; + } self.cell_buf.appendAssumeCapacity(.{ .x = @intCast(cluster), @@ -341,10 +352,6 @@ pub const Shaper = struct { cell_offset.x += advance.width; cell_offset.y += advance.height; - // TODO: harfbuzz shaper has handling for inserting blank - // cells for multi-cell ligatures. Do we need to port that? - // Example: try Monaspace "===" with a background color. - _ = pos; // const i = self.cell_buf.items.len - 1; // log.warn( @@ -355,6 +362,25 @@ pub const Shaper = struct { //log.warn("-------------------------------", .{}); } + // If our last cell doesn't match our last cluster then we have + // a left-replaced ligature that needs to have spaces appended + // so that cells retain their background colors. + if (self.cell_buf.items.len > 0) pad: { + const last_cell = self.cell_buf.items[self.cell_buf.items.len - 1]; + const last_cp = state.codepoints.items[state.codepoints.items.len - 1]; + if (last_cell.x == last_cp.cluster) break :pad; + assert(last_cell.x < last_cp.cluster); + + // We need to go back to the last matched cluster and add + // padding up to there. + for (last_cell.x + 1..last_cp.cluster + 1) |x| { + self.cell_buf.appendAssumeCapacity(.{ + .x = @intCast(x), + .glyph_index = null, + }); + } + } + return self.cell_buf.items; } @@ -388,13 +414,10 @@ pub const Shaper = struct { // If the UTF-16 codepoint is a pair then we need to insert // a dummy entry so that the CTRunGetStringIndices() function // maps correctly. - if (pair) { - try state.codepoints.append(self.shaper.alloc, .{ - .codepoint = 0, - .cluster = cluster, - }); - log.warn("run pair cp=0", .{}); - } + if (pair) try state.codepoints.append(self.shaper.alloc, .{ + .codepoint = 0, + .cluster = cluster, + }); } pub fn finalize(self: RunIteratorHook) !void { @@ -620,8 +643,9 @@ test "shape inconsolata ligs" { count += 1; const cells = try shaper.shape(run); - try testing.expectEqual(@as(usize, 1), cells.len); + try testing.expectEqual(@as(usize, 2), cells.len); try testing.expect(cells[0].glyph_index != null); + try testing.expect(cells[1].glyph_index == null); } try testing.expectEqual(@as(usize, 1), count); } @@ -644,8 +668,10 @@ test "shape inconsolata ligs" { count += 1; const cells = try shaper.shape(run); - try testing.expectEqual(@as(usize, 1), cells.len); + try testing.expectEqual(@as(usize, 3), cells.len); try testing.expect(cells[0].glyph_index != null); + try testing.expect(cells[1].glyph_index == null); + try testing.expect(cells[2].glyph_index == null); } try testing.expectEqual(@as(usize, 1), count); } @@ -676,13 +702,82 @@ test "shape monaspace ligs" { count += 1; const cells = try shaper.shape(run); - try testing.expectEqual(@as(usize, 1), cells.len); + try testing.expectEqual(@as(usize, 3), cells.len); try testing.expect(cells[0].glyph_index != null); + try testing.expect(cells[1].glyph_index == null); + try testing.expect(cells[2].glyph_index == null); } try testing.expectEqual(@as(usize, 1), count); } } +// https://github.com/mitchellh/ghostty/issues/1708 +test "shape left-replaced lig in last run" { + const testing = std.testing; + const alloc = testing.allocator; + + var testdata = try testShaperWithFont(alloc, .geist_mono); + defer testdata.deinit(); + + { + var screen = try terminal.Screen.init(alloc, 5, 3, 0); + defer screen.deinit(); + try screen.testWriteString("!=="); + + var shaper = &testdata.shaper; + var it = shaper.runIterator( + testdata.grid, + &screen, + screen.pages.pin(.{ .screen = .{ .y = 0 } }).?, + null, + null, + ); + var count: usize = 0; + while (try it.next(alloc)) |run| { + count += 1; + + const cells = try shaper.shape(run); + try testing.expectEqual(@as(usize, 3), cells.len); + try testing.expect(cells[0].glyph_index != null); + try testing.expect(cells[1].glyph_index == null); + try testing.expect(cells[2].glyph_index == null); + } + try testing.expectEqual(@as(usize, 1), count); + } +} + +// https://github.com/mitchellh/ghostty/issues/1708 +test "shape left-replaced lig in early run" { + const testing = std.testing; + const alloc = testing.allocator; + + var testdata = try testShaperWithFont(alloc, .geist_mono); + defer testdata.deinit(); + + { + var screen = try terminal.Screen.init(alloc, 5, 3, 0); + defer screen.deinit(); + try screen.testWriteString("!==X"); + + var shaper = &testdata.shaper; + var it = shaper.runIterator( + testdata.grid, + &screen, + screen.pages.pin(.{ .screen = .{ .y = 0 } }).?, + null, + null, + ); + + const run = (try it.next(alloc)).?; + const cells = try shaper.shape(run); + try testing.expectEqual(@as(usize, 4), cells.len); + try testing.expect(cells[0].glyph_index != null); + try testing.expect(cells[1].glyph_index == null); + try testing.expect(cells[2].glyph_index == null); + try testing.expect(cells[3].glyph_index != null); + } +} + // https://github.com/mitchellh/ghostty/issues/1664 test "shape U+3C9 with JB Mono" { const testing = std.testing; @@ -782,8 +877,8 @@ test "shape emoji width long" { count += 1; const cells = try shaper.shape(run); - // screen.testWriteString isn't grapheme aware, otherwise this is two - try testing.expectEqual(@as(usize, 1), cells.len); + // screen.testWriteString isn't grapheme aware, otherwise this is one + try testing.expectEqual(@as(usize, 5), cells.len); } try testing.expectEqual(@as(usize, 1), count); } @@ -1401,6 +1496,7 @@ const TestShaper = struct { const TestFont = enum { inconsolata, + geist_mono, jetbrains_mono, monaspace_neon, nerd_font, @@ -1416,6 +1512,7 @@ fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper { const testEmojiText = @import("../test.zig").fontEmojiText; const testFont = switch (font_req) { .inconsolata => @import("../test.zig").fontRegular, + .geist_mono => @import("../test.zig").fontGeistMono, .jetbrains_mono => @import("../test.zig").fontJetBrainsMono, .monaspace_neon => @import("../test.zig").fontMonaspaceNeon, .nerd_font => @import("../test.zig").fontNerdFont, diff --git a/src/font/test.zig b/src/font/test.zig index 499a75158..253d067b4 100644 --- a/src/font/test.zig +++ b/src/font/test.zig @@ -16,6 +16,7 @@ pub const fontVariable = @embedFile("res/Lilex-VF.ttf"); pub const fontNerdFont = @embedFile("res/JetBrainsMonoNerdFont-Regular.ttf"); /// Specific font families below: +pub const fontGeistMono = @embedFile("res/GeistMono-Regular.ttf"); pub const fontJetBrainsMono = @embedFile("res/JetBrainsMonoNoNF-Regular.ttf"); /// Cozette is a unique font because it embeds some emoji characters