mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Matrix baseline alignment
This commit is contained in:
parent
bb12624e8e
commit
e6400861ab
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 |
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user