summaryrefslogtreecommitdiff
path: root/library/src/math
diff options
context:
space:
mode:
Diffstat (limited to 'library/src/math')
-rw-r--r--library/src/math/attach.rs26
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] = &[