Skip to content

Commit 0d20567

Browse files
committed
FontManager fixes.
Previously, when using findfont with rebuild_is_missing (the default) _rebuild() would generate a new fontManager instance, but because findfont is defined as `findfont = fontManager.findfont`, this would keep using the old fontManager instance; we can't just fix this with `def findfont(...): return fontManager.findfont(...)` because people may be importing the fontManager instance anyways and not benefitting from the rebuilt one. Instead, overwrite(!) the contents of the existing fontManager instance with the new one as needed.
1 parent baead7d commit 0d20567

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

lib/matplotlib/font_manager.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,8 +1285,13 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
12851285
if rebuild_if_missing:
12861286
_log.info(
12871287
'findfont: Found a missing font file. Rebuilding cache.')
1288-
_rebuild()
1289-
return fontManager.findfont(
1288+
new_fm = _load_fontmanager(try_read_cache=False)
1289+
# Replace self by the new fontmanager, because users may have
1290+
# a reference to this specific instance.
1291+
# TODO: _load_fontmanager should really be (used by) a method
1292+
# modifying the instance in place.
1293+
vars(self).update(vars(new_fm))
1294+
return self.findfont(
12901295
prop, fontext, directory, rebuild_if_missing=False)
12911296
else:
12921297
raise ValueError("No valid font could be found")
@@ -1308,11 +1313,6 @@ def is_opentype_cff_font(filename):
13081313
return False
13091314

13101315

1311-
_fmcache = os.path.join(
1312-
mpl.get_cachedir(), 'fontlist-v{}.json'.format(FontManager.__version__))
1313-
fontManager = None
1314-
1315-
13161316
_get_font = lru_cache(64)(ft2font.FT2Font)
13171317
# FT2Font objects cannot be used across fork()s because they reference the same
13181318
# FT_Library object. While invalidating *all* existing FT2Fonts after a fork
@@ -1332,22 +1332,23 @@ def get_font(filename, hinting_factor=None):
13321332
_kerning_factor=rcParams['text.kerning_factor'])
13331333

13341334

1335-
def _rebuild():
1336-
global fontManager
1337-
_log.info("Generating new fontManager, this may take some time...")
1338-
fontManager = FontManager()
1339-
json_dump(fontManager, _fmcache)
1340-
1341-
1342-
try:
1343-
fontManager = json_load(_fmcache)
1344-
except Exception:
1345-
_rebuild()
1346-
else:
1347-
if getattr(fontManager, '_version', object()) != FontManager.__version__:
1348-
_rebuild()
1349-
else:
1350-
_log.debug("Using fontManager instance from %s", _fmcache)
1335+
def _load_fontmanager(*, try_read_cache=True):
1336+
if try_read_cache:
1337+
fm_path = Path(
1338+
mpl.get_cachedir(), f"fontlist-v{FontManager.__version__}.json")
1339+
try:
1340+
fm = json_load(fm_path)
1341+
except Exception as exc:
1342+
pass
1343+
else:
1344+
if getattr(fm, "_version", object()) == FontManager.__version__:
1345+
_log.debug("Using fontManager instance from %s", fm_path)
1346+
return fm
1347+
fm = FontManager()
1348+
json_dump(fm, fm_path)
1349+
_log.info("generated new fontManager")
1350+
return fm
13511351

13521352

1353+
fontManager = _load_fontmanager()
13531354
findfont = fontManager.findfont

0 commit comments

Comments
 (0)