Better named MathContext.layout_*() methods (#3455)

This commit is contained in:
Leedehai 2024-02-20 08:19:31 -05:00 committed by GitHub
parent 72d324c5b4
commit b3ed2df27e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 53 additions and 49 deletions

View File

@ -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();

View File

@ -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(())

View File

@ -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();

View File

@ -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);

View File

@ -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,

View File

@ -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));

View File

@ -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),

View File

@ -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 {

View File

@ -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());

View File

@ -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();

View File

@ -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

View File

@ -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()?,
); );