Update uucode to the latest, for future width and grapheme break changes

pull/9678/head
Jacob Sandlund 2025-11-22 14:16:58 -05:00
parent 6b28671ead
commit 97926ca307
3 changed files with 15 additions and 21 deletions

View File

@ -38,9 +38,8 @@
.lazy = true,
},
.uucode = .{
// TODO: currently the use-llvm branch because its broken on self-hosted
.url = "https://github.com/jacobsandlund/uucode/archive/b309dfb4e25a38201d7b300b201a698e02283862.tar.gz",
.hash = "uucode-0.1.0-ZZjBPl_mQwDHQowHOzXwgTPhAqcFekfYpAeUfeHZNCl3",
.url = "https://github.com/jacobsandlund/uucode/archive/4f474cf311877701d9f09b415b1aff11df30e3b5.tar.gz",
.hash = "uucode-0.1.0-ZZjBPu4HTQAN0P6B0WxKHM2ugS2adGDWk3hW8i9L8ufw",
},
.zig_wayland = .{
// codeberg ifreund/zig-wayland

View File

@ -19,23 +19,23 @@ fn computeWidth(
_ = backing;
_ = tracking;
// Emoji modifiers are technically width 0 because they're joining
// points. But we handle joining via grapheme break and don't use width
// there. If a emoji modifier is standalone, we want it to take up
// two columns.
if (data.is_emoji_modifier) {
assert(data.wcwidth == 0);
data.wcwidth = 2;
return;
// This condition is to get the previous behavior of uucode's `wcwidth`,
// returning the width of a code point in a grapheme cluster but with the
// exception to treat emoji modifiers as width 2 so they can be displayed
// in isolation. PRs immediately to follow will take advantage of the new
// uucode `wcwidt_standalone` vs `wcwidth_zero_in_grapheme` split.
if (data.wcwidth_zero_in_grapheme and !data.is_emoji_modifier) {
data.width = 0;
} else {
data.width = @min(2, data.wcwidth_standalone);
}
data.width = @intCast(@min(2, @max(0, data.wcwidth)));
}
const width = config.Extension{
.inputs = &.{
"wcwidth_standalone",
"wcwidth_zero_in_grapheme",
"is_emoji_modifier",
"wcwidth",
},
.compute = &computeWidth,
.fields = &.{
@ -90,8 +90,6 @@ pub const tables = [_]config.Table{
width.field("width"),
d.field("grapheme_break"),
is_symbol.field("is_symbol"),
d.field("is_emoji_modifier"),
d.field("is_emoji_modifier_base"),
d.field("is_emoji_vs_text"),
d.field("is_emoji_vs_emoji"),
},

View File

@ -11,11 +11,6 @@ const GraphemeBoundaryClass = @import("props.zig").GraphemeBoundaryClass;
fn graphemeBoundaryClass(cp: u21) GraphemeBoundaryClass {
if (cp > uucode.config.max_code_point) return .invalid;
// We special-case modifier bases because we should not break
// if a modifier isn't next to a base.
if (uucode.get(.is_emoji_modifier, cp)) return .emoji_modifier;
if (uucode.get(.is_emoji_modifier_base, cp)) return .extended_pictographic_base;
return switch (uucode.get(.grapheme_break, cp)) {
.extended_pictographic => .extended_pictographic,
.l => .L,
@ -27,6 +22,8 @@ fn graphemeBoundaryClass(cp: u21) GraphemeBoundaryClass {
.zwj => .zwj,
.spacing_mark => .spacing_mark,
.regional_indicator => .regional_indicator,
.emoji_modifier => .emoji_modifier,
.emoji_modifier_base => .extended_pictographic_base,
.zwnj,
.indic_conjunct_break_extend,