Respect alignment in math formulas

This commit is contained in:
Laurenz 2023-01-29 19:42:30 +01:00
parent f7458f9533
commit 9d715fd11c

View File

@ -1,3 +1,5 @@
use crate::layout::AlignNode;
use super::*; use super::*;
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
@ -78,7 +80,9 @@ impl MathRow {
} }
pub fn to_frame(self, ctx: &MathContext) -> Frame { pub fn to_frame(self, ctx: &MathContext) -> Frame {
self.to_aligned_frame(ctx, &[], Align::Center) let styles = ctx.styles();
let align = styles.get(AlignNode::ALIGNS).x.resolve(styles);
self.to_aligned_frame(ctx, &[], align)
} }
pub fn to_aligned_frame( pub fn to_aligned_frame(
@ -88,23 +92,29 @@ impl MathRow {
align: Align, align: Align,
) -> Frame { ) -> Frame {
if self.0.iter().any(|frag| matches!(frag, MathFragment::Linebreak)) { if self.0.iter().any(|frag| matches!(frag, MathFragment::Linebreak)) {
let mut frame = Frame::new(Size::zero());
let fragments = std::mem::take(&mut self.0); let fragments = std::mem::take(&mut self.0);
let leading = ctx.styles().get(ParNode::LEADING); let leading = ctx.styles().get(ParNode::LEADING) * ctx.style.size.factor(ctx);
let rows: Vec<_> = fragments let rows: Vec<_> = fragments
.split(|frag| matches!(frag, MathFragment::Linebreak)) .split(|frag| matches!(frag, MathFragment::Linebreak))
.map(|slice| Self(slice.to_vec())) .map(|slice| Self(slice.to_vec()))
.collect(); .collect();
let width = rows.iter().map(|row| row.width()).max().unwrap_or_default();
let points = alignments(&rows); let points = alignments(&rows);
let mut frame = Frame::new(Size::zero());
for (i, row) in rows.into_iter().enumerate() { for (i, row) in rows.into_iter().enumerate() {
let size = frame.size_mut();
let sub = row.to_line_frame(ctx, &points, align); let sub = row.to_line_frame(ctx, &points, align);
let size = frame.size_mut();
if i > 0 { if i > 0 {
size.y += leading; size.y += leading;
} }
let pos = Point::with_y(size.y);
let mut pos = Point::with_y(size.y);
if points.is_empty() {
pos.x = align.position(width - sub.width());
}
size.y += sub.height(); size.y += sub.height();
size.x.set_max(sub.width()); size.x.set_max(sub.width());
frame.push_frame(pos, sub); frame.push_frame(pos, sub);
@ -123,13 +133,14 @@ impl MathRow {
frame.set_baseline(ascent); frame.set_baseline(ascent);
if let (Some(&first), Align::Center) = (points.first(), align) { if let (Some(&first), Align::Center) = (points.first(), align) {
let segment: Abs = self let mut offset = first;
.0 for fragment in &self.0 {
.iter() offset -= fragment.width();
.take_while(|fragment| !matches!(fragment, MathFragment::Align)) if matches!(fragment, MathFragment::Align) {
.map(|fragment| fragment.width()) x = offset;
.sum(); break;
x = first - segment; }
}
} }
let mut fragments = self.0.into_iter().peekable(); let mut fragments = self.0.into_iter().peekable();