You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Request to support PostScript-flavoured (CFF) OpenType fonts in PDF backend #2869
I would like to request support for OpenType fonts. I have the main text written with Lucida and I'm unable to get the font on the graphs match the ones in the text.
I'm using the latest matplotlib with Python 3.3 on Mac OS X 10.7. When I try to use any give OpenType font
matplotlib.rcParams['font.family'] = 'Any Name Of OpenType Font'
this is what I get:
Traceback (most recent call last):
File "test.py", line 26, in <module>
plt.savefig('test.pdf')
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/matplotlib/pyplot.py", line 571, in savefig
res = fig.savefig(*args, **kwargs)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/matplotlib/figure.py", line 1448, in savefig
self.canvas.print_figure(*args, **kwargs)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/matplotlib/backend_bases.py", line 2192, in print_figure
**kwargs)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/matplotlib/backends/backend_pdf.py", line 2476, in print_pdf
file.close()
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/matplotlib/backends/backend_pdf.py", line 528, in close
self.writeFonts()
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/matplotlib/backends/backend_pdf.py", line 631, in writeFonts
fonts[Fx] = self.embedTTF(realpath, chars[1])
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/matplotlib/backends/backend_pdf.py", line 1106, in embedTTF
return embedTTFType3(font, characters, descriptor)
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/matplotlib/backends/backend_pdf.py", line 892, in embedTTFType3
filename.encode(sys.getfilesystemencoding()), glyph_ids)
RuntimeError: TrueType font is missing table
The weird thing is that my colleagues get a different warning (complaining that font substitution isn't supported and then some garbled output).
The problem is that apparently backend_pdf.py is only taking
into account:
*.afm fonts
something with dvi info (which came from TeX)
everything else is treated as TTF, so it goes though ttconv which apparently isn't able to handle PostScript-flavoured fonts
The interactive display and PNG work just fine, but I would like to have vector graphics.
I then tried to fetch a TrueType version of Lucida from Java, but that one behaves weird enough that I'm unable to use it (I'll open a new issue for that). I also experienced something very very odd – fonts from those fonts are rendered on our high end laser printer as if they were high resolution bitmap images, somewhat fuzzy. Fonts from gnuplot graphics and the rest of text is crisp clear, while text from pyplot graphs is somewhat smoothed at the edges, it looks like rasterized or weirdly hinted font.
An alternative would be to render the text labels through TeX, but I don't know how to set it up for (OpenType) Lucida fonts. (I know how to set it up outside of matplotlib.)
A slightly related issue is #1366. It would be great if pyplot supported OpenType Math fonts indeed, like Latin Modern Math, XITS Math, TeX Gyre Math (basically Helvetica, Times, Palatino, Bookman), Lucida Bright Math, Cambria, ...
There was some abandoned work to get this done by replacing FT2Font and ttconv with a more modern freetype wrapper that gives us what we need to do the font subsetting for any font that freetype supports. The wrappers are mostly done: https://github.com/matplotlib/freetypy, but things stalled getting this then integrated with matplotlib, as I lost time to work on it. I'd love to see someone take that on, but it's a fair bit of work.
Are you able to provide a short list of things that need to be done? (And maybe the desired skillset?)
What is the relation between this change and support for, say, OpenType Math layout?
Just brainstorming: would it help if one of TeX user groups would provide a tiny bit of funding in the name of "better support for graphs, compatible with TeX documents"?
You can read MEP14 : https://github.com/matplotlib/matplotlib/wiki/Mep14. It actually has a much larger scope than just this -- the relevant sections to this bug are "Font subsetting" and "Freetype wrappers".
Essentially, all of the calls to FT2Font (the current matplotlib freetype wrapper) and ttconv (the TTF-only font subsetting code) would need to be replaced with calls to the new freetypy wrapper (which is mostly complete -- just missing a little final polish). The ttconv code will need to directly convert the outlines obtained from freetypy into the native outline format of PDF, PS, SVG etc. directly in Python (rather than using C as ttconv does now). At least the Agg, PDF, PS and SVG backends as well as the path effects stuff will be affected. The skill set required is mostly Python at this point (the C parts are mostly done), but it does require understanding the font outline API of freetype and the font outline formats of PS, PDF and SVG.
OpenType Math layout is somewhat orthogonal to this. Here, we're talking only about supporting the OpenType file format, as opposed to the TrueType file format, without using any of the OpenType specific features and information. OpenType Math layout allows the font to specify certain things about the math layout -- such as how deep subscripts should be etc. -- that the layout engine would use to adapt itself to a particular font. My understanding is that STIX does not have this information, but there is a fork, XITS, that aims to add it.
Funding always helps, but we'd also need someone with the time... ;) I'm not sure that's me at the moment.
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
ttconv was replaced in #20866, but without a specific (non-proprietary) font to test, I cannot confirm whether this is working or not, but I suspect it was fixed.
I'm also interested in this! The situation seems to have improved since the ticket was opened (a PDF is generated), but the resulting file appears to be malformed?
In particular, many LaTeX OTF fonts (distributed by, e.g., TeXLive) seem to originate from a Postscript format and trigger this error:
importmatplotlibasmplimportmatplotlib.pyplotasplt# A copy of TeX Gyre Heros can also be found here: https://www.gust.org.pl/projects/e-foundry/tex-gyre/herosmpl.rcdefaults()
mpl.rcParams["pdf.fonttype"] =42mpl.rcParams["font.sans-serif"] = ["TeX Gyre Heros"] +mpl.rcParamsDefault["font.sans-serif"]
plt.subplots()
plt.savefig("/tmp/text.pdf")
Executing pdffonts /tmp/text.pdf yields:
Syntax Warning: Mismatch between font type and embedded font file
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
CCVYUO+TeXGyreHeros-Regular CID Type 0C (OT) Identity-H yes yes yes 15 0
If the default font, DejaVu Sans, is used, the output is:
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
BMQQDV+DejaVuSans CID TrueType Identity-H yes yes yes 15 0
In the current Matplotlib version, this seems to be due to the following backend location, which hardcodes the font type when Opentype output is requested. In this backend, CIDFontType2 supposedly indicates the font is in Truetype format.
The hardcoded behavior can be checked by decompressing the output PDF:
Activity
mdboom commentedon Mar 11, 2014
There was some abandoned work to get this done by replacing
FT2Fontandttconvwith a more modern freetype wrapper that gives us what we need to do the font subsetting for any font that freetype supports. The wrappers are mostly done: https://github.com/matplotlib/freetypy, but things stalled getting this then integrated with matplotlib, as I lost time to work on it. I'd love to see someone take that on, but it's a fair bit of work.mojca commentedon Mar 11, 2014
Are you able to provide a short list of things that need to be done? (And maybe the desired skillset?)
What is the relation between this change and support for, say, OpenType Math layout?
Just brainstorming: would it help if one of TeX user groups would provide a tiny bit of funding in the name of "better support for graphs, compatible with TeX documents"?
mdboom commentedon Mar 11, 2014
You can read MEP14 : https://github.com/matplotlib/matplotlib/wiki/Mep14. It actually has a much larger scope than just this -- the relevant sections to this bug are "Font subsetting" and "Freetype wrappers".
Essentially, all of the calls to FT2Font (the current matplotlib freetype wrapper) and ttconv (the TTF-only font subsetting code) would need to be replaced with calls to the new freetypy wrapper (which is mostly complete -- just missing a little final polish). The ttconv code will need to directly convert the outlines obtained from freetypy into the native outline format of PDF, PS, SVG etc. directly in Python (rather than using C as ttconv does now). At least the Agg, PDF, PS and SVG backends as well as the path effects stuff will be affected. The skill set required is mostly Python at this point (the C parts are mostly done), but it does require understanding the font outline API of freetype and the font outline formats of PS, PDF and SVG.
OpenType Math layout is somewhat orthogonal to this. Here, we're talking only about supporting the OpenType file format, as opposed to the TrueType file format, without using any of the OpenType specific features and information. OpenType Math layout allows the font to specify certain things about the math layout -- such as how deep subscripts should be etc. -- that the layout engine would use to adapt itself to a particular font. My understanding is that STIX does not have this information, but there is a fork, XITS, that aims to add it.
Funding always helps, but we'd also need someone with the time... ;) I'm not sure that's me at the moment.
petehuang commentedon Jan 7, 2017
Just tossing in an update: doesn't seem like there's been any movement, please comment if otherwise
anntzer commentedon Nov 7, 2018
If you're still interested: the https://github.com/anntzer/mplcairo backend should support all reasonably common font formats.
github-actions commentedon Mar 4, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
mojca commentedon Mar 5, 2023
Still interested
oscargus commentedon Mar 5, 2023
There seems to be alternative bindings now: https://pypi.org/project/freetype-py/
QuLogic commentedon Jul 1, 2025
ttconvwas replaced in #20866, but without a specific (non-proprietary) font to test, I cannot confirm whether this is working or not, but I suspect it was fixed.lstngr commentedon Dec 3, 2025
I'm also interested in this! The situation seems to have improved since the ticket was opened (a PDF is generated), but the resulting file appears to be malformed?
In particular, many LaTeX OTF fonts (distributed by, e.g., TeXLive) seem to originate from a Postscript format and trigger this error:
Executing
pdffonts /tmp/text.pdfyields:If the default font, DejaVu Sans, is used, the output is:
In the current Matplotlib version, this seems to be due to the following backend location, which hardcodes the font type when Opentype output is requested. In this backend, CIDFontType2 supposedly indicates the font is in Truetype format.
The hardcoded behavior can be checked by decompressing the output PDF:
I'm far from knowledgeable on this topic, so I hope my conclusions are not erroneous and that this helps!