@@ -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