mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Fix math size resolving (#5596)
This commit is contained in:
parent
39706fe42f
commit
bb38a01d06
@ -1,12 +1,9 @@
|
||||
use typst_library::diag::SourceResult;
|
||||
use typst_library::foundations::{Packed, StyleChain};
|
||||
use typst_library::layout::{Em, Frame, Point, Rel, Size};
|
||||
use typst_library::layout::{Em, Frame, Point, Size};
|
||||
use typst_library::math::{Accent, AccentElem};
|
||||
|
||||
use super::{
|
||||
scaled_font_size, style_cramped, FrameFragment, GlyphFragment, MathContext,
|
||||
MathFragment,
|
||||
};
|
||||
use super::{style_cramped, FrameFragment, GlyphFragment, MathContext, MathFragment};
|
||||
|
||||
/// How much the accent can be shorter than the base.
|
||||
const ACCENT_SHORT_FALL: Em = Em::new(0.5);
|
||||
@ -30,11 +27,7 @@ pub fn layout_accent(
|
||||
let base_class = base.class();
|
||||
let base_attach = base.accent_attach();
|
||||
|
||||
let width = elem
|
||||
.size(styles)
|
||||
.unwrap_or(Rel::one())
|
||||
.at(scaled_font_size(ctx, styles))
|
||||
.relative_to(base.width());
|
||||
let width = elem.size(styles).relative_to(base.width());
|
||||
|
||||
let Accent(c) = elem.accent();
|
||||
let mut glyph = GlyphFragment::new(ctx, styles, *c, elem.span());
|
||||
@ -75,7 +68,7 @@ pub fn layout_accent(
|
||||
frame.push_frame(accent_pos, accent);
|
||||
frame.push_frame(base_pos, base.into_frame());
|
||||
ctx.push(
|
||||
FrameFragment::new(ctx, styles, frame)
|
||||
FrameFragment::new(styles, frame)
|
||||
.with_class(base_class)
|
||||
.with_base_ascent(base_ascent)
|
||||
.with_italics_correction(base_italics_correction)
|
||||
|
@ -1,6 +1,6 @@
|
||||
use typst_library::diag::SourceResult;
|
||||
use typst_library::foundations::{Packed, Smart, StyleChain};
|
||||
use typst_library::layout::{Abs, Axis, Corner, Frame, Length, Point, Rel, Size};
|
||||
use typst_library::foundations::{Packed, StyleChain};
|
||||
use typst_library::layout::{Abs, Axis, Corner, Frame, Point, Rel, Size};
|
||||
use typst_library::math::{
|
||||
AttachElem, EquationElem, LimitsElem, PrimesElem, ScriptsElem, StretchElem,
|
||||
};
|
||||
@ -121,7 +121,7 @@ pub fn layout_primes(
|
||||
prime.clone(),
|
||||
)
|
||||
}
|
||||
ctx.push(FrameFragment::new(ctx, styles, frame).with_text_like(true));
|
||||
ctx.push(FrameFragment::new(styles, frame).with_text_like(true));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -154,11 +154,8 @@ pub fn layout_limits(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get the size to stretch the base to, if the attach argument is true.
|
||||
fn stretch_size(
|
||||
styles: StyleChain,
|
||||
elem: &Packed<AttachElem>,
|
||||
) -> Option<Smart<Rel<Length>>> {
|
||||
/// Get the size to stretch the base to.
|
||||
fn stretch_size(styles: StyleChain, elem: &Packed<AttachElem>) -> Option<Rel<Abs>> {
|
||||
// Extract from an EquationElem.
|
||||
let mut base = elem.base();
|
||||
while let Some(equation) = base.to_packed::<EquationElem>() {
|
||||
@ -277,7 +274,7 @@ fn layout_attachments(
|
||||
layout!(b, b_x, b_y); // lower-limit
|
||||
|
||||
// Done! Note that we retain the class of the base.
|
||||
ctx.push(FrameFragment::new(ctx, styles, frame).with_class(base_class));
|
||||
ctx.push(FrameFragment::new(styles, frame).with_class(base_class));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use typst_library::text::TextElem;
|
||||
use typst_library::visualize::{FixedStroke, Geometry};
|
||||
use typst_syntax::Span;
|
||||
|
||||
use super::{scaled_font_size, FrameFragment, MathContext};
|
||||
use super::{FrameFragment, MathContext};
|
||||
|
||||
/// Lays out a [`CancelElem`].
|
||||
#[typst_macros::time(name = "math.cancel", span = elem.span())]
|
||||
@ -27,7 +27,7 @@ pub fn layout_cancel(
|
||||
let mut body = body.into_frame();
|
||||
let body_size = body.size();
|
||||
let span = elem.span();
|
||||
let length = elem.length(styles).at(scaled_font_size(ctx, styles));
|
||||
let length = elem.length(styles);
|
||||
|
||||
let stroke = elem.stroke(styles).unwrap_or(FixedStroke {
|
||||
paint: TextElem::fill_in(styles).as_decoration(),
|
||||
@ -63,7 +63,7 @@ pub fn layout_cancel(
|
||||
}
|
||||
|
||||
ctx.push(
|
||||
FrameFragment::new(ctx, styles, body)
|
||||
FrameFragment::new(styles, body)
|
||||
.with_class(body_class)
|
||||
.with_italics_correction(body_italics)
|
||||
.with_accent_attach(body_attach)
|
||||
|
@ -1,5 +1,5 @@
|
||||
use typst_library::diag::SourceResult;
|
||||
use typst_library::foundations::{Content, Packed, StyleChain};
|
||||
use typst_library::foundations::{Content, Packed, Resolve, StyleChain};
|
||||
use typst_library::layout::{Em, Frame, FrameItem, Point, Size};
|
||||
use typst_library::math::{BinomElem, FracElem};
|
||||
use typst_library::text::TextElem;
|
||||
@ -7,8 +7,8 @@ use typst_library::visualize::{FixedStroke, Geometry};
|
||||
use typst_syntax::Span;
|
||||
|
||||
use super::{
|
||||
scaled_font_size, style_for_denominator, style_for_numerator, FrameFragment,
|
||||
GlyphFragment, MathContext, DELIM_SHORT_FALL,
|
||||
style_for_denominator, style_for_numerator, FrameFragment, GlyphFragment,
|
||||
MathContext, DELIM_SHORT_FALL,
|
||||
};
|
||||
|
||||
const FRAC_AROUND: Em = Em::new(0.1);
|
||||
@ -49,8 +49,7 @@ fn layout_frac_like(
|
||||
binom: bool,
|
||||
span: Span,
|
||||
) -> SourceResult<()> {
|
||||
let font_size = scaled_font_size(ctx, styles);
|
||||
let short_fall = DELIM_SHORT_FALL.at(font_size);
|
||||
let short_fall = DELIM_SHORT_FALL.resolve(styles);
|
||||
let axis = scaled!(ctx, styles, axis_height);
|
||||
let thickness = scaled!(ctx, styles, fraction_rule_thickness);
|
||||
let shift_up = scaled!(
|
||||
@ -86,7 +85,7 @@ fn layout_frac_like(
|
||||
styles.chain(&denom_style),
|
||||
)?;
|
||||
|
||||
let around = FRAC_AROUND.at(font_size);
|
||||
let around = FRAC_AROUND.resolve(styles);
|
||||
let num_gap = (shift_up - (axis + thickness / 2.0) - num.descent()).max(num_min);
|
||||
let denom_gap =
|
||||
(shift_down + (axis - thickness / 2.0) - denom.ascent()).max(denom_min);
|
||||
@ -111,7 +110,7 @@ fn layout_frac_like(
|
||||
.stretch_vertical(ctx, height, short_fall);
|
||||
left.center_on_axis(ctx);
|
||||
ctx.push(left);
|
||||
ctx.push(FrameFragment::new(ctx, styles, frame));
|
||||
ctx.push(FrameFragment::new(styles, frame));
|
||||
let mut right = GlyphFragment::new(ctx, styles, ')', span)
|
||||
.stretch_vertical(ctx, height, short_fall);
|
||||
right.center_on_axis(ctx);
|
||||
@ -129,7 +128,7 @@ fn layout_frac_like(
|
||||
span,
|
||||
),
|
||||
);
|
||||
ctx.push(FrameFragment::new(ctx, styles, frame));
|
||||
ctx.push(FrameFragment::new(styles, frame));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -17,7 +17,7 @@ use typst_library::visualize::Paint;
|
||||
use typst_syntax::Span;
|
||||
use unicode_math_class::MathClass;
|
||||
|
||||
use super::{scaled_font_size, stretch_glyph, MathContext, Scaled};
|
||||
use super::{stretch_glyph, MathContext, Scaled};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MathFragment {
|
||||
@ -292,7 +292,7 @@ impl GlyphFragment {
|
||||
region: TextElem::region_in(styles),
|
||||
fill: TextElem::fill_in(styles).as_decoration(),
|
||||
shift: TextElem::baseline_in(styles),
|
||||
font_size: scaled_font_size(ctx, styles),
|
||||
font_size: TextElem::size_in(styles),
|
||||
math_size: EquationElem::size_in(styles),
|
||||
width: Abs::zero(),
|
||||
ascent: Abs::zero(),
|
||||
@ -512,12 +512,12 @@ pub struct FrameFragment {
|
||||
}
|
||||
|
||||
impl FrameFragment {
|
||||
pub fn new(ctx: &MathContext, styles: StyleChain, frame: Frame) -> Self {
|
||||
pub fn new(styles: StyleChain, frame: Frame) -> Self {
|
||||
let base_ascent = frame.ascent();
|
||||
let accent_attach = frame.width() / 2.0;
|
||||
Self {
|
||||
frame: frame.post_processed(styles),
|
||||
font_size: scaled_font_size(ctx, styles),
|
||||
font_size: TextElem::size_in(styles),
|
||||
class: EquationElem::class_in(styles).unwrap_or(MathClass::Normal),
|
||||
math_size: EquationElem::size_in(styles),
|
||||
limits: Limits::Never,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use typst_library::diag::SourceResult;
|
||||
use typst_library::foundations::{Packed, Smart, StyleChain};
|
||||
use typst_library::layout::{Abs, Axis, Length, Rel};
|
||||
use typst_library::foundations::{Packed, StyleChain};
|
||||
use typst_library::layout::{Abs, Axis, Rel};
|
||||
use typst_library::math::{EquationElem, LrElem, MidElem};
|
||||
use unicode_math_class::MathClass;
|
||||
|
||||
@ -22,7 +22,7 @@ pub fn layout_lr(
|
||||
|
||||
// Extract implicit LrElem.
|
||||
if let Some(lr) = body.to_packed::<LrElem>() {
|
||||
if lr.size(styles).is_auto() {
|
||||
if lr.size(styles).is_one() {
|
||||
body = lr.body();
|
||||
}
|
||||
}
|
||||
@ -128,7 +128,7 @@ fn scale(
|
||||
styles: StyleChain,
|
||||
fragment: &mut MathFragment,
|
||||
relative_to: Abs,
|
||||
height: Smart<Rel<Length>>,
|
||||
height: Rel<Abs>,
|
||||
apply: Option<MathClass>,
|
||||
) {
|
||||
if matches!(
|
||||
|
@ -1,5 +1,5 @@
|
||||
use typst_library::diag::{bail, SourceResult};
|
||||
use typst_library::foundations::{Content, Packed, StyleChain};
|
||||
use typst_library::foundations::{Content, Packed, Resolve, StyleChain};
|
||||
use typst_library::layout::{
|
||||
Abs, Axes, Em, FixedAlignment, Frame, FrameItem, Point, Ratio, Rel, Size,
|
||||
};
|
||||
@ -9,9 +9,8 @@ use typst_library::visualize::{FillRule, FixedStroke, Geometry, LineCap, Shape};
|
||||
use typst_syntax::Span;
|
||||
|
||||
use super::{
|
||||
alignments, delimiter_alignment, scaled_font_size, stack, style_for_denominator,
|
||||
AlignmentResult, FrameFragment, GlyphFragment, LeftRightAlternator, MathContext,
|
||||
Scaled, DELIM_SHORT_FALL,
|
||||
alignments, delimiter_alignment, stack, style_for_denominator, AlignmentResult,
|
||||
FrameFragment, GlyphFragment, LeftRightAlternator, MathContext, DELIM_SHORT_FALL,
|
||||
};
|
||||
|
||||
const VERTICAL_PADDING: Ratio = Ratio::new(0.1);
|
||||
@ -30,7 +29,7 @@ pub fn layout_vec(
|
||||
styles,
|
||||
elem.children(),
|
||||
elem.align(styles),
|
||||
elem.gap(styles).at(scaled_font_size(ctx, styles)),
|
||||
elem.gap(styles),
|
||||
LeftRightAlternator::Right,
|
||||
)?;
|
||||
|
||||
@ -73,9 +72,6 @@ pub fn layout_mat(
|
||||
}
|
||||
}
|
||||
|
||||
let font_size = scaled_font_size(ctx, styles);
|
||||
let column_gap = elem.column_gap(styles).at(font_size);
|
||||
let row_gap = elem.row_gap(styles).at(font_size);
|
||||
let delim = elem.delim(styles);
|
||||
let frame = layout_mat_body(
|
||||
ctx,
|
||||
@ -83,7 +79,7 @@ pub fn layout_mat(
|
||||
rows,
|
||||
elem.align(styles),
|
||||
augment,
|
||||
Axes::new(column_gap, row_gap),
|
||||
Axes::new(elem.column_gap(styles), elem.row_gap(styles)),
|
||||
elem.span(),
|
||||
)?;
|
||||
|
||||
@ -103,7 +99,7 @@ pub fn layout_cases(
|
||||
styles,
|
||||
elem.children(),
|
||||
FixedAlignment::Start,
|
||||
elem.gap(styles).at(scaled_font_size(ctx, styles)),
|
||||
elem.gap(styles),
|
||||
LeftRightAlternator::None,
|
||||
)?;
|
||||
|
||||
@ -162,8 +158,7 @@ fn layout_mat_body(
|
||||
// with font size to ensure that augmentation lines
|
||||
// look correct by default at all matrix sizes.
|
||||
// The line cap is also set to square because it looks more "correct".
|
||||
let font_size = scaled_font_size(ctx, styles);
|
||||
let default_stroke_thickness = DEFAULT_STROKE_THICKNESS.at(font_size);
|
||||
let default_stroke_thickness = DEFAULT_STROKE_THICKNESS.resolve(styles);
|
||||
let default_stroke = FixedStroke {
|
||||
thickness: default_stroke_thickness,
|
||||
paint: TextElem::fill_in(styles).as_decoration(),
|
||||
@ -308,9 +303,8 @@ fn layout_delimiters(
|
||||
right: Option<char>,
|
||||
span: Span,
|
||||
) -> SourceResult<()> {
|
||||
let font_size = scaled_font_size(ctx, styles);
|
||||
let short_fall = DELIM_SHORT_FALL.at(font_size);
|
||||
let axis = ctx.constants.axis_height().scaled(ctx, font_size);
|
||||
let short_fall = DELIM_SHORT_FALL.resolve(styles);
|
||||
let axis = scaled!(ctx, styles, axis_height);
|
||||
let height = frame.height();
|
||||
let target = height + VERTICAL_PADDING.of(height);
|
||||
frame.set_baseline(height / 2.0 + axis);
|
||||
@ -322,7 +316,7 @@ fn layout_delimiters(
|
||||
ctx.push(left);
|
||||
}
|
||||
|
||||
ctx.push(FrameFragment::new(ctx, styles, frame));
|
||||
ctx.push(FrameFragment::new(styles, frame));
|
||||
|
||||
if let Some(right) = right {
|
||||
let mut right = GlyphFragment::new(ctx, styles, right, span)
|
||||
|
@ -28,8 +28,7 @@ use typst_library::math::*;
|
||||
use typst_library::model::ParElem;
|
||||
use typst_library::routines::{Arenas, RealizationKind};
|
||||
use typst_library::text::{
|
||||
families, features, variant, Font, LinebreakElem, SpaceElem, TextEdgeBounds,
|
||||
TextElem, TextSize,
|
||||
families, features, variant, Font, LinebreakElem, SpaceElem, TextEdgeBounds, TextElem,
|
||||
};
|
||||
use typst_library::World;
|
||||
use typst_syntax::Span;
|
||||
@ -58,12 +57,16 @@ pub fn layout_equation_inline(
|
||||
|
||||
let mut locator = locator.split();
|
||||
let mut ctx = MathContext::new(engine, &mut locator, styles, region, &font);
|
||||
|
||||
let scale_style = style_for_script_scale(&ctx);
|
||||
let styles = styles.chain(&scale_style);
|
||||
|
||||
let run = ctx.layout_into_run(&elem.body, styles)?;
|
||||
|
||||
let mut items = if run.row_count() == 1 {
|
||||
run.into_par_items()
|
||||
} else {
|
||||
vec![InlineItem::Frame(run.into_fragment(&ctx, styles).into_frame())]
|
||||
vec![InlineItem::Frame(run.into_fragment(styles).into_frame())]
|
||||
};
|
||||
|
||||
// An empty equation should have a height, so we still create a frame
|
||||
@ -75,13 +78,12 @@ pub fn layout_equation_inline(
|
||||
for item in &mut items {
|
||||
let InlineItem::Frame(frame) = item else { continue };
|
||||
|
||||
let font_size = scaled_font_size(&ctx, styles);
|
||||
let slack = ParElem::leading_in(styles) * 0.7;
|
||||
|
||||
let (t, b) = font.edges(
|
||||
TextElem::top_edge_in(styles),
|
||||
TextElem::bottom_edge_in(styles),
|
||||
font_size,
|
||||
TextElem::size_in(styles),
|
||||
TextEdgeBounds::Frame(frame),
|
||||
);
|
||||
|
||||
@ -110,9 +112,13 @@ pub fn layout_equation_block(
|
||||
|
||||
let mut locator = locator.split();
|
||||
let mut ctx = MathContext::new(engine, &mut locator, styles, regions.base(), &font);
|
||||
|
||||
let scale_style = style_for_script_scale(&ctx);
|
||||
let styles = styles.chain(&scale_style);
|
||||
|
||||
let full_equation_builder = ctx
|
||||
.layout_into_run(&elem.body, styles)?
|
||||
.multiline_frame_builder(&ctx, styles);
|
||||
.multiline_frame_builder(styles);
|
||||
let width = full_equation_builder.size.x;
|
||||
|
||||
let equation_builders = if BlockElem::breakable_in(styles) {
|
||||
@ -469,7 +475,7 @@ impl<'a, 'v, 'e> MathContext<'a, 'v, 'e> {
|
||||
elem: &Content,
|
||||
styles: StyleChain,
|
||||
) -> SourceResult<MathFragment> {
|
||||
Ok(self.layout_into_run(elem, styles)?.into_fragment(self, styles))
|
||||
Ok(self.layout_into_run(elem, styles)?.into_fragment(styles))
|
||||
}
|
||||
|
||||
/// Layout the given element and return the result as a [`Frame`].
|
||||
@ -502,7 +508,7 @@ impl<'a, 'v, 'e> MathContext<'a, 'v, 'e> {
|
||||
// Hack because the font is fixed in math.
|
||||
if styles != outer && TextElem::font_in(styles) != TextElem::font_in(outer) {
|
||||
let frame = layout_external(elem, self, styles)?;
|
||||
self.push(FrameFragment::new(self, styles, frame).with_spaced(true));
|
||||
self.push(FrameFragment::new(styles, frame).with_spaced(true));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -522,8 +528,7 @@ fn layout_realized(
|
||||
if let Some(elem) = elem.to_packed::<TagElem>() {
|
||||
ctx.push(MathFragment::Tag(elem.tag.clone()));
|
||||
} else if elem.is::<SpaceElem>() {
|
||||
let font_size = scaled_font_size(ctx, styles);
|
||||
ctx.push(MathFragment::Space(ctx.space_width.at(font_size)));
|
||||
ctx.push(MathFragment::Space(ctx.space_width.resolve(styles)));
|
||||
} else if elem.is::<LinebreakElem>() {
|
||||
ctx.push(MathFragment::Linebreak);
|
||||
} else if let Some(elem) = elem.to_packed::<HElem>() {
|
||||
@ -595,7 +600,7 @@ fn layout_realized(
|
||||
frame.set_baseline(frame.height() / 2.0 + axis);
|
||||
}
|
||||
ctx.push(
|
||||
FrameFragment::new(ctx, styles, frame)
|
||||
FrameFragment::new(styles, frame)
|
||||
.with_spaced(true)
|
||||
.with_ignorant(elem.is::<PlaceElem>()),
|
||||
);
|
||||
@ -610,15 +615,14 @@ fn layout_box(
|
||||
ctx: &mut MathContext,
|
||||
styles: StyleChain,
|
||||
) -> SourceResult<()> {
|
||||
let local = TextElem::set_size(TextSize(scaled_font_size(ctx, styles).into())).wrap();
|
||||
let frame = (ctx.engine.routines.layout_box)(
|
||||
elem,
|
||||
ctx.engine,
|
||||
ctx.locator.next(&elem.span()),
|
||||
styles.chain(&local),
|
||||
styles,
|
||||
ctx.region.size,
|
||||
)?;
|
||||
ctx.push(FrameFragment::new(ctx, styles, frame).with_spaced(true));
|
||||
ctx.push(FrameFragment::new(styles, frame).with_spaced(true));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -630,10 +634,7 @@ fn layout_h(
|
||||
) -> SourceResult<()> {
|
||||
if let Spacing::Rel(rel) = elem.amount() {
|
||||
if rel.rel.is_zero() {
|
||||
ctx.push(MathFragment::Spacing(
|
||||
rel.abs.at(scaled_font_size(ctx, styles)),
|
||||
elem.weak(styles),
|
||||
));
|
||||
ctx.push(MathFragment::Spacing(rel.abs.resolve(styles), elem.weak(styles)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -668,7 +669,7 @@ fn layout_op(
|
||||
let text_like = fragment.is_text_like();
|
||||
|
||||
ctx.push(
|
||||
FrameFragment::new(ctx, styles, fragment.into_frame())
|
||||
FrameFragment::new(styles, fragment.into_frame())
|
||||
.with_class(MathClass::Large)
|
||||
.with_italics_correction(italics)
|
||||
.with_accent_attach(accent_attach)
|
||||
@ -688,12 +689,11 @@ fn layout_external(
|
||||
ctx: &mut MathContext,
|
||||
styles: StyleChain,
|
||||
) -> SourceResult<Frame> {
|
||||
let local = TextElem::set_size(TextSize(scaled_font_size(ctx, styles).into())).wrap();
|
||||
(ctx.engine.routines.layout_frame)(
|
||||
ctx.engine,
|
||||
content,
|
||||
ctx.locator.next(&content.span()),
|
||||
styles.chain(&local),
|
||||
styles,
|
||||
ctx.region,
|
||||
)
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ pub fn layout_root(
|
||||
let styles = styles.chain(&cramped);
|
||||
let run = ctx.layout_into_run(radicand, styles)?;
|
||||
let multiline = run.is_multiline();
|
||||
let mut radicand = run.into_fragment(ctx, styles).into_frame();
|
||||
let mut radicand = run.into_fragment(styles).into_frame();
|
||||
if multiline {
|
||||
// Align the frame center line with the math axis.
|
||||
radicand.set_baseline(
|
||||
@ -120,7 +120,7 @@ pub fn layout_root(
|
||||
);
|
||||
|
||||
frame.push_frame(radicand_pos, radicand);
|
||||
ctx.push(FrameFragment::new(ctx, styles, frame));
|
||||
ctx.push(FrameFragment::new(styles, frame));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use typst_library::math::{EquationElem, MathSize, MEDIUM, THICK, THIN};
|
||||
use typst_library::model::ParElem;
|
||||
use unicode_math_class::MathClass;
|
||||
|
||||
use super::{alignments, scaled_font_size, FrameFragment, MathContext, MathFragment};
|
||||
use super::{alignments, FrameFragment, MathFragment};
|
||||
|
||||
const TIGHT_LEADING: Em = Em::new(0.25);
|
||||
|
||||
@ -161,15 +161,15 @@ impl MathRun {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_frame(self, ctx: &MathContext, styles: StyleChain) -> Frame {
|
||||
pub fn into_frame(self, styles: StyleChain) -> Frame {
|
||||
if !self.is_multiline() {
|
||||
self.into_line_frame(&[], LeftRightAlternator::Right)
|
||||
} else {
|
||||
self.multiline_frame_builder(ctx, styles).build()
|
||||
self.multiline_frame_builder(styles).build()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_fragment(self, ctx: &MathContext, styles: StyleChain) -> MathFragment {
|
||||
pub fn into_fragment(self, styles: StyleChain) -> MathFragment {
|
||||
if self.0.len() == 1 {
|
||||
return self.0.into_iter().next().unwrap();
|
||||
}
|
||||
@ -181,7 +181,7 @@ impl MathRun {
|
||||
.filter(|e| e.math_size().is_some())
|
||||
.all(|e| e.is_text_like());
|
||||
|
||||
FrameFragment::new(ctx, styles, self.into_frame(ctx, styles))
|
||||
FrameFragment::new(styles, self.into_frame(styles))
|
||||
.with_text_like(text_like)
|
||||
.into()
|
||||
}
|
||||
@ -189,11 +189,7 @@ impl MathRun {
|
||||
/// Returns a builder that lays out the [`MathFragment`]s into a possibly
|
||||
/// multi-row [`Frame`]. The rows are aligned using the same set of alignment
|
||||
/// points computed from them as a whole.
|
||||
pub fn multiline_frame_builder(
|
||||
self,
|
||||
ctx: &MathContext,
|
||||
styles: StyleChain,
|
||||
) -> MathRunFrameBuilder {
|
||||
pub fn multiline_frame_builder(self, styles: StyleChain) -> MathRunFrameBuilder {
|
||||
let rows: Vec<_> = self.rows();
|
||||
let row_count = rows.len();
|
||||
let alignments = alignments(&rows);
|
||||
@ -201,8 +197,7 @@ impl MathRun {
|
||||
let leading = if EquationElem::size_in(styles) >= MathSize::Text {
|
||||
ParElem::leading_in(styles)
|
||||
} else {
|
||||
let font_size = scaled_font_size(ctx, styles);
|
||||
TIGHT_LEADING.at(font_size)
|
||||
TIGHT_LEADING.resolve(styles)
|
||||
};
|
||||
|
||||
let align = AlignElem::alignment_in(styles).resolve(styles).x;
|
||||
|
@ -2,7 +2,6 @@ use ttf_parser::math::MathValue;
|
||||
use typst_library::foundations::{Style, StyleChain};
|
||||
use typst_library::layout::{Abs, Em, FixedAlignment, Frame, Point, Size, VAlignment};
|
||||
use typst_library::math::{EquationElem, MathSize};
|
||||
use typst_library::text::TextElem;
|
||||
use typst_utils::LazyHash;
|
||||
|
||||
use super::{LeftRightAlternator, MathContext, MathFragment, MathRun};
|
||||
@ -18,7 +17,7 @@ macro_rules! scaled {
|
||||
$crate::math::Scaled::scaled(
|
||||
$ctx.constants.$name(),
|
||||
$ctx,
|
||||
$crate::math::scaled_font_size($ctx, $styles),
|
||||
typst_library::text::TextElem::size_in($styles),
|
||||
)
|
||||
};
|
||||
}
|
||||
@ -55,16 +54,6 @@ impl Scaled for MathValue<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the font size scaled with the `MathSize`.
|
||||
pub fn scaled_font_size(ctx: &MathContext, styles: StyleChain) -> Abs {
|
||||
let factor = match EquationElem::size_in(styles) {
|
||||
MathSize::Display | MathSize::Text => 1.0,
|
||||
MathSize::Script => percent!(ctx, script_percent_scale_down),
|
||||
MathSize::ScriptScript => percent!(ctx, script_script_percent_scale_down),
|
||||
};
|
||||
factor * TextElem::size_in(styles)
|
||||
}
|
||||
|
||||
/// Styles something as cramped.
|
||||
pub fn style_cramped() -> LazyHash<Style> {
|
||||
EquationElem::set_cramped(true).wrap()
|
||||
@ -99,6 +88,15 @@ pub fn style_for_denominator(styles: StyleChain) -> [LazyHash<Style>; 2] {
|
||||
[style_for_numerator(styles), EquationElem::set_cramped(true).wrap()]
|
||||
}
|
||||
|
||||
/// Styles to add font constants to the style chain.
|
||||
pub fn style_for_script_scale(ctx: &MathContext) -> LazyHash<Style> {
|
||||
EquationElem::set_script_scale((
|
||||
ctx.constants.script_percent_scale_down(),
|
||||
ctx.constants.script_script_percent_scale_down(),
|
||||
))
|
||||
.wrap()
|
||||
}
|
||||
|
||||
/// How a delimieter should be aligned when scaling.
|
||||
pub fn delimiter_alignment(delimiter: char) -> VAlignment {
|
||||
match delimiter {
|
||||
|
@ -1,14 +1,14 @@
|
||||
use ttf_parser::math::{GlyphAssembly, GlyphConstruction, GlyphPart};
|
||||
use ttf_parser::LazyArray16;
|
||||
use typst_library::diag::{warning, SourceResult};
|
||||
use typst_library::foundations::{Packed, Smart, StyleChain};
|
||||
use typst_library::layout::{Abs, Axis, Frame, Length, Point, Rel, Size};
|
||||
use typst_library::foundations::{Packed, StyleChain};
|
||||
use typst_library::layout::{Abs, Axis, Frame, Point, Rel, Size};
|
||||
use typst_library::math::StretchElem;
|
||||
use typst_utils::Get;
|
||||
|
||||
use super::{
|
||||
delimiter_alignment, scaled_font_size, GlyphFragment, MathContext, MathFragment,
|
||||
Scaled, VariantFragment,
|
||||
delimiter_alignment, GlyphFragment, MathContext, MathFragment, Scaled,
|
||||
VariantFragment,
|
||||
};
|
||||
|
||||
/// Maximum number of times extenders can be repeated.
|
||||
@ -42,7 +42,7 @@ pub fn stretch_fragment(
|
||||
fragment: &mut MathFragment,
|
||||
axis: Option<Axis>,
|
||||
relative_to: Option<Abs>,
|
||||
stretch: Smart<Rel<Length>>,
|
||||
stretch: Rel<Abs>,
|
||||
short_fall: Abs,
|
||||
) {
|
||||
let glyph = match fragment {
|
||||
@ -66,10 +66,7 @@ pub fn stretch_fragment(
|
||||
let mut variant = stretch_glyph(
|
||||
ctx,
|
||||
glyph,
|
||||
stretch
|
||||
.unwrap_or(Rel::one())
|
||||
.at(scaled_font_size(ctx, styles))
|
||||
.relative_to(relative_to_size),
|
||||
stretch.relative_to(relative_to_size),
|
||||
short_fall,
|
||||
axis,
|
||||
);
|
||||
|
@ -6,15 +6,13 @@ use typst_library::foundations::{Packed, StyleChain, StyleVec};
|
||||
use typst_library::layout::{Abs, Size};
|
||||
use typst_library::math::{EquationElem, MathSize, MathVariant};
|
||||
use typst_library::text::{
|
||||
BottomEdge, BottomEdgeMetric, TextElem, TextSize, TopEdge, TopEdgeMetric,
|
||||
BottomEdge, BottomEdgeMetric, TextElem, TopEdge, TopEdgeMetric,
|
||||
};
|
||||
use typst_syntax::{is_newline, Span};
|
||||
use unicode_math_class::MathClass;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use super::{
|
||||
scaled_font_size, FrameFragment, GlyphFragment, MathContext, MathFragment, MathRun,
|
||||
};
|
||||
use super::{FrameFragment, GlyphFragment, MathContext, MathFragment, MathRun};
|
||||
|
||||
/// Lays out a [`TextElem`].
|
||||
pub fn layout_text(
|
||||
@ -70,13 +68,12 @@ pub fn layout_text(
|
||||
let c = styled_char(styles, c, false);
|
||||
fragments.push(GlyphFragment::new(ctx, styles, c, span).into());
|
||||
}
|
||||
let frame = MathRun::new(fragments).into_frame(ctx, styles);
|
||||
FrameFragment::new(ctx, styles, frame).with_text_like(true).into()
|
||||
let frame = MathRun::new(fragments).into_frame(styles);
|
||||
FrameFragment::new(styles, frame).with_text_like(true).into()
|
||||
} else {
|
||||
let local = [
|
||||
TextElem::set_top_edge(TopEdge::Metric(TopEdgeMetric::Bounds)),
|
||||
TextElem::set_bottom_edge(BottomEdge::Metric(BottomEdgeMetric::Bounds)),
|
||||
TextElem::set_size(TextSize(scaled_font_size(ctx, styles).into())),
|
||||
]
|
||||
.map(|p| p.wrap());
|
||||
|
||||
@ -94,10 +91,10 @@ pub fn layout_text(
|
||||
fragments.push(layout_complex_text(piece, ctx, span, styles)?.into());
|
||||
}
|
||||
}
|
||||
let mut frame = MathRun::new(fragments).into_frame(ctx, styles);
|
||||
let mut frame = MathRun::new(fragments).into_frame(styles);
|
||||
let axis = scaled!(ctx, styles, axis_height);
|
||||
frame.set_baseline(frame.height() / 2.0 + axis);
|
||||
FrameFragment::new(ctx, styles, frame).into()
|
||||
FrameFragment::new(styles, frame).into()
|
||||
} else {
|
||||
layout_complex_text(&text, ctx, span, styles)?.into()
|
||||
}
|
||||
@ -131,7 +128,7 @@ fn layout_complex_text(
|
||||
)?
|
||||
.into_frame();
|
||||
|
||||
Ok(FrameFragment::new(ctx, styles, frame)
|
||||
Ok(FrameFragment::new(styles, frame)
|
||||
.with_class(MathClass::Alphabetic)
|
||||
.with_text_like(true)
|
||||
.with_spaced(spaced))
|
||||
|
@ -1,5 +1,5 @@
|
||||
use typst_library::diag::SourceResult;
|
||||
use typst_library::foundations::{Content, Packed, StyleChain};
|
||||
use typst_library::foundations::{Content, Packed, Resolve, StyleChain};
|
||||
use typst_library::layout::{Abs, Em, FixedAlignment, Frame, FrameItem, Point, Size};
|
||||
use typst_library::math::{
|
||||
OverbraceElem, OverbracketElem, OverlineElem, OverparenElem, OvershellElem,
|
||||
@ -10,8 +10,8 @@ use typst_library::visualize::{FixedStroke, Geometry};
|
||||
use typst_syntax::Span;
|
||||
|
||||
use super::{
|
||||
scaled_font_size, stack, style_cramped, style_for_subscript, style_for_superscript,
|
||||
FrameFragment, GlyphFragment, LeftRightAlternator, MathContext, MathRun,
|
||||
stack, style_cramped, style_for_subscript, style_for_superscript, FrameFragment,
|
||||
GlyphFragment, LeftRightAlternator, MathContext, MathRun,
|
||||
};
|
||||
|
||||
const BRACE_GAP: Em = Em::new(0.25);
|
||||
@ -260,7 +260,7 @@ fn layout_underoverline(
|
||||
);
|
||||
|
||||
ctx.push(
|
||||
FrameFragment::new(ctx, styles, frame)
|
||||
FrameFragment::new(styles, frame)
|
||||
.with_class(content_class)
|
||||
.with_text_like(content_is_text_like)
|
||||
.with_italics_correction(content_italics_correction),
|
||||
@ -281,11 +281,10 @@ fn layout_underoverspreader(
|
||||
position: Position,
|
||||
span: Span,
|
||||
) -> SourceResult<()> {
|
||||
let font_size = scaled_font_size(ctx, styles);
|
||||
let gap = gap.at(font_size);
|
||||
let gap = gap.resolve(styles);
|
||||
let body = ctx.layout_into_run(body, styles)?;
|
||||
let body_class = body.class();
|
||||
let body = body.into_fragment(ctx, styles);
|
||||
let body = body.into_fragment(styles);
|
||||
let glyph = GlyphFragment::new(ctx, styles, c, span);
|
||||
let stretched = glyph.stretch_horizontal(ctx, body.width(), Abs::zero());
|
||||
|
||||
@ -321,7 +320,7 @@ fn layout_underoverspreader(
|
||||
LeftRightAlternator::Right,
|
||||
None,
|
||||
);
|
||||
ctx.push(FrameFragment::new(ctx, styles, frame).with_class(body_class));
|
||||
ctx.push(FrameFragment::new(styles, frame).with_class(body_class));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -86,12 +86,6 @@ impl Rel<Length> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert to a relative length with the absolute part resolved at the
|
||||
/// given font size.
|
||||
pub fn at(self, font_size: Abs) -> Rel<Abs> {
|
||||
self.map(|abs| abs.at(font_size))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Numeric + Debug> Debug for Rel<T> {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::diag::bail;
|
||||
use crate::foundations::{cast, elem, func, Content, NativeElement, Smart, Value};
|
||||
use crate::foundations::{cast, elem, func, Content, NativeElement, Value};
|
||||
use crate::layout::{Length, Rel};
|
||||
use crate::math::Mathy;
|
||||
use crate::text::TextElem;
|
||||
@ -52,7 +52,9 @@ pub struct AccentElem {
|
||||
pub accent: Accent,
|
||||
|
||||
/// The size of the accent, relative to the width of the base.
|
||||
pub size: Smart<Rel<Length>>,
|
||||
#[resolve]
|
||||
#[default(Rel::one())]
|
||||
pub size: Rel<Length>,
|
||||
}
|
||||
|
||||
/// An accent character.
|
||||
@ -101,7 +103,7 @@ macro_rules! accents {
|
||||
base: Content,
|
||||
/// The size of the accent, relative to the width of the base.
|
||||
#[named]
|
||||
size: Option<Smart<Rel<Length>>>,
|
||||
size: Option<Rel<Length>>,
|
||||
) -> Content {
|
||||
let mut accent = AccentElem::new(base, Accent::new($primary));
|
||||
if let Some(size) = size {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::foundations::{elem, Content, Packed, Smart};
|
||||
use crate::foundations::{elem, Content, Packed};
|
||||
use crate::layout::{Length, Rel};
|
||||
use crate::math::{EquationElem, Mathy};
|
||||
|
||||
@ -152,5 +152,7 @@ pub struct StretchElem {
|
||||
|
||||
/// The size to stretch to, relative to the maximum size of the glyph and
|
||||
/// its attachments.
|
||||
pub size: Smart<Rel<Length>>,
|
||||
#[resolve]
|
||||
#[default(Rel::one())]
|
||||
pub size: Rel<Length>,
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ pub struct CancelElem {
|
||||
/// $ a + cancel(x, length: #200%)
|
||||
/// - cancel(x, length: #200%) $
|
||||
/// ```
|
||||
#[resolve]
|
||||
#[default(Rel::new(Ratio::one(), Abs::pt(3.0).into()))]
|
||||
pub length: Rel<Length>,
|
||||
|
||||
|
@ -135,6 +135,13 @@ pub struct EquationElem {
|
||||
#[internal]
|
||||
#[ghost]
|
||||
pub class: Option<MathClass>,
|
||||
|
||||
/// Values of `scriptPercentScaleDown` and `scriptScriptPercentScaleDown`
|
||||
/// respectively in the current font's MathConstants table.
|
||||
#[internal]
|
||||
#[default((70, 50))]
|
||||
#[ghost]
|
||||
pub script_scale: (i16, i16),
|
||||
}
|
||||
|
||||
impl Synthesize for Packed<EquationElem> {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::foundations::{elem, func, Content, NativeElement, Smart};
|
||||
use crate::foundations::{elem, func, Content, NativeElement};
|
||||
use crate::layout::{Length, Rel};
|
||||
use crate::math::Mathy;
|
||||
use crate::text::TextElem;
|
||||
@ -10,7 +10,9 @@ use crate::text::TextElem;
|
||||
#[elem(title = "Left/Right", Mathy)]
|
||||
pub struct LrElem {
|
||||
/// The size of the brackets, relative to the height of the wrapped content.
|
||||
pub size: Smart<Rel<Length>>,
|
||||
#[resolve]
|
||||
#[default(Rel::one())]
|
||||
pub size: Rel<Length>,
|
||||
|
||||
/// The delimited content, including the delimiters.
|
||||
#[required]
|
||||
@ -44,7 +46,7 @@ pub struct MidElem {
|
||||
pub fn floor(
|
||||
/// The size of the brackets, relative to the height of the wrapped content.
|
||||
#[named]
|
||||
size: Option<Smart<Rel<Length>>>,
|
||||
size: Option<Rel<Length>>,
|
||||
/// The expression to floor.
|
||||
body: Content,
|
||||
) -> Content {
|
||||
@ -60,7 +62,7 @@ pub fn floor(
|
||||
pub fn ceil(
|
||||
/// The size of the brackets, relative to the height of the wrapped content.
|
||||
#[named]
|
||||
size: Option<Smart<Rel<Length>>>,
|
||||
size: Option<Rel<Length>>,
|
||||
/// The expression to ceil.
|
||||
body: Content,
|
||||
) -> Content {
|
||||
@ -76,7 +78,7 @@ pub fn ceil(
|
||||
pub fn round(
|
||||
/// The size of the brackets, relative to the height of the wrapped content.
|
||||
#[named]
|
||||
size: Option<Smart<Rel<Length>>>,
|
||||
size: Option<Rel<Length>>,
|
||||
/// The expression to round.
|
||||
body: Content,
|
||||
) -> Content {
|
||||
@ -92,7 +94,7 @@ pub fn round(
|
||||
pub fn abs(
|
||||
/// The size of the brackets, relative to the height of the wrapped content.
|
||||
#[named]
|
||||
size: Option<Smart<Rel<Length>>>,
|
||||
size: Option<Rel<Length>>,
|
||||
/// The expression to take the absolute value of.
|
||||
body: Content,
|
||||
) -> Content {
|
||||
@ -108,7 +110,7 @@ pub fn abs(
|
||||
pub fn norm(
|
||||
/// The size of the brackets, relative to the height of the wrapped content.
|
||||
#[named]
|
||||
size: Option<Smart<Rel<Length>>>,
|
||||
size: Option<Rel<Length>>,
|
||||
/// The expression to take the norm of.
|
||||
body: Content,
|
||||
) -> Content {
|
||||
@ -119,7 +121,7 @@ fn delimited(
|
||||
body: Content,
|
||||
left: char,
|
||||
right: char,
|
||||
size: Option<Smart<Rel<Length>>>,
|
||||
size: Option<Rel<Length>>,
|
||||
) -> Content {
|
||||
let span = body.span();
|
||||
let mut elem = LrElem::new(Content::sequence([
|
||||
|
@ -56,6 +56,7 @@ pub struct VecElem {
|
||||
/// #set math.vec(gap: 1em)
|
||||
/// $ vec(1, 2) $
|
||||
/// ```
|
||||
#[resolve]
|
||||
#[default(DEFAULT_ROW_GAP.into())]
|
||||
pub gap: Rel<Length>,
|
||||
|
||||
@ -161,6 +162,7 @@ pub struct MatElem {
|
||||
/// #set math.mat(row-gap: 1em)
|
||||
/// $ mat(1, 2; 3, 4) $
|
||||
/// ```
|
||||
#[resolve]
|
||||
#[parse(
|
||||
let gap = args.named("gap")?;
|
||||
args.named("row-gap")?.or(gap)
|
||||
@ -174,6 +176,7 @@ pub struct MatElem {
|
||||
/// #set math.mat(column-gap: 1em)
|
||||
/// $ mat(1, 2; 3, 4) $
|
||||
/// ```
|
||||
#[resolve]
|
||||
#[parse(args.named("column-gap")?.or(gap))]
|
||||
#[default(DEFAULT_COL_GAP.into())]
|
||||
pub column_gap: Rel<Length>,
|
||||
@ -256,6 +259,7 @@ pub struct CasesElem {
|
||||
/// #set math.cases(gap: 1em)
|
||||
/// $ x = cases(1, 2) $
|
||||
/// ```
|
||||
#[resolve]
|
||||
#[default(DEFAULT_ROW_GAP.into())]
|
||||
pub gap: Rel<Length>,
|
||||
|
||||
|
@ -50,6 +50,7 @@ use crate::foundations::{
|
||||
Resolve, Scope, Set, Smart, StyleChain,
|
||||
};
|
||||
use crate::layout::{Abs, Axis, Dir, Em, Length, Ratio, Rel};
|
||||
use crate::math::{EquationElem, MathSize};
|
||||
use crate::model::ParElem;
|
||||
use crate::visualize::{Color, Paint, RelativeTo, Stroke};
|
||||
use crate::World;
|
||||
@ -981,7 +982,14 @@ impl Resolve for TextSize {
|
||||
type Output = Abs;
|
||||
|
||||
fn resolve(self, styles: StyleChain) -> Self::Output {
|
||||
self.0.resolve(styles)
|
||||
let factor = match EquationElem::size_in(styles) {
|
||||
MathSize::Display | MathSize::Text => 1.0,
|
||||
MathSize::Script => EquationElem::script_scale_in(styles).0 as f64 / 100.0,
|
||||
MathSize::ScriptScript => {
|
||||
EquationElem::script_scale_in(styles).1 as f64 / 100.0
|
||||
}
|
||||
};
|
||||
factor * self.0.resolve(styles)
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
tests/ref/math-size-arbitrary-content.png
Normal file
BIN
tests/ref/math-size-arbitrary-content.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 603 B |
BIN
tests/ref/math-size-math-content-1.png
Normal file
BIN
tests/ref/math-size-math-content-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
BIN
tests/ref/math-size-math-content-2.png
Normal file
BIN
tests/ref/math-size-math-content-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
tests/ref/math-size-math-content-3.png
Normal file
BIN
tests/ref/math-size-math-content-3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 877 B |
BIN
tests/ref/math-size-resolve.png
Normal file
BIN
tests/ref/math-size-resolve.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 460 B |
BIN
tests/ref/math-text-size.png
Normal file
BIN
tests/ref/math-text-size.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
@ -114,3 +114,41 @@ Inline $2 baz(x,y,baz(u, v))$.
|
||||
$ 2 foo(alpha, (M+foo(a, b))) $
|
||||
$ 2 bar(alpha, (M+foo(a, b))) $
|
||||
$ 2 baz(x,y,baz(u, v)) $
|
||||
|
||||
--- math-size-resolve ---
|
||||
#let length = context repr(measure("--").width)
|
||||
$ a length a ^ length $
|
||||
|
||||
--- math-size-arbitrary-content ---
|
||||
// Test sizing of both relative and absolute non math content in math sizes.
|
||||
#let stuff = square(inset: 0pt)[hello]
|
||||
#let square = square(size: 5pt)
|
||||
$ stuff sum^stuff_square square $
|
||||
|
||||
--- math-size-math-content-1 ---
|
||||
// Nested math content has styles overwritten by the inner equation.
|
||||
// Ideally the widths would match the actual length of the arrows.
|
||||
#let arrow = $stretch(->)^"much text"$
|
||||
$ arrow A^arrow A^A^arrow $
|
||||
#let width = context measure(arrow).width
|
||||
$ width A^width A^A^width $
|
||||
|
||||
--- math-size-math-content-2 ---
|
||||
// Nested math content has styles overwritten by the inner equation.
|
||||
// Ideally the heights would match the actual height of the sums.
|
||||
#let sum = $sum^2$
|
||||
#let height(x) = context measure(x).height
|
||||
$sum = height(sum) $
|
||||
$ sum != height(sum) $
|
||||
|
||||
--- math-size-math-content-3 ---
|
||||
// Sum doesn't get wrapped in math as it is a single expr.
|
||||
// Ideally the height would match the actual height of the sum.
|
||||
#let height(x) = context measure(x).height
|
||||
$ sum != height(sum) $
|
||||
|
||||
--- math-text-size ---
|
||||
// Values retrieved from function are not resolved at the moment.
|
||||
// Ideally the left size would match the right size.
|
||||
#let size = context [#text.size.to-absolute() #1em.to-absolute()]
|
||||
$ size x^size x^x^size $
|
||||
|
Loading…
x
Reference in New Issue
Block a user