Pad matrix cell to make matrix have a consistent height (#4153)
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
tests/ref/issue-1617-mat-align.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 669 B After Width: | Height: | Size: 674 B |
Before Width: | Height: | Size: 757 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 568 B |
Before Width: | Height: | Size: 796 B After Width: | Height: | Size: 793 B |
Before Width: | Height: | Size: 308 B After Width: | Height: | Size: 343 B |
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 340 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 984 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 908 B After Width: | Height: | Size: 1009 B |
Before Width: | Height: | Size: 896 B After Width: | Height: | Size: 992 B |
Before Width: | Height: | Size: 916 B After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 930 B After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 837 B After Width: | Height: | Size: 802 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 580 B After Width: | Height: | Size: 620 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 521 B After Width: | Height: | Size: 552 B |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 489 B After Width: | Height: | Size: 496 B |
Before Width: | Height: | Size: 493 B After Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 898 B After Width: | Height: | Size: 882 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 770 B After Width: | Height: | Size: 784 B |
Before Width: | Height: | Size: 908 B After Width: | Height: | Size: 1009 B |
Before Width: | Height: | Size: 196 B After Width: | Height: | Size: 203 B |
Before Width: | Height: | Size: 397 B After Width: | Height: | Size: 420 B |
Before Width: | Height: | Size: 591 B After Width: | Height: | Size: 620 B |
@ -212,3 +212,18 @@ $ mat(delim: angle.r, 1, 2; 3, 4) $
|
||||
--- math-mat-delims-pair ---
|
||||
$ mat(delim: #(none, "["), 1, 2; 3, 4) $
|
||||
$ mat(delim: #(sym.angle.r, sym.bracket.double.r), 1, 2; 3, 4) $
|
||||
|
||||
--- issue-1617-mat-align ---
|
||||
#set page(width: auto)
|
||||
$ mat(a, b; c, d) mat(x; y) $
|
||||
|
||||
$ x mat(a; c) + y mat(b; d)
|
||||
= mat(a x+b y; c x+d y) $
|
||||
|
||||
$ mat(
|
||||
-d_0, lambda_0, 0, 0, dots;
|
||||
mu_1, -d_1, lambda_1, 0, dots;
|
||||
0, mu_2, -d_2, lambda_2, dots;
|
||||
dots.v, dots.v, dots.v, dots.v, dots.down;
|
||||
)
|
||||
mat(p_0; p_1; p_2; dots.v) $
|
||||
|