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