Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a815ea0

Browse files
committed
Remove "experimental" fontconfig font_manager backend.
The "experimental" fontconfig backend for font_manager was never publicly accessible: even if one does `matplotlib.font_manager.USE_FONTCONFIG = True`, that didn't change the already existing `findfont`. The only way to access it was to edit the source, or use `reload()`, neither of which really count as public API... Note that our "use" of "fontconfig-like" patterns actually has subtly different semantics from actual fontconfig patterns, so it's not as if that backend was correctly working anyways. We don't need to set `fontManager.default_size` when loading it as we already check that fontManager has the correct `__version__` (and thus must have a correct `default_size`; moreover the only use of `default_size` is in `sizeval1 = self.default_size * font_scalings[size1]` so it's not as if a value of `None` (if it had somehow been missing) was going to be helpful anyways... `get_cachedir()` always returns a real directory (creating a temporary one if necessary), so we can drop the code paths handling `get_cachedir() == None`. Note that we still rely on fontconfig to *list* fonts; the backend only added an (non-publicly-accessible, per above) option to *match* fonts using fontconfig.
1 parent f1b64ad commit a815ea0

File tree

4 files changed

+37
-102
lines changed

4 files changed

+37
-102
lines changed

.flake8

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ per-file-ignores =
3838
matplotlib/backends/backend_pgf.py: E303, E731
3939
matplotlib/backends/qt_editor/formlayout.py: E301, E501
4040
matplotlib/backends/tkagg.py: E231, E302, E701
41-
matplotlib/font_manager.py: E203, E221, E251, E261, E262, E302, E501
41+
matplotlib/font_manager.py: E203, E221, E251, E261, E262, E501
4242
matplotlib/fontconfig_pattern.py: E201, E203, E221, E222, E225, E302
4343
matplotlib/mathtext.py: E201, E202, E203, E211, E221, E222, E225, E251, E301, E402
4444
matplotlib/projections/geo.py: E203, E221, E231, E261, E502
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
API removals
2+
````````````
3+
The following API elements have been removed:
4+
5+
- ``font_manager.USE_FONTCONFIG``, ``font_manager.cachedir``,

lib/matplotlib/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,9 +564,9 @@ def get_home():
564564
return None
565565

566566

567-
def _create_tmp_config_dir():
567+
def _create_tmp_config_or_cache_dir():
568568
"""
569-
If the config directory can not be created, create a temporary directory.
569+
If the config or cache directory cannot be created, create a temporary one.
570570
"""
571571
configdir = os.environ['MPLCONFIGDIR'] = (
572572
tempfile.mkdtemp(prefix='matplotlib-'))
@@ -618,7 +618,7 @@ def _get_config_or_cache_dir(xdg_base):
618618
if os.access(str(configdir), os.W_OK) and configdir.is_dir():
619619
return str(configdir)
620620

621-
return _create_tmp_config_dir()
621+
return _create_tmp_config_or_cache_dir()
622622

623623

624624
@_logged_cached('CONFIGDIR=%s')

lib/matplotlib/font_manager.py

