From d5d5d93b91771e6f3bdeb00128c9c818b09507c0 Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Mon, 5 May 2025 17:27:24 +0200 Subject: [PATCH] fix: prohibit some line break opportunities between LTR-ISOLATE and OBJECT-REPLACEMENT-CHARACTER Don't provide a line breaking opportunity between and LTR-ISOLATE and an OBJECT-REPLACEMENT-CHARACTER representing and inline item, if the LTR-ISOLATE could end up as the only character on the previous line. --- crates/typst-layout/src/inline/linebreak.rs | 26 +++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/crates/typst-layout/src/inline/linebreak.rs b/crates/typst-layout/src/inline/linebreak.rs index 31512604f..ef8159035 100644 --- a/crates/typst-layout/src/inline/linebreak.rs +++ b/crates/typst-layout/src/inline/linebreak.rs @@ -690,13 +690,35 @@ fn breakpoints(p: &Preparation, mut f: impl FnMut(usize, Breakpoint)) { let breakpoint = if point == text.len() { Breakpoint::Mandatory } else { + const LTR_ISOLATE: char = '\u{2066}'; + 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 and an OBJECT-REPLACEMENT-CHARACTER representing + // and inline item, if the LTR-ISOLATE could end up as the + // only character on the previous line. + LineBreak::CombiningMark + if c == LTR_ISOLATE + && text[point..].starts_with(OBJ_REPLACE) + && last == (point - LTR_ISOLATE.len_utf8()) => + { + continue; + } + _ => Breakpoint::Normal, } };