3333import subprocess
3434import sys
3535try :
36+ import threading
3637 from threading import Timer
3738except ImportError :
39+ import dummy_threading as threading
3840 from dummy_threading import Timer
3941
4042import matplotlib as mpl
@@ -1394,7 +1396,12 @@ def is_opentype_cff_font(filename):
13941396 return False
13951397
13961398
1397- _get_font = lru_cache (64 )(ft2font .FT2Font )
1399+ @lru_cache (64 )
1400+ def _get_font (filename , hinting_factor , * , _kerning_factor , thread_id ):
1401+ return ft2font .FT2Font (
1402+ filename , hinting_factor , _kerning_factor = _kerning_factor )
1403+
1404+
13981405# FT2Font objects cannot be used across fork()s because they reference the same
13991406# FT_Library object. While invalidating *all* existing FT2Fonts after a fork
14001407# would be too complicated to be worth it, the main way FT2Fonts get reused is
@@ -1409,8 +1416,10 @@ def get_font(filename, hinting_factor=None):
14091416 filename = _cached_realpath (filename )
14101417 if hinting_factor is None :
14111418 hinting_factor = rcParams ['text.hinting_factor' ]
1419+ # also key on the thread ID to prevent segfaults with multi-threading
14121420 return _get_font (filename , hinting_factor ,
1413- _kerning_factor = rcParams ['text.kerning_factor' ])
1421+ _kerning_factor = rcParams ['text.kerning_factor' ],
1422+ thread_id = threading .get_ident ())
14141423
14151424
14161425def _load_fontmanager (* , try_read_cache = True ):
0 commit comments