diff options
| author | Wenzhuo Liu <mgt@oi-wiki.org> | 2024-06-04 23:42:02 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-04 15:42:02 +0000 |
| commit | 681badf76a029e421415986aa3a46c0081d28470 (patch) | |
| tree | 43ee7f1cad04f6ad41b23d329d9da6e472a06b0a /crates | |
| parent | ada0f5da65ef41ac8fa11111839437c76edd3c68 (diff) | |
Pad matrix cell to make matrix have a consistent height (#4153)
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/typst/src/math/matrix.rs | 20 | ||||
| -rw-r--r-- | crates/typst/src/math/underover.rs | 26 |
2 files changed, 35 insertions, 11 deletions
diff --git a/crates/typst/src/math/matrix.rs b/crates/typst/src/math/matrix.rs index 4dadd756..34e0611a 100644 --- a/crates/typst/src/math/matrix.rs +++ b/crates/typst/src/math/matrix.rs @@ -22,7 +22,7 @@ use crate::visualize::{FixedStroke, Geometry, LineCap, Shape, Stroke}; use super::delimiter_alignment; -const DEFAULT_ROW_GAP: Em = Em::new(0.5); +const DEFAULT_ROW_GAP: Em = Em::new(0.2); const DEFAULT_COL_GAP: Em = Em::new(0.5); const VERTICAL_PADDING: Ratio = Ratio::new(0.1); const DEFAULT_STROKE_THICKNESS: Em = Em::new(0.05); @@ -441,8 +441,12 @@ fn layout_vec_body( for child in column { flat.push(ctx.layout_into_run(child, styles.chain(&denom_style))?); } - - Ok(stack(flat, align, gap, 0, alternator)) + // We pad ascent and descent with the ascent and descent of the paren + // to ensure that normal vectors are aligned with others unless they are + // way too big. + let paren = + GlyphFragment::new(ctx, styles.chain(&denom_style), '(', Span::detached()); + Ok(stack(flat, align, gap, 0, alternator, Some((paren.ascent, paren.descent)))) } /// Layout the inner contents of a matrix. @@ -499,12 +503,18 @@ fn layout_mat_body( let mut cols = vec![vec![]; ncols]; let denom_style = style_for_denominator(styles); + // We pad ascent and descent with the ascent and descent of the paren + // to ensure that normal matrices are aligned with others unless they are + // way too big. + let paren = + GlyphFragment::new(ctx, styles.chain(&denom_style), '(', Span::detached()); + for (row, (ascent, descent)) in rows.iter().zip(&mut heights) { for (cell, col) in row.iter().zip(&mut cols) { let cell = ctx.layout_into_run(cell, styles.chain(&denom_style))?; - ascent.set_max(cell.ascent()); - descent.set_max(cell.descent()); + ascent.set_max(cell.ascent().max(paren.ascent)); + descent.set_max(cell.descent().max(paren.descent)); col.push(cell); } diff --git a/crates/typst/src/math/underover.rs b/crates/typst/src/math/underover.rs index 6be86d9f..defa46c1 100644 --- a/crates/typst/src/math/underover.rs +++ b/crates/typst/src/math/underover.rs @@ -291,8 +291,14 @@ fn layout_underoverspreader( baseline = rows.len() - 1; } - let frame = - stack(rows, FixedAlignment::Center, gap, baseline, LeftRightAlternator::Right); + let frame = stack( + rows, + FixedAlignment::Center, + gap, + baseline, + LeftRightAlternator::Right, + None, + ); ctx.push(FrameFragment::new(ctx, styles, frame).with_class(body_class)); Ok(()) @@ -309,6 +315,7 @@ pub(super) fn stack( gap: Abs, baseline: usize, alternator: LeftRightAlternator, + minimum_ascent_descent: Option<(Abs, Abs)>, ) -> Frame { let rows: Vec<_> = rows.into_iter().flat_map(|r| r.rows()).collect(); let AlignmentResult { points, width } = alignments(&rows); @@ -317,20 +324,27 @@ pub(super) fn stack( .map(|row| row.into_line_frame(&points, alternator)) .collect(); + let padded_height = |height: Abs| { + height.max(minimum_ascent_descent.map_or(Abs::zero(), |(a, d)| a + d)) + }; + let mut frame = Frame::soft(Size::new( width, - rows.iter().map(|row| row.height()).sum::<Abs>() + rows.iter().map(|row| padded_height(row.height())).sum::<Abs>() + rows.len().saturating_sub(1) as f64 * gap, )); let mut y = Abs::zero(); for (i, row) in rows.into_iter().enumerate() { let x = align.position(width - row.width()); - let pos = Point::new(x, y); + let ascent_padded_part = minimum_ascent_descent + .map_or(Abs::zero(), |(a, _)| (a - row.ascent())) + .max(Abs::zero()); + let pos = Point::new(x, y + ascent_padded_part); if i == baseline { - frame.set_baseline(y + row.baseline()); + frame.set_baseline(y + row.baseline() + ascent_padded_part); } - y += row.height() + gap; + y += padded_height(row.height()) + gap; frame.push_frame(pos, row); } |
