diff options
author | 2024-01-11 08:29:44 +0100 | |
---|---|---|
committer | 2024-01-11 08:29:44 +0100 | |
commit | 9c50a7ed7ee439b658f406da9018c9249ffa0b81 (patch) | |
tree | f08f81354ea0af51845d9617537019e22f5b15d2 /graphics | |
parent | 68c0484b5cf6f572e4cb0bf72c22c1a93dbb654e (diff) | |
download | iced-9c50a7ed7ee439b658f406da9018c9249ffa0b81.tar.gz iced-9c50a7ed7ee439b658f406da9018c9249ffa0b81.tar.bz2 iced-9c50a7ed7ee439b658f406da9018c9249ffa0b81.zip |
Fix `grapheme_position` when ligatures are present
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/src/text/paragraph.rs | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index 4a08a8f4..56cd8868 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -187,38 +187,43 @@ impl core::text::Paragraph for Paragraph { } fn grapheme_position(&self, line: usize, index: usize) -> Option<Point> { + use unicode_segmentation::UnicodeSegmentation; + let run = self.internal().buffer.layout_runs().nth(line)?; // index represents a grapheme, not a glyph // Let's find the first glyph for the given grapheme cluster let mut last_start = None; + let mut last_grapheme_count = 0; let mut graphemes_seen = 0; let glyph = run .glyphs .iter() .find(|glyph| { - if graphemes_seen == index { - return true; - } - if Some(glyph.start) != last_start { + last_grapheme_count = run.text[glyph.start..glyph.end] + .graphemes(false) + .count(); last_start = Some(glyph.start); - graphemes_seen += 1; + graphemes_seen += last_grapheme_count; } - false + graphemes_seen >= index }) .or_else(|| run.glyphs.last())?; - let advance_last = if index == run.glyphs.len() { - glyph.w - } else { + let advance = if index == 0 { 0.0 + } else { + glyph.w + * (1.0 + - graphemes_seen.saturating_sub(index) as f32 + / last_grapheme_count as f32) }; Some(Point::new( - glyph.x + glyph.x_offset * glyph.font_size + advance_last, + glyph.x + glyph.x_offset * glyph.font_size + advance, glyph.y - glyph.y_offset * glyph.font_size, )) } |