diff --git a/library/src/math/attach.rs b/library/src/math/attach.rs index e4fad4704..f9ac4aa0a 100644 --- a/library/src/math/attach.rs +++ b/library/src/math/attach.rs @@ -299,6 +299,7 @@ fn compute_shifts_up_and_down( let mut shift_up = Abs::zero(); let mut shift_down = Abs::zero(); + let is_char_box = is_character_box(base); for e in [tl, tr].into_iter().flatten() { let ascent = match &base { @@ -308,13 +309,13 @@ fn compute_shifts_up_and_down( shift_up = shift_up .max(sup_shift_up) - .max(ascent - sup_drop_max) + .max(if is_char_box { Abs::zero() } else { ascent - sup_drop_max }) .max(sup_bottom_min + e.descent()); } for e in [bl, br].into_iter().flatten() { shift_down = shift_down .max(sub_shift_down) - .max(base.descent() + sub_drop_min) + .max(if is_char_box { Abs::zero() } else { base.descent() + sub_drop_min }) .max(e.ascent() - sub_top_max); } @@ -339,6 +340,27 @@ fn compute_shifts_up_and_down( (shift_up, shift_down) } +/// Whether the fragment consists of a single character or atomic piece of text. +fn is_character_box(fragment: &MathFragment) -> bool { + match fragment { + MathFragment::Glyph(_) | MathFragment::Variant(_) => { + fragment.class() != Some(MathClass::Large) + } + MathFragment::Frame(fragment) => is_atomic_text_frame(&fragment.frame), + _ => false, + } +} + +/// Handles e.g. "sin", "log", "exp", "CustomOperator". +fn is_atomic_text_frame(frame: &Frame) -> bool { + // Meta information isn't visible or renderable, so we exclude it. + let mut iter = frame + .items() + .map(|(_, item)| item) + .filter(|item| !matches!(item, FrameItem::Meta(_, _))); + matches!(iter.next(), Some(FrameItem::Text(_))) && iter.next().is_none() +} + /// Unicode codepoints that should have sub- and superscripts attached as limits. #[rustfmt::skip] const LIMITS: &[char] = &[ diff --git a/tests/ref/bugs/math-realize.png b/tests/ref/bugs/math-realize.png index c48244039..4f5b887ed 100644 Binary files a/tests/ref/bugs/math-realize.png and b/tests/ref/bugs/math-realize.png differ diff --git a/tests/ref/math/accent.png b/tests/ref/math/accent.png index a324d3f0d..11de9e286 100644 Binary files a/tests/ref/math/accent.png and b/tests/ref/math/accent.png differ diff --git a/tests/ref/math/attach.png b/tests/ref/math/attach.png index e65a16910..9a32b64c1 100644 Binary files a/tests/ref/math/attach.png and b/tests/ref/math/attach.png differ diff --git a/tests/ref/math/frac.png b/tests/ref/math/frac.png index 58d8ef898..6f0e81395 100644 Binary files a/tests/ref/math/frac.png and b/tests/ref/math/frac.png differ diff --git a/tests/ref/math/matrix.png b/tests/ref/math/matrix.png index f74384a36..9e3571462 100644 Binary files a/tests/ref/math/matrix.png and b/tests/ref/math/matrix.png differ diff --git a/tests/ref/math/multiline.png b/tests/ref/math/multiline.png index a5e53bc7e..ae847434d 100644 Binary files a/tests/ref/math/multiline.png and b/tests/ref/math/multiline.png differ diff --git a/tests/ref/math/numbering.png b/tests/ref/math/numbering.png index 8ccb3ac61..6256310f8 100644 Binary files a/tests/ref/math/numbering.png and b/tests/ref/math/numbering.png differ diff --git a/tests/ref/math/root.png b/tests/ref/math/root.png index b7d2807d0..8a6a6e131 100644 Binary files a/tests/ref/math/root.png and b/tests/ref/math/root.png differ diff --git a/tests/ref/math/spacing.png b/tests/ref/math/spacing.png index 94ca9b98e..d15d66075 100644 Binary files a/tests/ref/math/spacing.png and b/tests/ref/math/spacing.png differ diff --git a/tests/ref/math/style.png b/tests/ref/math/style.png index 46d726628..f4a42c707 100644 Binary files a/tests/ref/math/style.png and b/tests/ref/math/style.png differ diff --git a/tests/ref/meta/figure.png b/tests/ref/meta/figure.png index 35d7b4a07..4969e5a0e 100644 Binary files a/tests/ref/meta/figure.png and b/tests/ref/meta/figure.png differ diff --git a/tests/typ/math/attach.typ b/tests/typ/math/attach.typ index 070b9eca0..1649ae024 100644 --- a/tests/typ/math/attach.typ +++ b/tests/typ/math/attach.typ @@ -68,6 +68,16 @@ $ sqrt(a_(1/2)^zeta), sqrt(a_alpha^(1/2)), sqrt(a_(1/2)^(3/4)) \ // Test frame base. $ (-1)^n + (1/2 + 3)^(-1/2) $ +--- +#set text(size: 8pt) + +// Test that the attachments are aligned horizontally. +$ x_1 p_1 frak(p)_1 2_1 dot_1 lg_1 !_1 \\_1 ]_1 "ip"_1 op("iq")_1 \ + x^1 b^1 frak(b)^1 2^1 dot^1 lg^1 !^1 \\^1 ]^1 "ib"^1 op("id")^1 \ + x_1 y_1 "_"_1 x^1 l^1 "`"^1 attach(I,tl:1,bl:1,tr:1,br:1) + scripts(sum)_1^1 integral_1^1 |1/2|_1^1 \ + x^1_1, "("b y")"^1_1 != (b y)^1_1, "[∫]"_1 [integral]_1 $ + --- // Test limit. $ lim_(n->oo \ n "grows") sum_(k=0 \ k in NN)^n k $