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>) { fn push_text(&mut self, text: &str, styles: StyleChain<'a>) {
self.full.push_str(text); self.build_text(styles, |full| full.push_str(text));
self.push_segment(Segment::Text(text.len(), styles));
} }
fn build_text<F>(&mut self, styles: StyleChain<'a>, f: F) fn build_text<F>(&mut self, styles: StyleChain<'a>, f: F)
@ -266,33 +265,33 @@ impl<'a> Collector<'a> {
{ {
let prev = self.full.len(); let prev = self.full.len();
f(&mut self.full); f(&mut self.full);
let len = self.full.len() - prev; let segment_len = self.full.len() - prev;
self.push_segment(Segment::Text(len, styles));
// 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>) { fn push_item(&mut self, item: Item<'a>) {
self.full.push_str(item.textual()); match (self.segments.last_mut(), &item) {
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 weak spacing by taking the maximum. // Merge adjacent weak spacing by taking the maximum.
( (
Some(Segment::Item(Item::Absolute(prev_amount, true))), Some(Segment::Item(Item::Absolute(prev_amount, true))),
Segment::Item(Item::Absolute(amount, true)), Item::Absolute(amount, true),
) => { ) => {
*prev_amount = (*prev_amount).max(*amount); *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. /// Estimates the metrics for the line spanned by the range.
#[track_caller]
fn estimate(&self, range: Range) -> T { fn estimate(&self, range: Range) -> T {
self.get(range.end) - self.get(range.start) self.get(range.end) - self.get(range.start)
} }
/// Get the metric at the given byte position. /// Get the metric at the given byte position.
#[track_caller]
fn get(&self, index: usize) -> T { fn get(&self, index: usize) -> T {
match index.checked_sub(1) { match index.checked_sub(1) {
None => T::default(), 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. // Non-weak-spacing, on the other hand, is not removed.
This is the first line \ #h(2cm, weak: false) A new line 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