From 499c5f24448d313b988721f212536fe170953905 Mon Sep 17 00:00:00 2001 From: bluebear94 Date: Mon, 4 Sep 2023 05:46:17 -0400 Subject: [PATCH] Fix improper line wrapping in the presence of medial newlines (#2056) Fixes #2019. --- crates/typst-library/src/layout/par.rs | 32 ++++++++++++++----------- tests/ref/layout/par-justify.png | Bin 27297 -> 52393 bytes tests/typ/layout/par-justify.typ | 13 ++++++++++ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/crates/typst-library/src/layout/par.rs b/crates/typst-library/src/layout/par.rs index d3cd6cbff..5ae7db761 100644 --- a/crates/typst-library/src/layout/par.rs +++ b/crates/typst-library/src/layout/par.rs @@ -1,3 +1,5 @@ +use std::iter::Peekable; + use icu_properties::{maps::CodePointMapData, LineBreak}; use icu_provider::AsDeserializingBufferProvider; use icu_provider_adapters::fork::ForkByKeyProvider; @@ -933,18 +935,6 @@ fn linebreak_optimized<'a>(vt: &Vt, p: &'a Preparation<'a>, width: Abs) -> Vec 0 { - if let Some(s_pred) = table.get(i + 1) { - let next_start = s_pred.line.end; - if !p.bidi.text[start..next_start] - .contains(|c: char| !c.is_whitespace()) - { - continue; - } - } - } - let attempt = line(vt, p, start..end, mandatory, hyphen); // Determine how much the line's spaces would need to be stretched @@ -1103,7 +1093,7 @@ fn breakpoints<'a>(p: &'a Preparation<'a>) -> Breakpoints<'a> { linebreaks.next(); Breakpoints { p, - linebreaks, + linebreaks: linebreaks.peekable(), syllables: None, offset: 0, suffix: 0, @@ -1117,7 +1107,7 @@ struct Breakpoints<'a> { /// The paragraph's items. p: &'a Preparation<'a>, /// The inner iterator over the unicode line break opportunities. - linebreaks: LineBreakIteratorUtf8<'a, 'a>, + linebreaks: Peekable>, /// Iterator over syllables of the current word. syllables: Option>, /// The current text offset. @@ -1179,6 +1169,20 @@ impl Iterator for Breakpoints<'_> { } } + // Fix for https://github.com/unicode-org/icu4x/issues/3811 + if !self.mandatory { + while let Some(&next) = self.linebreaks.peek() { + if !self.p.bidi.text[self.end..next] + .contains(|c: char| !c.is_whitespace()) + { + self.end = next; + self.linebreaks.next(); + } else { + break; + } + } + } + self.offset = self.end; Some((self.end, self.mandatory, false)) } diff --git a/tests/ref/layout/par-justify.png b/tests/ref/layout/par-justify.png index 5745f08175d05c5d4ba263948c22ee265f51d192..0cd9cbcdcfef6bcfac70294457e8284ca0a7e844 100644 GIT binary patch literal 52393 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