Skip to content

Commit 88ed882

Browse files
committed
Remove font preamble caching in TexManager.
TexManager has a complex caching machinery (... among other caching layers) to map font-related rcParams to a tex preamble (see `_rc_cache`, `_rc_cache_keys`, `_reinit`) but that's just a matter of a few dict lookups which are negligible compared to invoking the subprocess; so just strip out that caching and always regenerate the font-related preamble. That caching also set some attributes (`texmanager.serif`, etc.) as a side-effect via `setattr`/`getattr`, which are used nowhere else (and it's hard to know they even exist other than figuring out the relevant `setattr` calls); just deprecate them.
1 parent 382be60 commit 88ed882

File tree

2 files changed

+41
-43
lines changed

2 files changed

+41
-43
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Deprecations
2+
````````````
3+
4+
The ``TexManager.serif``, ``TexManager.sans_serif``, ``TexManager.cursive`` and
5+
``TexManager.monospace`` attributes are deprecated.

lib/matplotlib/texmanager.py

Lines changed: 36 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
:rc:`text.usetex` to True.
2929
"""
3030

31-
import copy
3231
import functools
3332
import glob
3433
import hashlib
@@ -58,10 +57,6 @@ class TexManager:
5857
rgba_arrayd = {}
5958
grey_arrayd = {}
6059

61-
serif = ('cmr', '')
62-
sans_serif = ('cmss', '')
63-
monospace = ('cmtt', '')
64-
cursive = ('pzc', r'\usepackage{chancery}')
6560
font_family = 'serif'
6661
font_families = ('serif', 'sans-serif', 'cursive', 'monospace')
6762

@@ -86,24 +81,39 @@ class TexManager:
8681
'computer modern sans serif': ('cmss', r'\usepackage{type1ec}'),
8782
'computer modern typewriter': ('cmtt', r'\usepackage{type1ec}')}
8883

89-
_rc_cache = None
90-
_rc_cache_keys = [
91-
'text.latex.preamble', 'text.latex.preview', 'font.family',
92-
*['font.' + n for n in font_families]]
93-
9484
@cbook.deprecated("3.3", alternative="matplotlib.get_cachedir()")
9585
@property
9686
def cachedir(self):
9787
return mpl.get_cachedir()
9888

9989
@functools.lru_cache() # Always return the same instance.
10090
def __new__(cls):
101-
self = object.__new__(cls)
102-
self._reinit()
103-
return self
91+
Path(cls.texcache).mkdir(parents=True, exist_ok=True)
92+
return object.__new__(cls)
93+
94+
_fonts = {} # Only for deprecation period.
95+
96+
@cbook.deprecated("3.3")
97+
@property
98+
def serif(self):
99+
return self._fonts.get("serif", ('cmr', ''))
100+
101+
@cbook.deprecated("3.3")
102+
@property
103+
def sans_serif(self):
104+
return self._fonts.get("sans-serif", ('cmss', ''))
105+
106+
@cbook.deprecated("3.3")
107+
@property
108+
def cursive(self):
109+
return self._fonts.get("cursive", ('pzc', r'\usepackage{chancery}'))
110+
111+
@cbook.deprecated("3.3")
112+
@property
113+
def monospace(self):
114+
return self._fonts.get("monospace", ('cmtt', ''))
104115

105-
def _reinit(self):
106-
Path(self.texcache).mkdir(parents=True, exist_ok=True)
116+
def get_font_config(self):
107117
ff = rcParams['font.family']
108118
if len(ff) == 1 and ff[0].lower() in self.font_families:
109119
self.font_family = ff[0].lower()
@@ -115,11 +125,9 @@ def _reinit(self):
115125

116126
fontconfig = [self.font_family]
117127
for font_family in self.font_families:
118-
font_family_attr = font_family.replace('-', '_')
119128
for font in rcParams['font.' + font_family]:
120129
if font.lower() in self.font_info:
121-
setattr(self, font_family_attr,
122-
self.font_info[font.lower()])
130+
self._fonts[font_family] = self.font_info[font.lower()]
123131
_log.debug('family: %s, font: %s, info: %s',
124132
font_family, font, self.font_info[font.lower()])
125133
break
@@ -129,22 +137,25 @@ def _reinit(self):
129137
else:
130138
_log.info('No LaTeX-compatible font found for the %s font '
131139
'family in rcParams. Using default.', font_family)
132-
setattr(self, font_family_attr, self.font_info[font_family])
133-
fontconfig.append(getattr(self, font_family_attr)[0])
134-
# Add a hash of the latex preamble to self._fontconfig so that the
140+
self._fonts[font_family] = self.font_info[font_family]
141+
fontconfig.append(self._fonts[font_family][0])
142+
# Add a hash of the latex preamble to fontconfig so that the
135143
# correct png is selected for strings rendered with same font and dpi
136144
# even if the latex preamble changes within the session
137145
preamble_bytes = self.get_custom_preamble().encode('utf-8')
138146
fontconfig.append(hashlib.md5(preamble_bytes).hexdigest())
139-
self._fontconfig = ''.join(fontconfig)
140147

141148
# The following packages and commands need to be included in the latex
142149
# file's preamble:
143-
cmd = [self.serif[1], self.sans_serif[1], self.monospace[1]]
150+
cmd = [self._fonts['serif'][1],
151+
self._fonts['sans-serif'][1],
152+
self._fonts['monospace'][1]]
144153
if self.font_family == 'cursive':
145-
cmd.append(self.cursive[1])
154+
cmd.append(self._fonts['cursive'][1])
146155
self._font_preamble = '\n'.join(
147-
[r'\usepackage{type1cm}'] + cmd + [r'\usepackage{textcomp}'])
156+
[r'\usepackage{type1cm}', *cmd, r'\usepackage{textcomp}'])
157+
158+
return ''.join(fontconfig)
148159

149160
def get_basefile(self, tex, fontsize, dpi=None):
150161
"""
@@ -155,24 +166,6 @@ def get_basefile(self, tex, fontsize, dpi=None):
155166
return os.path.join(
156167
self.texcache, hashlib.md5(s.encode('utf-8')).hexdigest())
157168

158-
def get_font_config(self):
159-
"""Reinitializes self if relevant rcParams on have changed."""
160-
if self._rc_cache is None:
161-
self._rc_cache = dict.fromkeys(self._rc_cache_keys)
162-
changed = [par for par in self._rc_cache_keys
163-
if rcParams[par] != self._rc_cache[par]]
164-
if changed:
165-
_log.debug('following keys changed: %s', changed)
166-
for k in changed:
167-
_log.debug('%-20s: %-10s -> %-10s',
168-
k, self._rc_cache[k], rcParams[k])
169-
# deepcopy may not be necessary, but feels more future-proof
170-
self._rc_cache[k] = copy.deepcopy(rcParams[k])
171-
_log.debug('RE-INIT\nold fontconfig: %s', self._fontconfig)
172-
self._reinit()
173-
_log.debug('fontconfig: %s', self._fontconfig)
174-
return self._fontconfig
175-
176169
def get_font_preamble(self):
177170
"""
178171
Return a string containing font configuration for the tex preamble.

0 commit comments

Comments
 (0)