Skip to content

Commit 384c55a

Browse files
committed
Fix auto-sized glyphs with BaKoMa fonts
If the larger glyphs for an auto-sized character in `cmex10` uses a character that is in the `latex_to_bakoma` table, then it will be mapped an extra time into `cmr10` (usually). Thus we end up with a large version of a "normal" character, such as an exclamation point. Instead map these glyphs through the `latex_to_bakoma` table by using their glyph names as "commands". This ensures they don't get double-mapped to the wrong font and fixes the following issues: - slash (/) uses a comma at the larger sizes - right parenthesis uses an exclamation point at the largest size - left and right braces use parentheses at the largest size - right floor uses a percentage sign at the largest size - left ceiling uses an ampersand at the largest size Also, drop the regular size braces, as they are the same as the first `big`-sized version.
1 parent 344b922 commit 384c55a

File tree

3 files changed

+114
-54
lines changed

3 files changed

+114
-54
lines changed

lib/matplotlib/_mathtext.py

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -479,60 +479,40 @@ def _get_glyph(self, fontname: str, font_class: str,
479479
else:
480480
return self._stix_fallback._get_glyph(fontname, font_class, sym)
481481

482-
# The Bakoma fonts contain many pre-sized alternatives for the
483-
# delimiters. The AutoSizedChar class will use these alternatives
484-
# and select the best (closest sized) glyph.
482+
# The Bakoma fonts contain many pre-sized alternatives for the delimiters. The
483+
# Auto(Height|Width)Char classes will use these alternatives and select the best
484+
# (closest sized) glyph.
485+
_latex_sizes = ('big', 'Big', 'bigg', 'Bigg')
485486
_size_alternatives = {
486-
'(': [('rm', '('), ('ex', '\xa1'), ('ex', '\xb3'),
487-
('ex', '\xb5'), ('ex', '\xc3')],
488-
')': [('rm', ')'), ('ex', '\xa2'), ('ex', '\xb4'),
489-
('ex', '\xb6'), ('ex', '\x21')],
490-
'{': [('cal', '{'), ('ex', '\xa9'), ('ex', '\x6e'),
491-
('ex', '\xbd'), ('ex', '\x28')],
492-
'}': [('cal', '}'), ('ex', '\xaa'), ('ex', '\x6f'),
493-
('ex', '\xbe'), ('ex', '\x29')],
494-
# The fourth size of '[' is mysteriously missing from the BaKoMa
495-
# font, so I've omitted it for both '[' and ']'
496-
'[': [('rm', '['), ('ex', '\xa3'), ('ex', '\x68'),
497-
('ex', '\x22')],
498-
']': [('rm', ']'), ('ex', '\xa4'), ('ex', '\x69'),
499-
('ex', '\x23')],
500-
r'\lfloor': [('ex', '\xa5'), ('ex', '\x6a'),
501-
('ex', '\xb9'), ('ex', '\x24')],
502-
r'\rfloor': [('ex', '\xa6'), ('ex', '\x6b'),
503-
('ex', '\xba'), ('ex', '\x25')],
504-
r'\lceil': [('ex', '\xa7'), ('ex', '\x6c'),
505-
('ex', '\xbb'), ('ex', '\x26')],
506-
r'\rceil': [('ex', '\xa8'), ('ex', '\x6d'),
507-
('ex', '\xbc'), ('ex', '\x27')],
508-
r'\langle': [('ex', '\xad'), ('ex', '\x44'),
509-
('ex', '\xbf'), ('ex', '\x2a')],
510-
r'\rangle': [('ex', '\xae'), ('ex', '\x45'),
511-
('ex', '\xc0'), ('ex', '\x2b')],
512-
r'\__sqrt__': [('ex', '\x70'), ('ex', '\x71'),
513-
('ex', '\x72'), ('ex', '\x73')],
514-
r'\backslash': [('ex', '\xb2'), ('ex', '\x2f'),
515-
('ex', '\xc2'), ('ex', '\x2d')],
516-
r'/': [('rm', '/'), ('ex', '\xb1'), ('ex', '\x2e'),
517-
('ex', '\xcb'), ('ex', '\x2c')],
518-
r'\widehat': [('rm', '\x5e'), ('ex', '\x62'), ('ex', '\x63'),
519-
('ex', '\x64')],
520-
r'\widetilde': [('rm', '\x7e'), ('ex', '\x65'), ('ex', '\x66'),
521-
('ex', '\x67')],
522-
r'<': [('cal', 'h'), ('ex', 'D')],
523-
r'>': [('cal', 'i'), ('ex', 'E')]
524-
}
487+
'(': [('rm', '('), *[('ex', fr'\__parenleft{s}__') for s in _latex_sizes]],
488+
')': [('rm', ')'), *[('ex', fr'\__parenright{s}__') for s in _latex_sizes]],
489+
'{': [('ex', fr'\__braceleft{s}__') for s in _latex_sizes],
490+
'}': [('ex', fr'\__braceright{s}__') for s in _latex_sizes],
491+
'[': [('rm', '['), *[('ex', fr'\__bracketleft{s}__') for s in _latex_sizes]],
492+
']': [('rm', ']'), *[('ex', fr'\__bracketright{s}__') for s in _latex_sizes]],
493+
'<': [('cal', r'\__angbracketleft__'),
494+
*[('ex', fr'\__angbracketleft{s}__') for s in _latex_sizes]],
495+
'>': [('cal', r'\__angbracketright__'),
496+
*[('ex', fr'\__angbracketright{s}__') for s in _latex_sizes]],
497+
r'\lfloor': [('ex', fr'\__floorleft{s}__') for s in _latex_sizes],
498+
r'\rfloor': [('ex', fr'\__floorright{s}__') for s in _latex_sizes],
499+
r'\lceil': [('ex', fr'\__ceilingleft{s}__') for s in _latex_sizes],
500+
r'\rceil': [('ex', fr'\__ceilingright{s}__') for s in _latex_sizes],
501+
r'\__sqrt__': [('ex', fr'\__radical{s}__') for s in _latex_sizes],
502+
r'\backslash': [('ex', fr'\__backslash{s}__') for s in _latex_sizes],
503+
r'/': [('rm', '/'), *[('ex', fr'\__slash{s}__') for s in _latex_sizes]],
504+
r'\widehat': [('rm', '\x5e'), ('ex', r'\__hatwide__'), ('ex', r'\__hatwider__'),
505+
('ex', r'\__hatwidest__')],
506+
r'\widetilde': [('rm', '\x7e'), ('ex', r'\__tildewide__'),
507+
('ex', r'\__tildewider__'), ('ex', r'\__tildewidest__')],
508+
}
525509

