diff options
Diffstat (limited to '')
| -rw-r--r-- | src/text.rs | 38 |
1 files changed, 24 insertions, 14 deletions
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) } |
