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

Skip to content

Commit 7c93309

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 a43fd85 commit 7c93309

File tree

3 files changed

+33
-103
lines changed

3 files changed

+33
-103
lines changed
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
@@ -555,9 +555,9 @@ def get_home():
555555
return None
556556

557557

558-
def _create_tmp_config_dir():
558+
def _create_tmp_config_or_cache_dir():
559559
"""
560-
If the config directory can not be created, create a temporary directory.
560+
If the config or cache directory cannot be created, create a temporary one.
561561
"""
562562
configdir = os.environ['MPLCONFIGDIR'] = (
563563
tempfile.mkdtemp(prefix='matplotlib-'))
@@ -609,7 +609,7 @@ def _get_config_or_cache_dir(xdg_base):
609609
if os.access(str(configdir), os.W_OK) and configdir.is_dir():
610610
return str(configdir)
611611

612-
return _create_tmp_config_dir()
612+
return _create_tmp_config_or_cache_dir()
613613

614614

615615
@_logged_cached('CONFIGDIR=%s')

lib/matplotlib/font_manager.py

Lines changed: 25 additions & 100 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
@@ -44,14 +37,12 @@
4437
import warnings
4538

4639
import matplotlib as mpl
47-
from matplotlib import afm, cbook, ft2font, rcParams, get_cachedir
40+
from matplotlib import afm, cbook, ft2font, rcParams
4841
from matplotlib.fontconfig_pattern import (
4942
parse_fontconfig_pattern, generate_fontconfig_pattern)
5043

5144
_log = logging.getLogger(__name__)
5245

53-
USE_FONTCONFIG = False
54-
5546
font_scalings = {
5647
'xx-small' : 0.579,
5748
'x-small' : 0.694,
@@ -104,12 +95,10 @@
10495
MSFolders = \
10596
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
10697

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

112-
113102
X11FontDirectories = [
114103
# an old standard installation point
115104
"/usr/X11R6/lib/X11/fonts/TTF/",
@@ -120,20 +109,20 @@
120109
"/usr/local/share/fonts/",
121110
# common application, not really useful
122111
"/usr/lib/openoffice/share/fonts/truetype/",
123-
]
112+
# user fonts
113+
str(Path.home() / ".fonts"),
114+
]
124115

125116
OSXFontDirectories = [
126117
"/Library/Fonts/",
127118
"/Network/Library/Fonts/",
128119
"/System/Library/Fonts/",
129120
# fonts installed via MacPorts
130121
"/opt/local/share/fonts",
122+
# user fonts
123+
str(Path.home() / "Library/Fonts"),
131124
]
132125

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

138127
def get_fontext_synonyms(fontext):
139128
"""
@@ -1149,7 +1138,7 @@ def score_size(self, size1, size2):
11491138
sizeval2 = float(size2)
11501139
except ValueError:
11511140
return 1.0
1152-
return abs(sizeval1 - sizeval2) / 72.0
1141+
return abs(sizeval1 - sizeval2) / 72
11531142

11541143
def findfont(self, prop, fontext='ttf', directory=None,
11551144
fallback_to_default=True, rebuild_if_missing=True):
@@ -1273,11 +1262,10 @@ def is_opentype_cff_font(filename):
12731262
return False
12741263

12751264

1276-
fontManager = None
1277-
_fmcache = None
1278-
1279-
12801265
_get_font = lru_cache(64)(ft2font.FT2Font)
1266+
_fmcache = os.path.join(
1267+
mpl.get_cachedir(), 'fontlist-v{}.json'.format(FontManager.__version__))
1268+
fontManager = None
12811269

12821270

12831271
def get_font(filename, hinting_factor=None):
@@ -1286,86 +1274,23 @@ def get_font(filename, hinting_factor=None):
12861274
return _get_font(filename, hinting_factor)
12871275

12881276

1289-
# The experimental fontconfig-based backend.
1290-
if USE_FONTCONFIG and sys.platform != 'win32':
1277+
def _rebuild():
1278+
global fontManager
1279+
fontManager = FontManager()
1280+
with cbook._lock_path(_fmcache):
1281+
json_dump(fontManager, _fmcache)
1282+
_log.info("generated new fontManager")
12911283

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

1285+
try:
1286+
fontManager = json_load(_fmcache)
1287+
except Exception:
1288+
_rebuild()
13291289
else:
1330-
_fmcache = None
1331-
1332-
cachedir = get_cachedir()
1333-
if cachedir is not None:
1334-
_fmcache = os.path.join(
1335-
cachedir, 'fontlist-v{}.json'.format(FontManager.__version__))
1336-
1337-
fontManager = None
1338-
1339-
def _rebuild():
1340-
global fontManager
1341-
1342-
fontManager = FontManager()
1343-
1344-
if _fmcache:
1345-
with cbook._lock_path(_fmcache):
1346-
json_dump(fontManager, _fmcache)
1347-
_log.debug("generated new fontManager")
1348-
1349-
if _fmcache:
1350-
try:
1351-
fontManager = json_load(_fmcache)
1352-
except FileNotFoundError:
1353-
_log.debug("No font cache found %s", _fmcache)
1354-
except json.JSONDecodeError:
1355-
_log.warning("Font cache parsing failed %s", _fmcache)
1356-
else:
1357-
if (not hasattr(fontManager, '_version') or
1358-
fontManager._version != FontManager.__version__):
1359-
_log.debug("Font cache needs rebuild (version mismatch)")
1360-
fontManager = None
1361-
else:
1362-
fontManager.default_size = None
1363-
_log.debug("Using fontManager instance from %s", _fmcache)
1364-
1365-
if fontManager is None:
1290+
if getattr(fontManager, '_version', object()) != FontManager.__version__:
13661291
_rebuild()
1292+
else:
1293+
_log.debug("Using fontManager instance from %s", _fmcache)
1294+
13671295

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

0 commit comments

Comments
 (0)