Add getlength and getbbox functions for TrueType fonts#4959
Add getlength and getbbox functions for TrueType fonts#4959hugovk merged 12 commits intopython-pillow:masterfrom
Conversation
Squashed commits: [ec9ec31] add tests for invalid anchor (cherry picked from commit 9e50a6a) [386a917] fix lint and docs (cherry picked from commit 2d0d528) [29f5d4c] restore and document previous getsize behaviour see discussion in issue 4789 (cherry picked from commit 9fbc945) [0ffd51a] add getbbox and getlength, with tests (cherry picked from commit c5f6373)
Using this PR I get (Windows 10 laptop): Using master I get: Using 7.2.0 from PyPI I get: Code used (click to expand)
def run_test(function, layout):
try:
print(
f"{layout}, {function}:",
min(timeit.repeat(
f"font.{function}('Hello world')",
f"from PIL import ImageFont; font = ImageFont.truetype('Tests/fonts/FreeMono.ttf', 20, layout_engine={layout})",
number=100, repeat=30,
))
)
except AttributeError:
return -1 |
Co-authored-by: Andrew Murray <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
# Conflicts: # Tests/test_imagefontctl.py
hugovk
left a comment
There was a problem hiding this comment.
This should also have release notes, can be here or in another PR.
|
Did you see my comment #4959 (comment) about "following"/"given" text? GitHub insists on hiding it for me. I have written the release notes in a separate branch so it will be a followup PR in a few minutes. |
Thanks, I'd missed that too. Thanks for the explanation! |
| self.textsize("A", font=font, stroke_width=stroke_width)[1] + spacing | ||
| ) | ||
| for line in lines: | ||
| line_width = self.textlength( |
There was a problem hiding this comment.
@nulano if you wouldn't mind helping my understanding, if getlength will
measure the advance length of text instead of the rendered width/height
then why wouldn't we want to use getsize width when determining the max_width of a rendered line? You mentioned that getlength is faster. Is this just for performance?
Third part of #4724, adding
getlengthandgetbboxfor TrueType fonts.Changes proposed in this pull request:
FreeTypeFont.getlengthandImageDraw.textlengthwhich measure the advance length of text instead of the rendered width/height. These functions are both very precise (return the exact values from FreeType/Raqm) and fast (2-3x faster depending on the string, font, and layout engine).ImageDraw.textlengthfalls back onImageDraw.textsizeif using a non-FreeType font. Helps ImageFont module: getsize is slow? #4651, Font spacing changes #3977 (comment), font.getsize() changes after installing libraqm #4483, Obtain Character-Level Bounding Boxes of Generated Text #3921, Character bounding boxes and negative offsetx #4789.ImageDraw.multiline_textto use this new value, see test casetest_imagefontctl.test_combine_multilinefor an example (essentially fixing multiline version of issue Vertical text alignment ignores yOffset #4553).FreeTypeFont.getbboxandImageDraw.[multiline_]textbbox, inspired by Fix return value of FreeTypeFont.textsize() does not include font offsets #784 (comment), which are a direct way to access the internalFreeTypeFont.font.getsizefunction, see Character bounding boxes and negative offsetx #4789 (comment) for the reasoning. This function will fail for non-FreeType fonts. Helps Obtain Character-Level Bounding Boxes of Generated Text #3921, Character bounding boxes and negative offsetx #4789.