-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Drop the FT2Font intermediate buffer. #30059
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
Conversation
|
Would you be open to using a tracking issue or project board for the font work (sample categories: draft, waiting on other PRs, ready for review, please review first)? I think breaking everything up into small PRs is fantastic but I'm finding it a bit overwhelming to keep track of the order for reviewing things (and figure I'm not alone here) and how these PRs relate to each other. |
|
Sure, I'll do that. I'm sorry for the mess, but this is basically me trying to remember all the patches or even just ideas I have accumulated over the years that went nowhere because they would thrash all the baseline images, and that I now try to present given that I see an opportunity with the FreeType upgrade. Also, some of them are not fully complete patches but things that I believe can be made complete with relatively little effort (for some value of "little effort"...) simply because I do not have the time now to finalize them but want to put them up for discussion as the underlying idea should be clear. |
No apologies needed, I commend you for taking advantage of the freetype upgrade. And thanks for the wiki, though some reason can't link cleanly |
|
link fixed |
d44360f to
66fdae0
Compare
|
Edit: fraction bar rendering has been added too. |
|
A few warnings from compiling locally: |
|
This is semi-intentional: if these checks fail (error > 0) then the error should really be raised using throw_ft_error, not with a plain raise as I currently do, but throw_ft_error is not visible from ft2font_wrapper.cpp so some code needs to be moved around, e.g. make throw_ft_error an inline function defined in ft2font.h, or move the new implementations into real C++ FT2Font methods in ft2font.cpp and add wrapper lambdas in ft2font_wrapper.cpp, or (would be my preferred choice) switch error checking to the FT_CHECK macro used in mplcairo (see mplcairo's macros.h). |
|
On a side note, I'm in favour of this in general as removing the intermediate buffer will make emoji/colour glyphs easier since they won't need to go through it. |
|
On the call, we were discussing whether it made sense to target all these font-related (and requiring full image rebuild) PRs to a separate feature branch, which would contain the final test image updates. Do you have any thoughts on retargetting this PR (instead of folding it in to #29816)? |
Sure, I don't really mind either way? Should the branch live on this repo and be ultimately pruned out, or on yours? |
|
Fixed #30059 (comment) by using FT_CHECK (thus also needs #30123). |
|
What this PR provides:
(* this is about alpha compositing of opaque glyphs with partial coverage of some pixels due to antialiasing, not about alpha compositing of semitransparent glyphs as mentioned in the comment above, which is a separate issue) Certainly all of these issues can also be fixed while maintaining the intermediate buffer, but it would be more complicated (though perhaps not overly so). I think the main reason for merging this into 3.11 is to have a single baseline image update, because this change will certainly break all baseline images (that include text) again. Looking at this again I would guess we can still go in with this PR (if it's good enough for Chrome and Firefox it's good enough for us, as you say) and then later, if there's demand, move back to a (new, different) intermediate-buffer based implementation; it should be possible (if slightly tedious) to write it in a way that's fully backcompatible with this PR except for the case of overlapping semitransparent glyphs, which likely don't occur in the test suite, so that later change shouldn't trigger a mass baseline-image regen again. |
|
My thoughts are that I think an intermediate buffer is the only way to fix the transparent text, but it is also currently implemented in the wrong place, causing the issues that @anntzer outlined. I think it makes sense to take this PR and then switch to an intermediate buffer only in the case of transparent text, but at a location much closer to the rendering step. It should be possible to then handle emojis reasonably there as well. However, as there are no tests that could fail this, there's no rush to get it done, and it could certainly wait until after the rc. I just merged |
fea96d8 to
9c96bc1
Compare
|
There is something odd going on here with font/glyph caches; if I run (Note, I have updated the |
|
I've narrowed it down to just running anything with mathtext before will cause the failure, e.g., I suspect that somewhere a |
|
When Agg's So something like this does fix it for PDF: diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py
index c6b7cf0ac9..813d4a73ff 100644
--- a/lib/matplotlib/backends/backend_pdf.py
+++ b/lib/matplotlib/backends/backend_pdf.py
@@ -598,6 +598,8 @@ class Stream:
def _get_pdf_charprocs(font_path, glyph_indices):
font = get_font(font_path, hinting_factor=1)
+ hf = font._hinting_factor
+ font._set_transform([[round(0x10000 / hf), 0], [0, 0x10000]], [0, 0])
conv = 1000 / font.units_per_EM # Conversion to PS units (1/1000's).
procs = {}
for glyph_index in glyph_indices:
@@ -1121,6 +1123,8 @@ end"""
def embedTTF(self, filename, subset_index, charmap):
"""Embed the TTF font from the named file into the document."""
font = get_font(filename)
+ hf = font._hinting_factor
+ font._set_transform([[round(0x10000 / hf), 0], [0, 0x10000]], [0, 0])
fonttype = mpl.rcParams['pdf.fonttype']
def cvt(length, upe=font.units_per_EM, nearest=True):and similar would probably work for EPS. However, I wonder if we should be resetting this somewhere more central? Maybe in |
|
Ah, good catch, thanks for the debugging. I suspect that the most efficient way would be to reset the transform just once at the end of draw_mathtext(), and the most "principled" way would be indeed to do it in get_font() and document that the latter always returns a font with the default transform. |
9c96bc1 to
f13fe82
Compare
|
While looking at #22852, I noticed that some fraction bars were missing, both in that PR and here. For example, mathtext_cm_45 lost its fraction bar from this PR. I assume this has something to do with snapping to smaller than a pixel; should we impose some kind of minimum height when snapping is enabled here? |
|
Note if we were to simply give up on snapping for the rectangles, then that would affect |
|
If we do something like this, then it affects <20 images and seems like the lightest fix. |
|
Oops. Yes, that definitely seems like the reasonable fix; good catch. |
f13fe82 to
f5e7bc0
Compare
|
OK, I pushed that change along with updated test images to the other branch. I'm a bit uncertain why |
|
Ah, I just noticed that those tests have a tolerance; probably they changed little enough that I didn't replace them, but just enough that they were different on another platform. I force regenerated them and running CI again. |
Directly render FT glyphs to the Agg buffer. In particular, this naturally provides, with no extra work, subpixel positioning of glyphs (which could also have been implemented in the old framework, but would have required careful tracking of subpixel offets). Note that all baseline images should be regenerated. The new APIs added to FT2Font are also up to bikeshedding (but they are all private).
f5e7bc0 to
9d7d7b4
Compare
|
No luck, so I've just pushed a minor tolerance bump there and I can clean that up later when refreshing the images for good. |
|
Thank you for shepherding this through! |
Directly render FT glyphs to the Agg buffer. In particular, this naturally provides, with no extra work, subpixel positioning of glyphs (closing #29551) (this could also have been implemented in the old framework, but would have required careful tracking of subpixel offets).
Note that rendering of mathtext boxes (e.g., fraction bars) is currently missing, but should be "easy" (the main question being whether/how to ensure proper hinting/alignment to pixel edges in the horizontal or vertical output cases).Likewise, all baseline images should be regenerated. Finally, the new APIs added to FT2Font are likely up to bikeshedding (but they are all private).In practice this should get included (if we agree to go this way) into the FreeType update (#29816). This would also supersede the patch advertised at #29816 (comment).
test modified from #29551 to also include mathtext:
PR summary
PR checklist