Hello,

I have recently created a prototype of a system that will fix rendering
issues for a few characters in autohinting mode.  This prototype can be
found in the gsoc-craig-2023 branch.  The system consists of 3 parts:

- The adjustments database, containing what should be done for each
character.
- The reverse character mapping, which works out what unicode character a
glyph index is.
- The modifications to the autohinter to apply these adjustments.

Currently, the only adjustment that I have tried to implement are "vertical
contour separation adjustments", which try to fix cases where a character
has 2 distinct shapes that should never touch.  Lowercase i and j, and
characters with accents fall under this category.

To implement this adjustment, I inserted a step after all other alignment
steps in af_latin_hints_apply, which corrects the results of the previous
steps to ensure proper separation.

The function implementing that step looks up the glyph index to determine
what type of vertical separation is needed, or if it doesn't apply.  To do
this, it uses a reverse character map that was calculated by looking up
every unicode code point referenced in the adjustment database in the
font's cmap and stored with the global metrics.
Only one type of vertical separation is implemented right now: the case
where there is one contour stacked on top of another, where the 2 must stay
separate, and the adjustment should be done by pushing the higher contour
up.  If the actual glyph turns out to have more or less than 2 contours, no
adjustment will be done.  Otherwise, the algorithm will measure the
distance between the top and bottom contour and move the top contour up
until the distance is 1 pixel.
This algorithm won't work for letters like O with an accent, where at least
2 contours are needed to represent the bottom shape.  I have also learned
that fonts using multiple contours where a single one would do isn't an
unusual case, so a mode that does not need to assume the bottom shape is 1
contour will be the next thing I do.
Here are some pictures demonstrating the changes:
https://imgur.com/a/HXGY2oJ

Please let me know if you have any feedback on this.  Here are my main
concerns about this approach:
- Because vertical separation adjustments are a step after all other steps,
they have the potential to clash with assumptions made by the previous
steps, or to violate constraints.  Does anyone know of issues I should
watch out for?
- To determine which contours are higher or lower, and to adjust their
position, the algorithm makes multiple passes through all points in the
glyph.  Could this be a performance issue?
- When the assumptions the algorithm makes are broken, it can do extreme
modifications to the glyph's shape.  For example, this is what happens when
you tell it that the double quotes character should be adjusted with the
"one glyph stacked on another" mode:
https://imgur.com/a/JrUTMrQ
The algorithm arbitrarily chose one of the quotes as being higher, and
pushed it until it cleared the other one by a pixel.  This would happen in
practice if someone mapped codepoint i to double quotes in their font.  How
much of an issue is this?  Do any fonts do this?  I could prevent it by
limiting the distance it can push something up by a pixel or two.
- Werner previously suggested that a gap of less than one pixel, instead of
one full pixel as I'm currently doing, might be better in some cases.  Does
anyone know of such a case?

Thanks to all of you for your support :)

Reply via email to