Skip to content

Commit 69109de

Browse files
committed
Merge branch 'font-manager-state'
2 parents e018616 + 0456e5a commit 69109de

File tree

3 files changed

+51
-14
lines changed

3 files changed

+51
-14
lines changed

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2014-05-20 Added logic to in FontManager to invalidate font-cache if
2+
if font-family rcparams have changed.
3+
14
2014-05-16 Fixed the positioning of multi-line text in the PGF backend.
25

36
2014-05-14 Added Axes.add_image() as the standard way to add AxesImage

lib/matplotlib/font_manager.py

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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()

lib/matplotlib/tests/test_font_manager.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,14 @@
66

77
import os
88

9-
from matplotlib.font_manager import findfont, FontProperties, _rebuild
9+
from matplotlib.font_manager import findfont, FontProperties
1010
from matplotlib import rc_context
1111

1212

1313
def test_font_priority():
1414
with rc_context(rc={
1515
'font.sans-serif':
1616
['cmmi10', 'Bitstream Vera Sans']}):
17-
# force the font manager to rebuild it self
18-
_rebuild()
1917
font = findfont(
2018
FontProperties(family=["sans-serif"]))
2119
assert_equal(os.path.basename(font), 'cmmi10.ttf')
22-
# force it again
23-
_rebuild()

0 commit comments

Comments
 (0)