Fix crash due to consecutive weak spacing (#5562)

This commit is contained in:
Laurenz 2024-12-11 16:46:10 +01:00 committed by GitHub
parent 5e0e58d26e
commit 521ceae889
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 38 additions and 19 deletions

View File

@ -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;
// 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>) {
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;
}
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));
}
}
}
}

View File

@ -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(),

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

View File

@ -58,3 +58,21 @@ This is the first line \ #h(2cm, weak: true) A new line
// Non-weak-spacing, on the other hand, is not removed.
This is the first line \ #h(2cm, weak: false) A new line
--- issue-5244-consecutive-weak-space ---
#set par(linebreaks: "optimized")
#{
[A]
h(0.3em, weak: true)
h(0.3em, weak: true)
[B]
}
--- issue-5244-consecutive-weak-space-heading ---
#set par(justify: true)
#set heading(numbering: "I.")
= #h(0.3em, weak: true) test
--- issue-5253-consecutive-weak-space-math ---
$= thin thin$ a