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.
This commit is contained in:
Tobias Schmitz 2025-05-05 17:27:24 +02:00
parent 9b09146a6b
commit d5d5d93b91
No known key found for this signature in database

View File

@ -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,
}
};