From ae618f34f367cf5cd3cfba004271071eb2b6cae9 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 14 Nov 2017 16:12:58 -0800 Subject: [PATCH 1/2] Support (first font of) TTC files. TTC is a TrueType Collection file (a collection of TTFs). Currently, ft2font only supports getting the first font from the collection, and neither the pdf nor ps backends are able to use them (due to limitations of ttconv). Still, it seems better than nothing to support them for Agg and SVG (that comes for free via FreeType). --- .travis.yml | 3 ++- lib/matplotlib/backends/backend_pdf.py | 9 +++++++-- lib/matplotlib/backends/backend_ps.py | 10 ++++++++-- lib/matplotlib/font_manager.py | 9 ++++++--- lib/matplotlib/tests/test_font_manager.py | 23 +++++++++++++++++++++-- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5c1bc3890dde..56015283dcd9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,7 @@ addons: - texlive-latex-recommended - texlive-xetex - texlive-luatex + - ttf-wqy-zenhei env: global: @@ -110,7 +111,7 @@ before_install: | ci/silence brew update brew uninstall numpy gdal postgis brew upgrade python - brew install ffmpeg imagemagick mplayer ccache + brew install ffmpeg imagemagick mplayer ccache font-wenquanyi-zen-hei hash -r which python python --version diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 8e2818f098e1..c5d61bf1e1a8 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -973,8 +973,13 @@ def get_char_width(charcode): # Make the charprocs array (using ttconv to generate the # actual outlines) - rawcharprocs = ttconv.get_pdf_charprocs( - os.fsencode(filename), glyph_ids) + try: + rawcharprocs = ttconv.get_pdf_charprocs( + os.fsencode(filename), glyph_ids) + except RuntimeError: + _log.warning("The PDF backend does not currently support the " + "selected font.") + raise charprocs = {} for charname in sorted(rawcharprocs): stream = rawcharprocs[charname] diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 62edbb919fc2..3a01d9595602 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -1117,8 +1117,14 @@ def print_figure_impl(fh): "time; consider using the Cairo backend") else: fh.flush() - convert_ttf_to_ps(os.fsencode(font_filename), - fh, fonttype, glyph_ids) + try: + convert_ttf_to_ps(os.fsencode(font_filename), + fh, fonttype, glyph_ids) + except RuntimeError: + _log.warning("The PostScript backend does not " + "currently support the selected " + "font.") + raise print("end", file=fh) print("%%EndProlog", file=fh) diff --git a/lib/matplotlib/font_manager.py b/lib/matplotlib/font_manager.py index 827aa411125c..832a1f46a551 100644 --- a/lib/matplotlib/font_manager.py +++ b/lib/matplotlib/font_manager.py @@ -129,9 +129,12 @@ def get_fontext_synonyms(fontext): Return a list of file extensions extensions that are synonyms for the given file extension *fileext*. """ - return {'ttf': ('ttf', 'otf'), - 'otf': ('ttf', 'otf'), - 'afm': ('afm',)}[fontext] + return { + 'afm': ['afm'], + 'otf': ['otf', 'ttc', 'ttf'], + 'ttc': ['otf', 'ttc', 'ttf'], + 'ttf': ['otf', 'ttc', 'ttf'], + }[fontext] def list_fonts(directory, extensions): diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py index 7ba02954ab05..abda945ad9fc 100644 --- a/lib/matplotlib/tests/test_font_manager.py +++ b/lib/matplotlib/tests/test_font_manager.py @@ -1,3 +1,5 @@ +from io import BytesIO +import os from pathlib import Path import shutil import sys @@ -9,7 +11,7 @@ from matplotlib.font_manager import ( findfont, FontProperties, fontManager, json_dump, json_load, get_font, get_fontconfig_fonts, is_opentype_cff_font) -from matplotlib import rc_context +from matplotlib import pyplot as plt, rc_context has_fclist = shutil.which('fc-list') is not None @@ -91,7 +93,7 @@ def test_hinting_factor(factor): @pytest.mark.skipif(sys.platform != "win32", - reason="Need Windows font to test against") + reason="Need Windows font to test against") def test_utf16m_sfnt(): segoe_ui_semibold = None for f in fontManager.ttflist: @@ -105,3 +107,20 @@ def test_utf16m_sfnt(): # Check that we successfully read the "semibold" from the font's # sfnt table and set its weight accordingly assert segoe_ui_semibold.weight == "semibold" + + +@pytest.mark.xfail(not (os.environ.get("TRAVIS") and sys.platform == "linux"), + reason="Font may be missing.") +def test_find_ttc(): + fp = FontProperties(family=["WenQuanYi Zen Hei"]) + font = findfont(fp) + assert Path(font).name == "wqy-zenhei.ttc" + + fig, ax = plt.subplots() + ax.text(.5, .5, "\N{KANGXI RADICAL DRAGON}", fontproperties=fp) + fig.savefig(BytesIO(), format="raw") + fig.savefig(BytesIO(), format="svg") + with pytest.raises(RuntimeError): + fig.savefig(BytesIO(), format="pdf") + with pytest.raises(RuntimeError): + fig.savefig(BytesIO(), format="ps") From d3e6a9104dcbe23b626c152cd47b3dcbd1a81bb5 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Sun, 25 Nov 2018 14:48:29 +0100 Subject: [PATCH 2/2] Temporarily force use of new font caches. --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 56015283dcd9..4e91d22dd53d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,8 +86,12 @@ matrix: - EXTRAREQS='-r requirements/testing/travis36.txt' - python: 3.7 sudo: true + env: + - DELETE_FONT_CACHE=1 - python: "nightly" - env: PRE=--pre + env: + - PRE=--pre + - DELETE_FONT_CACHE=1 - os: osx language: generic # https://github.com/travis-ci/travis-ci/issues/2312 only: master