summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/math/equation.rs109
-rw-r--r--crates/typst/src/math/row.rs4
-rw-r--r--tests/ref/math-equation-align-numbered.pngbin1314 -> 1298 bytes
-rw-r--r--tests/ref/math-equation-number-align-end.pngbin1541 -> 1519 bytes
-rw-r--r--tests/ref/math-equation-number-align-left.pngbin1526 -> 1511 bytes
-rw-r--r--tests/ref/math-equation-number-align-monoline.pngbin0 -> 1379 bytes
-rw-r--r--tests/ref/math-equation-number-align-multiline-bottom.pngbin758 -> 1318 bytes
-rw-r--r--tests/ref/math-equation-number-align-multiline-expand.pngbin510 -> 518 bytes
-rw-r--r--tests/ref/math-equation-number-align-multiline-top-start.pngbin597 -> 1302 bytes
-rw-r--r--tests/ref/math-equation-number-align-right.pngbin1506 -> 1496 bytes
-rw-r--r--tests/ref/math-equation-number-align-start.pngbin1528 -> 1514 bytes
-rw-r--r--tests/ref/math-equation-number-align.pngbin1541 -> 1519 bytes
-rw-r--r--tests/ref/math-equation-numbering.pngbin4604 -> 4600 bytes
-rw-r--r--tests/ref/outline.pngbin40746 -> 40846 bytes
-rw-r--r--tests/ref/ref-supplements.pngbin8276 -> 8267 bytes
-rw-r--r--tests/suite/math/equation.typ18
16 files changed, 88 insertions, 43 deletions
diff --git a/crates/typst/src/math/equation.rs b/crates/typst/src/math/equation.rs
index 4e844d07..18ef5150 100644
--- a/crates/typst/src/math/equation.rs
+++ b/crates/typst/src/math/equation.rs
@@ -389,18 +389,17 @@ fn add_equation_number(
region_size_x: Abs,
full_number_width: Abs,
) -> Frame {
- let first = equation_builder
- .frames
- .first()
- .map_or((equation_builder.size, Point::zero()), |(frame, point)| {
- (frame.size(), *point)
- });
- let last = equation_builder
- .frames
- .last()
- .map_or((equation_builder.size, Point::zero()), |(frame, point)| {
- (frame.size(), *point)
- });
+ let first =
+ equation_builder.frames.first().map_or(
+ (equation_builder.size, Point::zero(), Abs::zero()),
+ |(frame, pos)| (frame.size(), *pos, frame.baseline()),
+ );
+ let last =
+ equation_builder.frames.last().map_or(
+ (equation_builder.size, Point::zero(), Abs::zero()),
+ |(frame, pos)| (frame.size(), *pos, frame.baseline()),
+ );
+ let line_count = equation_builder.frames.len();
let mut equation = equation_builder.build();
let width = if region_size_x.is_finite() {
@@ -408,23 +407,16 @@ fn add_equation_number(
} else {
equation.width() + 2.0 * full_number_width
};
- let height = match number_align.y {
- FixedAlignment::Start => {
- let (size, point) = first;
- let excess_above = (number.height() - size.y) / 2.0 - point.y;
- equation.height() + Abs::zero().max(excess_above)
- }
- FixedAlignment::Center => equation.height().max(number.height()),
- FixedAlignment::End => {
- let (size, point) = last;
- let excess_below =
- (number.height() + size.y) / 2.0 - equation.height() + point.y;
- equation.height() + Abs::zero().max(excess_below)
- }
- };
- let resizing_offset = equation.resize(
- Size::new(width, height),
- Axes::<FixedAlignment>::new(equation_align, number_align.y.inv()),
+
+ let is_multiline = line_count >= 2;
+ let resizing_offset = resize_equation(
+ &mut equation,
+ &number,
+ number_align,
+ equation_align,
+ width,
+ is_multiline,
+ [first, last],
);
equation.translate(Point::with_x(match (equation_align, number_align.x) {
(FixedAlignment::Start, FixedAlignment::Start) => full_number_width,
@@ -437,19 +429,58 @@ fn add_equation_number(
FixedAlignment::End => equation.width() - number.width(),
_ => unreachable!(),
};
- let dh = |h1: Abs, h2: Abs| (h1 - h2) / 2.0;
- let y = match number_align.y {
- FixedAlignment::Start => {
- let (size, point) = first;
- resizing_offset.y + point.y + dh(size.y, number.height())
- }
- FixedAlignment::Center => dh(equation.height(), number.height()),
- FixedAlignment::End => {
- let (size, point) = last;
- resizing_offset.y + point.y + dh(size.y, number.height())
+ let y = {
+ let align_baselines = |(_, pos, baseline): (_, Point, Abs), number: &Frame| {
+ resizing_offset.y + pos.y + baseline - number.baseline()
+ };
+ match number_align.y {
+ FixedAlignment::Start => align_baselines(first, &number),
+ FixedAlignment::Center if !is_multiline => align_baselines(first, &number),
+ // In this case, the center lines (not baselines) of the number frame
+ // and the equation frame shall be aligned.
+ FixedAlignment::Center => (equation.height() - number.height()) / 2.0,
+ FixedAlignment::End => align_baselines(last, &number),
}
};
equation.push_frame(Point::new(x, y), number);
equation
}
+
+/// Resize the equation's frame accordingly so that it emcompasses the number.
+fn resize_equation(
+ equation: &mut Frame,
+ number: &Frame,
+ number_align: Axes<FixedAlignment>,
+ equation_align: FixedAlignment,
+ width: Abs,
+ is_multiline: bool,
+ [first, last]: [(Axes<Abs>, Point, Abs); 2],
+) -> Point {
+ if matches!(number_align.y, FixedAlignment::Center if is_multiline) {
+ // In this case, the center lines (not baselines) of the number frame
+ // and the equation frame shall be aligned.
+ let height = equation.height().max(number.height());
+ return equation.resize(
+ Size::new(width, height),
+ Axes::<FixedAlignment>::new(equation_align, FixedAlignment::Center),
+ );
+ }
+
+ let excess_above = Abs::zero().max({
+ let (.., baseline) = first;
+ number.baseline() - baseline
+ });
+ let excess_below = Abs::zero().max({
+ let (size, .., baseline) = last;
+ (number.height() - number.baseline()) - (size.y - baseline)
+ });
+ let height = equation.height() + excess_above + excess_below;
+
+ let resizing_offset = equation.resize(
+ Size::new(width, height),
+ Axes::<FixedAlignment>::new(equation_align, FixedAlignment::Start),
+ );
+ equation.translate(Point::with_y(excess_above));
+ resizing_offset + Point::with_y(excess_above)
+}
diff --git a/crates/typst/src/math/row.rs b/crates/typst/src/math/row.rs
index afed8231..0ce17ce5 100644
--- a/crates/typst/src/math/row.rs
+++ b/crates/typst/src/math/row.rs
@@ -375,8 +375,8 @@ impl Iterator for LeftRightAlternator {
pub struct MathRunFrameBuilder {
/// The size of the resulting frame.
pub size: Size,
- /// Sub frames for each row, and the positions where they should be pushed into
- /// the resulting frame.
+ /// Each row's frame, and the position where the frame should
+ /// be pushed into the resulting frame.
pub frames: Vec<(Frame, Point)>,
}
diff --git a/tests/ref/math-equation-align-numbered.png b/tests/ref/math-equation-align-numbered.png
index e43054c8..11d4b3b1 100644
--- a/tests/ref/math-equation-align-numbered.png
+++ b/tests/ref/math-equation-align-numbered.png
Binary files differ
diff --git a/tests/ref/math-equation-number-align-end.png b/tests/ref/math-equation-number-align-end.png
index f60a15ec..857d56f6 100644
--- a/tests/ref/math-equation-number-align-end.png
+++ b/tests/ref/math-equation-number-align-end.png
Binary files differ
diff --git a/tests/ref/math-equation-number-align-left.png b/tests/ref/math-equation-number-align-left.png
index a8ed40a5..ec6cfca0 100644
--- a/tests/ref/math-equation-number-align-left.png
+++ b/tests/ref/math-equation-number-align-left.png
Binary files differ
diff --git a/tests/ref/math-equation-number-align-monoline.png b/tests/ref/math-equation-number-align-monoline.png
new file mode 100644
index 00000000..681997d4
--- /dev/null
+++ b/tests/ref/math-equation-number-align-monoline.png
Binary files differ
diff --git a/tests/ref/math-equation-number-align-multiline-bottom.png b/tests/ref/math-equation-number-align-multiline-bottom.png
index cb0e5daa..08c80f97 100644
--- a/tests/ref/math-equation-number-align-multiline-bottom.png
+++ b/tests/ref/math-equation-number-align-multiline-bottom.png
Binary files differ
diff --git a/tests/ref/math-equation-number-align-multiline-expand.png b/tests/ref/math-equation-number-align-multiline-expand.png
index 3c3cdc05..b6546433 100644
--- a/tests/ref/math-equation-number-align-multiline-expand.png
+++ b/tests/ref/math-equation-number-align-multiline-expand.png
Binary files differ
diff --git a/tests/ref/math-equation-number-align-multiline-top-start.png b/tests/ref/math-equation-number-align-multiline-top-start.png
index 43346de9..6a3dad50 100644
--- a/tests/ref/math-equation-number-align-multiline-top-start.png
+++ b/tests/ref/math-equation-number-align-multiline-top-start.png
Binary files differ
diff --git a/tests/ref/math-equation-number-align-right.png b/tests/ref/math-equation-number-align-right.png
index e3d588c4..63daed6c 100644
--- a/tests/ref/math-equation-number-align-right.png
+++ b/tests/ref/math-equation-number-align-right.png
Binary files differ
diff --git a/tests/ref/math-equation-number-align-start.png b/tests/ref/math-equation-number-align-start.png
index 67ed3c4c..769f3b82 100644
--- a/tests/ref/math-equation-number-align-start.png
+++ b/tests/ref/math-equation-number-align-start.png
Binary files differ
diff --git a/tests/ref/math-equation-number-align.png b/tests/ref/math-equation-number-align.png
index f60a15ec..857d56f6 100644
--- a/tests/ref/math-equation-number-align.png
+++ b/tests/ref/math-equation-number-align.png
Binary files differ
diff --git a/tests/ref/math-equation-numbering.png b/tests/ref/math-equation-numbering.png
index b1e6b10e..3210da23 100644
--- a/tests/ref/math-equation-numbering.png
+++ b/tests/ref/math-equation-numbering.png
Binary files differ
diff --git a/tests/ref/outline.png b/tests/ref/outline.png
index e5c24a98..71dd6e1a 100644
--- a/tests/ref/outline.png
+++ b/tests/ref/outline.png
Binary files differ
diff --git a/tests/ref/ref-supplements.png b/tests/ref/ref-supplements.png
index 46d1524a..3bd8a30f 100644
--- a/tests/ref/ref-supplements.png
+++ b/tests/ref/ref-supplements.png
Binary files differ
diff --git a/tests/suite/math/equation.typ b/tests/suite/math/equation.typ
index dd2745d1..d5771f95 100644
--- a/tests/suite/math/equation.typ
+++ b/tests/suite/math/equation.typ
@@ -152,6 +152,16 @@ $ a + b = c $
// Error: 52-67 expected `start`, `left`, `right`, or `end`, found center
#set math.equation(numbering: "(1)", number-align: center + bottom)
+--- math-equation-number-align-monoline ---
+#set math.equation(numbering: "(1)")
+$ p = sum_k k ln a $
+
+#set math.equation(numbering: "(1)", number-align: top)
+$ p = sum_k k ln a $
+
+#set math.equation(numbering: "(1)", number-align: bottom)
+$ p = sum_k k ln a $
+
--- math-equation-number-align-multiline ---
#set math.equation(numbering: "(1)")
@@ -163,13 +173,17 @@ $ p &= ln a b \
$ p &= ln a b \
&= ln a + ln b $
+$ q &= sum_k k ln a \
+ &= sum_k ln A $
--- math-equation-number-align-multiline-bottom ---
#show math.equation: set align(left)
#set math.equation(numbering: "(1)", number-align: bottom)
-$ q &= ln sqrt(a b) \
- &= 1/2 (ln a + ln b) $
+$ p &= ln a b \
+ &= ln a + ln b $
+$ q &= sum_k ln A \
+ &= sum_k k ln a $
--- math-equation-number-align-multiline-expand ---
// Tests that if the numbering's layout box vertically exceeds the box of