From 99ee469c86c8c187d874253ad8f0e3274cf97943 Mon Sep 17 00:00:00 2001 From: alex-ds13 <145657253+alex-ds13@users.noreply.github.com> Date: Tue, 25 Nov 2025 18:43:51 +0000 Subject: fix: select graphemes with multi codepoints properly - We continue to use the graphemes index for the selection ends, however when calculating the selection rectangles we now check if the visual line had any glyph with `start` and `end` index bigger than 1 before or within the range and update the range accordingly. This way all the code that checks for word boundaries when selecting by words still functions properly. --- src/text.rs | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'src/text.rs') diff --git a/src/text.rs b/src/text.rs index ac51395..143a78d 100644 --- a/src/text.rs +++ b/src/text.rs @@ -831,7 +831,7 @@ fn highlight_line( .map(|glyph| glyph.end) .unwrap_or(0); - let range = start.max(from)..end.min(to); + let mut range = start.max(from)..end.min(to); let x_offset = visual_line .glyphs @@ -844,21 +844,31 @@ fn highlight_line( } else if range.start == start && range.end == end { (x_offset, visual_line.w) } else { - let first_glyph = visual_line - .glyphs - .iter() - .position(|glyph| range.start <= glyph.start) - .unwrap_or(0); - - let mut glyphs = visual_line.glyphs.iter(); + let mut x = 0.0; + let mut width = 0.0; + for glyph in &visual_line.glyphs { + let glyph_count = glyph.start.abs_diff(glyph.end); + + // Check for multi codepoint glyphs before or within the range + if glyph_count > 1 { + if range.start > glyph.start { + range.start += glyph_count - 1; + range.end += glyph_count - 1; + } else if range.end > glyph.start { + range.end += glyph_count - 1; + } + } - let x: f32 = - glyphs.by_ref().take(first_glyph).map(|glyph| glyph.w).sum(); + if range.start > glyph.start { + x += glyph.w; + } - let width: f32 = glyphs - .take_while(|glyph| range.end > glyph.start) - .map(|glyph| glyph.w) - .sum(); + if range.start <= glyph.start && range.end > glyph.start { + width += glyph.w; + } else if range.end <= glyph.start { + break; + } + } (x_offset + x, width) } -- cgit v1.2.3