Skip to content

[Bug]: TTC font files containing CFF data result in (crashes or) broken PS and PDF files #20870

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jkseppan opened this issue Aug 21, 2021 · 0 comments

Comments

@jkseppan
Copy link
Member

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

image

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant