Repository navigation
Closed
Labels
Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.status: confirmed bugtopic: text/fonts
Milestone
Description
Bug summary
I have installed the font Inter with brew install font-inter and successfully imported it into matplotlib such that the figure from the plot below displays correctly with the Inter font as specified; however, when it comes to saving, I get the error below in "actual outcome".
Code for reproduction
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
matplotlib.use("QtAgg")
# Ensure 'Inter' is available
available_fonts = [f.name for f in fm.fontManager.ttflist]
if 'Inter' in available_fonts:
plt.rcParams['font.family'] = 'Inter'
else:
print("Inter font is not available. Please ensure it is installed.")
# generate a test plot and save it
fig, ax = plt.subplots()
ax.plot([0, 1], [0, 1])
ax.set_title("Example Plot with Inter Font")
plt.show()
fig.savefig("example_plot.pdf", format='pdf')Actual outcome
Traceback (most recent call last):
File "/Users/atom/hemanpro/HeMan/misc_tools/addfont.py", line 18, in <module>
fig.savefig("example_plot.pdf", format='pdf')
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/atom/hemanpro/HeMan/.venv/lib/python3.13/site-packages/matplotlib/figure.py", line 3490, in savefig
self.canvas.print_figure(fname, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/Users/atom/hemanpro/HeMan/.venv/lib/python3.13/site-packages/matplotlib/backends/backend_qtagg.py", line 75, in print_figure
super().print_figure(*args, **kwargs)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/Users/atom/hemanpro/HeMan/.venv/lib/python3.13/site-packages/matplotlib/backend_bases.py", line 2184, in print_figure
result = print_method(
filename,
...<3 lines>...
bbox_inches_restore=_bbox_inches_restore,
**kwargs)
File "/Users/atom/hemanpro/HeMan/.venv/lib/python3.13/site-packages/matplotlib/backend_bases.py", line 2040, in <lambda>
print_method = functools.wraps(meth)(lambda *args, **kwargs: meth(
~~~~^
*args, **{k: v for k, v in kwargs.items() if k not in skip}))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/atom/hemanpro/HeMan/.venv/lib/python3.13/site-packages/matplotlib/backends/backend_pdf.py", line 2789, in print_pdf
file.finalize()
~~~~~~~~~~~~~^^
File "/Users/atom/hemanpro/HeMan/.venv/lib/python3.13/site-packages/matplotlib/backends/backend_pdf.py", line 827, in finalize
self.writeFonts()
~~~~~~~~~~~~~~~^^
File "/Users/atom/hemanpro/HeMan/.venv/lib/python3.13/site-packages/matplotlib/backends/backend_pdf.py", line 973, in writeFonts
fonts[Fx] = self.embedTTF(filename, chars)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/Users/atom/hemanpro/HeMan/.venv/lib/python3.13/site-packages/matplotlib/backends/backend_pdf.py", line 1416, in embedTTF
sf = font.style_flags
^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.13/3.13.1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/enum.py", line 726, in __call__
return cls.__new__(cls, value)
~~~~~~~~~~~^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.13/3.13.1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/enum.py", line 1207, in __new__
raise exc
File "/opt/homebrew/Cellar/python@3.13/3.13.1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/enum.py", line 1184, in __new__
result = cls._missing_(value)
File "/opt/homebrew/Cellar/python@3.13/3.13.1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/enum.py", line 1480, in _missing_
raise ValueError(
...<2 lines>...
))
ValueError: <flag 'StyleFlags'> invalid value 589824
given 0b0 10010000000000000000
allowed 0b0 00000000000000000011
.venvFAIL
Expected outcome
The figure is saved as a PDF with the Inter font.
Additional information
This only occurs on my macOS installation of Python 3.13.1 with matplotlib 3.10.0.
Operating system
macOS Sequoia 15.2
Matplotlib Version
3.10.0
Matplotlib Backend
QtAgg, cairo, macosx
Python version
3.13.1
Jupyter version
No response
Installation
pip
Metadata
Metadata
Assignees
Labels
Release criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.status: confirmed bugtopic: text/fonts
Activity
anntzer commentedon Jan 4, 2025
Note for repro: to trigger the bug it may be necessary to use the explicit path to the "bad" (actually, variable) font, i.e. something like
but the bug is valid.
It basically arises because of the conversion of FT_STYLE_FLAG_XXX to enum.Flag (regression in #28842), which means that any unknown value in style_flags raises the error seen above. Note that such values are explicitly allowed by the FreeType docs (https://freetype.org/freetype2/docs/reference/ft2-face_creation.html#ft_facerec): "[Since 2.6.1] Bits 16-30 hold the number of named instances available for the current face if we have a GX or OpenType variation (sub)font. Bit 31 is always zero (that is, style_flags is always a positive value). Note that a variation font has always at least one named instance, namely the default instance."
There's a few fixes possible there:
boundary=KEEPwhen declaring the enum (the easiest way to do so with the current pybind11 enum machinery is probablyp11x::enums["StyleFlags"].attr("_boundary_") = py::module::import("enum").attr("KEEP");at the same place as where the enum docs are set, but one can probably also adjust the P11X_DECLARE_ENUM macro to avoid touching at semi-internal APIs if desired). However I don't think there's an equivalent available on Py3.10.Note that face_flags likely suffers from the same issue; at least, the commented out FaceFlag values in ft2font_wrapper.cpp's
P11X_DECLARE_ENUM("FaceFlags", ...)should probably be ifdef'd as done inDECLARE_FLAGjust above.QuLogic commentedon Jan 8, 2025
These can't be
#ifdefbecauseP11X_DECLARE_ENUMis a macro invocation. If we could rewrite that as some kind of template, then it might be possible, but not as a macro.anntzer commentedon Jan 8, 2025
Good catch. The following appears to work, though: