Skip to content
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

Fix text kerning calculations and some FT2Font cleanup #14940

Merged
merged 6 commits into from Aug 23, 2019

Conversation

QuLogic
Copy link
Member

@QuLogic QuLogic commented Jul 31, 2019

PR Summary

Kerning values were incorrectly divided by 64 (possibly some confusion from FreeType using both 26.6 and 16.16 types) rendering them effectively 0, unless used with very large fonts.

This corrects that error, but also adds an rcParam (text.kerning_factor) to restore the old behaviour. This is set to the old value in the _classic_test style to allow ~100 test images to continue working. There are about 20 more tests using the new style that fail now. If this looks like a reasonable way to write out the rcParam, I will add a line in those tests so their images do not need to be regenerated.

Fixes #14887.

PR Checklist

  • Has Pytest style unit tests
  • Code is Flake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@@ -1285,7 +1285,8 @@ def is_opentype_cff_font(filename):
def get_font(filename, hinting_factor=None):
if hinting_factor is None:
hinting_factor = rcParams['text.hinting_factor']
return _get_font(os.fspath(filename), hinting_factor)
return _get_font(os.fspath(filename), hinting_factor,
_kerning_factor=rcParams['text.kerning_factor'])
Copy link
Contributor

Choose a reason for hiding this comment

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

What about folding this into rcParams['_internal.classic_mode']? (how many images would need to be regen'd?)

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, I didn't update the non-classic tests yet, so you can see from the CI results it'd be 21 failures.

Copy link
Contributor

Choose a reason for hiding this comment

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

Had a quick look at the failures. A few of them can be improved:

  • regen test_acorr, test_image_interps without any text (remove_text)
  • test_titletwiny can be rewritten to a non-image-comparison, just checking the title position, like test_titlesetpos which is just below it
  • for test_hatching the text labels can probably removed? (can we generate legends with empty labels? not sure...)
  • I think the others images would need to be regen'd (assuming we fold the switch into _internal.classic_mode) and need to keep the text to be meaningful.

Or perhaps make this a private rcParam (leading underscore, like _internal.classic_mode)? Or perhaps I'm just overthinking this and text.kerning_factor is fine.

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, I added the rcParam for downstream testing's benefits; not sure if only classic mode will be helpful there.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure. I guess my preferred solution would be _internal.old_kerning or something like that, but won't insist on it.

Copy link
Member Author

Choose a reason for hiding this comment

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

I opened #15054 to track these suggestions, but for tests here I just modified the rcParam to use the old value.

@jklymak
Copy link
Member

jklymak commented Aug 12, 2019

Does this need further discussion? How many images will have to be rebuilt, and can this be done at the same time as other tests that need an image rebuild?

@tacaswell tacaswell added this to the v3.3.0 milestone Aug 12, 2019
@QuLogic
Copy link
Member Author

QuLogic commented Aug 12, 2019

The only question remaining is what to name the rcParam. With that, we can allow classic tests to continue working (~100 tests) and then the remaining ones can patch the parameter to avoid regenerating results (16 tests).

Then they can be removed piece-by-piece as images are regenerated, or all at once with the larger font fixes.

@anntzer
Copy link
Contributor

anntzer commented Aug 12, 2019

Given that there's already text.hinting_factor which should be considered a relic of the past, text.kerning_factor looks fine to me.

@QuLogic
Copy link
Member Author

QuLogic commented Aug 14, 2019

Rebased for fixed docs and added a what's new entry.

@QuLogic
Copy link
Member Author

QuLogic commented Aug 19, 2019

@tacaswell any reason to wait on this now that it's passing?

Copy link
Contributor

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

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

In general the changes seem fine, but I'm no freetype expert, so I'm not inclined to be the one to push the button. 😉

@anntzer anntzer modified the milestones: v3.3.0, v3.2.0 Aug 19, 2019
@anntzer
Copy link
Contributor

anntzer commented Aug 19, 2019

Seems like a pity to wait for 3.3 so I remilestoned this to 3.2. @tacaswell please ping if you think this should wait, otherwise I'll merge.

src/ft2font_wrapper.cpp Outdated Show resolved Hide resolved
For the straight `get_kerning` call, the result should be in subpixels,
since the callers (in Python) correctly scale it by 64 themselves.

For the glyph advancement calculation, both `pen` (used for glyph
transform and with content boxes) and kerning are in 26.6 fractional
pixels.

Therefore, there's no need to scale either case by 2**6 (64).
This is enabled for the classic test style, so that the 100 or so old
images do not need to be regenerated.
Copy link
Contributor

@anntzer anntzer left a comment

Choose a reason for hiding this comment

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

doc failure is unrelated
@tacaswell feel free to remilestone if desired

@anntzer anntzer merged commit 1e6946c into matplotlib:master Aug 23, 2019
@QuLogic QuLogic deleted the fix-kerning branch August 23, 2019 19:43
astrofrog added a commit to astrofrog/astropy-data that referenced this pull request Aug 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

kerning seems generally wrong
5 participants