diff --git a/library/src/math/matrix.rs b/library/src/math/matrix.rs index 5f448901b..e5ae6a1d2 100644 --- a/library/src/math/matrix.rs +++ b/library/src/math/matrix.rs @@ -249,38 +249,40 @@ fn layout_mat_body(ctx: &mut MathContext, rows: &[Vec]) -> SourceResult return Ok(Frame::new(Size::zero())); } - let mut rcols = vec![Abs::zero(); ncols]; - let mut rrows = vec![Abs::zero(); nrows]; + let mut widths = vec![Abs::zero(); ncols]; + let mut ascents = vec![Abs::zero(); nrows]; + let mut descents = vec![Abs::zero(); nrows]; ctx.style(ctx.style.for_denominator()); let mut cols = vec![vec![]; ncols]; - for (row, rrow) in rows.iter().zip(&mut rrows) { - for ((cell, rcol), col) in row.iter().zip(&mut rcols).zip(&mut cols) { + for ((row, ascent), descent) in rows.iter().zip(&mut ascents).zip(&mut descents) { + for ((cell, rcol), col) in row.iter().zip(&mut widths).zip(&mut cols) { let cell = ctx.layout_row(cell)?; rcol.set_max(cell.width()); - rrow.set_max(cell.height()); + ascent.set_max(cell.ascent()); + descent.set_max(cell.descent()); col.push(cell); } } ctx.unstyle(); - let width = rcols.iter().sum::() + col_gap * (ncols - 1) as f64; - let height = rrows.iter().sum::() + row_gap * (nrows - 1) as f64; + let width = widths.iter().sum::() + col_gap * (ncols - 1) as f64; + let height = ascents.iter().sum::() + + descents.iter().sum::() + + row_gap * (nrows - 1) as f64; let size = Size::new(width, height); let mut frame = Frame::new(size); let mut x = Abs::zero(); - for (col, &rcol) in cols.into_iter().zip(&rcols) { + for (col, &rcol) in cols.into_iter().zip(&widths) { let points = alignments(&col); let mut y = Abs::zero(); - for (cell, &rrow) in col.into_iter().zip(&rrows) { + for ((cell, &ascent), &descent) in col.into_iter().zip(&ascents).zip(&descents) { let cell = cell.to_aligned_frame(ctx, &points, Align::Center); - let pos = Point::new( - x + (rcol - cell.width()) / 2.0, - y + (rrow - cell.height()) / 2.0, - ); + let pos = + Point::new(x + (rcol - cell.width()) / 2.0, y + ascent - cell.ascent()); frame.push_frame(pos, cell); - y += rrow + row_gap; + y += ascent + descent + row_gap; } x += rcol + col_gap; } diff --git a/library/src/math/row.rs b/library/src/math/row.rs index e66fc18e8..41136a9e3 100644 --- a/library/src/math/row.rs +++ b/library/src/math/row.rs @@ -17,8 +17,15 @@ impl MathRow { } pub fn height(&self) -> Abs { - let (ascent, descent) = self.extent(); - ascent + descent + self.ascent() + self.descent() + } + + pub fn ascent(&self) -> Abs { + self.0.iter().map(MathFragment::ascent).max().unwrap_or_default() + } + + pub fn descent(&self) -> Abs { + self.0.iter().map(MathFragment::descent).max().unwrap_or_default() } pub fn push( @@ -124,7 +131,8 @@ impl MathRow { } fn to_line_frame(self, ctx: &MathContext, points: &[Abs], align: Align) -> Frame { - let (ascent, descent) = self.extent(); + let ascent = self.ascent(); + let descent = self.descent(); let size = Size::new(Abs::zero(), ascent + descent); let mut frame = Frame::new(size); let mut x = Abs::zero(); @@ -161,12 +169,6 @@ impl MathRow { frame.size_mut().x = x; frame } - - fn extent(&self) -> (Abs, Abs) { - let ascent = self.0.iter().map(MathFragment::ascent).max().unwrap_or_default(); - let descent = self.0.iter().map(MathFragment::descent).max().unwrap_or_default(); - (ascent, descent) - } } impl From for MathRow diff --git a/tests/ref/math/content.png b/tests/ref/math/content.png index 5d222f929..f02045269 100644 Binary files a/tests/ref/math/content.png and b/tests/ref/math/content.png differ diff --git a/tests/ref/math/matrix.png b/tests/ref/math/matrix.png index 4a60b3ff1..fa6e53f31 100644 Binary files a/tests/ref/math/matrix.png and b/tests/ref/math/matrix.png differ diff --git a/tests/typ/math/matrix.typ b/tests/typ/math/matrix.typ index 99e8fa19d..63294e039 100644 --- a/tests/typ/math/matrix.typ +++ b/tests/typ/math/matrix.typ @@ -13,12 +13,20 @@ $mat() dot --- // Test sparse matrix. -$mat( +$ mat( 1, 2, ..., 10; 2, 2, ..., 10; dots.v, dots.v, dots.down, dots.v; 10, 10, ..., 10; -)$ +) $ + +--- +// Test baseline alignment. +$ mat( + a, b^2; + sum_(x \ y) x, a^(1/2); + zeta, alpha; + ) $ --- // Test alternative delimiter.