mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +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.
|
/// Determine the position of the alignment points.
|
||||||
pub(super) fn alignments(rows: &[MathRow]) -> Vec<Abs> {
|
pub(super) fn alignments(rows: &[MathRow]) -> Vec<Abs> {
|
||||||
let count = rows
|
let mut widths = Vec::<Abs>::new();
|
||||||
.iter()
|
|
||||||
.map(|row| {
|
|
||||||
row.iter()
|
|
||||||
.filter(|fragment| matches!(fragment, MathFragment::Align))
|
|
||||||
.count()
|
|
||||||
})
|
|
||||||
.max()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
let mut points = vec![Abs::zero(); count];
|
for row in rows {
|
||||||
for current in 0..count {
|
let mut width = Abs::zero();
|
||||||
for row in rows {
|
let mut alignment_index = 0;
|
||||||
let mut x = Abs::zero();
|
for fragment in row.iter() {
|
||||||
let mut i = 0;
|
if matches!(fragment, MathFragment::Align) {
|
||||||
for fragment in row.iter() {
|
if alignment_index < widths.len() {
|
||||||
if matches!(fragment, MathFragment::Align) {
|
widths[alignment_index].set_max(width);
|
||||||
if i < current {
|
} else {
|
||||||
x = points[i];
|
widths.push(width);
|
||||||
} else if i == current {
|
|
||||||
points[i].set_max(x);
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
}
|
}
|
||||||
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
|
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