Skip to content

Fix auto-sized glyphs with BaKoMa fonts #29936

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

QuLogic
Copy link
Member

@QuLogic QuLogic commented Apr 18, 2025

PR summary

If the larger glyphs for an auto-sized character in cmex10 uses a character that is in the latex_to_bakoma table, then it will be mapped an extra time into cmr10 (usually). Thus we end up with a large version of a "normal" character, such as an exclamation point.

Instead map these glyphs through the latex_to_bakoma table by using their glyph names as "commands". This ensures they don't get double-mapped to the wrong font and fixes the following issues:

  • slash (/) uses a comma at the larger sizes mathtext_cm_85
  • right parenthesis uses an exclamation point at the largest size mathtext_cm_84
  • left and right braces use parentheses at the largest size mathtext_cm_87
  • right floor uses a percentage sign at the largest size mathtext_cm_88
  • left ceiling uses an ampersand at the largest size mathtext_cm_89

It also found the missing [ size, so it and the corresponding ] are now available again (causing the one test image change.)

In the future, it may make sense to only use the glyph names (using FT2Font.get_name_index instead of FT2Font.get_char_index), and not have a mapping to character codes in our code. Unfortunately, TruetypeFonts._get_glyph expects a font+character code, so this would be a much larger refactor than this bugfix.

I'm turning the above images into tests, but I'm finding that characters that have a "regular" glyph may not be able to select the smallest "big" glyph, because it's actually smaller that the regular one. I'm not yet sure if that's a bug in the selection logic from AutoHeightChar or whether regular glyphs shouldn't count. Since I'll be adding some test images, this PR can wait until after the FreeType 2.13 change.

Fixes #5210 (and #18740 and #29886)

PR checklist

@anntzer
Copy link
Contributor

anntzer commented Apr 18, 2025

In the future, it may make sense to only use the glyph names (using FT2Font.get_name_index instead of FT2Font.get_char_index), and not have a mapping to character codes in our code. Unfortunately, TruetypeFonts._get_glyph expects a font+character code, so this would be a much larger refactor than this bugfix.

I don't remember the exact semantics of _get_glyph off the top of my head, but from a quick look at it, did you mean "returns" instead of "expects" (emphasis mine in the quote above)?

@QuLogic
Copy link
Member Author

QuLogic commented Apr 18, 2025

In the future, it may make sense to only use the glyph names (using FT2Font.get_name_index instead of FT2Font.get_char_index), and not have a mapping to character codes in our code. Unfortunately, TruetypeFonts._get_glyph expects a font+character code, so this would be a much larger refactor than this bugfix.

I don't remember the exact semantics of _get_glyph off the top of my head, but from a quick look at it, did you mean "returns" instead of "expects" (emphasis mine in the quote above)?

Right yes. In fact, I meant that its callers expect the character codes (they use FT2Font.load_char, not FT2Font.load_glyph), though I actually found an unrelated bug there: 6c7b9d0 that I tacked on to #29816.

@QuLogic QuLogic mentioned this pull request Apr 18, 2025
5 tasks
@tacaswell tacaswell added this to the v3.11.0 milestone Apr 18, 2025
@QuLogic QuLogic force-pushed the bakoma-sizes branch 2 times, most recently from b019f76 to 2b0fd80 Compare April 24, 2025 08:05
@QuLogic
Copy link
Member Author

QuLogic commented Apr 24, 2025

After a bit of checking, I've found that for 12pt@100dpi, the multi-sized glyphs are 20, 30, 40, and 50 pixels, with regular text size being 16.671875 pixels (if available). So the text in the tests should look for an interior of 8.915625, 18.320833333333333, 25.156041666666667, 32.16734375, 42.03599479166666, which should hit all sizes of glyphs.

Also, removed the regular sized braces {} because they seem to be the same glyph as the first 'big' size.

@anntzer
Copy link
Contributor

anntzer commented Apr 24, 2025

I like the new implementation a lot, it's very clear (well, relative to the complexity of the task).
Only a few minor points:

  • Perhaps use \__parenleftbig__ instead of \parenleftbig to make it clearer that this is an internal (intermediate) construct that's not a valid mathtext string. There's precedent in doing so for \__sqrt__.
  • Perhaps start adding some code that interprets Char("\__foo__") as performing a (cached) glyph name lookup if we want to move towards using glyph names instead of glyph indices? (Note that \__sqrt__ will also need a change.)

@@ -473,57 +473,37 @@ def _get_glyph(self, fontname: str, font_class: str,
# The Bakoma fonts contain many pre-sized alternatives for the
# delimiters. The AutoSizedChar class will use these alternatives
# and select the best (closest sized) glyph.
_latex_sizes = ('big', 'Big', 'bigg', 'Bigg')
Copy link
Contributor

Choose a reason for hiding this comment

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

minor typo two lines above, while you're at it: it's AutoHeightChar, not AutoSizedChar.

QuLogic added 2 commits April 24, 2025 22:32
If the larger glyphs for an auto-sized character in `cmex10` uses a
character that is in the `latex_to_bakoma` table, then it will be mapped
an extra time into `cmr10` (usually). Thus we end up with a large
version of a "normal" character, such as an exclamation point.

Instead map these glyphs through the `latex_to_bakoma` table by using
their glyph names as "commands". This ensures they don't get
double-mapped to the wrong font and fixes the following issues:

- slash (/) uses a comma at the larger sizes
- right parenthesis uses an exclamation point at the largest size
- left and right braces use parentheses at the largest size
- right floor uses a percentage sign at the largest size
- left ceiling uses an ampersand at the largest size

Also, drop the regular size braces, as they are the same as the first
`big`-sized version.
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.

I guess it would be OK to test only one of the output formats, as we only care that the right glyphs are selected?

@QuLogic
Copy link
Member Author

QuLogic commented Apr 28, 2025

I guess it would be OK to test only one of the output formats, as we only care that the right glyphs are selected?

Do we have anything for that yet? There's lightweight_math_tests, but it only checks DejaVu Sans, which is not the font we really want to check here.

@anntzer
Copy link
Contributor

anntzer commented Apr 28, 2025

There's svgastext?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Waiting for other PR
Development

Successfully merging this pull request may close these issues.

Unexpected replacement of \right) with exlamation point in MathTextParser output
3 participants