GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Improve Type-1 font parsing by jkseppan · Pull Request #20715 · matplotlib/matplotlib

Conversation

@jkseppan

@jkseppan jkseppan commented Jul 22, 2021 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

PR Summary

Parse font properties also from the encrypted part of the file, and reimplement the parsing so it understands more of PostScript's syntax. This fixes a bug where Type1Font.transform would not remove the UniqueID key but break some PostScript code referring to UniqueID instead.

Incidentally, fix the bug where every font had a weight property with value 'Normal' - the correct property is spelled Weight with a capital letter.

This is a prerequisite for subsetting Type-1 fonts (#127).

PR Checklist

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (run flake8 on changed files to check).
  • 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).
  • 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).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@jkseppan
jkseppan force-pushed the type1-improved-parsing branch 4 times, most recently from 981ef67 to 90b5889 Compare July 22, 2021 12:46
jkseppan added a commit to jkseppan/matplotlib that referenced this pull request Jul 22, 2021
@jkseppan
Type-1 subsetting
b66579d
With this I can produce smaller pdf files with usetex in some small
tests, but this obviously needs more extensive testing, thus marking
as draft.

On top of matplotlib#20634 and matplotlib#20715. Closes matplotlib#127.
@jkseppan jkseppan mentioned this pull request Jul 22, 2021
Type-1 font subsetting #20716
Merged
7 tasks
@jklymak jklymak added topic: text/fonts status: waiting for other PR labels Jul 22, 2021
jkseppan added a commit to jkseppan/matplotlib that referenced this pull request Jul 22, 2021
@jkseppan
Type-1 subsetting
6546417
With this I can produce smaller pdf files with usetex in some small
tests, but this obviously needs more extensive testing, thus marking
as draft.

On top of matplotlib#20634 and matplotlib#20715. Closes matplotlib#127.
@jkseppan
jkseppan force-pushed the type1-improved-parsing branch 2 times, most recently from e35728b to 9418b35 Compare July 22, 2021 15:59
@jklymak jklymak removed the status: waiting for other PR label Jul 22, 2021
jkseppan added a commit to jkseppan/matplotlib that referenced this pull request Jul 22, 2021
@jkseppan
Type-1 subsetting
3aaf4c9
With this I can produce smaller pdf files with usetex in some small
tests, but this obviously needs more extensive testing, thus marking
as draft.

On top of matplotlib#20715. Closes matplotlib#127.
anntzer
anntzer reviewed Aug 22, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 22, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 22, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 22, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 22, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 22, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 22, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@jkseppan
jkseppan force-pushed the type1-improved-parsing branch 2 times, most recently from 19119d8 to 25613b9 Compare August 28, 2021 18:15
@jkseppan

jkseppan commented Aug 28, 2021

Copy link
Copy Markdown
Member Author

Thanks for the review @anntzer!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 28, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 28, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 28, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer reviewed Aug 28, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

jkseppan added 2 commits August 29, 2021 09:51
@jkseppan
Improve the Type-1 font parsing
3d443e5
Move Type1Font._tokens into a top-level function _tokenize that is a
coroutine. The parsing stage consuming the tokens can instruct the
tokenizer to return a binary token - this is necessary when decrypting
the CharStrings and Subrs arrays, since the preceding context determines
which parts of the data need to be decrypted.

The function now also parses the encrypted portion of the font file.

To support usage as a coroutine, move the whitespace filtering into the
function, since passing the information about binary tokens would not
easily work through a filter.

The function now returns tokens as subclasses of a new _Token class,
which carry the position and value of the token and can have
token-specific helper methods. The position data will be needed when
modifying the file, as the font is transformed or subsetted.

A new helper function _expression can be used to consume tokens that
form a balanced subexpression delimited by [] or {}. This helps fix a
bug in UniqueID removal: if the font includes PostScript code that
checks if the UniqueID is set in the current dictionary, the previous
code broke that code instead of removing the UniqueID definition. Fonts
can include UniqueID in the encrypted portion as well as the cleartext
one, and removal is now done in both portions.

