Fix grapheme_position when ligatures are present
This commit is contained in:
parent
68c0484b5c
commit
9c50a7ed7e
1 changed files with 15 additions and 10 deletions
|
|
@ -187,38 +187,43 @@ impl core::text::Paragraph for Paragraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn grapheme_position(&self, line: usize, index: usize) -> Option<Point> {
|
fn grapheme_position(&self, line: usize, index: usize) -> Option<Point> {
|
||||||
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
let run = self.internal().buffer.layout_runs().nth(line)?;
|
let run = self.internal().buffer.layout_runs().nth(line)?;
|
||||||
|
|
||||||
// index represents a grapheme, not a glyph
|
// index represents a grapheme, not a glyph
|
||||||
// Let's find the first glyph for the given grapheme cluster
|
// Let's find the first glyph for the given grapheme cluster
|
||||||
let mut last_start = None;
|
let mut last_start = None;
|
||||||
|
let mut last_grapheme_count = 0;
|
||||||
let mut graphemes_seen = 0;
|
let mut graphemes_seen = 0;
|
||||||
|
|
||||||
let glyph = run
|
let glyph = run
|
||||||
.glyphs
|
.glyphs
|
||||||
.iter()
|
.iter()
|
||||||
.find(|glyph| {
|
.find(|glyph| {
|
||||||
if graphemes_seen == index {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if Some(glyph.start) != last_start {
|
if Some(glyph.start) != last_start {
|
||||||
|
last_grapheme_count = run.text[glyph.start..glyph.end]
|
||||||
|
.graphemes(false)
|
||||||
|
.count();
|
||||||
last_start = Some(glyph.start);
|
last_start = Some(glyph.start);
|
||||||
graphemes_seen += 1;
|
graphemes_seen += last_grapheme_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
graphemes_seen >= index
|
||||||
})
|
})
|
||||||
.or_else(|| run.glyphs.last())?;
|
.or_else(|| run.glyphs.last())?;
|
||||||
|
|
||||||
let advance_last = if index == run.glyphs.len() {
|
let advance = if index == 0 {
|
||||||
glyph.w
|
|
||||||
} else {
|
|
||||||
0.0
|
0.0
|
||||||
|
} else {
|
||||||
|
glyph.w
|
||||||
|
* (1.0
|
||||||
|
- graphemes_seen.saturating_sub(index) as f32
|
||||||
|
/ last_grapheme_count as f32)
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(Point::new(
|
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,
|
glyph.y - glyph.y_offset * glyph.font_size,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue