X Tutup
Skip to content

Rasterize dvi files without dvipng.#30039

Merged
QuLogic merged 1 commit intomatplotlib:text-overhaulfrom
anntzer:dvirender
Feb 5, 2026
Merged

Rasterize dvi files without dvipng.#30039
QuLogic merged 1 commit intomatplotlib:text-overhaulfrom
anntzer:dvirender

Conversation

@anntzer
Copy link
Copy Markdown
Contributor

@anntzer anntzer commented May 11, 2025

This patch drops the reliance on dvipng to rasterize dvi files prior to inclusion by agg, instead performing the rasterization ourselves (as a consequence, the rasterization output also becomes dependent of the freetype version used). Note that this approach will be needed anyways to support xetex and luatex, as dvipng doesn't support dvi files generated by these engines.

Baseline images change slightly, for the better or the worse. The top-left blue cross text in test_rotation.py ("Myrt0") seems to be better top-aligned against the blue line (the old version overshot a bit); the bounding box of the formulas in test_usetex.py seems a bit worse.

Small API point that needs to be discussed: do we want to keep the old dvipng-based codepath? (likely, at least temporarily) If so, what kind of switch do we want to expose to the end-user? I would suggest already looking forward to the future support for xetex/luatex which would likely be implemented using rcParams["text.latex.engine"] = {"latex", "xelatex", "lualatex"} and further add a possible "latex+dvipng" value in there, which would correspond to the old default; "latex" would be the dvipng-less codepath; both "latex" and "latex+dvipng" would behave the same for backends other than agg. (Also note that if we decide later to remove that dvipng codepath, it is easier to deprecate an allowable value from a rcParams entry than to completely deprecate an entry.)

I will either implement the switch or strip out the dvipng code, and write the corresponding docs, depending on the decision above.

Edit: This closes #28766.

PR summary

PR checklist

@oscargus
Copy link
Copy Markdown
Member

do we want to keep the old dvipng-based codepath?

What is the consequence of not doing that? Font output depending on installed FreeType version?

It seems like the bonding boxes are a bit off in the new one? The top part of \frac{1}{2}\pi seems to be rendered outside of the box?

rcParams["text.latex.use_dvipng"]? Which maybe should be True for one release? (But must be set to False to use xelatex etc.)

@oscargus
Copy link
Copy Markdown
Member

The top part of \frac{1}{2}\pi seems to be rendered outside of the box?

But in most cases, the "new" bounding boxes look "better"!

@anntzer
Copy link
Copy Markdown
Contributor Author

anntzer commented May 18, 2025

do we want to keep the old dvipng-based codepath?

What is the consequence of not doing that? Font output depending on installed FreeType version?

It would, although I don't think this is really a problem (there's just 3 usetex baseline images which would now need to get the same treatment as all other baseline images with text, so that only very slightly makes things worse in that aspect). The main reason to keep the old path would be for strict backcompat if anyone really cares. Also, there's the somewhat obscure case of #20469, where dvipng was providing extra support for an otherwise unsupported font type, but this was already broken for other output formats anyways, and if/when we merge {xe,lua}tex support, users will be able to use TrueType versions of the concrete math font which will just work everywhere. (Plus, if someone wants to implement pk font support per #20469 (comment), that's still an option.)

It seems like the bonding boxes are a bit off in the new one? The top part of \frac{1}{2}\pi seems to be rendered outside of the box?

I did notice that, probably needs a more careful investigation. But I also suspect this may be related to how exactly we draw the bbox (which itself has nonzero thickness). Even if we arrange for it to have exactly 1-px width, we'd probably want it to be drawn immediately outside the outermost inked pixels, which means that the height/width would likely be 1-px bigger than the text extents, and I don't think we do any of that...

rcParams["text.latex.use_dvipng"]? Which maybe should be True for one release? (But must be set to False to use xelatex etc.)

Deprecating a rcParam is a bit annoying, hence the suggestion to fold into text.latex.engine.

@QuLogic
Copy link
Copy Markdown
Member

QuLogic commented Sep 4, 2025

Baseline images change slightly, for the better or the worse.

Shall we target the text-overhaul branch then? Likely wouldn't need the old dvipng code if it lands at the same time.

