Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7dde595

Browse files
committed
Get metrics for sub/superscript from actual font
...not just from the rcParam mathtext.fontset
1 parent 4c98ef2 commit 7dde595

File tree

1 file changed

+127
-70
lines changed

1 file changed

+127
-70
lines changed

lib/matplotlib/mathtext.py

Lines changed: 127 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,58 +1240,115 @@ def get_underline_thickness(self, font, fontsize, dpi):
12401240
# The number of different sizes of chars to use, beyond which they will not
12411241
# get any smaller
12421242
NUM_SIZE_LEVELS = 6
1243-
# Percentage of x-height of additional horiz. space after sub/superscripts
1244-
SCRIPT_SPACE = {'cm': 0.075,
1245-
'stix': 0.10,
1246-
'stixsans': 0.05,
1247-
'dejavuserif': 0.05,
1248-
'dejavusans': 0.05}
1249-
## Percentage of x-height that sub/superscripts drop below the baseline
1250-
SUBDROP = {'cm': 0.2,
1251-
'stix': 0.4,
1252-
'stixsans': 0.4,
1253-
'dejavuserif': 0.4,
1254-
'dejavusans': 0.4}
1255-
# Percentage of x-height that superscripts are raised from the baseline
1256-
SUP1 = {'cm': 0.45,
1257-
'stix': 0.8,
1258-
'stixsans': 0.8,
1259-
'dejavuserif': 0.7,
1260-
'dejavusans': 0.7}
1261-
# Percentage of x-height that subscripts drop below the baseline
1262-
SUB1 = {'cm': 0.2,
1263-
'stix': 0.3,
1264-
'stixsans': 0.3,
1265-
'dejavuserif': 0.3,
1266-
'dejavusans': 0.3}
1267-
# Percentage of x-height that subscripts drop below the baseline when a
1268-
# superscript is present
1269-
SUB2 = {'cm': 0.3,
1270-
'stix': 0.6,
1271-
'stixsans': 0.5,
1272-
'dejavuserif': 0.5,
1273-
'dejavusans': 0.5}
1274-
# Percentage of x-height that sub/supercripts are offset relative to the
1275-
# nucleus edge for non-slanted nuclei
1276-
DELTA = {'cm': 0.075,
1277-
'stix': 0.05,
1278-
'stixsans': 0.025,
1279-
'dejavuserif': 0.025,
1280-
'dejavusans': 0.025}
1281-
# Additional percentage of last character height above 2/3 of the x-height that
1282-
# supercripts are offset relative to the subscript for slanted nuclei
1283-
DELTASLANTED = {'cm': 0.3,
1284-
'stix': 0.3,
1285-
'stixsans': 0.6,
1286-
'dejavuserif': 0.2,
1287-
'dejavusans': 0.2}
1288-
# Percentage of x-height that supercripts and subscripts are offset for
1289-
# integrals
1290-
DELTAINTEGRAL = {'cm': 0.3,
1291-
'stix': 0.3,
1292-
'stixsans': 0.3,
1293-
'dejavuserif': 0.1,
1294-
'dejavusans': 0.1}
1243+
1244+
1245+
class FontConstantsBase(object):
1246+
"""
1247+
A set of constants that controls how certain things, such as sub-
1248+
and superscripts are laid out. These are all metrics that can't
1249+
be reliably retrieved from the font metrics in the font itself.
1250+
"""
1251+
# Percentage of x-height of additional horiz. space after sub/superscripts
1252+
script_space = 0.05
1253+
1254+
# Percentage of x-height that sub/superscripts drop below the baseline
1255+
subdrop = 0.4
1256+
1257+
# Percentage of x-height that superscripts are raised from the baseline
1258+
sup1 = 0.7
1259+
1260+
# Percentage of x-height that subscripts drop below the baseline
1261+
sub1 = 0.3
1262+
1263+
# Percentage of x-height that subscripts drop below the baseline when a
1264+
# superscript is present
1265+
sub2 = 0.5
1266+
1267+
# Percentage of x-height that sub/supercripts are offset relative to the
1268+
# nucleus edge for non-slanted nuclei
1269+
delta = 0.025
1270+
1271+
# Additional percentage of last character height above 2/3 of the
1272+
# x-height that supercripts are offset relative to the subscript
1273+
# for slanted nuclei
1274+
delta_slanted = 0.2
1275+
1276+
# Percentage of x-height that supercripts and subscripts are offset for
1277+
# integrals
1278+
delta_integral = 0.1
1279+
1280+
1281+
class ComputerModernFontConstants(FontConstantsBase):
1282+
script_space = 0.075
1283+
subdrop = 0.2
1284+
sup1 = 0.45
1285+
sub1 = 0.2
1286+
sub2 = 0.3
1287+
delta = 0.075
1288+
delta_slanted = 0.3
1289+
delta_integral = 0.3
1290+
1291+
1292+
class STIXFontConstants(FontConstantsBase):
1293+
script_space = 0.1
1294+
sup1 = 0.8
1295+
sub2 = 0.6
1296+
delta = 0.05
1297+
delta_slanted = 0.3
1298+
delta_integral = 0.3
1299+
1300+
1301+
class STIXSansFontConstants(FontConstantsBase):
1302+
script_space = 0.05
1303+
sup1 = 0.8
1304+
delta_slanted = 0.6
1305+
delta_integral = 0.3
1306+
1307+
1308+
class DejaVuSerifFontConstants(FontConstantsBase):
1309+
pass
1310+
1311+
1312+
class DejaVuSansFontConstants(FontConstantsBase):
1313+
pass
1314+
1315+
1316+
# Maps font family names to the FontConstantBase subclass to use
1317+
_font_constant_mapping = {
1318+
'DejaVu Sans': DejaVuSansFontConstants,
1319+
'DejaVu Sans Mono': DejaVuSansFontConstants,
1320+
'DejaVu Serif': DejaVuSerifFontConstants,
1321+
'cmb10': ComputerModernFontConstants,
1322+
'cmex10': ComputerModernFontConstants,
1323+
'cmmi10': ComputerModernFontConstants,
1324+
'cmr10': ComputerModernFontConstants,
1325+
'cmss10': ComputerModernFontConstants,
1326+
'cmsy10': ComputerModernFontConstants,
1327+
'cmtt10': ComputerModernFontConstants,
1328+
'STIXGeneral': STIXFontConstants,
1329+
'STIXNonUnicode': STIXFontConstants,
1330+
'STIXSizeFiveSym': STIXFontConstants,
1331+
'STIXSizeFourSym': STIXFontConstants,
1332+
'STIXSizeThreeSym': STIXFontConstants,
1333+
'STIXSizeTwoSym': STIXFontConstants,
1334+
'STIXSizeOneSym': STIXFontConstants,
1335+
# Map the fonts we used to ship, just for good measure
1336+
'Bitstream Vera Sans': DejaVuSansFontConstants,
1337+
'Bitstream Vera': DejaVuSansFontConstants,
1338+
}
1339+
1340+
1341+
def _get_font_constant_set(state):
1342+
constants = _font_constant_mapping.get(
1343+
state.font_output._get_font(state.font).family_name,
1344+
FontConstantsBase)
1345+
# STIX sans isn't really its own fonts, just different code points
1346+
# in the STIX fonts, so we have to detect this one separately.
1347+
if (constants is STIXFontConstants and
1348+
isinstance(state.font_output, StixSansFonts)):
1349+
return STIXSansFontConstants
1350+
return constants
1351+
12951352

