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,          ))      }  | 
