mirror of
https://github.com/typst/typst
synced 2025-05-13 12:36:23 +08:00
Respect alignment in math formulas
This commit is contained in:
parent
f7458f9533
commit
9d715fd11c
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user