From 28aa25a86c0a1e551469ab74dda4a1636108e11b Mon Sep 17 00:00:00 2001 From: Lich Date: Sun, 20 Jul 2025 15:09:09 +0300 Subject: Moved part of the `strWidth` into its own `graphemeClusterWidth` function --- src/DisplayWidth.zig | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/DisplayWidth.zig b/src/DisplayWidth.zig index 3da2d24..629087b 100644 --- a/src/DisplayWidth.zig +++ b/src/DisplayWidth.zig @@ -102,6 +102,32 @@ test "codePointWidth" { try testing.expectEqual(@as(i4, 2), dw.codePointWidth('统')); } +/// graphemeClusterWidth returns the total display width of `gc` as the number +/// of cells required in a fixed-pitch font (i.e. a terminal screen). +/// `gc` is a slice corresponding to one grapheme cluster. +pub fn graphemeClusterWidth(dw: DisplayWidth, gc: []const u8) isize { + var cp_iter = CodePointIterator{ .bytes = gc }; + var gc_total: isize = 0; + + while (cp_iter.next()) |cp| { + var w = dw.codePointWidth(cp.code); + + if (w != 0) { + // Handle text emoji sequence. + if (cp_iter.next()) |ncp| { + // emoji text sequence. + if (ncp.code == 0xFE0E) w = 1; + if (ncp.code == 0xFE0F) w = 2; + } + + // Only adding width of first non-zero-width code point. + gc_total = w; + break; + } + } + return gc_total; +} + /// strWidth returns the total display width of `str` as the number of cells /// required in a fixed-pitch font (i.e. a terminal screen). pub fn strWidth(dw: DisplayWidth, str: []const u8) usize { @@ -116,29 +142,7 @@ pub fn strWidth(dw: DisplayWidth, str: []const u8) usize { var giter = dw.graphemes.iterator(str); while (giter.next()) |gc| { - var cp_iter = CodePointIterator{ .bytes = gc.bytes(str) }; - var gc_total: isize = 0; - - while (cp_iter.next()) |cp| { - var w = dw.codePointWidth(cp.code); - - if (w != 0) { - // Handle text emoji sequence. - if (cp_iter.next()) |ncp| { - // emoji text sequence. - if (ncp.code == 0xFE0E) w = 1; - if (ncp.code == 0xFE0F) w = 2; - } - - // Only adding width of first non-zero-width code point. - if (gc_total == 0) { - gc_total = w; - break; - } - } - } - - total += gc_total; + total += dw.graphemeClusterWidth(gc.bytes(str)); } return @intCast(@max(0, total)); -- cgit v1.2.3