diff --git a/lib/matplotlib/_mathtext.py b/lib/matplotlib/_mathtext.py index 551898d546ac..eb6e6047f9bf 100644 --- a/lib/matplotlib/_mathtext.py +++ b/lib/matplotlib/_mathtext.py @@ -1830,6 +1830,7 @@ def set_names_and_parse_actions(): | p.underset | p.sqrt | p.overline + | p.auto_delim ) p.simple <<= ( @@ -2206,6 +2207,16 @@ def subsuper(self, s, loc, toks): result = Hlist([vlist]) return [result] + # Set the minimum shifts for the superscript and subscript (node756). + constants = _get_font_constant_set(state) + if isinstance(nucleus, Char): + shift_up = 0 + shift_down = 0 + else: + drop_amount = constants.subdrop * xHeight * SHRINK_FACTOR + shift_up = nucleus.height - drop_amount + shift_down = nucleus.depth + drop_amount + # We remove kerning on the last character for consistency (otherwise # it will compute kerning based on non-shrunk characters and may put # them too close together when superscripted) @@ -2232,7 +2243,6 @@ def subsuper(self, s, loc, toks): nucleus = Hlist([nucleus]) # Handle regular sub/superscripts - constants = _get_font_constant_set(state) lc_height = last_char.height lc_baseline = 0 if self.is_dropsub(last_char): @@ -2254,35 +2264,44 @@ def subsuper(self, s, loc, toks): subkern = 0 if super is None: - # node757 + # Align subscript without superscript (node757). x = Hlist([Kern(subkern), sub]) x.shrink() if self.is_dropsub(last_char): shift_down = lc_baseline + constants.subdrop * xHeight else: - shift_down = constants.sub1 * xHeight + shift_down = max(shift_down, constants.sub1 * xHeight, + x.height - xHeight * 4 / 5) x.shift_amount = shift_down else: + # Align superscript (node758). x = Hlist([Kern(superkern), super]) x.shrink() if self.is_dropsub(last_char): shift_up = lc_height - constants.subdrop * xHeight else: - shift_up = constants.sup1 * xHeight + shift_up = max(shift_up, constants.sup1 * xHeight, + x.depth + xHeight / 4) if sub is None: x.shift_amount = -shift_up - else: # Both sub and superscript + else: + # Align subscript with superscript (node759). y = Hlist([Kern(subkern), sub]) y.shrink() if self.is_dropsub(last_char): shift_down = lc_baseline + constants.subdrop * xHeight else: - shift_down = constants.sub2 * xHeight - # If sub and superscript collide, move super up - clr = (2.0 * rule_thickness - + shift_down = max(shift_down, constants.sub2 * xHeight) + # If the subscript and superscript are too close to each other, + # move the subscript down. + clr = (4 * rule_thickness - ((shift_up - x.depth) - (y.height - shift_down))) if clr > 0.: - shift_up += clr + shift_down += clr + clr = xHeight * 4 / 5 - shift_up + x.depth + if clr > 0: + shift_up += clr + shift_down -= clr x = Vlist([ x, Kern((shift_up - x.depth) - (y.height - shift_down)),