Skip to content

Commit bcba233

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 640ecd9 commit bcba233

File tree

3 files changed

+33
-101
lines changed

3 files changed

+33
-101
lines changed

doc/api/next_api_changes/2018-02-26-AL-removals.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ The following deprecated API elements have been removed:
1414
``cbook.reverse_dict``, ``cbook.restrict_dict``, ``cbook.issubclass_safe``,
1515
``cbook.recursive_remove``, ``cbook.unmasked_index_ranges``,
1616
``cbook.Null``, ``cbook.RingBuffer``, ``cbook.Sorter``, ``cbook.Xlator``,
17-
- ``font_manager.weight_as_number``, ``font_manager.ttfdict_to_fnames``,
17+
- ``font_manager.ttfdict_to_fnames``, ``font_manager.weight_as_number``,
18+
``font_manager.USE_FONTCONFIG``, ``font_manager.cachedir``,
1819
- ``pyplot.colors``, ``pyplot.spectral``,
1920
- ``rcsetup.validate_negative_linestyle``,
2021
``rcsetup.validate_negative_linestyle_legacy``,

lib/matplotlib/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ def _get_home():
576576
return None
577577

578578

579-
def _create_tmp_config_dir():
579+
def _create_tmp_config_or_cache_dir():
580580
"""
581581
If the config directory can not be created, create a temporary
582582
directory.
@@ -624,7 +624,7 @@ def _get_config_or_cache_dir(xdg_base):
624624
configdir = os.path.abspath(configdir)
625625
Path(configdir).mkdir(parents=True, exist_ok=True)
626626
if not _is_writable_dir(configdir):
627-
return _create_tmp_config_dir()
627+
return _create_tmp_config_or_cache_dir()
628628
return configdir
629629

630630
p = None
@@ -648,7 +648,7 @@ def _get_config_or_cache_dir(xdg_base):
648648
else:
649649
return p
650650

651-
return _create_tmp_config_dir()
651+
return _create_tmp_config_or_cache_dir()
652652

653653

654654
def _get_configdir():

lib/matplotlib/font_manager.py

Lines changed: 28 additions & 97 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
@@ -42,14 +35,13 @@
4235
from threading import Timer
4336
import warnings
4437

45-
from matplotlib import afm, cbook, ft2font, rcParams, get_cachedir
38+
import matplotlib as mpl
39+
from matplotlib import afm, cbook, ft2font, rcParams
4640
from matplotlib.fontconfig_pattern import (
4741
parse_fontconfig_pattern, generate_fontconfig_pattern)
4842

4943
_log = logging.getLogger(__name__)
5044

51-
USE_FONTCONFIG = False
52-
5345
font_scalings = {
5446
'xx-small' : 0.579,
5547
'x-small' : 0.694,
@@ -102,12 +94,10 @@
10294
MSFolders = \
10395
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
10496

105-
10697
MSFontDirectories = [
10798
r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts',
10899
r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts']
109100

110-
111101
X11FontDirectories = [
112102
# an old standard installation point
113103
"/usr/X11R6/lib/X11/fonts/TTF/",
@@ -118,21 +108,20 @@
118108
"/usr/local/share/fonts/",
119109
# common application, not really useful
120110
"/usr/lib/openoffice/share/fonts/truetype/",
121-
]
111+
# user fonts
112+
str(Path.home() / ".fonts"),
113+
]
122114

123115
OSXFontDirectories = [
124116
"/Library/Fonts/",
125117
"/Network/Library/Fonts/",
126118
"/System/Library/Fonts/",
127119
# fonts installed via MacPorts
128-
"/opt/local/share/fonts"
129-
""
120+
"/opt/local/share/fonts",
121+
# user fonts
122+
str(Path.home() / "Library/Fonts"),
130123
]
131124

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

137126
def get_fontext_synonyms(fontext):
138127
"""
@@ -1136,7 +1125,7 @@ def score_size(self, size1, size2):
11361125
sizeval2 = float(size2)
11371126
except ValueError:
11381127
return 1.0
1139-
return abs(sizeval1 - sizeval2) / 72.0
1128+
return abs(sizeval1 - sizeval2) / 72
11401129

11411130
def findfont(self, prop, fontext='ttf', directory=None,
11421131
fallback_to_default=True, rebuild_if_missing=True):
@@ -1245,6 +1234,7 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
12451234

