-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Refactor font_getsize and font_render #4910
Conversation
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 don't see any obvious problems, further reviews also welcome :)
src/PIL/ImageFont.py
Outdated
# vertical offset is added for historical reasons, see discussion in #4789 | ||
size, offset = self.font.getsize(text, False, direction, features, language) | ||
return ( | ||
size[0] + stroke_width * 2 + offset[0], | ||
size[0] + stroke_width * 2, | ||
size[1] + stroke_width * 2 + offset[1], | ||
) |
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.
This PR fixes an issue introduced in #2576 (Pillow 4.2.0) where the x offset was sometimes added (subtracted) twice in the C function, see #4789 (comment). This change adjusts the Python function to match this behaviour after fixing the C function.
The offset was first added in #784 to match pre-#45/#185 behaviour (and make getsize
return the bottom right text coordinate, which used to match the size), but #2576 effectively reverted this change for the horizontal axis when the first character has a negative X bearing in horizontal text (otherwise the x offset is 0).
I think it is better to stick with the current behaviour (which returns the actual width but might be confusing if the first character has a negative bearing) and document it (in part 3 of #4724) rather than reverting back to the previous behaviour, as it has been this way for a long time now.
I have updated the comment to link to this explanation for future reference.
Thank you! |
First part of #4724, refactoring the main font functions.
Changes proposed in this pull request:
x_position
andy_max
had almost the same meaning for horizontal and vertical text respectively)FT_GLYPH_BBOX_PIXELS
instead of rounding up the difference returned forFT_GLYPH_BBOX_SUBPIXELS
, this fixes some text clipping (e.g. Absent pixels when drawing font #4569 (comment)), see documentationPIXEL
macro to round to nearest instead of higher, as it is no longer used to compute size, only positions; should help with kerning in basic layout in future PR;visually comparing the output gives an almost imperceptible spacing difference
bitmap_top
instead ofhoriBearingY
when rendering, fixes issue Incorrect vertical alignment of character when using fontmode = '1' #2293These changes require modifying the
test_imagefontctl
test images, but in most cases there is only a minor spacing change, a vertical or horizontal adjustment due to #4553 and related issues, or the original image even had clipped text (e.g.test_direction_ttb
)Text clipping comparisons
I added some test code to compare alignment in
getsize
andrender
. In case of mismatch a warning is generated in test branches. I tested both the standard test suite, as well as the following extra test cases:Test cases
For each test case I give the generated images with basic layout first, raqm second.
"gjpqy()|{[[}],;/_"
usingHelvetica LT Std Light.otf
at size 48 from Fix rendered characters have been chipped for some TrueType fonts #45 discussion."0123456789"
usingvista-hei-all.ttf
at size 35 from Absent pixels when drawing font #4569."01234567890123456789"
usingverdanab.ttf
at size 13 with mode1
from Incorrect vertical alignment of character when using fontmode = '1' #2293, see also Truetype fonts not being rendered correctly with the TEXT method #4177 (comment)master
(click to expand)
It was a bit tricky to figure out which variables are best to compare, but I think I got the best possible match between
getsize
andrender
, see branch master...nulano:anchor-part1-clip-test15 extra warnings in test suite (7 due to clipping, 8 due to different alignment).
PR
(click to expand)
There were no problems writing debug code here, as both functions now have the same variables with the same names and meaning, see branch nulano/Pillow@anchor-part1...nulano:anchor4
no warnings in test suite
These warnings are not surprising due to the following from the FreeType tutorial II section 4b (emphasis mine):
Fixing this would essentially require reverting #4652, so it is up for discussion. However, unlike master, the PR at least renders this case properly.
Regarding changing
FT_Outline_Get_CBox
withFT_Outline_Get_BBox
, it is my understanding that the former always returns a larger or same bbox, so is likely unnecessary to change. From the documentation forFT_Outline_Get_CBox
(emphasis mine):