From 156b99ac767b6813fd39caa9ceb1222064aa14a7 Mon Sep 17 00:00:00 2001 From: tfpf Date: Fri, 10 Jun 2022 17:06:27 +0530 Subject: [PATCH 1/3] Implement the TeX alignment of subscripts [skip ci] No point running the tests if we are absolutely sure they are going to fail. --- lib/matplotlib/_mathtext.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/_mathtext.py b/lib/matplotlib/_mathtext.py index 551898d546ac..a07faa0a05e1 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. + constants = _get_font_constant_set(state) + if isinstance(nucleus, Char): + shift_up = 0 + shift_down = 0 + else: + # TODO Optimise and reduce line length. + shift_up = nucleus.height - constants.subdrop * xHeight * SHRINK_FACTOR + shift_down = nucleus.depth + constants.subdrop * xHeight * SHRINK_FACTOR + # 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): @@ -2260,7 +2270,12 @@ def subsuper(self, s, loc, toks): if self.is_dropsub(last_char): shift_down = lc_baseline + constants.subdrop * xHeight else: - shift_down = constants.sub1 * xHeight + # TODO Optimise. + if shift_down < constants.sub1 * xHeight: + shift_down = constants.sub1 * xHeight + clr = x.height - xHeight * 4 / 5 + if shift_down < clr: + shift_down = clr x.shift_amount = shift_down else: x = Hlist([Kern(superkern), super]) From 6d2815c8f5a0b528a46956b81c7a49753b01c178 Mon Sep 17 00:00:00 2001 From: tfpf Date: Sat, 11 Jun 2022 06:52:23 +0530 Subject: [PATCH 2/3] Align both subscript and superscript the way TeX does. --- lib/matplotlib/_mathtext.py | 38 ++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/lib/matplotlib/_mathtext.py b/lib/matplotlib/_mathtext.py index a07faa0a05e1..e90a8d160e3c 100644 --- a/lib/matplotlib/_mathtext.py +++ b/lib/matplotlib/_mathtext.py @@ -2207,15 +2207,15 @@ def subsuper(self, s, loc, toks): result = Hlist([vlist]) return [result] - # Set the minimum shifts for the superscript and subscript. + # 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: - # TODO Optimise and reduce line length. - shift_up = nucleus.height - constants.subdrop * xHeight * SHRINK_FACTOR - shift_down = nucleus.depth + constants.subdrop * xHeight * SHRINK_FACTOR + 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 @@ -2264,40 +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: - # TODO Optimise. - if shift_down < constants.sub1 * xHeight: - shift_down = constants.sub1 * xHeight - clr = x.height - xHeight * 4 / 5 - if shift_down < clr: - shift_down = clr + 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)), From 584166eb985d21f88efdd388064b9e5b7404e879 Mon Sep 17 00:00:00 2001 From: tfpf Date: Sat, 11 Jun 2022 07:00:17 +0530 Subject: [PATCH 3/3] Fix Flake8 errors. --- lib/matplotlib/_mathtext.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/_mathtext.py b/lib/matplotlib/_mathtext.py index e90a8d160e3c..eb6e6047f9bf 100644 --- a/lib/matplotlib/_mathtext.py +++ b/lib/matplotlib/_mathtext.py @@ -2271,7 +2271,7 @@ def subsuper(self, s, loc, toks): shift_down = lc_baseline + constants.subdrop * xHeight else: shift_down = max(shift_down, constants.sub1 * xHeight, - x.height - xHeight * 4 / 5) + x.height - xHeight * 4 / 5) x.shift_amount = shift_down else: # Align superscript (node758). @@ -2281,7 +2281,7 @@ def subsuper(self, s, loc, toks): shift_up = lc_height - constants.subdrop * xHeight else: shift_up = max(shift_up, constants.sup1 * xHeight, - x.depth + xHeight / 4) + x.depth + xHeight / 4) if sub is None: x.shift_amount = -shift_up else: