diff --git a/crates/typst/src/layout/rel.rs b/crates/typst/src/layout/rel.rs index 2af63ba3f..cce0ac861 100644 --- a/crates/typst/src/layout/rel.rs +++ b/crates/typst/src/layout/rel.rs @@ -86,6 +86,12 @@ impl Rel { None } } + + /// Convert to a relative length with the absolute part resolved at the + /// given font size. + pub fn at(self, font_size: Abs) -> Rel { + self.map(|abs| abs.at(font_size)) + } } impl Debug for Rel { diff --git a/crates/typst/src/math/accent.rs b/crates/typst/src/math/accent.rs index dbc0fad67..08ed72380 100644 --- a/crates/typst/src/math/accent.rs +++ b/crates/typst/src/math/accent.rs @@ -1,11 +1,11 @@ use crate::diag::{bail, SourceResult}; use crate::foundations::{ - cast, elem, func, Content, NativeElement, Packed, Resolve, Smart, StyleChain, Value, + cast, elem, func, Content, NativeElement, Packed, Smart, StyleChain, Value, }; use crate::layout::{Em, Frame, Length, Point, Rel, Size}; use crate::math::{ - style_cramped, FrameFragment, GlyphFragment, LayoutMath, MathContext, MathFragment, - Scaled, + scaled_font_size, style_cramped, FrameFragment, GlyphFragment, LayoutMath, + MathContext, MathFragment, Scaled, }; use crate::text::TextElem; @@ -123,7 +123,7 @@ impl LayoutMath for Packed { let width = self .size(styles) .unwrap_or(Rel::one()) - .resolve(styles) + .at(scaled_font_size(ctx, styles)) .relative_to(base.width()); // Forcing the accent to be at least as large as the base makes it too diff --git a/crates/typst/src/math/cancel.rs b/crates/typst/src/math/cancel.rs index ef07a1c8e..0bc28f078 100644 --- a/crates/typst/src/math/cancel.rs +++ b/crates/typst/src/math/cancel.rs @@ -1,13 +1,11 @@ use comemo::Track; use crate::diag::{At, SourceResult}; -use crate::foundations::{ - cast, elem, Content, Context, Func, Packed, Resolve, Smart, StyleChain, -}; +use crate::foundations::{cast, elem, Content, Context, Func, Packed, Smart, StyleChain}; use crate::layout::{ Abs, Angle, Frame, FrameItem, Length, Point, Ratio, Rel, Size, Transform, }; -use crate::math::{FrameFragment, LayoutMath, MathContext}; +use crate::math::{scaled_font_size, FrameFragment, LayoutMath, MathContext}; use crate::syntax::Span; use crate::text::TextElem; use crate::visualize::{FixedStroke, Geometry, Stroke}; @@ -120,7 +118,7 @@ impl LayoutMath for Packed { let mut body = body.into_frame(); let body_size = body.size(); let span = self.span(); - let length = self.length(styles).resolve(styles); + let length = self.length(styles).at(scaled_font_size(ctx, styles)); let stroke = self.stroke(styles).unwrap_or(FixedStroke { paint: TextElem::fill_in(styles).as_decoration(), diff --git a/crates/typst/src/math/ctx.rs b/crates/typst/src/math/ctx.rs index 6da16406e..35eb665c6 100644 --- a/crates/typst/src/math/ctx.rs +++ b/crates/typst/src/math/ctx.rs @@ -11,7 +11,7 @@ use unicode_segmentation::UnicodeSegmentation; use crate::diag::SourceResult; use crate::engine::Engine; -use crate::foundations::{Content, Packed, Resolve, StyleChain, StyleVec}; +use crate::foundations::{Content, Packed, StyleChain, StyleVec}; use crate::introspection::{SplitLocator, TagElem}; use crate::layout::{ layout_frame, Abs, Axes, BoxElem, Em, Frame, HElem, PlaceElem, Region, Size, Spacing, @@ -220,7 +220,7 @@ impl MathContext<'_, '_, '_> { if let Spacing::Rel(rel) = elem.amount() { if rel.rel.is_zero() { self.push(MathFragment::Spacing( - rel.abs.resolve(styles), + rel.abs.at(scaled_font_size(self, styles)), elem.weak(styles), )); } diff --git a/crates/typst/src/math/matrix.rs b/crates/typst/src/math/matrix.rs index 6a3012ba0..15ada1f36 100644 --- a/crates/typst/src/math/matrix.rs +++ b/crates/typst/src/math/matrix.rs @@ -63,7 +63,6 @@ pub struct VecElem { /// #set math.vec(gap: 1em) /// $ vec(1, 2) $ /// ``` - #[resolve] #[default(DEFAULT_ROW_GAP.into())] pub gap: Rel, @@ -81,7 +80,7 @@ impl LayoutMath for Packed { styles, self.children(), self.align(styles), - self.gap(styles), + self.gap(styles).at(scaled_font_size(ctx, styles)), LeftRightAlternator::Right, )?; @@ -182,7 +181,6 @@ 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) @@ -196,7 +194,6 @@ 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, @@ -268,6 +265,9 @@ impl LayoutMath for Packed { } } + let font_size = scaled_font_size(ctx, styles); + let column_gap = self.column_gap(styles).at(font_size); + let row_gap = self.row_gap(styles).at(font_size); let delim = self.delim(styles); let frame = layout_mat_body( ctx, @@ -275,7 +275,7 @@ impl LayoutMath for Packed { rows, self.align(styles), augment, - Axes::new(self.column_gap(styles), self.row_gap(styles)), + Axes::new(column_gap, row_gap), self.span(), )?; @@ -322,7 +322,6 @@ pub struct CasesElem { /// #set math.cases(gap: 1em) /// $ x = cases(1, 2) $ /// ``` - #[resolve] #[default(DEFAULT_ROW_GAP.into())] pub gap: Rel, @@ -340,7 +339,7 @@ impl LayoutMath for Packed { styles, self.children(), FixedAlignment::Start, - self.gap(styles), + self.gap(styles).at(scaled_font_size(ctx, styles)), LeftRightAlternator::None, )?; diff --git a/crates/typst/src/math/stretch.rs b/crates/typst/src/math/stretch.rs index e411da930..18a42b18c 100644 --- a/crates/typst/src/math/stretch.rs +++ b/crates/typst/src/math/stretch.rs @@ -2,10 +2,11 @@ use ttf_parser::math::{GlyphAssembly, GlyphConstruction, GlyphPart}; use ttf_parser::LazyArray16; use crate::diag::SourceResult; -use crate::foundations::{elem, Content, Packed, Resolve, Smart, StyleChain}; +use crate::foundations::{elem, Content, Packed, Smart, StyleChain}; use crate::layout::{Abs, Axis, Frame, Length, Point, Rel, Size, VAlignment}; use crate::math::{ - GlyphFragment, LayoutMath, MathContext, MathFragment, Scaled, VariantFragment, + scaled_font_size, GlyphFragment, LayoutMath, MathContext, MathFragment, Scaled, + VariantFragment, }; use crate::utils::Get; @@ -91,7 +92,7 @@ pub(super) fn stretch_fragment( glyph, stretch .unwrap_or(Rel::one()) - .resolve(styles) + .at(scaled_font_size(ctx, styles)) .relative_to(relative_to_size), short_fall, axis, diff --git a/tests/ref/math-accent-sized-script.png b/tests/ref/math-accent-sized-script.png new file mode 100644 index 000000000..cf468dd15 Binary files /dev/null and b/tests/ref/math-accent-sized-script.png differ diff --git a/tests/ref/math-spacing-script.png b/tests/ref/math-spacing-script.png new file mode 100644 index 000000000..3ded96229 Binary files /dev/null and b/tests/ref/math-spacing-script.png differ diff --git a/tests/suite/math/accent.typ b/tests/suite/math/accent.typ index 9f57d69b0..87ed81586 100644 --- a/tests/suite/math/accent.typ +++ b/tests/suite/math/accent.typ @@ -31,3 +31,7 @@ $ tilde(integral), tilde(integral)_a^b, tilde(integral_a^b) $ --- math-accent-sized --- // Test accent size. $tilde(sum), tilde(sum, size: #50%), accent(H, hat, size: #200%)$ + +--- math-accent-sized-script --- +// Test accent size in script size. +$tilde(U, size: #1.1em), x^tilde(U, size: #1.1em), sscript(tilde(U, size: #1.1em))$ diff --git a/tests/suite/math/spacing.typ b/tests/suite/math/spacing.typ index 707c09bb8..db8b905c6 100644 --- a/tests/suite/math/spacing.typ +++ b/tests/suite/math/spacing.typ @@ -49,6 +49,10 @@ $integral f(x) thin dif x$, // Both are weak, collide $integral f(x) #h(0.166em, weak: true)dif x$ +--- math-spacing-script --- +// Test spacing in script size +$x^(a #h(1em) b) + x^x^(a #h(1em) b) + sscript(a #h(1em) b)$ + --- math-spacing-ignorant --- // Test spacing with ignorant elements $#metadata(none) "text"$ \