526-
for alias, target in [(r'\leftparen', '('),
527-
(r'\rightparen', ')'),
528-
(r'\leftbrace', '{'),
529-
(r'\rightbrace', '}'),
530-
(r'\leftbracket', '['),
531-
(r'\rightbracket', ']'),
532-
(r'\{', '{'),
533-
(r'\}', '}'),
534-
(r'\[', '['),
535-
(r'\]', ']')]:
510+
for alias, target in [(r'\leftparen', '('), (r'\rightparen', ')'),
511+
(r'\leftbrace', '{'), (r'\rightbrace', '}'),
512+
(r'\leftbracket', '['), (r'\rightbracket', ']'),
513+
(r'\langle', '<'), (r'\rangle', '>'),
514+
(r'\{', '{'), (r'\}', '}'),
515+
(r'\[', '['), (r'\]', ']')]:
536516
_size_alternatives[alias] = _size_alternatives[target]
537517

538518
def get_sized_alternatives_for_symbol(self, fontname: str,

lib/matplotlib/_mathtext_data.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,75 @@
3636
'{' : ('cmex10', 0xa9),
3737
'}' : ('cmex10', 0xaa),
3838

39+
'\\__angbracketleft__' : ('cmsy10', 0x68),
40+
'\\__angbracketright__' : ('cmsy10', 0x69),
41+
'\\__angbracketleftbig__' : ('cmex10', 0xad),
42+
'\\__angbracketleftBig__' : ('cmex10', 0x44),
43+
'\\__angbracketleftbigg__' : ('cmex10', 0xbf),
44+
'\\__angbracketleftBigg__' : ('cmex10', 0x2a),
45+
'\\__angbracketrightbig__' : ('cmex10', 0xae),
46+
'\\__angbracketrightBig__' : ('cmex10', 0x45),
47+
'\\__angbracketrightbigg__' : ('cmex10', 0xc0),
48+
'\\__angbracketrightBigg__' : ('cmex10', 0x2b),
49+
'\\__backslashbig__' : ('cmex10', 0xb2),
50+
'\\__backslashBig__' : ('cmex10', 0x2f),
51+
'\\__backslashbigg__' : ('cmex10', 0xc2),
52+
'\\__backslashBigg__' : ('cmex10', 0x2d),
53+
'\\__braceleftbig__' : ('cmex10', 0xa9),
54+
'\\__braceleftBig__' : ('cmex10', 0x6e),
55+
'\\__braceleftbigg__' : ('cmex10', 0xbd),
56+
'\\__braceleftBigg__' : ('cmex10', 0x28),
57+
'\\__bracerightbig__' : ('cmex10', 0xaa),
58+
'\\__bracerightBig__' : ('cmex10', 0x6f),
59+
'\\__bracerightbigg__' : ('cmex10', 0xbe),
60+
'\\__bracerightBigg__' : ('cmex10', 0x29),
61+
'\\__bracketleftbig__' : ('cmex10', 0xa3),
62+
'\\__bracketleftBig__' : ('cmex10', 0x68),
63+
'\\__bracketleftbigg__' : ('cmex10', 0x2219),
64+
'\\__bracketleftBigg__' : ('cmex10', 0x22),
65+
'\\__bracketrightbig__' : ('cmex10', 0xa4),
66+
'\\__bracketrightBig__' : ('cmex10', 0x69),
67+
'\\__bracketrightbigg__' : ('cmex10', 0xb8),
68+
'\\__bracketrightBigg__' : ('cmex10', 0x23),
69+
'\\__ceilingleftbig__' : ('cmex10', 0xa7),
70+
'\\__ceilingleftBig__' : ('cmex10', 0x6c),
71+
'\\__ceilingleftbigg__' : ('cmex10', 0xbb),
72+
'\\__ceilingleftBigg__' : ('cmex10', 0x26),
73+
'\\__ceilingrightbig__' : ('cmex10', 0xa8),
74+
'\\__ceilingrightBig__' : ('cmex10', 0x6d),
75+
'\\__ceilingrightbigg__' : ('cmex10', 0xbc),
76+
'\\__ceilingrightBigg__' : ('cmex10', 0x27),
77+
'\\__floorleftbig__' : ('cmex10', 0xa5),
78+
'\\__floorleftBig__' : ('cmex10', 0x6a),
79+
'\\__floorleftbigg__' : ('cmex10', 0xb9),
80+
'\\__floorleftBigg__' : ('cmex10', 0x24),
81+
'\\__floorrightbig__' : ('cmex10', 0xa6),
82+
'\\__floorrightBig__' : ('cmex10', 0x6b),
83+
'\\__floorrightbigg__' : ('cmex10', 0xba),
84+
'\\__floorrightBigg__' : ('cmex10', 0x25),
85+
'\\__hatwide__' : ('cmex10', 0x62),
86+
'\\__hatwider__' : ('cmex10', 0x63),
87+
'\\__hatwidest__' : ('cmex10', 0x64),
88+
'\\__parenleftbig__' : ('cmex10', 0xa1),
89+
'\\__parenleftBig__' : ('cmex10', 0xb3),
90+
'\\__parenleftbigg__' : ('cmex10', 0xb5),
91+
'\\__parenleftBigg__' : ('cmex10', 0xc3),
92+
'\\__parenrightbig__' : ('cmex10', 0xa2),
93+
'\\__parenrightBig__' : ('cmex10', 0xb4),
94+
'\\__parenrightbigg__' : ('cmex10', 0xb6),
95+
'\\__parenrightBigg__' : ('cmex10', 0x21),
96+
'\\__radicalbig__' : ('cmex10', 0x70),
97+
'\\__radicalBig__' : ('cmex10', 0x71),
98+
'\\__radicalbigg__' : ('cmex10', 0x72),
99+
'\\__radicalBigg__' : ('cmex10', 0x73),
100+
'\\__slashbig__' : ('cmex10', 0xb1),
101+
'\\__slashBig__' : ('cmex10', 0x2e),
102+
'\\__slashbigg__' : ('cmex10', 0xc1),
103+
'\\__slashBigg__' : ('cmex10', 0x2c),
104+
'\\__tildewide__' : ('cmex10', 0x65),
105+
'\\__tildewider__' : ('cmex10', 0x66),
106+
'\\__tildewidest__' : ('cmex10', 0x67),
107+
39108
',' : ('cmmi10', 0x3b),
40109
'.' : ('cmmi10', 0x3a),
41110
'/' : ('cmmi10', 0x3d),
@@ -1112,6 +1181,8 @@
11121181
'|' : 0x2016,
11131182
'}' : 0x7d,
11141183
}
1184+
tex2uni['__angbracketleft__'] = tex2uni['langle']
1185+
tex2uni['__angbracketright__'] = tex2uni['rangle']
11151186

