@@ -952,7 +952,47 @@ def pickle_load(filename):
952
952
data = pickle .load (fh )
953
953
return data
954
954
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 ):
956
996
"""
957
997
On import, the :class:`FontManager` singleton instance creates a
958
998
list of TrueType fonts based on the font properties: name, style,
@@ -1015,9 +1055,6 @@ def __init__(self, size=None, weight='normal'):
1015
1055
else :
1016
1056
self .defaultFont ['afm' ] = None
1017
1057
1018
- self .ttf_lookup_cache = {}
1019
- self .afm_lookup_cache = {}
1020
-
1021
1058
def get_default_weight (self ):
1022
1059
"""
1023
1060
Return the default font weight.
@@ -1200,15 +1237,13 @@ def findfont(self, prop, fontext='ttf', directory=None,
1200
1237
return fname
1201
1238
1202
1239
if fontext == 'afm' :
1203
- font_cache = self .afm_lookup_cache
1204
1240
fontlist = self .afmlist
1205
1241
else :
1206
- font_cache = self .ttf_lookup_cache
1207
1242
fontlist = self .ttflist
1208
1243
1209
1244
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 :
1212
1247
return cached
1213
1248
1214
1249
best_score = 1e64
@@ -1266,7 +1301,7 @@ def findfont(self, prop, fontext='ttf', directory=None,
1266
1301
raise ValueError ("No valid font could be found" )
1267
1302
1268
1303
if directory is None :
1269
- font_cache [ hash (prop )] = result
1304
+ _lookup_cache [ fontext ]. set (prop , result )
1270
1305
return result
1271
1306
1272
1307
@@ -1348,6 +1383,11 @@ def findfont(prop, fontext='ttf'):
1348
1383
1349
1384
fontManager = None
1350
1385
1386
+ _lookup_cache = {
1387
+ 'ttf' : TempCache (),
1388
+ 'afm' : TempCache ()
1389
+ }
1390
+
1351
1391
def _rebuild ():
1352
1392
global fontManager
1353
1393
fontManager = FontManager ()
0 commit comments