mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Convert math alignment to single-pass algorithm (#891)
This commit is contained in:
parent
42b93b7b53
commit
851b154a6c
@ -16,34 +16,30 @@ impl LayoutMath for AlignPointElem {
|
||||
|
||||
/// Determine the position of the alignment points.
|
||||
pub(super) fn alignments(rows: &[MathRow]) -> Vec<Abs> {
|
||||
let count = rows
|
||||
.iter()
|
||||
.map(|row| {
|
||||
row.iter()
|
||||
.filter(|fragment| matches!(fragment, MathFragment::Align))
|
||||
.count()
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
let mut widths = Vec::<Abs>::new();
|
||||
|
||||
let mut points = vec![Abs::zero(); count];
|
||||
for current in 0..count {
|
||||
for row in rows {
|
||||
let mut x = Abs::zero();
|
||||
let mut i = 0;
|
||||
for fragment in row.iter() {
|
||||
if matches!(fragment, MathFragment::Align) {
|
||||
if i < current {
|
||||
x = points[i];
|
||||
} else if i == current {
|
||||
points[i].set_max(x);
|
||||
}
|
||||
i += 1;
|
||||
for row in rows {
|
||||
let mut width = Abs::zero();
|
||||
let mut alignment_index = 0;
|
||||
for fragment in row.iter() {
|
||||
if matches!(fragment, MathFragment::Align) {
|
||||
if alignment_index < widths.len() {
|
||||
widths[alignment_index].set_max(width);
|
||||
} else {
|
||||
widths.push(width);
|
||||
}
|
||||
x += fragment.width();
|
||||
width = Abs::zero();
|
||||
alignment_index += 1;
|
||||
} else {
|
||||
width += fragment.width();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut points = widths;
|
||||
for i in 1..points.len() {
|
||||
let prev = points[i - 1];
|
||||
points[i] += prev;
|
||||
}
|
||||
points
|
||||
}
|
||||
|
BIN
tests/ref/math/alignment.png
Normal file
BIN
tests/ref/math/alignment.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.5 KiB |
28
tests/typ/math/alignment.typ
Normal file
28
tests/typ/math/alignment.typ
Normal file
@ -0,0 +1,28 @@
|
||||
// Test implicit alignment math.
|
||||
|
||||
---
|
||||
// Test alignment step functions.
|
||||
#set page(width: 300pt)
|
||||
$
|
||||
"abc" &= c \
|
||||
&= c + 1 & "By definition" \
|
||||
&= d + 100 + 1000 \
|
||||
&= x && "Even longer" \
|
||||
$
|
||||
|
||||
---
|
||||
// Test post-fix alignment.
|
||||
#set page(width: 300pt)
|
||||
$
|
||||
& "right" \
|
||||
"a very long line" \
|
||||
$
|
||||
|
||||
---
|
||||
// Test alternating alignment.
|
||||
#set page(width: 300pt)
|
||||
$
|
||||
"abc" & "abc abc abc" & "abc abc" \
|
||||
"abc abc" & "abc abc" & "abc" \
|
||||
"abc abc abc" & "abc" & "abc abc abc" \
|
||||
$
|
Loading…
x
Reference in New Issue
Block a user