Open justvanrossum opened 4 years ago
Agreed on closing the previous issue and starting a focused discussion, this has been dragging out too long (I know I am guilty here).
I believe one thought was to change the plists to hkerning.plist
and vkerning.plist
when doing this as to add vertical kerning, and have a clear break between the ambiguous kerning. Then tools can up convert if the user wants.
I've opened #97 to track vertical kerning. I think the renaming of kerning.plist
to hkerning.plist
is mostly tangential to this issue. I don't care much either way. A major version bump will be needed anyway.
I'm not sure if this is going to solve an issue. I've made a kerning tool that interprets any pair with an RTL
entry as an RTL
pair. So ر{
is RTL. The logic is based on the UFO3 spec and that is pair entries are written in logical order. You can see the tool here:
https://gitlab.com/typoman/robofont-kerning-tool
I can't see a situation that making the order visual, would solve a problem but maybe it's just because I haven't encountered that kerning pair.
As for neutral pairs like .{
they're already interpreted as LTR
so adding this to the spec would not solve the ambiguity?
@typoman it's not neutral when the kerning is stored as writing direction, it leads to abiguity (for example see this comment). Trust me, I used to think that storing kerning in the writing direction order made the most sense or tagging pairs with direction (LTR, RTL, both), but I've come around to what @behdad has been saying: UFO2 was right, visual order is the best encoding for this.
I also believe that visual order is more logical. What I'm not sure is if this is going to solve an issue or create more issues later, since everything works fine now.
As for neutral pairs like .{ they're already interpreted as LTR so adding this to the spec would not solve the ambiguity?
~It means you currently can't kern such pairs for RTL. And that is exactly the issue to be solved.~
It won't be an easy transition, and I'm sure there will be issues because of this transition, but it will ultimately be worth it.
And, to be very clear, any change to how kerning is encoded would mean a new file, like hkerning.plist
, so the two would not be mixed.
And, to be very clear, any change to how kerning is encoded would mean a new file, like hkerning.plist, so the two would not be mixed.
Exactly. Add a rkerning.plist
and keep it in trying order (cause processing it backwards doesn't make it any easier).
hkerning.plist
as in "horizontal", with accompanying vkerning.plist
for vertical.
Glyph pairs are written in visual order, left on the left, right on the right, top, bottom, etc.
Then the compiler encodes the kerning in both the LTR and RTL kern lookups, pruning away from the respective lookups the pairs that can never apply because involve glyphs associated with unicodes that belong to scripts with the other script direction.
@anthrotype gave me a thorough explanation about how things are changing and why this makes sense. I'm going to put a summary of what I understood from his explanation here on how this is changing the compiler behaviour. This example shows how the encoding of an example neutral kerning pair works in the two specs.
Left | Right | Value |
---|---|---|
{ |
. |
-30 |
pos parentheses period -30; # inside an LTR lookup
pos period parentheses <-30 0 -30 0>; # inside an RTL lookup
1st | 2nd | Value |
---|---|---|
{ |
. |
-30 |
pos parentheses period -30; # inside a dflt script lookup
Because the current spec sates the kerning pairs are written in logical order, there is no way to tell if the increase/decrease was in which direction (maybe LTR and RTL, maybe only one). But with visual order (neutral) this pair will be interpreted as an increase/decrease in space between those glyphs regardless of the direction and will be encoded in both LTR/RTL lookups (depending on what scripts are already present in the feature file). I hope I got this right but please correct me if I'm wrong.
So let's say I'm writing an UFO version 3 for a font that has only Hebrew letters and some Latin punctuation.
I have 3 kerning pairs:
LEFT: /mem-hb, RIGHT: /dalet-hb, VALUE: -20 LEFT: /period, RIGHT: /dalet-hb, VALUE: -70 LEFT: /slash, RIGHT: /period, VALUE: -50
How am I supposed to store this in kerning.plist ?
{
"dalet-hb": {
"mem-hb": -20,
"period": -70,
},
"period": {
"slash": -50
}
}
where the visual /slash/period is assumed to be used for RTL only (because no other strong scripts are in the font)?
But what happens if also Latin letters are present?
{
"mem-hb": {
"dalet-hb": -20
},
"period": {
"dalet-hb": -70
},
"slash": {
"period": -50
}
}
I'm talking about UFO 3, not UFO 4.
of course that's a rethorical question and the answer is "you can't", which is the main reason this issue exists. Would be nice to make progress on this front after three years of inactivity, we just need a "champion" that wants to carry this through the final line
But if I have to store, trying to follow the spec as best as poss is still a better choice than going simple/visual?
For visual, we’re waiting for UFO4?
since slash and period are both neutral direction-wise, and there's no way to guess whether font developer wants to reduce by -50 the xadvance of slash when it precedes a period in a LTR run of text, and/or reduce both xadvance and xorigin of period by -50 when it precedes a slash in a RTL run, one might argue that one should interpret a pair such as {("slash", "period"): -50} in kerning.plist as visual left/right terms, thus do pos slash period -50;
, in the lookup registered under a LTR script; and pos period slash <-50 0 -50 0>;
in the lookup registered under RTL scripts...
However, we have been doing just the former in ufo2ft kernFeatureWriter, to stay closer to the logical ordering rule of UFO3 spec. Perhaps we could revise that again since we are touching that code in https://github.com/googlefonts/ufo2ft/pull/679, though I am not 100% convinced this ambiguity is solvable within the current UFO3 logic framework.
UFO3 defines kerning pairs as "in writing direction", which is confusing and ambiguous, as documented in #16.
That issue is a mess, and it's hard to find important comments such as https://github.com/unified-font-object/ufo-spec/issues/16#issuecomment-361732707 and https://github.com/unified-font-object/ufo-spec/issues/16#issuecomment-488751554, so I propose to close it in favor of this one, where we can focus on the solution.
It seem the consensus is that the next major version of UFO should define kerning pairs as "visual left to right", to avoid ambiguity (as it was in UFO2).
We should come up with a recommendation of how to upconvert existing mixed LTR/RTL kerning. A special point of interest would be the naming of kern groups:
public.kern1.*
groups used in UFO3 RTL kerning should becomepublic.kern2.*
and vice versa, which may cause name clashes.