@anntzer
Copy link
Copy Markdown
Contributor Author

anntzer commented Sep 4, 2025

Sure, that works too.

@anntzer anntzer changed the base branch from main to text-overhaul September 4, 2025 08:54
@anntzer
Copy link
Copy Markdown
Contributor Author

anntzer commented Jan 31, 2026

Rebase done.

@QuLogic
Copy link
Copy Markdown
Member

QuLogic commented Jan 31, 2026

Some bits of glyph positioning seem a bit off:

import matplotlib.pyplot as plt

plt.rcParams['mathtext.fontset'] = 'cm'

texts = [
    (0.8, r'$\frac{\$100.00}{xy}$'),
    (0.5, r'$\frac{X}{\frac{X}{Y}}$'),
    (0.3, r'$\overline{\omega}^x \frac{1}{2}_0^x$'),
]

fig = plt.figure(figsize=(3, 3))

for y, t in texts:
    fig.text(0.2, y, t, verticalalignment='center', fontsize=24)
    fig.text(0.5, y, t, verticalalignment='center', usetex=True, fontsize=24)

plt.show()
Figure_1

@anntzer
Copy link
Copy Markdown
Contributor Author

anntzer commented Jan 31, 2026

The issue occurred because text.index calls get_font() (to resolve glyph indices), which would undo the call to FT_Set_Transform... fixed, and added a comment, but I guess this suggests either get_font() shouldn't reset the transform, or text.index should switch from being a property to being a real method call (e.g. resolve_index()), to make the side-effect clearer. However that doesn't need to happen in this PR.

@QuLogic
Copy link
Copy Markdown
Member

QuLogic commented Jan 31, 2026

Also need to update the rcParams type stubs.

@anntzer
Copy link
Copy Markdown
Contributor Author

anntzer commented Jan 31, 2026

done

Copy link
Copy Markdown
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

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

LGTM, but we should do the usual dance of dropping the image updates before merging.

@anntzer
Copy link
Copy Markdown
Contributor Author

anntzer commented Feb 3, 2026

I should just drop the second commit?

@anntzer
Copy link
Copy Markdown
Contributor Author

anntzer commented Feb 5, 2026

Thanks, copy-edited. (Side question for @timhoffm: What's the policy for multiline rcParams descriptions in rcsetup.py? e.g. here for text.latex.engine I would like to be able to do a bullet list.)
@QuLogic Should I drop the second commit (baselines update) or should I let you do it?

@QuLogic
Copy link
Copy Markdown
Member

QuLogic commented Feb 5, 2026

I can take care of dropping the commit.

Copy link
Copy Markdown
Member

@ksunden ksunden left a comment

Choose a reason for hiding this comment

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

I leave to @QuLogic to merge because it's going into the text-overhaul branch

This patch drops the reliance on dvipng to rasterize dvi files prior to
inclusion by agg, instead performing the rasterization ourselves (as a
consequence, the rasterization output also becomes dependent of the
freetype version used).  Note that this approach will be needed anyways
to support xetex and luatex, as dvipng doesn't support dvi files
generated by these engines.

Baseline images change slightly, for the better or the worse.  The
top-left blue cross text in test_rotation.py ("Myrt0") seems to be
better top-aligned against the blue line (the old version overshot a
bit); the bounding box of the formulas in test_usetex.py seems a bit
worse.
@QuLogic QuLogic removed the status: needs comment/discussion needs consensus on next step label Feb 5, 2026
@QuLogic QuLogic merged commit 695e9a1 into matplotlib:text-overhaul Feb 5, 2026
34 of 38 checks passed
@github-project-automation github-project-automation bot moved this from Ready for Review to Done in Font and text overhaul Feb 5, 2026
@anntzer anntzer deleted the dvirender branch February 5, 2026 21:24
@QuLogic QuLogic linked an issue Feb 6, 2026 that may be closed by this pull request
wavebyrd pushed a commit to wavebyrd/matplotlib that referenced this pull request Mar 13, 2026
Rasterize dvi files without dvipng.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Bug]: Alignment of minus sign when using LaTeX

5 participants

X Tutup