mirror of
https://github.com/typst/typst
synced 2025-05-22 13:05:29 +08:00
Better named MathContext.layout_*()
methods (#3455)
This commit is contained in:
parent
72d324c5b4
commit
b3ed2df27e
@ -67,7 +67,7 @@ impl LayoutMath for Packed<AccentElem> {
|
|||||||
#[typst_macros::time(name = "math.accent", span = self.span())]
|
#[typst_macros::time(name = "math.accent", span = self.span())]
|
||||||
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
||||||
let cramped = style_cramped();
|
let cramped = style_cramped();
|
||||||
let base = ctx.layout_fragment(self.base(), styles.chain(&cramped))?;
|
let base = ctx.layout_into_fragment(self.base(), styles.chain(&cramped))?;
|
||||||
|
|
||||||
// Preserve class to preserve automatic spacing.
|
// Preserve class to preserve automatic spacing.
|
||||||
let base_class = base.class();
|
let base_class = base.class();
|
||||||
|
@ -57,11 +57,11 @@ impl LayoutMath for Packed<AttachElem> {
|
|||||||
let layout_attachment =
|
let layout_attachment =
|
||||||
|ctx: &mut MathContext, styles: StyleChain, getter: GetAttachment| {
|
|ctx: &mut MathContext, styles: StyleChain, getter: GetAttachment| {
|
||||||
getter(self, styles)
|
getter(self, styles)
|
||||||
.map(|elem| ctx.layout_fragment(&elem, styles))
|
.map(|elem| ctx.layout_into_fragment(&elem, styles))
|
||||||
.transpose()
|
.transpose()
|
||||||
};
|
};
|
||||||
|
|
||||||
let base = ctx.layout_fragment(self.base(), styles)?;
|
let base = ctx.layout_into_fragment(self.base(), styles)?;
|
||||||
|
|
||||||
let sup_style = style_for_superscript(styles);
|
let sup_style = style_for_superscript(styles);
|
||||||
let tl = layout_attachment(ctx, styles.chain(&sup_style), AttachElem::tl)?;
|
let tl = layout_attachment(ctx, styles.chain(&sup_style), AttachElem::tl)?;
|
||||||
@ -109,13 +109,14 @@ impl LayoutMath for Packed<PrimesElem> {
|
|||||||
4 => '⁗',
|
4 => '⁗',
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let f = ctx.layout_fragment(&TextElem::packed(c), styles)?;
|
let f = ctx.layout_into_fragment(&TextElem::packed(c), styles)?;
|
||||||
ctx.push(f);
|
ctx.push(f);
|
||||||
}
|
}
|
||||||
count => {
|
count => {
|
||||||
// Custom amount of primes
|
// Custom amount of primes
|
||||||
let prime =
|
let prime = ctx
|
||||||
ctx.layout_fragment(&TextElem::packed('′'), styles)?.into_frame();
|
.layout_into_fragment(&TextElem::packed('′'), styles)?
|
||||||
|
.into_frame();
|
||||||
let width = prime.width() * (count + 1) as f64 / 2.0;
|
let width = prime.width() * (count + 1) as f64 / 2.0;
|
||||||
let mut frame = Frame::soft(Size::new(width, prime.height()));
|
let mut frame = Frame::soft(Size::new(width, prime.height()));
|
||||||
frame.set_baseline(prime.ascent());
|
frame.set_baseline(prime.ascent());
|
||||||
@ -148,7 +149,7 @@ pub struct ScriptsElem {
|
|||||||
impl LayoutMath for Packed<ScriptsElem> {
|
impl LayoutMath for Packed<ScriptsElem> {
|
||||||
#[typst_macros::time(name = "math.scripts", span = self.span())]
|
#[typst_macros::time(name = "math.scripts", span = self.span())]
|
||||||
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
||||||
let mut fragment = ctx.layout_fragment(self.body(), styles)?;
|
let mut fragment = ctx.layout_into_fragment(self.body(), styles)?;
|
||||||
fragment.set_limits(Limits::Never);
|
fragment.set_limits(Limits::Never);
|
||||||
ctx.push(fragment);
|
ctx.push(fragment);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -178,7 +179,7 @@ impl LayoutMath for Packed<LimitsElem> {
|
|||||||
#[typst_macros::time(name = "math.limits", span = self.span())]
|
#[typst_macros::time(name = "math.limits", span = self.span())]
|
||||||
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
||||||
let limits = if self.inline(styles) { Limits::Always } else { Limits::Display };
|
let limits = if self.inline(styles) { Limits::Always } else { Limits::Display };
|
||||||
let mut fragment = ctx.layout_fragment(self.body(), styles)?;
|
let mut fragment = ctx.layout_into_fragment(self.body(), styles)?;
|
||||||
fragment.set_limits(limits);
|
fragment.set_limits(limits);
|
||||||
ctx.push(fragment);
|
ctx.push(fragment);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -106,7 +106,7 @@ pub struct CancelElem {
|
|||||||
impl LayoutMath for Packed<CancelElem> {
|
impl LayoutMath for Packed<CancelElem> {
|
||||||
#[typst_macros::time(name = "math.cancel", span = self.span())]
|
#[typst_macros::time(name = "math.cancel", span = self.span())]
|
||||||
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
||||||
let body = ctx.layout_fragment(self.body(), styles)?;
|
let body = ctx.layout_into_fragment(self.body(), styles)?;
|
||||||
// Preserve properties of body.
|
// Preserve properties of body.
|
||||||
let body_class = body.class();
|
let body_class = body.class();
|
||||||
let body_italics = body.italics_correction();
|
let body_italics = body.italics_correction();
|
||||||
|
@ -37,7 +37,7 @@ impl LayoutMath for Packed<ClassElem> {
|
|||||||
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
||||||
let class = *self.class();
|
let class = *self.class();
|
||||||
let style = EquationElem::set_class(Some(class)).wrap();
|
let style = EquationElem::set_class(Some(class)).wrap();
|
||||||
let mut fragment = ctx.layout_fragment(self.body(), styles.chain(&style))?;
|
let mut fragment = ctx.layout_into_fragment(self.body(), styles.chain(&style))?;
|
||||||
fragment.set_class(class);
|
fragment.set_class(class);
|
||||||
fragment.set_limits(Limits::for_class(class));
|
fragment.set_limits(Limits::for_class(class));
|
||||||
ctx.push(fragment);
|
ctx.push(fragment);
|
||||||
|
@ -123,51 +123,51 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
|
|||||||
self.fragments.extend(fragments);
|
self.fragments.extend(fragments);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout_root(
|
/// Layout the given element and return the resulting `MathFragment`s.
|
||||||
&mut self,
|
pub fn layout_into_fragments(
|
||||||
elem: &dyn LayoutMath,
|
|
||||||
styles: StyleChain,
|
|
||||||
) -> SourceResult<MathRow> {
|
|
||||||
let row = self.layout_fragments(elem, styles)?;
|
|
||||||
Ok(MathRow::new(row))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn layout_fragment(
|
|
||||||
&mut self,
|
|
||||||
elem: &dyn LayoutMath,
|
|
||||||
styles: StyleChain,
|
|
||||||
) -> SourceResult<MathFragment> {
|
|
||||||
let row = self.layout_fragments(elem, styles)?;
|
|
||||||
Ok(MathRow::new(row).into_fragment(self, styles))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn layout_fragments(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
elem: &dyn LayoutMath,
|
elem: &dyn LayoutMath,
|
||||||
styles: StyleChain,
|
styles: StyleChain,
|
||||||
) -> SourceResult<Vec<MathFragment>> {
|
) -> SourceResult<Vec<MathFragment>> {
|
||||||
|
// The element's layout_math() changes the fragments held in this
|
||||||
|
// MathContext object, but for convenience this function shouldn't change
|
||||||
|
// them, so we restore the MathContext's fragments after obtaining the
|
||||||
|
// layout result.
|
||||||
let prev = std::mem::take(&mut self.fragments);
|
let prev = std::mem::take(&mut self.fragments);
|
||||||
elem.layout_math(self, styles)?;
|
elem.layout_math(self, styles)?;
|
||||||
Ok(std::mem::replace(&mut self.fragments, prev))
|
Ok(std::mem::replace(&mut self.fragments, prev))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout_row(
|
/// Layout the given element and return the result as a `MathRow`.
|
||||||
|
pub fn layout_into_row(
|
||||||
&mut self,
|
&mut self,
|
||||||
elem: &dyn LayoutMath,
|
elem: &dyn LayoutMath,
|
||||||
styles: StyleChain,
|
styles: StyleChain,
|
||||||
) -> SourceResult<MathRow> {
|
) -> SourceResult<MathRow> {
|
||||||
let fragments = self.layout_fragments(elem, styles)?;
|
let row = self.layout_into_fragments(elem, styles)?;
|
||||||
Ok(MathRow::new(fragments))
|
Ok(MathRow::new(row))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout_frame(
|
/// Layout the given element and return the result as a
|
||||||
|
/// unified `MathFragment`.
|
||||||
|
pub fn layout_into_fragment(
|
||||||
|
&mut self,
|
||||||
|
elem: &dyn LayoutMath,
|
||||||
|
styles: StyleChain,
|
||||||
|
) -> SourceResult<MathFragment> {
|
||||||
|
Ok(self.layout_into_row(elem, styles)?.into_fragment(self, styles))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Layout the given element and return the result as a `Frame`.
|
||||||
|
pub fn layout_into_frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
elem: &dyn LayoutMath,
|
elem: &dyn LayoutMath,
|
||||||
styles: StyleChain,
|
styles: StyleChain,
|
||||||
) -> SourceResult<Frame> {
|
) -> SourceResult<Frame> {
|
||||||
Ok(self.layout_fragment(elem, styles)?.into_frame())
|
Ok(self.layout_into_fragment(elem, styles)?.into_frame())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Layout the given `BoxElem` into a `Frame`.
|
||||||
pub fn layout_box(
|
pub fn layout_box(
|
||||||
&mut self,
|
&mut self,
|
||||||
boxed: &Packed<BoxElem>,
|
boxed: &Packed<BoxElem>,
|
||||||
@ -178,6 +178,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
|
|||||||
boxed.layout(self.engine, styles.chain(&local), self.regions)
|
boxed.layout(self.engine, styles.chain(&local), self.regions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Layout the given `Content` into a `Frame`.
|
||||||
pub fn layout_content(
|
pub fn layout_content(
|
||||||
&mut self,
|
&mut self,
|
||||||
content: &Content,
|
content: &Content,
|
||||||
@ -190,6 +191,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
|
|||||||
.into_frame())
|
.into_frame())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Layout the given `TextElem` into a `MathFragment`.
|
||||||
pub fn layout_text(
|
pub fn layout_text(
|
||||||
&mut self,
|
&mut self,
|
||||||
elem: &Packed<TextElem>,
|
elem: &Packed<TextElem>,
|
||||||
@ -273,6 +275,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
|
|||||||
Ok(fragment)
|
Ok(fragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Layout the given text string into a `FrameFragment`.
|
||||||
fn layout_complex_text(
|
fn layout_complex_text(
|
||||||
&mut self,
|
&mut self,
|
||||||
text: &str,
|
text: &str,
|
||||||
|
@ -196,7 +196,7 @@ impl Packed<EquationElem> {
|
|||||||
let font = find_math_font(engine, styles, self.span())?;
|
let font = find_math_font(engine, styles, self.span())?;
|
||||||
|
|
||||||
let mut ctx = MathContext::new(engine, styles, regions, &font);
|
let mut ctx = MathContext::new(engine, styles, regions, &font);
|
||||||
let rows = ctx.layout_root(self, styles)?;
|
let rows = ctx.layout_into_row(self, styles)?;
|
||||||
|
|
||||||
let mut items = if rows.row_count() == 1 {
|
let mut items = if rows.row_count() == 1 {
|
||||||
rows.into_par_items()
|
rows.into_par_items()
|
||||||
@ -239,7 +239,7 @@ impl LayoutSingle for Packed<EquationElem> {
|
|||||||
let font = find_math_font(engine, styles, self.span())?;
|
let font = find_math_font(engine, styles, self.span())?;
|
||||||
|
|
||||||
let mut ctx = MathContext::new(engine, styles, regions, &font);
|
let mut ctx = MathContext::new(engine, styles, regions, &font);
|
||||||
let mut frame = ctx.layout_frame(self, styles)?;
|
let mut frame = ctx.layout_into_frame(self, styles)?;
|
||||||
|
|
||||||
if let Some(numbering) = (**self).numbering(styles) {
|
if let Some(numbering) = (**self).numbering(styles) {
|
||||||
let pod = Regions::one(regions.base(), Axes::splat(false));
|
let pod = Regions::one(regions.base(), Axes::splat(false));
|
||||||
|
@ -118,10 +118,10 @@ fn layout(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let num_style = style_for_numerator(styles);
|
let num_style = style_for_numerator(styles);
|
||||||
let num = ctx.layout_frame(num, styles.chain(&num_style))?;
|
let num = ctx.layout_into_frame(num, styles.chain(&num_style))?;
|
||||||
|
|
||||||
let denom_style = style_for_denominator(styles);
|
let denom_style = style_for_denominator(styles);
|
||||||
let denom = ctx.layout_frame(
|
let denom = ctx.layout_into_frame(
|
||||||
&Content::sequence(
|
&Content::sequence(
|
||||||
// Add a comma between each element.
|
// Add a comma between each element.
|
||||||
denom.iter().flat_map(|a| [TextElem::packed(','), a.clone()]).skip(1),
|
denom.iter().flat_map(|a| [TextElem::packed(','), a.clone()]).skip(1),
|
||||||
|
@ -47,7 +47,7 @@ impl LayoutMath for Packed<LrElem> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut fragments = ctx.layout_fragments(body, styles)?;
|
let mut fragments = ctx.layout_into_fragments(body, styles)?;
|
||||||
let axis = scaled!(ctx, styles, axis_height);
|
let axis = scaled!(ctx, styles, axis_height);
|
||||||
let max_extent = fragments
|
let max_extent = fragments
|
||||||
.iter()
|
.iter()
|
||||||
@ -115,7 +115,7 @@ pub struct MidElem {
|
|||||||
impl LayoutMath for Packed<MidElem> {
|
impl LayoutMath for Packed<MidElem> {
|
||||||
#[typst_macros::time(name = "math.mid", span = self.span())]
|
#[typst_macros::time(name = "math.mid", span = self.span())]
|
||||||
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
||||||
let mut fragments = ctx.layout_fragments(self.body(), styles)?;
|
let mut fragments = ctx.layout_into_fragments(self.body(), styles)?;
|
||||||
|
|
||||||
for fragment in &mut fragments {
|
for fragment in &mut fragments {
|
||||||
match fragment {
|
match fragment {
|
||||||
|
@ -393,7 +393,7 @@ fn layout_vec_body(
|
|||||||
let denom_style = style_for_denominator(styles);
|
let denom_style = style_for_denominator(styles);
|
||||||
let mut flat = vec![];
|
let mut flat = vec![];
|
||||||
for child in column {
|
for child in column {
|
||||||
flat.push(ctx.layout_row(child, styles.chain(&denom_style))?);
|
flat.push(ctx.layout_into_row(child, styles.chain(&denom_style))?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(stack(ctx, styles, flat, align, gap, 0))
|
Ok(stack(ctx, styles, flat, align, gap, 0))
|
||||||
@ -455,7 +455,7 @@ fn layout_mat_body(
|
|||||||
let denom_style = style_for_denominator(styles);
|
let denom_style = style_for_denominator(styles);
|
||||||
for (row, (ascent, descent)) in rows.iter().zip(&mut heights) {
|
for (row, (ascent, descent)) in rows.iter().zip(&mut heights) {
|
||||||
for (cell, col) in row.iter().zip(&mut cols) {
|
for (cell, col) in row.iter().zip(&mut cols) {
|
||||||
let cell = ctx.layout_row(cell, styles.chain(&denom_style))?;
|
let cell = ctx.layout_into_row(cell, styles.chain(&denom_style))?;
|
||||||
|
|
||||||
ascent.set_max(cell.ascent());
|
ascent.set_max(cell.ascent());
|
||||||
descent.set_max(cell.descent());
|
descent.set_max(cell.descent());
|
||||||
|
@ -36,7 +36,7 @@ pub struct OpElem {
|
|||||||
impl LayoutMath for Packed<OpElem> {
|
impl LayoutMath for Packed<OpElem> {
|
||||||
#[typst_macros::time(name = "math.op", span = self.span())]
|
#[typst_macros::time(name = "math.op", span = self.span())]
|
||||||
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
fn layout_math(&self, ctx: &mut MathContext, styles: StyleChain) -> SourceResult<()> {
|
||||||
let fragment = ctx.layout_fragment(self.text(), styles)?;
|
let fragment = ctx.layout_into_fragment(self.text(), styles)?;
|
||||||
let italics = fragment.italics_correction();
|
let italics = fragment.italics_correction();
|
||||||
let accent_attach = fragment.accent_attach();
|
let accent_attach = fragment.accent_attach();
|
||||||
let text_like = fragment.is_text_like();
|
let text_like = fragment.is_text_like();
|
||||||
|
@ -71,7 +71,7 @@ fn layout(
|
|||||||
|
|
||||||
// Layout radicand.
|
// Layout radicand.
|
||||||
let cramped = style_cramped();
|
let cramped = style_cramped();
|
||||||
let radicand = ctx.layout_frame(radicand, styles.chain(&cramped))?;
|
let radicand = ctx.layout_into_frame(radicand, styles.chain(&cramped))?;
|
||||||
|
|
||||||
// Layout root symbol.
|
// Layout root symbol.
|
||||||
let target = radicand.height() + thickness + gap;
|
let target = radicand.height() + thickness + gap;
|
||||||
@ -82,7 +82,7 @@ fn layout(
|
|||||||
// Layout the index.
|
// Layout the index.
|
||||||
let sscript = EquationElem::set_size(MathSize::ScriptScript).wrap();
|
let sscript = EquationElem::set_size(MathSize::ScriptScript).wrap();
|
||||||
let index = index
|
let index = index
|
||||||
.map(|elem| ctx.layout_frame(elem, styles.chain(&sscript)))
|
.map(|elem| ctx.layout_into_frame(elem, styles.chain(&sscript)))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
// TeXbook, page 443, item 11
|
// TeXbook, page 443, item 11
|
||||||
|
@ -72,7 +72,7 @@ fn layout_underoverline(
|
|||||||
let gap = scaled!(ctx, styles, underbar_vertical_gap);
|
let gap = scaled!(ctx, styles, underbar_vertical_gap);
|
||||||
extra_height = sep + bar_height + gap;
|
extra_height = sep + bar_height + gap;
|
||||||
|
|
||||||
content = ctx.layout_fragment(body, styles)?;
|
content = ctx.layout_into_fragment(body, styles)?;
|
||||||
|
|
||||||
line_pos = Point::with_y(content.height() + gap + bar_height / 2.0);
|
line_pos = Point::with_y(content.height() + gap + bar_height / 2.0);
|
||||||
content_pos = Point::zero();
|
content_pos = Point::zero();
|
||||||
@ -85,7 +85,7 @@ fn layout_underoverline(
|
|||||||
extra_height = sep + bar_height + gap;
|
extra_height = sep + bar_height + gap;
|
||||||
|
|
||||||
let cramped = style_cramped();
|
let cramped = style_cramped();
|
||||||
content = ctx.layout_fragment(body, styles.chain(&cramped))?;
|
content = ctx.layout_into_fragment(body, styles.chain(&cramped))?;
|
||||||
|
|
||||||
line_pos = Point::with_y(sep + bar_height / 2.0);
|
line_pos = Point::with_y(sep + bar_height / 2.0);
|
||||||
content_pos = Point::with_y(extra_height);
|
content_pos = Point::with_y(extra_height);
|
||||||
@ -260,7 +260,7 @@ fn layout_underoverspreader(
|
|||||||
) -> SourceResult<()> {
|
) -> SourceResult<()> {
|
||||||
let font_size = scaled_font_size(ctx, styles);
|
let font_size = scaled_font_size(ctx, styles);
|
||||||
let gap = gap.at(font_size);
|
let gap = gap.at(font_size);
|
||||||
let body = ctx.layout_row(body, styles)?;
|
let body = ctx.layout_into_row(body, styles)?;
|
||||||
let body_class = body.class();
|
let body_class = body.class();
|
||||||
let body = body.into_fragment(ctx, styles);
|
let body = body.into_fragment(ctx, styles);
|
||||||
let glyph = GlyphFragment::new(ctx, styles, c, span);
|
let glyph = GlyphFragment::new(ctx, styles, c, span);
|
||||||
@ -280,7 +280,7 @@ fn layout_underoverspreader(
|
|||||||
rows.extend(
|
rows.extend(
|
||||||
annotation
|
annotation
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|annotation| ctx.layout_row(annotation, row_styles))
|
.map(|annotation| ctx.layout_into_row(annotation, row_styles))
|
||||||
.transpose()?,
|
.transpose()?,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user