diff --git a/crates/typst-layout/src/math/accent.rs b/crates/typst-layout/src/math/accent.rs index 73d821019..70c34e611 100644 --- a/crates/typst-layout/src/math/accent.rs +++ b/crates/typst-layout/src/math/accent.rs @@ -1,13 +1,10 @@ use typst_library::diag::SourceResult; use typst_library::foundations::{Packed, StyleChain}; -use typst_library::layout::{Em, Frame, Point, Size}; +use typst_library::layout::{Abs, Frame, Point, Size}; use typst_library::math::{Accent, AccentElem}; 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); - /// Lays out an [`AccentElem`]. #[typst_macros::time(name = "math.accent", span = elem.span())] pub fn layout_accent( @@ -29,7 +26,7 @@ pub fn layout_accent( let base_class = base.class(); let base_attach = base.accent_attach(); - let width = elem.size(styles).relative_to(base.width()); + let width = elem.size(styles).resolve(ctx.engine, styles, base.width())?; let Accent(c) = elem.accent; let mut glyph = GlyphFragment::new(ctx, styles, c, elem.span()); @@ -42,8 +39,7 @@ pub fn layout_accent( // Forcing the accent to be at least as large as the base makes it too // wide in many case. - let short_fall = ACCENT_SHORT_FALL.at(glyph.font_size); - let variant = glyph.stretch_horizontal(ctx, width, short_fall); + let variant = glyph.stretch_horizontal(ctx, width, Abs::zero()); let accent = variant.frame; let accent_attach = variant.accent_attach; diff --git a/crates/typst-library/src/math/accent.rs b/crates/typst-library/src/math/accent.rs index e62b63872..a6b7e29a5 100644 --- a/crates/typst-library/src/math/accent.rs +++ b/crates/typst-library/src/math/accent.rs @@ -1,7 +1,19 @@ use crate::diag::bail; -use crate::foundations::{cast, elem, func, Content, NativeElement, SymbolElem}; -use crate::layout::{Length, Rel}; -use crate::math::Mathy; +use crate::foundations::{ + cast, elem, func, Content, NativeElement, NativeFunc, SymbolElem, +}; +use crate::layout::{Em, Length, Ratio, Rel}; +use crate::math::{Mathy, StretchSize}; + +const ACCENT_SHORT_FALL: Em = Em::new(-0.5); + +#[func(name = "x => x - 0.5em")] +const fn default_accent_size(base: Length) -> Rel { + Rel { + rel: Ratio::zero(), + abs: Length { abs: base.abs, em: ACCENT_SHORT_FALL }, + } +} /// Attaches an accent to a base. /// @@ -52,12 +64,14 @@ pub struct AccentElem { /// The size of the accent, relative to the width of the base. /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. + /// /// ```example /// $dash(A, size: #150%)$ /// ``` - #[resolve] - #[default(Rel::one())] - pub size: Rel, + #[default(::data().into())] + pub size: StretchSize, /// Whether to remove the dot on top of lowercase i and j when adding a top /// accent. @@ -116,8 +130,11 @@ macro_rules! accents { /// The base to which the accent is applied. base: Content, /// The size of the accent, relative to the width of the base. + /// + /// See the [stretch documentation]($math.stretch.size) for + /// more information on sizes. #[named] - size: Option>, + size: Option, /// Whether to remove the dot on top of lowercase i and j when /// adding a top accent. #[named] diff --git a/tests/ref/math-accent-sized-function.png b/tests/ref/math-accent-sized-function.png new file mode 100644 index 000000000..9bd52a6e7 Binary files /dev/null and b/tests/ref/math-accent-sized-function.png differ diff --git a/tests/ref/math-accent-sized-script.png b/tests/ref/math-accent-sized-script.png index cf468dd15..ae5e62211 100644 Binary files a/tests/ref/math-accent-sized-script.png and b/tests/ref/math-accent-sized-script.png differ diff --git a/tests/suite/math/accent.typ b/tests/suite/math/accent.typ index ecc0588c5..23e11a697 100644 --- a/tests/suite/math/accent.typ +++ b/tests/suite/math/accent.typ @@ -30,12 +30,18 @@ $ 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%)$ +$tilde(sum), tilde(sum, size: #25%), accent(H, hat, size: #125%)$ --- 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))$ +--- math-accent-sized-function --- +// Test accent size with a function. +$dash(A) arrow(I) hat(L)$ \ +#set math.accent(size: x => x - 0.1em) +$dash(A) arrow(I) hat(L)$ + --- math-accent-dotless --- // Test dotless glyph variants. #let test(c) = $grave(#c), acute(sans(#c)), hat(frak(#c)), tilde(mono(#c)),