diff options
Diffstat (limited to 'library/src/math')
| -rw-r--r-- | library/src/math/attach.rs | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/library/src/math/attach.rs b/library/src/math/attach.rs index e4fad470..f9ac4aa0 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] = &[ |