11161187
# Each element is a 4-tuple of the form:
11171188
# src_start, src_end, dst_font, dst_start

lib/matplotlib/tests/test_mathtext.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,21 @@
125125
r'$,$ $.$ $1{,}234{, }567{ , }890$ and $1,234,567,890$', # github issue 5799
126126
r'$\left(X\right)_{a}^{b}$', # github issue 7615
127127
r'$\dfrac{\$100.00}{y}$', # github issue #1888
128-
r'$a=-b-c$' # github issue #28180
128+
r'$a=-b-c$', # github issue #28180
129129
]
130130
# 'svgastext' tests switch svg output to embed text as text (rather than as
131131
# paths).
132132
svgastext_math_tests = [
133133
r'$-$-',
134+
# Check all AutoHeightChar substitutions.
135+
*[
136+
r'$\left' + lc + r' M \middle/ ? \middle\backslash ? \right' + rc + ' ' + # Normal size.
137+
r'\left' + lc + r' \frac{M}{B} \middle/ ? \middle\backslash ? \right' + rc + ' ' + # big size.
138+
r'\left' + lc + r' \frac{\frac{M}{I}}{B} \middle/ ? \middle\backslash ? \right' + rc + ' ' + # bigg size.
139+
r'\left' + lc + r' \frac{\frac{M}{I}}{\frac{B}{U}} \middle/ ? \middle\backslash ? \right' + rc + ' ' + # Big size.
140+
r'\left' + lc + r'\frac{\frac{\frac{M}{I}}{N}}{\frac{\frac{B}{U}}{G}} \middle/ ? \middle\backslash ? \right' + rc + '$' # Bigg size.
141+
for lc, rc in ['()', '[]', '<>', (r'\{', r'\}'), (r'\lfloor', r'\rfloor'), (r'\lceil', r'\rceil')]
142+
],
134143
]
135144
# 'lightweight' tests test only a single fontset (dejavusans, which is the
136145
# default) and only png outputs, in order to minimize the size of baseline
@@ -237,7 +246,7 @@ def test_mathtext_rendering_svgastext(baseline_images, fontset, index, text):
237246
mpl.rcParams['svg.fonttype'] = 'none' # Minimize image size.
238247
fig = plt.figure(figsize=(5.25, 0.75))
239248
fig.patch.set(visible=False) # Minimize image size.
240-
fig.text(0.5, 0.5, text,
249+
fig.text(0.5, 0.5, text, fontsize=16,
241250
horizontalalignment='center', verticalalignment='center')
242251

243252

0 commit comments

Comments
 (0)