summaryrefslogtreecommitdiff
path: root/crates/typst-layout/src
diff options
context:
space:
mode:
authorTobias Schmitz <tobiasschmitz2001@gmail.com>2025-05-12 11:16:38 +0200
committerGitHub <noreply@github.com>2025-05-12 09:16:38 +0000
commit22a117a091f2d5936533d361098e7483f2997568 (patch)
tree9c4eaaae9d710681bfe1cf1869c9674c7d521fe4 /crates/typst-layout/src
parent26c19a49c8a73b1e7f7c299b9e25e57acfcd7eac (diff)
Prohibit some line break opportunities between LTR-ISOLATE and OBJECT-REPLACEMENT-CHARACTER (#6251)
Co-authored-by: Max <max@mkor.je> Co-authored-by: Laurenz <laurmaedje@gmail.com>
Diffstat (limited to 'crates/typst-layout/src')
-rw-r--r--crates/typst-layout/src/inline/linebreak.rs25
1 files changed, 23 insertions, 2 deletions
diff --git a/crates/typst-layout/src/inline/linebreak.rs b/crates/typst-layout/src/inline/linebreak.rs
index 31512604..ada048c7 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,
}
};