From 22a117a091f2d5936533d361098e7483f2997568 Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Mon, 12 May 2025 11:16:38 +0200 Subject: [PATCH] Prohibit some line break opportunities between LTR-ISOLATE and OBJECT-REPLACEMENT-CHARACTER (#6251) Co-authored-by: Max Co-authored-by: Laurenz --- crates/typst-layout/src/inline/linebreak.rs | 25 ++++++++++++++++-- .../ref/issue-5489-matrix-stray-linebreak.png | Bin 0 -> 644 bytes tests/suite/layout/inline/linebreak.typ | 8 ++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/ref/issue-5489-matrix-stray-linebreak.png diff --git a/crates/typst-layout/src/inline/linebreak.rs b/crates/typst-layout/src/inline/linebreak.rs index 31512604f..ada048c7d 100644 --- a/crates/typst-layout/src/inline/linebreak.rs +++ b/crates/typst-layout/src/inline/linebreak.rs @@ -690,13 +690,34 @@ fn breakpoints(p: &Preparation, mut f: impl FnMut(usize, Breakpoint)) { let breakpoint = if point == text.len() { Breakpoint::Mandatory } else { + const OBJ_REPLACE: char = '\u{FFFC}'; match lb.get(c) { - // Fix for: https://github.com/unicode-org/icu4x/issues/4146 - LineBreak::Glue | LineBreak::WordJoiner | LineBreak::ZWJ => continue, LineBreak::MandatoryBreak | LineBreak::CarriageReturn | LineBreak::LineFeed | LineBreak::NextLine => Breakpoint::Mandatory, + + // https://github.com/typst/typst/issues/5489 + // + // OBJECT-REPLACEMENT-CHARACTERs provide Contingent Break + // opportunities before and after by default. This behaviour + // is however tailorable, see: + // https://www.unicode.org/reports/tr14/#CB + // https://www.unicode.org/reports/tr14/#TailorableBreakingRules + // https://www.unicode.org/reports/tr14/#LB20 + // + // Don't provide a line breaking opportunity between a LTR- + // ISOLATE (or any other Combining Mark) and an OBJECT- + // REPLACEMENT-CHARACTER representing an inline item, if the + // LTR-ISOLATE could end up as the only character on the + // previous line. + LineBreak::CombiningMark + if text[point..].starts_with(OBJ_REPLACE) + && last + c.len_utf8() == point => + { + continue; + } + _ => Breakpoint::Normal, } }; diff --git a/tests/ref/issue-5489-matrix-stray-linebreak.png b/tests/ref/issue-5489-matrix-stray-linebreak.png new file mode 100644 index 0000000000000000000000000000000000000000..2d278bd5c9cadb4b26a5f26dd0565f6a4bfafedf GIT binary patch literal 644 zcmV-~0(FAT!-&LSWKIn|;D1$L9BQHvo)N3y(o! zS^G3^ywWxJ5Y)`U>Po{Kj5rF?Ij!(01~NLFa2Ngby2A*Mfxxfs9@;=E=}=+VWfyTy zDLf8Rpj);=g+Xcye&U=~c=84WJ<1lSysCzuK@Zu@B(?CoAF_@h2uUI05ri6KJ>i?Z zaPIuG{t1Zu^VGu81pscAW#cuE;v-~jkKzL$T8L5$;~^CL!D~H2uJmddiVWMpND28$Q z9Fi2@V5|9T^`HX94_n7lygY3NE&yP;c+c?b=?&7-`o^8CFR7l>TLXtnp#%lTCG97n eg|)C29=6|_=gtD%*Z=JR0000