Skip to content

Commit e4ba4f2

Browse files
authored
Merge pull request #10933 from anntzer/font_manager-fontconfig
Remove "experimental" fontconfig font_manager backend.
2 parents 9cecc98 + 7c93309 commit e4ba4f2

File tree

3 files changed

+33
-103
lines changed

3 files changed

+33
-103
lines changed
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

+3-3
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

+25-100
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
"""
@@ -1148,7 +1137,7 @@ def score_size(self, size1, size2):
11481137
sizeval2 = float(size2)
11491138
except ValueError:
11501139
return 1.0
1151-
return abs(sizeval1 - sizeval2) / 72.0
1140+
return abs(sizeval1 - sizeval2) / 72
11521141

11531142
def findfont(self, prop, fontext='ttf', directory=None,
11541143
fallback_to_default=True, rebuild_if_missing=True):
@@ -1272,11 +1261,10 @@ def is_opentype_cff_font(filename):
12721261
return False
12731262

12741263

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

12811269

12821270
def get_font(filename, hinting_factor=None):
@@ -1285,86 +1273,23 @@ def get_font(filename, hinting_factor=None):
12851273
return _get_font(filename, hinting_factor)
12861274

12871275

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

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

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

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

0 commit comments

Comments
 (0)