diff --git a/Cargo.toml b/Cargo.toml index 227b603..67e9485 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,8 +30,6 @@ sys-locale = { version = "0.3.2", optional = true } unicode-linebreak = "0.1.5" unicode-script = "0.5.8" unicode-segmentation = "1.12.0" -# Yoda: EAW-aware cell width for monospace/terminal rendering. -unicode-width = "0.2" [dependencies.swash] version = "0.2.6" diff --git a/src/shape.rs b/src/shape.rs index 5e76c73..ec98963 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -237,8 +237,6 @@ fn shape_fallback( metadata: attrs.metadata, cache_key_flags: override_fake_italic(attrs.cache_key_flags, font, &attrs), metrics_opt: attrs.metrics_opt.map(Into::into), - // Set by the post-loop pass below once `end` is finalized. - terminal_cells: 1, }); } @@ -267,19 +265,6 @@ fn shape_fallback( } } - // Yoda: compute EAW terminal width per glyph now that `end` is finalized. - // We use the cluster's text (byte range into `line`) rather than just the - // first char so ZWJ emoji sequences collapse to a single cluster width. - // `unicode-width` returns 0 for combining marks / variation selectors, 2 - // for CJK & most emoji, 1 for everything else including Arabic. - { - use unicode_width::UnicodeWidthStr; - for glyph in &mut glyphs[glyph_start..] { - let cluster = line.get(glyph.start..glyph.end).unwrap_or(""); - glyph.terminal_cells = UnicodeWidthStr::width(cluster).min(2) as u8; - } - } - // Restore the buffer to save an allocation. scratch.harfrust_buffer = Some(glyph_buffer.clear()); @@ -605,12 +590,6 @@ fn shape_skip_glyphs( .letter_spacing_opt .map_or(0.0, |spacing| spacing.0); let attrs = attrs_list.get_span(start_run + chr_idx); - // Yoda: EAW width for terminal-aware monospace snap (see - // ShapeGlyph.terminal_cells doc). - let terminal_cells = { - use unicode_width::UnicodeWidthChar; - UnicodeWidthChar::width(codepoint).unwrap_or(1).min(2) as u8 - }; ShapeGlyph { start: chr_idx + start_run, @@ -629,7 +608,6 @@ fn shape_skip_glyphs( metadata: attrs.metadata, cache_key_flags: override_fake_italic(attrs.cache_key_flags, font, &attrs), metrics_opt: attrs.metrics_opt.map(Into::into), - terminal_cells, } }), ); @@ -666,14 +644,6 @@ pub struct ShapeGlyph { pub metadata: usize, pub cache_key_flags: CacheKeyFlags, pub metrics_opt: Option, - /// Yoda: Unicode East Asian Width of the source text covered by this glyph, - /// in terminal cells (0, 1 or 2 per `unicode_width::UnicodeWidthStr::width`). - /// Populated at shape time from `line[start..end]`. Consumed by - /// `layout_to_buffer` when `match_mono_width` is Some — wide chars (emoji, - /// CJK, fullwidth forms) snap to 2 cells instead of rounding based on the - /// fallback font's natural glyph advance, which was the upstream bug - /// breaking terminal column alignment. - pub terminal_cells: u8, } impl ShapeGlyph { @@ -2933,21 +2903,9 @@ impl ShapeLine { 0.0 }, ); - if let Some(mono_width) = match_mono_width { - // Yoda: use Unicode East Asian Width, stored at - // shape time, as the authoritative cell count. - // `terminal_cells` is 0 for combining marks / - // variation selectors (they stay 0-advance), - // 2 for CJK & emoji clusters, 1 for everything - // else (including Arabic, Latin, etc.). - // - // This replaces the previous round-to-nearest - // logic which produced variable cell widths - // for fallback glyphs because it depended on - // the glyph's natural advance in the fallback - // font rather than on the source character's - // terminal width spec. - x_advance = f32::from(glyph.terminal_cells) * mono_width; + if let Some(match_em_width) = match_mono_em_width { + // Round to nearest monospace width + x_advance = ((x_advance / match_em_width).round()) * match_em_width; } if hinting == Hinting::Enabled { x_advance = x_advance.round();