Skip to content

Conversation

@nulano
Copy link
Contributor

@nulano nulano commented Oct 9, 2020

Third part of #4724, adding getlength and getbbox for TrueType fonts.

Changes proposed in this pull request:

nulano added 3 commits October 9, 2020 00:56
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)
@nulano
Copy link
Contributor Author

nulano commented Oct 9, 2020

Add functions FreeTypeFont.getlength... These functions are both very ... fast (2-3x faster depending on the string, font, and layout engine).

Using this PR I get (Windows 10 laptop):

ImageFont.LAYOUT_BASIC, getsize: 0.040550500000000045
ImageFont.LAYOUT_BASIC, getbbox: 0.040425799999999956
ImageFont.LAYOUT_BASIC, getlength: 0.019836500000000035
ImageFont.LAYOUT_RAQM, getsize: 0.030743399999999532
ImageFont.LAYOUT_RAQM, getbbox: 0.030728799999999445
ImageFont.LAYOUT_RAQM, getlength: 0.009379100000000307

Using master I get:

ImageFont.LAYOUT_BASIC, getsize: 0.040138600000000135
ImageFont.LAYOUT_RAQM, getsize: 0.030360500000000012

Using 7.2.0 from PyPI I get:

ImageFont.LAYOUT_BASIC, getsize: 0.040966599999999964
ImageFont.LAYOUT_RAQM, getsize: 0.030823299999999776
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]>
@hugovk hugovk added the Fonts label Oct 11, 2020
Copy link
Member

@hugovk hugovk left a comment

Choose a reason for hiding this comment

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

Some minor bits n pieces.

Copy link
Member

@hugovk hugovk left a comment

Choose a reason for hiding this comment

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

This should also have release notes, can be here or in another PR.

@nulano
Copy link
Contributor Author

nulano commented Oct 12, 2020

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.

@hugovk
Copy link
Member

hugovk commented Oct 12, 2020

Did you see my comment #4959 (comment) about "following"/"given" text? GitHub insists on hiding it for me.

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(
Copy link
Member

Choose a reason for hiding this comment

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

@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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants