Description
Bug summary
Some font files have the .ttc extension ("TrueType collection") but actually contain CFF data ("compact font format") which is not supported by the PDF and PS backends (#2869). Currently ttc files cause a crash which is easily fixed with
diff --git a/lib/matplotlib/backends/_backend_pdf_ps.py b/lib/matplotlib/backends/_backend_pdf_ps.py
index 3224fb90e3..eaf8c8c094 100644
--- a/lib/matplotlib/backends/_backend_pdf_ps.py
+++ b/lib/matplotlib/backends/_backend_pdf_ps.py
@@ -39,6 +39,10 @@ def get_glyphs_subset(fontfile, characters):
# prevent subsetting FontForge Timestamp and other tables
options.drop_tables += ['FFTM', 'PfEd']
+ if fontfile.endswith('ttc'):
+ options.font_number = 0
with subset.load_font(fontfile, options) as font:
subsetter = subset.Subsetter(options=options)
subsetter.populate(text=characters)
but with this fix, some ttc fonts result in broken output files if using font type 42 (type 3 seems to be fine).
The font manager lists fonts using fc-list -f '%{file}\n'
and selects based on file extensions. A better way might be fc-list :fontformat=TrueType -f '%{file}\n'
since fontconfig knows about the real font format. However, FreeType supports CFF fonts so we probably shouldn't exclude them from other backends or type 3 embedding.
(The correct way to embed CFF fonts in PostScript is described in https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf, and in PDF the font type needs to be Type1C, CIDFontType0C, or OpenType.)
Code for reproduction
# this needs the patch above
import matplotlib
from pathlib import Path
matplotlib.use('ps')
from matplotlib import pyplot as plt
# the following font is in CFF format on my Mac
font = Path('/System/Library/Fonts/AppleSDGothicNeo.ttc')
fig = plt.figure()
plt.axis((0,10,0,10))
plt.text(3,3,'Glib jocks quiz nymph to vex dwarf.', font=font)
matplotlib.rc('ps', fonttype=42)
plt.savefig('fmt42.ps')
matplotlib.rc('ps', fonttype=3)
plt.savefig('fmt3.ps')
Actual outcome
ps2pdf fmt42.ps
errors out with
Error: /invalidfont in definefont
Operand stack:
AppleSDGothicNeo-Regular --dict:11/15(L)-- Font
Execution stack:
%interp_exit .runexec2 --nostringval-- definefont --nostringval-- 2 %stopped_push --nostringval-- definefont definefont false 1 %stopped_push 1990 1 3 %oparray_pop 1989 1 3 %oparray_pop 1977 1 3 %oparray_pop 1833 1 3 %oparray_pop --nostringval-- %errorexec_pop .runexec2 --nostringval-- definefont --nostringval-- 2 %stopped_push --nostringval-- 1923 2 4 %oparray_pop
Dictionary stack:
--dict:729/1123(ro)(G)-- --dict:0/20(G)-- --dict:76/200(L)-- --dict:10/12(L)--
Current allocation mode is local
Current file position is 11851
GPL Ghostscript 9.54.0: Unrecoverable error, exit code 1
Expected outcome
Operating system
macOS 11.5.2
Matplotlib Version
master as of a4e81e7 + some of my local changes
Matplotlib Backend
No response
Python version
No response
Jupyter version
No response
Other libraries
fontTools 4.24.4
Installation
source
Conda channel
No response