Fix a bug related to font weight: the key is title-cased and not
lower-cased, so font.prop['weight'] should not exist.
@jkseppan
Recognize abbreviations of PostScript code
e98bb83
Type-1 fonts are required to have subroutines with specific contents
but their names may vary. They are usually ND, NP and RD but names
like | and |- appear too.
@jkseppan
jkseppan force-pushed the type1-improved-parsing branch from 25613b9 to e98bb83 Compare August 29, 2021 06:55
@jkseppan

jkseppan commented Aug 29, 2021

Copy link
Copy Markdown
Member Author

I added some tests and realized that the string escaping was slightly wrong. Now the code also parses string values, although it is unlikely that font properties would include escaped whitespace characters.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

anntzer
anntzer approved these changes Aug 29, 2021
View reviewed changes

@anntzer anntzer left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I admit I still haven't followed all the logic, but we can always check again later :)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
jkseppan added a commit to jkseppan/matplotlib that referenced this pull request Aug 29, 2021
@jkseppan
Type-1 subsetting
f6861ad
With this I can produce smaller pdf files with usetex in some small
tests, but this obviously needs more extensive testing, thus marking
as draft.

Give dviread.DviFont a fake filename attribute for character tracking.

On top of matplotlib#20715. Closes matplotlib#127.
jkseppan added a commit to jkseppan/matplotlib that referenced this pull request Aug 30, 2021
@jkseppan
Type-1 subsetting
d8ae364
With this I can produce smaller pdf files with usetex in some small
tests, but this obviously needs more extensive testing, thus marking
as draft.

Give dviread.DviFont a fake filename attribute for character tracking.

On top of matplotlib#20715. Closes matplotlib#127.
anntzer
anntzer reviewed Aug 30, 2021
View reviewed changes
Comment thread lib/matplotlib/type1font.py
depth += 1
elif match.group() == ')':
depth -= 1
else: # a backslash

@anntzer anntzer Aug 30, 2021

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I guess that here you don't really care about handling the backslash escapes, and all you want to do is simply to match the (unescaped) parentheses, so you could perhaps just replace instring_re by something like (?<!\\)[()] (parentheses not preceded by a backslash)?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@anntzer anntzer Oct 4, 2021

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Ah, I gave this a try but it wouldn't work because the parenthesis can be preceded by backslashes if the backslash is itself escaped (i.e. one would really need to search for "parenthesis not preceded by an even number of backslashes"). So let's forget about this for now.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
jklymak
jklymak approved these changes Oct 4, 2021
View reviewed changes

@jklymak jklymak left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I'll merge based on @anntzer review. This should not go into 3.5 so that it has time to be used on master...

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@jklymak jklymak added this to the v3.6.0 milestone Oct 4, 2021
@jklymak
jklymak merged commit e9bd017 into matplotlib:master Oct 4, 2021
tacaswell pushed a commit to tacaswell/matplotlib that referenced this pull request Oct 12, 2021
@jklymak
Merge pull request matplotlib#20715 from jkseppan/type1-improved-parsing
42e8e12
Improve Type-1 font parsing
tacaswell pushed a commit that referenced this pull request Oct 20, 2021
@jklymak
Merge pull request #20715 from jkseppan/type1-improved-parsing
0bb36e8
Improve Type-1 font parsing
@oscargus oscargus mentioned this pull request Jan 6, 2022
Deprecated afm, fontconfig_pattern, and type1font #22133
Merged
3 tasks done
jkseppan added a commit to jkseppan/matplotlib that referenced this pull request May 4, 2025
@jkseppan
Type-1 subsetting
4dcd073
With this I can produce smaller pdf files with usetex in some small
tests, but this obviously needs more extensive testing, thus marking
as draft.

Give dviread.DviFont a fake filename attribute for character tracking.

On top of matplotlib#20715. Closes matplotlib#127.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@anntzer anntzer anntzer approved these changes
@jklymak jklymak jklymak approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

topic: text/fonts

Projects

None yet

Milestone

v3.6.0

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@jkseppan @anntzer @jklymak
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.