summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector@hecrj.dev>2024-01-11 08:45:13 +0100
committerLibravatar GitHub <noreply@github.com>2024-01-11 08:45:13 +0100
commitfba5326e136c6486bc55e8ba0fed44fe60bb444f (patch)
tree8d62c87599e24f76988ee9b4d1f08ba5c0a66399
parent90332acc4b18d7ea539459908b4e59517d8b48cb (diff)
parent3d88ceb482855549271fe73165eeea4871222048 (diff)
downloadiced-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.rs25
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,
))
}