summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst-library/src/text/shaping.rs40
-rw-r--r--tests/ref/layout/cjk-latin-spacing.pngbin6039 -> 8399 bytes
-rw-r--r--tests/typ/layout/cjk-latin-spacing.typ13
3 files changed, 42 insertions, 11 deletions
diff --git a/crates/typst-library/src/text/shaping.rs b/crates/typst-library/src/text/shaping.rs
index f7cf90bd..05ed4633 100644
--- a/crates/typst-library/src/text/shaping.rs
+++ b/crates/typst-library/src/text/shaping.rs
@@ -488,17 +488,35 @@ impl<'a> ShapedText<'a> {
}
// Find any glyph with the text index.
- let mut idx = self
- .glyphs
- .binary_search_by(|g| {
- let ordering = g.range.start.cmp(&text_index);
- if ltr {
- ordering
- } else {
- ordering.reverse()
- }
- })
- .ok()?;
+ let found = self.glyphs.binary_search_by(|g: &ShapedGlyph| {
+ let ordering = g.range.start.cmp(&text_index);
+ if ltr {
+ ordering
+ } else {
+ ordering.reverse()
+ }
+ });
+ let mut idx = match found {
+ Ok(idx) => idx,
+ Err(idx) => {
+ // Handle the special case where we break before a '\n'
+ //
+ // For example: (assume `a` is a CJK character with three bytes)
+ // text: " a \n b "
+ // index: 0 1 2 3 4 5
+ // text_index: ^
+ // glyphs: 0 . 1
+ //
+ // We will get found = Err(1), because '\n' does not have a glyph.
+ // But it's safe to break here. Thus the following condition:
+ // - glyphs[0].end == text_index == 3
+ // - text[3] == '\n'
+ return (idx > 0
+ && self.glyphs[idx - 1].range.end == text_index
+ && self.text[text_index - self.base..].starts_with('\n'))
+ .then_some(idx);
+ }
+ };
let next = match towards {
Side::Left => usize::checked_sub,
diff --git a/tests/ref/layout/cjk-latin-spacing.png b/tests/ref/layout/cjk-latin-spacing.png
index bd4eed9b..629145e4 100644
--- a/tests/ref/layout/cjk-latin-spacing.png
+++ b/tests/ref/layout/cjk-latin-spacing.png
Binary files differ
diff --git a/tests/typ/layout/cjk-latin-spacing.typ b/tests/typ/layout/cjk-latin-spacing.typ
index 9cc94fd2..c6fff5d7 100644
--- a/tests/typ/layout/cjk-latin-spacing.typ
+++ b/tests/typ/layout/cjk-latin-spacing.typ
@@ -14,3 +14,16 @@
中文,中ab文a中,文ab中文
+---
+// Issue #2538
+#set text(cjk-latin-spacing: auto)
+
+abc字
+
+abc字#linebreak()
+
+abc字#linebreak()
+母
+
+abc字\
+母