diff --git a/crates/typst-layout/src/math/accent.rs b/crates/typst-layout/src/math/accent.rs index f2dfa2c45..73d821019 100644 --- a/crates/typst-layout/src/math/accent.rs +++ b/crates/typst-layout/src/math/accent.rs @@ -19,8 +19,10 @@ pub fn layout_accent( let mut base = ctx.layout_into_fragment(&elem.base, styles.chain(&cramped))?; // Try to replace a glyph with its dotless variant. - if let MathFragment::Glyph(glyph) = &mut base { - glyph.make_dotless_form(ctx); + if elem.dotless(styles) { + if let MathFragment::Glyph(glyph) = &mut base { + glyph.make_dotless_form(ctx); + } } // Preserve class to preserve automatic spacing. diff --git a/crates/typst-library/src/math/accent.rs b/crates/typst-library/src/math/accent.rs index b162c52b1..e62b63872 100644 --- a/crates/typst-library/src/math/accent.rs +++ b/crates/typst-library/src/math/accent.rs @@ -13,8 +13,8 @@ use crate::math::Mathy; /// ``` #[elem(Mathy)] pub struct AccentElem { - /// The base to which the accent is applied. - /// May consist of multiple letters. + /// The base to which the accent is applied. May consist of multiple + /// letters. /// /// ```example /// $arrow(A B C)$ @@ -51,9 +51,24 @@ pub struct AccentElem { pub accent: Accent, /// The size of the accent, relative to the width of the base. + /// + /// ```example + /// $dash(A, size: #150%)$ + /// ``` #[resolve] #[default(Rel::one())] pub size: Rel, + + /// Whether to remove the dot on top of lowercase i and j when adding a top + /// accent. + /// + /// This enables the `dtls` OpenType feature. + /// + /// ```example + /// $hat(dotless: #false, i)$ + /// ``` + #[default(true)] + pub dotless: bool, } /// An accent character. @@ -103,11 +118,18 @@ macro_rules! accents { /// The size of the accent, relative to the width of the base. #[named] size: Option>, + /// Whether to remove the dot on top of lowercase i and j when + /// adding a top accent. + #[named] + dotless: Option, ) -> Content { let mut accent = AccentElem::new(base, Accent::new($primary)); if let Some(size) = size { accent = accent.with_size(size); } + if let Some(dotless) = dotless { + accent = accent.with_dotless(dotless); + } accent.pack() } )+ diff --git a/tests/ref/math-accent-dotless-disabled.png b/tests/ref/math-accent-dotless-disabled.png new file mode 100644 index 000000000..d75ec4580 Binary files /dev/null and b/tests/ref/math-accent-dotless-disabled.png differ diff --git a/tests/ref/math-accent-dotless-set-rule.png b/tests/ref/math-accent-dotless-set-rule.png new file mode 100644 index 000000000..ae5ef017a Binary files /dev/null and b/tests/ref/math-accent-dotless-set-rule.png differ diff --git a/tests/suite/math/accent.typ b/tests/suite/math/accent.typ index 5be4f576f..ab0078a5f 100644 --- a/tests/suite/math/accent.typ +++ b/tests/suite/math/accent.typ @@ -42,3 +42,11 @@ $tilde(U, size: #1.1em), x^tilde(U, size: #1.1em), sscript(tilde(U, size: #1.1em macron(bb(#c)), dot(cal(#c)), diaer(upright(#c)), breve(bold(#c)), circle(bold(upright(#c))), caron(upright(sans(#c))), arrow(bold(frak(#c)))$ $test(i) \ test(j)$ + +--- math-accent-dotless-disabled --- +// Test disabling the dotless glyph variants. +$hat(i), hat(i, dotless: #false), accent(j, tilde), accent(j, tilde, dotless: #false)$ + +--- math-accent-dotless-set-rule --- +#set math.accent(dotless: false) +$ hat(i) $