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

Skip to content

Commit 9915b65

Browse files
committed
Don't store cache lookups in the file. Invalid the cache when font
family parameters change.
1 parent 4af8e7d commit 9915b65

1 file changed

Lines changed: 49 additions & 9 deletions

File tree

lib/matplotlib/font_manager.py

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,47 @@ def pickle_load(filename):
952952
data = pickle.load(fh)
953953
return data
954954

955-
class FontManager:
955+
956+
class TempCache(object):
957+
"""
958+
A class to store temporary caches that are (a) not saved to disk
959+
and (b) invalidated whenever certain font-related
960+
rcParams---namely the family lookup lists---are changed or the
961+
font cache is reloaded. This avoids the expensive linear search
962+
through all fonts every time a font is looked up.
963+
"""
964+
# A list of rcparam names that, when changed, invalidated this
965+
# cache.
966+
invalidating_rcparams = [
967+
'font.serif', 'font.sans-serif', 'font.cursive', 'font.fantasy',
968+
'font.monospace']
969+
970+
def __init__(self):
971+
self._lookup_cache = {}
972+
self._last_rcParams = self.make_rcparams_key()
973+
974+
def make_rcparams_key(self):
975+
key = [id(fontManager)]
976+
for param in self.invalidating_rcparams:
977+
key.append(rcParams[param])
978+
return key
979+
980+
def get(self, prop):
981+
key = self.make_rcparams_key()
982+
if key != self._last_rcParams:
983+
self._lookup_cache = {}
984+
self._last_rcParams = key
985+
return self._lookup_cache.get(prop)
986+
987+
def set(self, prop, value):
988+
key = self.make_rcparams_key()
989+
if key != self._last_rcParams:
990+
self._lookup_cache = {}
991+
self._last_rcParams = key
992+
self._lookup_cache[prop] = value
993+
994+
995+
class FontManager(object):
956996
"""
957997
On import, the :class:`FontManager` singleton instance creates a
958998
list of TrueType fonts based on the font properties: name, style,
@@ -1015,9 +1055,6 @@ def __init__(self, size=None, weight='normal'):
10151055
else:
10161056
self.defaultFont['afm'] = None
10171057

1018-
self.ttf_lookup_cache = {}
1019-
self.afm_lookup_cache = {}
1020-
10211058
def get_default_weight(self):
10221059
"""
10231060
Return the default font weight.
@@ -1200,15 +1237,13 @@ def findfont(self, prop, fontext='ttf', directory=None,
12001237
return fname
12011238

12021239
if fontext == 'afm':
1203-
font_cache = self.afm_lookup_cache
12041240
fontlist = self.afmlist
12051241
else:
1206-
font_cache = self.ttf_lookup_cache
12071242
fontlist = self.ttflist
12081243

12091244
if directory is None:
1210-
cached = font_cache.get(hash(prop))
1211-
if cached:
1245+
cached = _lookup_cache[fontext].get(prop)
1246+
if cached is not None:
12121247
return cached
12131248

12141249
best_score = 1e64
@@ -1266,7 +1301,7 @@ def findfont(self, prop, fontext='ttf', directory=None,
12661301
raise ValueError("No valid font could be found")
12671302

12681303
if directory is None:
1269-
font_cache[hash(prop)] = result
1304+
_lookup_cache[fontext].set(prop, result)
12701305
return result
12711306

12721307

@@ -1348,6 +1383,11 @@ def findfont(prop, fontext='ttf'):
13481383

13491384
fontManager = None
13501385

1386+
_lookup_cache = {
1387+
'ttf': TempCache(),
1388+
'afm': TempCache()
1389+
}
1390+
13511391
def _rebuild():
13521392
global fontManager
13531393
fontManager = FontManager()

0 commit comments

Comments
 (0)