Matrix baseline alignment

This commit is contained in:
Laurenz 2023-02-02 14:40:16 +01:00
parent bb12624e8e
commit e6400861ab
5 changed files with 37 additions and 25 deletions

View File

@ -249,38 +249,40 @@ fn layout_mat_body(ctx: &mut MathContext, rows: &[Vec<Content>]) -> SourceResult
return Ok(Frame::new(Size::zero())); return Ok(Frame::new(Size::zero()));
} }
let mut rcols = vec![Abs::zero(); ncols]; let mut widths = vec![Abs::zero(); ncols];
let mut rrows = vec![Abs::zero(); nrows]; let mut ascents = vec![Abs::zero(); nrows];
let mut descents = vec![Abs::zero(); nrows];
ctx.style(ctx.style.for_denominator()); ctx.style(ctx.style.for_denominator());
let mut cols = vec![vec![]; ncols]; let mut cols = vec![vec![]; ncols];
for (row, rrow) in rows.iter().zip(&mut rrows) { for ((row, ascent), descent) in rows.iter().zip(&mut ascents).zip(&mut descents) {
for ((cell, rcol), col) in row.iter().zip(&mut rcols).zip(&mut cols) { for ((cell, rcol), col) in row.iter().zip(&mut widths).zip(&mut cols) {
let cell = ctx.layout_row(cell)?; let cell = ctx.layout_row(cell)?;
rcol.set_max(cell.width()); rcol.set_max(cell.width());
rrow.set_max(cell.height()); ascent.set_max(cell.ascent());
descent.set_max(cell.descent());
col.push(cell); col.push(cell);
} }
} }
ctx.unstyle(); ctx.unstyle();
let width = rcols.iter().sum::<Abs>() + col_gap * (ncols - 1) as f64; let width = widths.iter().sum::<Abs>() + col_gap * (ncols - 1) as f64;
let height = rrows.iter().sum::<Abs>() + row_gap * (nrows - 1) as f64; let height = ascents.iter().sum::<Abs>()
+ descents.iter().sum::<Abs>()
+ row_gap * (nrows - 1) as f64;
let size = Size::new(width, height); let size = Size::new(width, height);
let mut frame = Frame::new(size); let mut frame = Frame::new(size);
let mut x = Abs::zero(); 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 points = alignments(&col);
let mut y = Abs::zero(); 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 cell = cell.to_aligned_frame(ctx, &points, Align::Center);
let pos = Point::new( let pos =
x + (rcol - cell.width()) / 2.0, Point::new(x + (rcol - cell.width()) / 2.0, y + ascent - cell.ascent());
y + (rrow - cell.height()) / 2.0,
);
frame.push_frame(pos, cell); frame.push_frame(pos, cell);
y += rrow + row_gap; y += ascent + descent + row_gap;
} }
x += rcol + col_gap; x += rcol + col_gap;
} }

View File

@ -17,8 +17,15 @@ impl MathRow {
} }
pub fn height(&self) -> Abs { pub fn height(&self) -> Abs {
let (ascent, descent) = self.extent(); self.ascent() + self.descent()
ascent + 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( pub fn push(
@ -124,7 +131,8 @@ impl MathRow {
} }
fn to_line_frame(self, ctx: &MathContext, points: &[Abs], align: Align) -> Frame { 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 size = Size::new(Abs::zero(), ascent + descent);
let mut frame = Frame::new(size); let mut frame = Frame::new(size);
let mut x = Abs::zero(); let mut x = Abs::zero();
@ -161,12 +169,6 @@ impl MathRow {
frame.size_mut().x = x; frame.size_mut().x = x;
frame 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<T> From<T> for MathRow impl<T> From<T> for MathRow

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -13,12 +13,20 @@ $mat() dot
--- ---
// Test sparse matrix. // Test sparse matrix.
$mat( $ mat(
1, 2, ..., 10; 1, 2, ..., 10;
2, 2, ..., 10; 2, 2, ..., 10;
dots.v, dots.v, dots.down, dots.v; dots.v, dots.v, dots.down, dots.v;
10, 10, ..., 10; 10, 10, ..., 10;
)$ ) $
---
// Test baseline alignment.
$ mat(
a, b^2;
sum_(x \ y) x, a^(1/2);
zeta, alpha;
) $
--- ---
// Test alternative delimiter. // Test alternative delimiter.