mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 16:26:08 +03:00
handle graphemes with more than 1 joiner
This commit is contained in:
@ -1497,6 +1497,7 @@ pub fn testWriteString(self: *Screen, text: []const u8) !void {
|
||||
// Get our row
|
||||
var row = self.getRow(.{ .active = y });
|
||||
|
||||
// If we have a previous cell, we check if we're part of a grapheme.
|
||||
if (grapheme.cell) |prev_cell| {
|
||||
const grapheme_break = brk: {
|
||||
var state: i32 = 0;
|
||||
|
@ -474,22 +474,21 @@ pub fn print(self: *Terminal, c: u21) !void {
|
||||
};
|
||||
};
|
||||
|
||||
var state: i32 = 0;
|
||||
const grapheme_break = if (!prev.cell.attrs.grapheme)
|
||||
utf8proc.graphemeBreakStateful(@intCast(u21, prev.cell.char), c, &state)
|
||||
else brk: {
|
||||
// We need to rebuild the state by processing the grapheme breaks
|
||||
// for all the codepoints up to this point. This MUST exist because
|
||||
// grapheme is only true iff this exists.
|
||||
const points = self.screen.graphemes.getEntry(row.getId() + prev.x + 1).?;
|
||||
const cp1 = switch (points.value_ptr.*) {
|
||||
.one => |v| one: {
|
||||
assert(!utf8proc.graphemeBreakStateful(@intCast(u21, prev.cell.char), v, &state));
|
||||
break :one v;
|
||||
},
|
||||
const grapheme_break = brk: {
|
||||
var state: i32 = 0;
|
||||
var cp1 = @intCast(u21, prev.cell.char);
|
||||
if (prev.cell.attrs.grapheme) {
|
||||
var it = row.codepointIterator(prev.x);
|
||||
while (it.next()) |cp2| {
|
||||
assert(!utf8proc.graphemeBreakStateful(
|
||||
cp1,
|
||||
cp2,
|
||||
&state,
|
||||
));
|
||||
|
||||
else => @panic("NO"),
|
||||
};
|
||||
cp1 = cp2;
|
||||
}
|
||||
}
|
||||
|
||||
break :brk utf8proc.graphemeBreakStateful(cp1, c, &state);
|
||||
};
|
||||
|
Reference in New Issue
Block a user