@@ -952,7 +952,45 @@ 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+ return [id (fontManager )] + [
976+ rcParams [param ] for param in self .invalidating_rcparams ]
977+
978+ def get (self , prop ):
979+ key = self .make_rcparams_key ()
980+ if key != self ._last_rcParams :
981+ self ._lookup_cache = {}
982+ self ._last_rcParams = key
983+ return self ._lookup_cache .get (prop )
984+
985+ def set (self , prop , value ):
986+ key = self .make_rcparams_key ()
987+ if key != self ._last_rcParams :
988+ self ._lookup_cache = {}
989+ self ._last_rcParams = key
990+ self ._lookup_cache [prop ] = value
991+
992+
993+ class FontManager (object ):
956994 """
957995 On import, the :class:`FontManager` singleton instance creates a
958996 list of TrueType fonts based on the font properties: name, style,
@@ -1015,9 +1053,6 @@ def __init__(self, size=None, weight='normal'):
10151053 else :
10161054 self .defaultFont ['afm' ] = None
10171055
1018- self .ttf_lookup_cache = {}
1019- self .afm_lookup_cache = {}
1020-
10211056 def get_default_weight (self ):
10221057 """
10231058 Return the default font weight.
@@ -1200,15 +1235,13 @@ def findfont(self, prop, fontext='ttf', directory=None,
12001235 return fname
12011236
12021237 if fontext == 'afm' :
1203- font_cache = self .afm_lookup_cache
12041238 fontlist = self .afmlist
12051239 else :
1206- font_cache = self .ttf_lookup_cache
12071240 fontlist = self .ttflist
12081241
12091242 if directory is None :
1210- cached = font_cache .get (hash ( prop ) )
1211- if cached :
1243+ cached = _lookup_cache [ fontext ] .get (prop )
1244+ if cached is not None :
12121245 return cached
12131246
12141247 best_score = 1e64
@@ -1266,7 +1299,7 @@ def findfont(self, prop, fontext='ttf', directory=None,
12661299 raise ValueError ("No valid font could be found" )
12671300
12681301 if directory is None :
1269- font_cache [ hash (prop )] = result
1302+ _lookup_cache [ fontext ]. set (prop , result )
12701303 return result
12711304
12721305
@@ -1348,6 +1381,11 @@ def findfont(prop, fontext='ttf'):
13481381
13491382 fontManager = None
13501383
1384+ _lookup_cache = {
1385+ 'ttf' : TempCache (),
1386+ 'afm' : TempCache ()
1387+ }
1388+
13511389 def _rebuild ():
13521390 global fontManager
13531391 fontManager = FontManager ()
0 commit comments