12961353
class MathTextWarning(Warning):
12971354
pass
@@ -2873,25 +2930,24 @@ def subsuper(self, s, loc, toks):
28732930
nucleus = Hlist([nucleus])
28742931

28752932
# Handle regular sub/superscripts
2876-
2877-
fs = rcParams['mathtext.fontset']
2878-
if fs == 'custom':
2879-
fs = 'dejavusans'
2880-
2933+
constants = _get_font_constant_set(state)
28812934
lc_height = last_char.height
28822935
lc_baseline = 0
28832936
if self.is_dropsub(last_char):
28842937
lc_baseline = last_char.depth
28852938

28862939
# Compute kerning for sub and super
2887-
superkern = DELTA[fs] * xHeight
2888-
subkern = DELTA[fs] * xHeight
2940+
superkern = constants.delta * xHeight
2941+
subkern = constants.delta * xHeight
28892942
if self.is_slanted(last_char):
2890-
superkern += DELTA[fs] * xHeight
2891-
superkern += DELTASLANTED[fs] * (lc_height - xHeight * 2. / 3.)
2943+
superkern += constants.delta * xHeight
2944+
superkern += (constants.delta_slanted *
2945+
(lc_height - xHeight * 2. / 3.))
28922946
if self.is_dropsub(last_char):
2893-
subkern = (3 * DELTA[fs] - DELTAINTEGRAL[fs]) * lc_height
2894-
superkern = (3 * DELTA[fs] + DELTAINTEGRAL[fs]) * lc_height
2947+
subkern = (3 * constants.delta -
2948+
constants.delta_integral) * lc_height
2949+
superkern = (3 * constants.delta +
2950+
constants.delta_integral) * lc_height
28952951
else:
28962952
subkern = 0
28972953

@@ -2900,26 +2956,26 @@ def subsuper(self, s, loc, toks):
29002956
x = Hlist([Kern(subkern), sub])
29012957
x.shrink()
29022958
if self.is_dropsub(last_char):
2903-
shift_down = lc_baseline + SUBDROP[fs] * xHeight
2959+
shift_down = lc_baseline + constants.subdrop * xHeight
29042960
else:
2905-
shift_down = SUB1[fs] * xHeight
2961+
shift_down = constants.sub1 * xHeight
29062962
x.shift_amount = shift_down
29072963
else:
29082964
x = Hlist([Kern(superkern), super])
29092965
x.shrink()
29102966
if self.is_dropsub(last_char):
2911-
shift_up = lc_height - SUBDROP[fs] * xHeight
2967+
shift_up = lc_height - constants.subdrop * xHeight
29122968
else:
2913-
shift_up = SUP1[fs] * xHeight
2969+
shift_up = constants.sup1 * xHeight
29142970
if sub is None:
29152971
x.shift_amount = -shift_up
29162972
else: # Both sub and superscript
29172973
y = Hlist([Kern(subkern),sub])
29182974
y.shrink()
29192975
if self.is_dropsub(last_char):
2920-
shift_down = lc_baseline + SUBDROP[fs] * xHeight
2976+
shift_down = lc_baseline + constants.subdrop * xHeight
29212977
else:
2922-
shift_down = SUB2[fs] * xHeight
2978+
shift_down = constants.sub2 * xHeight
29232979
# If sub and superscript collide, move super up
29242980
clr = (2.0 * rule_thickness -
29252981
((shift_up - x.depth) - (y.height - shift_down)))
@@ -2931,8 +2987,9 @@ def subsuper(self, s, loc, toks):
29312987
x.shift_amount = shift_down
29322988

29332989
if not self.is_dropsub(last_char):
2934-
x.width += SCRIPT_SPACE[fs] * xHeight
2990+
x.width += constants.script_space * xHeight
29352991
result = Hlist([nucleus, x])
2992+
29362993
return [result]
29372994

29382995
def _genfrac(self, ldelim, rdelim, rule, style, num, den):

0 commit comments

Comments
 (0)