Skip to content

Commit efb0fd5

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 a922901 commit efb0fd5

File tree

2 files changed

+44
-41
lines changed

2 files changed

+44
-41
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: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -92,25 +92,40 @@ class TexManager:
9292
'monospace': ('cmtt', r'\usepackage{type1ec}'),
9393
'computer modern roman': ('cmr', r'\usepackage{type1ec}'),
9494
'computer modern sans serif': ('cmss', r'\usepackage{type1ec}'),
95-
'computer modern typewriter': ('cmtt', r'\usepackage{type1ec}')}
96-
97-
_rc_cache = None
98-
_rc_cache_keys = (
99-
('text.latex.preamble', 'text.latex.unicode', 'text.latex.preview',
100-
'font.family') + tuple('font.' + n for n in font_families))
95+
'computer modern typewriter': ('cmtt', r'\usepackage{type1ec}'),
96+
}
10197

10298
@functools.lru_cache() # Always return the same instance.
10399
def __new__(cls):
104-
self = object.__new__(cls)
105-
self._reinit()
106-
return self
107-
108-
def _reinit(self):
109-
if self.texcache is None:
100+
if cls.texcache is None:
110101
raise RuntimeError('Cannot create TexManager, as there is no '
111102
'cache directory available')
103+
Path(cls.texcache).mkdir(parents=True, exist_ok=True)
104+
return object.__new__(cls)
105+
106+
_fonts = {} # Only for deprecation period.
107+
108+
@cbook.deprecated("3.2")
109+
@property
110+
def serif(self):
111+
return self._fonts["serif"]
112+
113+
@cbook.deprecated("3.2")
114+
@property
115+
def sans_serif(self):
116+
return self._fonts["sans-serif"]
117+
118+
@cbook.deprecated("3.2")
119+
@property
120+
def cursive(self):
121+
return self._fonts["cursive"]
112122

113-
Path(self.texcache).mkdir(parents=True, exist_ok=True)
123+
@cbook.deprecated("3.2")
124+
@property
125+
def monospace(self):
126+
return self._fonts["monospace"]
127+
128+
def get_font_config(self):
114129
ff = rcParams['font.family']
115130
if len(ff) == 1 and ff[0].lower() in self.font_families:
116131
self.font_family = ff[0].lower()
@@ -124,11 +139,9 @@ def _reinit(self):
124139

125140
fontconfig = [self.font_family]
126141
for font_family in self.font_families:
127-
font_family_attr = font_family.replace('-', '_')
128142
for font in rcParams['font.' + font_family]:
129143
if font.lower() in self.font_info:
130-
setattr(self, font_family_attr,
131-
self.font_info[font.lower()])
144+
self._fonts[font_family] = self.font_info[font.lower()]
132145
_log.debug('family: %s, font: %s, info: %s',
133146
font_family, font, self.font_info[font.lower()])
134147
break
@@ -138,22 +151,25 @@ def _reinit(self):
138151
else:
139152
_log.info('No LaTeX-compatible font found for the %s font '
140153
'family in rcParams. Using default.', font_family)
141-
setattr(self, font_family_attr, self.font_info[font_family])
142-
fontconfig.append(getattr(self, font_family_attr)[0])
143-
# Add a hash of the latex preamble to self._fontconfig so that the
154+
self._fonts[font_family] = self.font_info[font_family]
155+
fontconfig.append(self._fonts[font_family][0])
156+
# Add a hash of the latex preamble to fontconfig so that the
144157
# correct png is selected for strings rendered with same font and dpi
145158
# even if the latex preamble changes within the session
146159
preamble_bytes = self.get_custom_preamble().encode('utf-8')
147160
fontconfig.append(hashlib.md5(preamble_bytes).hexdigest())
148-
self._fontconfig = ''.join(fontconfig)
149161

150162
# The following packages and commands need to be included in the latex
151163
# file's preamble:
152-
cmd = [self.serif[1], self.sans_serif[1], self.monospace[1]]
164+
cmd = [self._fonts['serif'][1],
165+
self._fonts['sans-serif'][1],
166+
self._fonts['monospace'][1]]
153167
if self.font_family == 'cursive':
154-
cmd.append(self.cursive[1])
168+
cmd.append(self._fonts['cursive'][1])
155169
self._font_preamble = '\n'.join(
156-
[r'\usepackage{type1cm}'] + cmd + [r'\usepackage{textcomp}'])
170+
[r'\usepackage{type1cm}', *cmd, r'\usepackage{textcomp}'])
171+
172+
return ''.join(fontconfig)
157173

158174
def get_basefile(self, tex, fontsize, dpi=None):
159175
"""
@@ -164,24 +180,6 @@ def get_basefile(self, tex, fontsize, dpi=None):
164180
return os.path.join(
165181
self.texcache, hashlib.md5(s.encode('utf-8')).hexdigest())
166182

167-
def get_font_config(self):
168-
"""Reinitializes self if relevant rcParams on have changed."""
169-
if self._rc_cache is None:
170-
self._rc_cache = dict.fromkeys(self._rc_cache_keys)
171-
changed = [par for par in self._rc_cache_keys
172-
if rcParams[par] != self._rc_cache[par]]
173-
if changed:
174-
_log.debug('following keys changed: %s', changed)
175-
for k in changed:
176-
_log.debug('%-20s: %-10s -> %-10s',
177-
k, self._rc_cache[k], rcParams[k])
178-
# deepcopy may not be necessary, but feels more future-proof
179-
self._rc_cache[k] = copy.deepcopy(rcParams[k])
180-
_log.debug('RE-INIT\nold fontconfig: %s', self._fontconfig)
181-
self._reinit()
182-
_log.debug('fontconfig: %s', self._fontconfig)
183-
return self._fontconfig
184-
185183
def get_font_preamble(self):
186184
"""
187185
Return a string containing font configuration for the tex preamble.

0 commit comments

Comments
 (0)