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

[variableFontsGenerator] Why does makeMasterKerningCompatible extrapolate? #25

Open
colinmford opened this issue Oct 24, 2017 · 5 comments

Comments

@colinmford
Copy link

colinmford commented Oct 24, 2017

While making Variable Fonts with Batch, I noticed some of the kerning going crazy.

In a design space, I had two masters very close together with different kerning values, and a master at the end of the space with a kerning value of "0", which by default is removed from the kerning plist.

EXPECTATION
===========

    A  B             C
----o--o-------------o
  -10 -15           (0)

What is expected is that the instances between B and C would have kerning values between -15 and 0. What was happening was that I was finding a huge negative number kern for C, something like -29583.

BATCH
=====

    A  B             C
----o--o-------------o
  -10 -15           -29583

It turns out Batch is causing this. In the makeMasterKerningCompatible method, it tries to even out the kerning lists for all the masters by making an extrapolation, based on a design space defined by existing kerning values. It ignores the "0" implied by the absence of a kern pair in the C master, and instead generates a value based off of the two existing masters.

I was wondering, why does Batch do this? This is wrong in my view. Instead, I think Batch should just assume that if a kerning pair is "missing" in a master, the pair should be inserted as "0". If the designer wanted there to be any other kern, he or she would have made it themselves.

@typemytype
Copy link
Owner

Batch does extrapolation for inconsistent kerning pairs.

Your C kerning has a missing pair as varLib requires masters to be 100% compatible, meaning each master needs to have an equal pairs set.

Batch fills this up with inter/extra-polation, as this makes more sense then making a kerning exception, setting it to 0, zero.

I understand in your case the value -29583 is reallllllllyyyy bad. I would recommend to have an exception in C where a that pair is set to 0

This is also how Superpol does it when generating instances.

@LettError
Copy link
Collaborator

LettError commented Oct 25, 2017

Reference: makeMasterKerningCompatible is at variableFontGenerator.init.py

@LettError
Copy link
Collaborator

LettError commented Oct 25, 2017

I've posted this gist that shows the difference between how Batch and Superpolator interpolate the kerning. While both use mutatorMath for the calculation, they approach the problem differently. The script only shows the differences and does not offer a solution, but it's a start.

  • Superpolator uses fontMath.MathKerning objects to represent the kerning of each master. If a pair is missing in a MathKerning object the value is assumed to be 0.
  • Batch needs to extend all kerning pairs to all masters. If a pair is not present in a specific master, it does not add that pair to the calculation. That can result in unexpected extrapolations.

Let's see if I can get a list of the different expectations in Batch. I'm not so sure extrapolated kerning is that useful. Kerning is a correction to an observed problem. Extrapolation just happens.

  1. if a pair exists in all masters, proceed as expected.
  2. if a pair only exists in one single master, its value should be copied to the neutral and all then other masters should be left empty so that the value is the same everywhere. The empty masters should not be interpreted as 0.
  3. if a pair exists in the neutral, but not in all of the other masters, the other values are... modifications of the neutral ? We can argue about how useful kerning extrapolation is going to be. Maybe a repetition of the last value might be useful.
  4. if a pair does not exist in the neutral, but does in some (or all) of the other masters, a value needs to be calculated for the neutral.

@andyclymer
Copy link

I have the assumption that the appearance of a master should not change, it should only have influence on neighboring instances. The example that Colin found of a pair off by -29583 is extreme, but even smaller values would be wrong — if we approved the fit of a master that didn’t need a kern adjustment for a particular pair I would be surprised to see a value show up in an instance taken from the same location.

It makes sense however that all kerning pairs need to have a value in all masters for them to be compatible. I would expect that if a pair is missing from a master it’s either because the pair is handled by a group kern (i.e. the missing pair might only exist as an exception in another master), or the value is an implied zero-value. If it's handled by a group kern, then an exception effectively needs to be made in the master (with the group value), or if it's an implied zero an exception of zero would need to be made.

It’s a different story if one or both of the glyphs associated with the kern don’t exist in the master: then it makes sense to inter/extrapolate the glyph to make the master compatible, and then to do the same with the kern (which is what it sounds like Batch is currently doing)

@LettError
Copy link
Collaborator

A problem arises when we want to make a variable font during the design process when not all data is complete and we just want to get an idea of what is happening. Batch then somehow has to negotiate between the the loose designdata and the strict fontTools.

Batch might be able to report about which pairs are missing, but that could be a massive task that needs more help and it should stand in the way to making a test font.

typemytype added a commit that referenced this issue Oct 26, 2017
#25

its using a MathKerning mutator to retrieve missing pairs instead of
single pair repair mutators
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants