Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Bug]: backend_pdf gives TTLibError with pdf.fonttype : 42 #21893

Copy link
Copy link
Closed
@shaharkadmiel

Description

@shaharkadmiel
Issue body actions

Bug summary

On macOS 12, fresh install of conda-forge matplotlib 3.5.0, when saving a figure to pdf, I get:

TTLibError: specify a font number between 0 and 5 (inclusive)

which I can trace to:

...
~/miniconda3/lib/python3.8/site-packages/matplotlib/backends/backend_pdf.py in embedTTF(self, filename, characters)
   1424             return embedTTFType3(font, characters, descriptor)
   1425         elif fonttype == 42:
-> 1426             return embedTTFType42(font, characters, descriptor)
   1427 
   1428     def alphaState(self, alpha):
...

Everything works as expected if I save to a png or if I set pdf.fonttype : 3 in my matplotlibrc file and save to pdf.

I can see that Helvetica*.afm is present under ~/miniconda3/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts but not under .../ttf

Code for reproduction

import matplotlib.pyplot as plt
plt.plot((1,2,3))
plt.title('Axes Title', font='Helvetica')
plt.savefig('text.pdf')

Actual outcome

---------------------------------------------------------------------------
TTLibError                                Traceback (most recent call last)
/var/folders/bj/czjbfh496258q1lc3p01lyz00000gn/T/ipykernel_58793/3096390865.py in <module>
      2 plt.plot((1,2,3))
      3 plt.title('Axes Title', font='Helvetica')
----> 4 plt.savefig('text.pdf')

~/miniconda3/lib/python3.8/site-packages/matplotlib/pyplot.py in savefig(*args, **kwargs)
    956 def savefig(*args, **kwargs):
    957     fig = gcf()
--> 958     res = fig.savefig(*args, **kwargs)
    959     fig.canvas.draw_idle()   # need this if 'transparent=True' to reset colors
    960     return res

~/miniconda3/lib/python3.8/site-packages/matplotlib/figure.py in savefig(self, fname, transparent, **kwargs)
   3010                         ax.patch._cm_set(facecolor='none', edgecolor='none'))
   3011 
-> 3012             self.canvas.print_figure(fname, **kwargs)
   3013 
   3014     def ginput(self, n=1, timeout=30, show_clicks=True,

~/miniconda3/lib/python3.8/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2312                 # force the figure dpi to 72), so we need to set it again here.
   2313                 with cbook._setattr_cm(self.figure, dpi=dpi):
-> 2314                     result = print_method(
   2315                         filename,
   2316                         facecolor=facecolor,

~/miniconda3/lib/python3.8/site-packages/matplotlib/backend_bases.py in wrapper(*args, **kwargs)
   1641             kwargs.pop(arg)
   1642 
-> 1643         return func(*args, **kwargs)
   1644 
   1645     return wrapper

~/miniconda3/lib/python3.8/site-packages/matplotlib/_api/deprecation.py in wrapper(*inner_args, **inner_kwargs)
    384             # Early return in the simple, non-deprecated case (much faster than
    385             # calling bind()).
--> 386             return func(*inner_args, **inner_kwargs)
    387         arguments = signature.bind(*inner_args, **inner_kwargs).arguments
    388         if is_varargs and arguments.get(name):

~/miniconda3/lib/python3.8/site-packages/matplotlib/backends/backend_pdf.py in print_pdf(self, filename, dpi, bbox_inches_restore, metadata)
   2786             renderer.finalize()
   2787             if not isinstance(filename, PdfPages):
-> 2788                 file.finalize()
   2789         finally:
   2790             if isinstance(filename, PdfPages):  # finish off this page

~/miniconda3/lib/python3.8/site-packages/matplotlib/backends/backend_pdf.py in finalize(self)
    792         self.endStream()
    793         self._write_annotations()
--> 794         self.writeFonts()
    795         self.writeExtGSTates()
    796         self._write_soft_mask_groups()

~/miniconda3/lib/python3.8/site-packages/matplotlib/backends/backend_pdf.py in writeFonts(self)
    925                 chars = self._character_tracker.used.get(filename)
    926                 if chars:
--> 927                     fonts[Fx] = self.embedTTF(filename, chars)
    928         self.writeObject(self.fontObject, fonts)
    929 

~/miniconda3/lib/python3.8/site-packages/matplotlib/backends/backend_pdf.py in embedTTF(self, filename, characters)
   1424             return embedTTFType3(font, characters, descriptor)
   1425         elif fonttype == 42:
-> 1426             return embedTTFType42(font, characters, descriptor)
   1427 
   1428     def alphaState(self, alpha):

~/miniconda3/lib/python3.8/site-packages/matplotlib/backends/backend_pdf.py in embedTTFType42(font, characters, descriptor)
   1230             subset_str = "".join(chr(c) for c in characters)
   1231             _log.debug("SUBSET %s characters: %s", filename, subset_str)
-> 1232             fontdata = _backend_pdf_ps.get_glyphs_subset(filename, subset_str)
   1233             _log.debug(
   1234                 "SUBSET %s %d -> %d", filename,

~/miniconda3/lib/python3.8/site-packages/matplotlib/backends/_backend_pdf_ps.py in get_glyphs_subset(fontfile, characters)
     40     options.drop_tables += ['FFTM', 'PfEd']
     41 
---> 42     with subset.load_font(fontfile, options) as font:
     43         subsetter = subset.Subsetter(options=options)
     44         subsetter.populate(text=characters)

~/miniconda3/lib/python3.8/site-packages/fontTools/misc/loggingTools.py in wrapper(*args, **kwds)
    370                         def wrapper(*args, **kwds):
    371                                 with self:
--> 372                                         return func(*args, **kwds)
    373                         return wrapper
    374                 else:

~/miniconda3/lib/python3.8/site-packages/fontTools/subset/__init__.py in load_font(fontFile, options, checkChecksums, dontLoadGlyphNames, lazy)
   3006 	      lazy=True):
   3007 
-> 3008 	font = ttLib.TTFont(fontFile,
   3009                             checkChecksums=checkChecksums,
   3010                             recalcBBoxes=options.recalc_bounds,

~/miniconda3/lib/python3.8/site-packages/fontTools/ttLib/ttFont.py in __init__(self, file, res_name_or_index, sfntVersion, flavor, checkChecksums, verbose, recalcBBoxes, allowVID, ignoreDecompileErrors, recalcTimestamp, fontNumber, lazy, quiet, _tableCache)
    141                         file = tmp
    142                 self._tableCache = _tableCache
--> 143                 self.reader = SFNTReader(file, checkChecksums, fontNumber=fontNumber)
    144                 self.sfntVersion = self.reader.sfntVersion
    145                 self.flavor = self.reader.flavor

~/miniconda3/lib/python3.8/site-packages/fontTools/ttLib/sfnt.py in __init__(self, file, checkChecksums, fontNumber)
     58                         numFonts = header.numFonts
     59                         if not 0 <= fontNumber < numFonts:
---> 60                                 raise TTLibError("specify a font number between 0 and %d (inclusive)" % (numFonts - 1))
     61                         self.numFonts = numFonts
     62                         self.file.seek(header.offsetTable[fontNumber])

TTLibError: specify a font number between 0 and 5 (inclusive)

Expected outcome

A pdf file saved to filesystem

Additional information

No response

Operating system

macOS 12, M1 pro, arm64

Matplotlib Version

3.5.0

Matplotlib Backend

No response

Python version

3.8.12

Jupyter version

6.4.6

Installation

conda

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.