diff options
author | 2024-01-11 08:45:13 +0100 | |
---|---|---|
committer | 2024-01-11 08:45:13 +0100 | |
commit | fba5326e136c6486bc55e8ba0fed44fe60bb444f (patch) | |
tree | 8d62c87599e24f76988ee9b4d1f08ba5c0a66399 | |
parent | 90332acc4b18d7ea539459908b4e59517d8b48cb (diff) | |
parent | 3d88ceb482855549271fe73165eeea4871222048 (diff) | |
download | iced-fba5326e136c6486bc55e8ba0fed44fe60bb444f.tar.gz iced-fba5326e136c6486bc55e8ba0fed44fe60bb444f.tar.bz2 iced-fba5326e136c6486bc55e8ba0fed44fe60bb444f.zip |
Merge pull request #2196 from iced-rs/fix/paragraph_grapheme_position
Fix `grapheme_position` when ligatures are present
Diffstat (limited to '')
-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..5d027542 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.max(1) 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, )) } |