Lines changed: 28 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,6 @@
1111
The design is based on the `W3C Cascading Style Sheet, Level 1 (CSS1)
1212
font specification <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_.
1313
Future versions may implement the Level 2 or 2.1 specifications.
14-
15-
Experimental support is included for using `fontconfig` on Unix
16-
variant platforms (Linux, OS X, Solaris). To enable it, set the
17-
constant ``USE_FONTCONFIG`` in this file to ``True``. Fontconfig has
18-
the advantage that it is the standard way to look up fonts on X11
19-
platforms, so if a font is installed, it is much more likely to be
20-
found.
2114
"""
2215

2316
# KNOWN ISSUES
@@ -45,14 +38,12 @@
4538
import warnings
4639

4740
import matplotlib as mpl
48-
from matplotlib import afm, cbook, ft2font, rcParams, get_cachedir
41+
from matplotlib import afm, cbook, ft2font, rcParams
4942
from matplotlib.fontconfig_pattern import (
5043
parse_fontconfig_pattern, generate_fontconfig_pattern)
5144

5245
_log = logging.getLogger(__name__)
5346

54-
USE_FONTCONFIG = False
55-
5647
font_scalings = {
5748
'xx-small' : 0.579,
5849
'x-small' : 0.694,
@@ -105,12 +96,10 @@
10596
MSFolders = \
10697
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
10798

108-
10999
MSFontDirectories = [
110100
r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts',
111101
r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts']
112102

113-
114103
X11FontDirectories = [
115104
# an old standard installation point
116105
"/usr/X11R6/lib/X11/fonts/TTF/",
@@ -121,21 +110,20 @@
121110
"/usr/local/share/fonts/",
122111
# common application, not really useful
123112
"/usr/lib/openoffice/share/fonts/truetype/",
124-
]
113+
# user fonts
114+
str(Path.home() / ".fonts"),
115+
]
125116

126117
OSXFontDirectories = [
127118
"/Library/Fonts/",
128119
"/Network/Library/Fonts/",
129120
"/System/Library/Fonts/",
130121
# fonts installed via MacPorts
131-
"/opt/local/share/fonts"
132-
""
122+
"/opt/local/share/fonts",
123+
# user fonts
124+
str(Path.home() / "Library/Fonts"),
133125
]
134126

135-
if not USE_FONTCONFIG and sys.platform != 'win32':
136-
OSXFontDirectories.append(str(Path.home() / "Library/Fonts"))
137-
X11FontDirectories.append(str(Path.home() / ".fonts"))
138-
139127

140128
def get_fontext_synonyms(fontext):
141129
"""
@@ -1154,7 +1142,7 @@ def score_size(self, size1, size2):
11541142
sizeval2 = float(size2)
11551143
except ValueError:
11561144
return 1.0
1157-
return abs(sizeval1 - sizeval2) / 72.0
1145+
return abs(sizeval1 - sizeval2) / 72
11581146

11591147
def findfont(self, prop, fontext='ttf', directory=None,
11601148
fallback_to_default=True, rebuild_if_missing=True):
@@ -1263,6 +1251,7 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
12631251

12641252
return result
12651253

1254+
12661255
@lru_cache()
12671256
def is_opentype_cff_font(filename):
12681257
"""
@@ -1276,95 +1265,36 @@ def is_opentype_cff_font(filename):
12761265
else:
12771266
return False
12781267

1279-
fontManager = None
1280-
_fmcache = None
1281-
12821268

12831269
_get_font = lru_cache(64)(ft2font.FT2Font)
1270+
_fmcache = os.path.join(
1271+
mpl.get_cachedir(), 'fontlist-v{}.json'.format(FontManager.__version__))
1272+
fontManager = None
1273+
12841274

12851275
def get_font(filename, hinting_factor=None):
12861276
if hinting_factor is None:
12871277
hinting_factor = rcParams['text.hinting_factor']
12881278
return _get_font(filename, hinting_factor)
12891279

12901280

1291-
# The experimental fontconfig-based backend.
1292-
if USE_FONTCONFIG and sys.platform != 'win32':
1281+
def _rebuild():
1282+
global fontManager
1283+
fontManager = FontManager()
1284+
with cbook._lock_path(_fmcache):
1285+
json_dump(fontManager, _fmcache)
1286+
_log.info("generated new fontManager")
12931287

1294-
def fc_match(pattern, fontext):
1295-
fontexts = get_fontext_synonyms(fontext)
1296-
ext = "." + fontext
1297-
try:
1298-
pipe = subprocess.Popen(
1299-
['fc-match', '-s', '--format=%{file}\\n', pattern],
1300-
stdout=subprocess.PIPE,
1301-
stderr=subprocess.PIPE)
1302-
output = pipe.communicate()[0]
1303-
except OSError:
1304-
return None
1305-
1306-
# The bulk of the output from fc-list is ascii, so we keep the
1307-
# result in bytes and parse it as bytes, until we extract the
1308-
# filename, which is in sys.filesystemencoding().
1309-
if pipe.returncode == 0:
1310-
for fname in map(os.fsdecode, output.split(b'\n')):
1311-
if os.path.splitext(fname)[1][1:] in fontexts:
1312-
return fname
1313-
return None
1314-
1315-
_fc_match_cache = {}
1316-
1317-
def findfont(prop, fontext='ttf'):
1318-
if not isinstance(prop, str):
1319-
prop = prop.get_fontconfig_pattern()
1320-
cached = _fc_match_cache.get(prop)
1321-
if cached is not None:
1322-
return cached
1323-
1324-
result = fc_match(prop, fontext)
1325-
if result is None:
1326-
result = fc_match(':', fontext)
1327-
1328-
_fc_match_cache[prop] = result
1329-
return result
13301288

1289+
try:
1290+
fontManager = json_load(_fmcache)
1291+
except Exception:
1292+
_rebuild()
13311293
else:
1332-
_fmcache = None
1333-
1334-
cachedir = get_cachedir()
1335-
if cachedir is not None:
1336-
_fmcache = os.path.join(
1337-
cachedir, 'fontlist-v{}.json'.format(FontManager.__version__))
1338-
1339-
fontManager = None
1340-
1341-
def _rebuild():
1342-
global fontManager
1343-
1344-
fontManager = FontManager()
1345-
1346-
if _fmcache:
1347-
with cbook._lock_path(_fmcache):
1348-
json_dump(fontManager, _fmcache)
1349-
_log.debug("generated new fontManager")
1350-
1351-
if _fmcache:
1352-
try:
1353-
fontManager = json_load(_fmcache)
1354-
if (not hasattr(fontManager, '_version') or
1355-
fontManager._version != FontManager.__version__):
1356-
_rebuild()
1357-
else:
1358-
fontManager.default_size = None
1359-
_log.debug("Using fontManager instance from %s", _fmcache)
1360-
except TimeoutError:
1361-
raise
1362-
except Exception:
1363-
_rebuild()
1364-
else:
1294+
if getattr(fontManager, '_version', object()) != FontManager.__version__:
13651295
_rebuild()
1296+
else:
1297+
_log.debug("Using fontManager instance from %s", _fmcache)
1298+
13661299

1367-
def findfont(prop, **kw):
1368-
global fontManager
1369-
font = fontManager.findfont(prop, **kw)
1370-
return font
1300+
findfont = fontManager.findfont

0 commit comments

Comments
 (0)