summaryrefslogtreecommitdiff
path: root/crates/typst-layout
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-12-11 16:46:10 +0100
committerGitHub <noreply@github.com>2024-12-11 15:46:10 +0000
commit521ceae889f15f2a93683ab776cd86a423e5dbed (patch)
tree9f81b78aef566843df943224aee8f661854b376b /crates/typst-layout
parent5e0e58d26ef656836aae8d16477bb059e97883a3 (diff)
Fix crash due to consecutive weak spacing (#5562)
Diffstat (limited to 'crates/typst-layout')
-rw-r--r--crates/typst-layout/src/inline/collect.rs37
-rw-r--r--crates/typst-layout/src/inline/linebreak.rs2
2 files changed, 20 insertions, 19 deletions
diff --git a/crates/typst-layout/src/inline/collect.rs b/crates/typst-layout/src/inline/collect.rs
index fbcddee5..23e82c41 100644
--- a/crates/typst-layout/src/inline/collect.rs
+++ b/crates/typst-layout/src/inline/collect.rs
@@ -256,8 +256,7 @@ impl<'a> Collector<'a> {
}
fn push_text(&mut self, text: &str, styles: StyleChain<'a>) {
- self.full.push_str(text);
- self.push_segment(Segment::Text(text.len(), styles));
+ self.build_text(styles, |full| full.push_str(text));
}
fn build_text<F>(&mut self, styles: StyleChain<'a>, f: F)
@@ -266,33 +265,33 @@ impl<'a> Collector<'a> {
{
let prev = self.full.len();
f(&mut self.full);
- let len = self.full.len() - prev;
- self.push_segment(Segment::Text(len, styles));
- }
+ let segment_len = self.full.len() - prev;
- fn push_item(&mut self, item: Item<'a>) {
- self.full.push_str(item.textual());
- self.push_segment(Segment::Item(item));
- }
-
- fn push_segment(&mut self, segment: Segment<'a>) {
- match (self.segments.last_mut(), &segment) {
- // Merge adjacent text segments with the same styles.
- (Some(Segment::Text(last_len, last_styles)), Segment::Text(len, styles))
- if *last_styles == *styles =>
- {
- *last_len += *len;
+ // Merge adjacent text segments with the same styles.
+ if let Some(Segment::Text(last_len, last_styles)) = self.segments.last_mut() {
+ if *last_styles == styles {
+ *last_len += segment_len;
+ return;
}
+ }
+ self.segments.push(Segment::Text(segment_len, styles));
+ }
+
+ fn push_item(&mut self, item: Item<'a>) {
+ match (self.segments.last_mut(), &item) {
// Merge adjacent weak spacing by taking the maximum.
(
Some(Segment::Item(Item::Absolute(prev_amount, true))),
- Segment::Item(Item::Absolute(amount, true)),
+ Item::Absolute(amount, true),
) => {
*prev_amount = (*prev_amount).max(*amount);
}
- _ => self.segments.push(segment),
+ _ => {
+ self.full.push_str(item.textual());
+ self.segments.push(Segment::Item(item));
+ }
}
}
}
diff --git a/crates/typst-layout/src/inline/linebreak.rs b/crates/typst-layout/src/inline/linebreak.rs
index 236d6892..7b66fcdb 100644
--- a/crates/typst-layout/src/inline/linebreak.rs
+++ b/crates/typst-layout/src/inline/linebreak.rs
@@ -971,11 +971,13 @@ where
}
/// Estimates the metrics for the line spanned by the range.
+ #[track_caller]
fn estimate(&self, range: Range) -> T {
self.get(range.end) - self.get(range.start)
}
/// Get the metric at the given byte position.
+ #[track_caller]
fn get(&self, index: usize) -> T {
match index.checked_sub(1) {
None => T::default(),