From 7c933098fda95f8a637eeb802c309ac53137a279 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sat, 31 Mar 2018 17:21:09 -0700 Subject: [PATCH] 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. --- .../2018-07-16-AL-removals.rst | 5 + lib/matplotlib/__init__.py | 6 +- lib/matplotlib/font_manager.py | 125 ++++-------------- 3 files changed, 33 insertions(+), 103 deletions(-) create mode 100644 doc/api/next_api_changes/2018-07-16-AL-removals.rst diff --git a/doc/api/next_api_changes/2018-07-16-AL-removals.rst b/doc/api/next_api_changes/2018-07-16-AL-removals.rst new file mode 100644 index 000000000000..46a060c73eff --- /dev/null +++ b/doc/api/next_api_changes/2018-07-16-AL-removals.rst @@ -0,0 +1,5 @@ +API removals +```````````` +The following API elements have been removed: + +- ``font_manager.USE_FONTCONFIG``, ``font_manager.cachedir``, diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index f504673776af..1ddb7e4bec7d 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -555,9 +555,9 @@ def get_home(): return None -def _create_tmp_config_dir(): +def _create_tmp_config_or_cache_dir(): """ - If the config directory can not be created, create a temporary directory. + If the config or cache directory cannot be created, create a temporary one. """ configdir = os.environ['MPLCONFIGDIR'] = ( tempfile.mkdtemp(prefix='matplotlib-')) @@ -609,7 +609,7 @@ def _get_config_or_cache_dir(xdg_base): if os.access(str(configdir), os.W_OK) and configdir.is_dir(): return str(configdir) - return _create_tmp_config_dir() + return _create_tmp_config_or_cache_dir() @_logged_cached('CONFIGDIR=%s') diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index 620a41620d58..3b01bf2c4b48 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -11,13 +11,6 @@ The design is based on the `W3C Cascading Style Sheet, Level 1 (CSS1) font specification `_. Future versions may implement the Level 2 or 2.1 specifications. - -Experimental support is included for using `fontconfig` on Unix -variant platforms (Linux, OS X, Solaris). To enable it, set the -constant ``USE_FONTCONFIG`` in this file to ``True``. Fontconfig has -the advantage that it is the standard way to look up fonts on X11 -platforms, so if a font is installed, it is much more likely to be -found. """ # KNOWN ISSUES @@ -44,14 +37,12 @@ import warnings import matplotlib as mpl -from matplotlib import afm, cbook, ft2font, rcParams, get_cachedir +from matplotlib import afm, cbook, ft2font, rcParams from matplotlib.fontconfig_pattern import ( parse_fontconfig_pattern, generate_fontconfig_pattern) _log = logging.getLogger(__name__) -USE_FONTCONFIG = False - font_scalings = { 'xx-small' : 0.579, 'x-small' : 0.694, @@ -104,12 +95,10 @@ MSFolders = \ r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders' - MSFontDirectories = [ r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts'] - X11FontDirectories = [ # an old standard installation point "/usr/X11R6/lib/X11/fonts/TTF/", @@ -120,7 +109,9 @@ "/usr/local/share/fonts/", # common application, not really useful "/usr/lib/openoffice/share/fonts/truetype/", - ] + # user fonts + str(Path.home() / ".fonts"), +] OSXFontDirectories = [ "/Library/Fonts/", @@ -128,12 +119,10 @@ "/System/Library/Fonts/", # fonts installed via MacPorts "/opt/local/share/fonts", + # user fonts + str(Path.home() / "Library/Fonts"), ] -if not USE_FONTCONFIG and sys.platform != 'win32': - OSXFontDirectories.append(str(Path.home() / "Library/Fonts")) - X11FontDirectories.append(str(Path.home() / ".fonts")) - def get_fontext_synonyms(fontext): """ @@ -1149,7 +1138,7 @@ def score_size(self, size1, size2): sizeval2 = float(size2) except ValueError: return 1.0 - return abs(sizeval1 - sizeval2) / 72.0 + return abs(sizeval1 - sizeval2) / 72 def findfont(self, prop, fontext='ttf', directory=None, fallback_to_default=True, rebuild_if_missing=True): @@ -1273,11 +1262,10 @@ def is_opentype_cff_font(filename): return False -fontManager = None -_fmcache = None - - _get_font = lru_cache(64)(ft2font.FT2Font) +_fmcache = os.path.join( + mpl.get_cachedir(), 'fontlist-v{}.json'.format(FontManager.__version__)) +fontManager = None def get_font(filename, hinting_factor=None): @@ -1286,86 +1274,23 @@ def get_font(filename, hinting_factor=None): return _get_font(filename, hinting_factor) -# The experimental fontconfig-based backend. -if USE_FONTCONFIG and sys.platform != 'win32': +def _rebuild(): + global fontManager + fontManager = FontManager() + with cbook._lock_path(_fmcache): + json_dump(fontManager, _fmcache) + _log.info("generated new fontManager") - def fc_match(pattern, fontext): - fontexts = get_fontext_synonyms(fontext) - ext = "." + fontext - try: - pipe = subprocess.Popen( - ['fc-match', '-s', '--format=%{file}\\n', pattern], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - output = pipe.communicate()[0] - except OSError: - return None - - # The bulk of the output from fc-list is ascii, so we keep the - # result in bytes and parse it as bytes, until we extract the - # filename, which is in sys.filesystemencoding(). - if pipe.returncode == 0: - for fname in map(os.fsdecode, output.split(b'\n')): - if os.path.splitext(fname)[1][1:] in fontexts: - return fname - return None - - _fc_match_cache = {} - - def findfont(prop, fontext='ttf'): - if not isinstance(prop, str): - prop = prop.get_fontconfig_pattern() - cached = _fc_match_cache.get(prop) - if cached is not None: - return cached - - result = fc_match(prop, fontext) - if result is None: - result = fc_match(':', fontext) - - _fc_match_cache[prop] = result - return result +try: + fontManager = json_load(_fmcache) +except Exception: + _rebuild() else: - _fmcache = None - - cachedir = get_cachedir() - if cachedir is not None: - _fmcache = os.path.join( - cachedir, 'fontlist-v{}.json'.format(FontManager.__version__)) - - fontManager = None - - def _rebuild(): - global fontManager - - fontManager = FontManager() - - if _fmcache: - with cbook._lock_path(_fmcache): - json_dump(fontManager, _fmcache) - _log.debug("generated new fontManager") - - if _fmcache: - try: - fontManager = json_load(_fmcache) - except FileNotFoundError: - _log.debug("No font cache found %s", _fmcache) - except json.JSONDecodeError: - _log.warning("Font cache parsing failed %s", _fmcache) - else: - if (not hasattr(fontManager, '_version') or - fontManager._version != FontManager.__version__): - _log.debug("Font cache needs rebuild (version mismatch)") - fontManager = None - else: - fontManager.default_size = None - _log.debug("Using fontManager instance from %s", _fmcache) - - if fontManager is None: + if getattr(fontManager, '_version', object()) != FontManager.__version__: _rebuild() + else: + _log.debug("Using fontManager instance from %s", _fmcache) + - def findfont(prop, **kw): - global fontManager - font = fontManager.findfont(prop, **kw) - return font +findfont = fontManager.findfont 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