Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Remove ttconv and implement Type-42 embedding using fontTools #20866

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

Merged
merged 10 commits into from
Oct 16, 2024

Conversation

jkseppan
Copy link
Member

@jkseppan jkseppan commented Aug 20, 2021

PR Summary

ttconv is now only being used for outputting fonts in Type-42 format in PostScript files, and with fontTools this turns out to be quite doable in pure Python.

PR Checklist

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (run flake8 on changed files to check).
  • [N/A] New features are documented, with examples if plot related.
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • Conforms to Matplotlib style conventions (install flake8-docstrings and run flake8 --docstring-convention=all).
  • [N/A] New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).

@jkseppan
Copy link
Member Author

Now this works with almost all TrueType fonts on my Mac, with the exception of CFF fonts (#20870) and Apple Color Emoji.ttc and NISC18030.ttf both of which cause a crash in FT2Font (#7305).

@jkseppan jkseppan marked this pull request as ready for review August 21, 2021 16:21
@jkseppan jkseppan force-pushed the remove-ttconv branch 2 times, most recently from 016713a to 7cea2d4 Compare August 22, 2021 14:20
if fontfile.endswith('ttc'):
# fix this once we support loading more fonts from a collection
# https://github.com/matplotlib/matplotlib/issues/3135#issuecomment-571085541
options.font_number = 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we test a ttc in CI already, so it could be used to test this line?

The Type-42 formatted font
"""
version, breakpoints = _version_and_breakpoints(font.get('loca'), fontdata)
post, name = font['post'], font['name']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these tables guaranteed to exist?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both post and name are required: https://docs.fileformat.com/font/ttf/

Comment on lines 314 to 322
tuple
((v1, v2), breakpoints) where v1 is the major version number,
v2 is the minor version number and breakpoints is a sorted list
of offsets into fontdata; if loca is not available, just the table
boundaries
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For multiple return, you should list the entries separately, like Parameters.

@tacaswell
Copy link
Member

Wow, I missed that this came in. 💯 on dropping an extension module!

@jklymak jklymak marked this pull request as draft February 1, 2022 11:52
@jklymak
Copy link
Member

jklymak commented Feb 1, 2022

Dropping to draft until the comments and rebase are addressed. Anyone should feel free to move back to active...

@QuLogic
Copy link
Member

QuLogic commented Mar 15, 2022

Ping @jkseppan?


Returns
-------
fontTools.ttLib.ttFont.TTFont
Copy link
Member

@oscargus oscargus Mar 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long term, it could make sense to link to the documentation? (Although fontTools is not in the intersphinx_mapping yet.)

@QuLogic QuLogic modified the milestones: v3.6.0, v3.7.0 Jul 5, 2022
@tacaswell tacaswell modified the milestones: v3.7.0, v3.8.0 Dec 9, 2022
@tacaswell
Copy link
Member

We want to try and do mpl 3.7 feature freeze around Jan 1 so I think it is unlikely we will have the bandwidth to get this rebased and reviewed by then, pushing to 3.8.

@jklymak
Copy link
Member

jklymak commented Feb 21, 2023

Do we have someone who can pick this up?

@QuLogic
Copy link
Member

QuLogic commented Sep 21, 2024

I dropped the new test (3a30265) because I don't think we should require DejaVu externally when we ship it already, and #28784 should be a good enough test.

@QuLogic QuLogic marked this pull request as ready for review September 21, 2024 04:54
@QuLogic QuLogic modified the milestones: future releases, v3.10.0 Sep 21, 2024
@QuLogic
Copy link
Member

QuLogic commented Oct 9, 2024

FYI, I think I'm okay with this as it stands, but as I did some followup cleanup work, I'm not sure if I should approve it myself.

Copy link
Member

@oscargus oscargus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still open to the possibility to add fontTools to the intersphinx-stuff and provide a proper link, but I am also open to do that myself in another PR.

@oscargus
Copy link
Member

Btw, do we (i.e. someone with a Mac(?)) know if #20866 (comment) still holds?

@QuLogic
Copy link
Member

QuLogic commented Oct 10, 2024

Btw, do we (i.e. someone with a Mac(?)) know if #20866 (comment) still holds?

Maybe @greglucas or @ksunden can have a look at it?

@greglucas
Copy link
Contributor

Using the example from the linked issue:

# 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')

The type42 is completely blank for me (no axes either). The type3 shows up as expected. I don't get an error though 🤷

@tacaswell
Copy link
Member

That example fails for me on main. Trying to open the fmt42.ps with ghostscript gives me:

@ ghostscript fmt42.ps
GPL Ghostscript 10.04.0 (2024-09-18)
Copyright (C) 2024 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Error: /invalidfont in definefont
Operand stack:
   unknown   --dict:11/15(L)--   Font
Execution stack:
   %interp_exit   .runexec2   --nostringval--   definefont   --nostringval--   2   %stopped_push   --nostringval--   definefont   definefont   false   1   %stopped_push   1949   1   3   %oparray_pop   1948   1   3   %oparray_pop   1933   1   3   %oparray_pop   1803   1   3   %oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--   definefont   --nostringval--   2   %stopped_push   --nostringval--   1897   2   4   %oparray_pop
Dictionary stack:
   --dict:745/1123(ro)(G)--   --dict:0/20(G)--   --dict:86/200(L)--   --dict:8/10(L)--
Current allocation mode is local
Current file position is 11715
GPL Ghostscript 10.04.0: Unrecoverable error, exit code 1

and with this branch I get

@ ghostscript fmt42.ps
GPL Ghostscript 10.04.0 (2024-09-18)
Copyright (C) 2024 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Error: /invalidfont in definefont
Operand stack:
   AppleSDGothicNeo-Regular   --dict:12/16(L)--   Font
Execution stack:
   %interp_exit   .runexec2   --nostringval--   definefont   --nostringval--   2   %stopped_push   --nostringval--   definefont   definefont   false   1   %stopped_push   1949   1   3   %oparray_pop   1948   1   3   %oparray_pop   1933   1   3   %oparray_pop   1803   1   3   %oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--   definefont   --nostringval--   2   %stopped_push   --nostringval--   1897   2   4   %oparray_pop
Dictionary stack:
   --dict:745/1123(ro)(G)--   --dict:0/20(G)--   --dict:86/200(L)--   --dict:8/10(L)--
Current allocation mode is local
Current file position is 18773
GPL Ghostscript 10.04.0: Unrecoverable error, exit code 1

@ksunden
Copy link
Member

ksunden commented Oct 11, 2024

Okay, looks like the answer is that this has not fixed #20866 (comment), however that is broken on main anyway, so I'd lean towards not blocking for merging this if we are otherwise satisfied.

@tacaswell
Copy link
Member

The issue also appears to be font specific, dejavu being embedded as type42 works OK.

jkseppan and others added 10 commits October 16, 2024 04:04
Split _backend_pdf_ps.get_glyphs_subset into two functions:
get_glyphs_subset returns the font object (which needs to be
closed after using) and font_as_file serializes this object
into a BytesIO file-like object.
Move the test in lib/matplotlib/tests/test_ttconv.py to
lib/matplotlib/tests/test_backend_pdf.py. Actually it has not been
a test of ttconv for a while, since type-3 conversion has not been
using ttconv.
Fonttools cannot subset these and drops them; avoid the warning.
Also don't end up in an infinite loop if there is a larger gap
between breakpoints than we would like.
FT2Font throws RuntimeError for some fonts
Not the subsetted one, since in some cases fontTools.subset
does not produce a good name table.
De-wrap a few lines now that we allow longer lines.
@ksunden ksunden merged commit 5e5ce02 into matplotlib:main Oct 16, 2024
40 of 44 checks passed
tacaswell added a commit to tacaswell/matplotlib that referenced this pull request Nov 7, 2024
tacaswell added a commit to tacaswell/matplotlib that referenced this pull request Nov 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

replace ttconv for ps/pdf
7 participants