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