mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Fix repetition of Thai characters (#4977)
Co-authored-by: Martin Haug <mhaug@live.de>
This commit is contained in:
parent
0abd46c379
commit
ab8295c07d
@ -515,14 +515,14 @@ impl<'a> ShapedText<'a> {
|
|||||||
std::mem::swap(&mut start, &mut end);
|
std::mem::swap(&mut start, &mut end);
|
||||||
}
|
}
|
||||||
|
|
||||||
let left = self.find_safe_to_break(start, Side::Left)?;
|
let left = self.find_safe_to_break(start)?;
|
||||||
let right = self.find_safe_to_break(end, Side::Right)?;
|
let right = self.find_safe_to_break(end)?;
|
||||||
Some(&self.glyphs[left..right])
|
Some(&self.glyphs[left..right])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the glyph offset matching the text index that is most towards the
|
/// Find the glyph offset matching the text index that is most towards the
|
||||||
/// given side and safe-to-break.
|
/// start of the text and safe-to-break.
|
||||||
fn find_safe_to_break(&self, text_index: usize, towards: Side) -> Option<usize> {
|
fn find_safe_to_break(&self, text_index: usize) -> Option<usize> {
|
||||||
let ltr = self.dir.is_positive();
|
let ltr = self.dir.is_positive();
|
||||||
|
|
||||||
// Handle edge cases.
|
// Handle edge cases.
|
||||||
@ -542,6 +542,7 @@ impl<'a> ShapedText<'a> {
|
|||||||
ordering.reverse()
|
ordering.reverse()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut idx = match found {
|
let mut idx = match found {
|
||||||
Ok(idx) => idx,
|
Ok(idx) => idx,
|
||||||
Err(idx) => {
|
Err(idx) => {
|
||||||
@ -565,13 +566,11 @@ impl<'a> ShapedText<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let next = match towards {
|
// Search for the start-most glyph with the text index. This means
|
||||||
Side::Left => usize::checked_sub,
|
// we take empty range glyphs at the start and leave those at the end
|
||||||
Side::Right => usize::checked_add,
|
// for the next line.
|
||||||
};
|
let dec = if ltr { usize::checked_sub } else { usize::checked_add };
|
||||||
|
while let Some(next) = dec(idx, 1) {
|
||||||
// Search for the outermost glyph with the text index.
|
|
||||||
while let Some(next) = next(idx, 1) {
|
|
||||||
if self.glyphs.get(next).map_or(true, |g| g.range.start != text_index) {
|
if self.glyphs.get(next).map_or(true, |g| g.range.start != text_index) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
BIN
tests/ref/issue-4468-linebreak-thai.png
Normal file
BIN
tests/ref/issue-4468-linebreak-thai.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 247 B |
Binary file not shown.
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.7 KiB |
@ -115,3 +115,11 @@ For info see #link("https://myhost.tld").
|
|||||||
// for links because it now splits on word boundaries. We avoid the link markup
|
// for links because it now splits on word boundaries. We avoid the link markup
|
||||||
// syntax because it's show rule interferes.
|
// syntax because it's show rule interferes.
|
||||||
#"http://creativecommons.org/licenses/by-nc-sa/4.0/"
|
#"http://creativecommons.org/licenses/by-nc-sa/4.0/"
|
||||||
|
|
||||||
|
--- issue-4468-linebreak-thai ---
|
||||||
|
// In this bug, empty-range glyphs at line break boundaries could be duplicated.
|
||||||
|
// This happens for Thai specifically because it has both
|
||||||
|
// - line break opportunities
|
||||||
|
// - shaping that results in multiple glyphs in the same cluster
|
||||||
|
#set text(font: "Noto Sans Thai")
|
||||||
|
#h(85pt) งบิก
|
||||||
|
Loading…
x
Reference in New Issue
Block a user