12461235
return result
12471236

1237+
12481238
@lru_cache()
12491239
def is_opentype_cff_font(filename):
12501240
"""
@@ -1258,94 +1248,35 @@ def is_opentype_cff_font(filename):
12581248
else:
12591249
return False
12601250

1261-
fontManager = None
1262-
_fmcache = None
1263-
12641251

12651252
_get_font = lru_cache(64)(ft2font.FT2Font)
1253+
_fmcache = os.path.join(mpl.get_cachedir(), 'fontList.json')
1254+
fontManager = None
1255+
12661256

12671257
def get_font(filename, hinting_factor=None):
12681258
if hinting_factor is None:
12691259
hinting_factor = rcParams['text.hinting_factor']
12701260
return _get_font(filename, hinting_factor)
12711261

12721262

1273-
# The experimental fontconfig-based backend.
1274-
if USE_FONTCONFIG and sys.platform != 'win32':
1263+
def _rebuild():
1264+
global fontManager
1265+
fontManager = FontManager()
1266+
with cbook._lock_path(_fmcache):
1267+
json_dump(fontManager, _fmcache)
1268+
_log.info("generated new fontManager")
12751269

1276-
def fc_match(pattern, fontext):
1277-
fontexts = get_fontext_synonyms(fontext)
1278-
ext = "." + fontext
1279-
try:
1280-
pipe = subprocess.Popen(
1281-
['fc-match', '-s', '--format=%{file}\\n', pattern],
1282-
stdout=subprocess.PIPE,
1283-
stderr=subprocess.PIPE)
1284-
output = pipe.communicate()[0]
1285-
except OSError:
1286-
return None
1287-
1288-
# The bulk of the output from fc-list is ascii, so we keep the
1289-
# result in bytes and parse it as bytes, until we extract the
1290-
# filename, which is in sys.filesystemencoding().
1291-
if pipe.returncode == 0:
1292-
for fname in map(os.fsdecode, output.split(b'\n')):
1293-
if os.path.splitext(fname)[1][1:] in fontexts:
1294-
return fname
1295-
return None
1296-
1297-
_fc_match_cache = {}
1298-
1299-
def findfont(prop, fontext='ttf'):
1300-
if not isinstance(prop, str):
1301-
prop = prop.get_fontconfig_pattern()
1302-
cached = _fc_match_cache.get(prop)
1303-
if cached is not None:
1304-
return cached
1305-
1306-
result = fc_match(prop, fontext)
1307-
if result is None:
1308-
result = fc_match(':', fontext)
1309-
1310-
_fc_match_cache[prop] = result
1311-
return result
13121270

1271+
try:
1272+
fontManager = json_load(_fmcache)
1273+
except Exception:
1274+
_rebuild()
13131275
else:
1314-
_fmcache = None
1315-
1316-
cachedir = get_cachedir()
1317-
if cachedir is not None:
1318-
_fmcache = os.path.join(cachedir, 'fontList.json')
1319-
1320-
fontManager = None
1321-
1322-
def _rebuild():
1323-
global fontManager
1324-
1325-
fontManager = FontManager()
1326-
1327-
if _fmcache:
1328-
with cbook._lock_path(_fmcache):
1329-
json_dump(fontManager, _fmcache)
1330-
_log.info("generated new fontManager")
1331-
1332-
if _fmcache:
1333-
try:
1334-
fontManager = json_load(_fmcache)
1335-
if (not hasattr(fontManager, '_version') or
1336-
fontManager._version != FontManager.__version__):
1337-
_rebuild()
1338-
else:
1339-
fontManager.default_size = None
1340-
_log.debug("Using fontManager instance from %s", _fmcache)
1341-
except TimeoutError:
1342-
raise
1343-
except Exception:
1344-
_rebuild()
1345-
else:
1276+
if getattr(fontManager, '_version', object()) != FontManager.__version__:
13461277
_rebuild()
1278+
else:
1279+
_log.debug("Using fontManager instance from %s", _fmcache)
1280+
13471281

1348-
def findfont(prop, **kw):
1349-
global fontManager
1350-
font = fontManager.findfont(prop, **kw)
1351-
return font
1282+
findfont = fontManager.findfont

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy