diff options
| author | 2025-07-20 15:09:09 +0300 | |
|---|---|---|
| committer | 2025-07-20 15:10:13 +0300 | |
| commit | 28aa25a86c0a1e551469ab74dda4a1636108e11b (patch) | |
| tree | 7e11c2f247652e91d679401fe6727fb8fb89a5d3 | |
| parent | Merge branch 'develop-next' (diff) | |
| download | zg-28aa25a86c0a1e551469ab74dda4a1636108e11b.tar.gz zg-28aa25a86c0a1e551469ab74dda4a1636108e11b.tar.xz zg-28aa25a86c0a1e551469ab74dda4a1636108e11b.zip | |
Moved part of the `strWidth` into its own `graphemeClusterWidth` function
| -rw-r--r-- | src/DisplayWidth.zig | 50 |
1 files 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" { | |||
| 102 | try testing.expectEqual(@as(i4, 2), dw.codePointWidth('统')); | 102 | try testing.expectEqual(@as(i4, 2), dw.codePointWidth('统')); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | /// graphemeClusterWidth returns the total display width of `gc` as the number | ||
| 106 | /// of cells required in a fixed-pitch font (i.e. a terminal screen). | ||
| 107 | /// `gc` is a slice corresponding to one grapheme cluster. | ||
| 108 | pub fn graphemeClusterWidth(dw: DisplayWidth, gc: []const u8) isize { | ||
| 109 | var cp_iter = CodePointIterator{ .bytes = gc }; | ||
| 110 | var gc_total: isize = 0; | ||
| 111 | |||
| 112 | while (cp_iter.next()) |cp| { | ||
| 113 | var w = dw.codePointWidth(cp.code); | ||
| 114 | |||
| 115 | if (w != 0) { | ||
| 116 | // Handle text emoji sequence. | ||
| 117 | if (cp_iter.next()) |ncp| { | ||
| 118 | // emoji text sequence. | ||
| 119 | if (ncp.code == 0xFE0E) w = 1; | ||
| 120 | if (ncp.code == 0xFE0F) w = 2; | ||
| 121 | } | ||
| 122 | |||
| 123 | // Only adding width of first non-zero-width code point. | ||
| 124 | gc_total = w; | ||
| 125 | break; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | return gc_total; | ||
| 129 | } | ||
| 130 | |||
| 105 | /// strWidth returns the total display width of `str` as the number of cells | 131 | /// strWidth returns the total display width of `str` as the number of cells |
| 106 | /// required in a fixed-pitch font (i.e. a terminal screen). | 132 | /// required in a fixed-pitch font (i.e. a terminal screen). |
| 107 | pub fn strWidth(dw: DisplayWidth, str: []const u8) usize { | 133 | pub fn strWidth(dw: DisplayWidth, str: []const u8) usize { |
| @@ -116,29 +142,7 @@ pub fn strWidth(dw: DisplayWidth, str: []const u8) usize { | |||
| 116 | var giter = dw.graphemes.iterator(str); | 142 | var giter = dw.graphemes.iterator(str); |
| 117 | 143 | ||
| 118 | while (giter.next()) |gc| { | 144 | while (giter.next()) |gc| { |
| 119 | var cp_iter = CodePointIterator{ .bytes = gc.bytes(str) }; | 145 | total += dw.graphemeClusterWidth(gc.bytes(str)); |
| 120 | var gc_total: isize = 0; | ||
| 121 | |||
| 122 | while (cp_iter.next()) |cp| { | ||
| 123 | var w = dw.codePointWidth(cp.code); | ||
| 124 | |||
| 125 | if (w != 0) { | ||
| 126 | // Handle text emoji sequence. | ||
| 127 | if (cp_iter.next()) |ncp| { | ||
| 128 | // emoji text sequence. | ||
| 129 | if (ncp.code == 0xFE0E) w = 1; | ||
| 130 | if (ncp.code == 0xFE0F) w = 2; | ||
| 131 | } | ||
| 132 | |||
| 133 | // Only adding width of first non-zero-width code point. | ||
| 134 | if (gc_total == 0) { | ||
| 135 | gc_total = w; | ||
| 136 | break; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | total += gc_total; | ||
| 142 | } | 146 | } |
| 143 | 147 | ||
| 144 | return @intCast(@max(0, total)); | 148 | return @intCast(@max(0, total)); |