adobe-type-tools / kern-dump

Scripts for working with and analyzing kerning information

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issues in getKerningPairsFromOTF.py

behdad opened this issue · comments

cc @justvanrossum

I read the code and noticed a few issues. Most of them don't affect well-constructed font, but one issue I think is rather serious. Though I have not debugged code to confirm. Hre it goes:

In the following code:

    lg = myLeftClass()
    lg.class1Record = class1Record
    leftClasses.setdefault(class1Record, lg).glyphs.append(leftGlyph)
    self.allLeftClasses.setdefault("class_%s_%s" % (loop, lg.class1Record), lg.glyphs)

(same is repeated for right glyph as well)

The problem is, in my understanding, that if class1Record was already in leftClasses, then leftClasses.setdefault(class1Record, lg) returns the existing leftClasses.setdefault[class1Record], which is different from lg. Then leftGlyph is corrected appended to .glyphs of that object. However, the next line, uses lg.glyphs, which is not outdated! To correct, you should also update lg:

    lg = myLeftClass()
    lg.class1Record = class1Record
    lg = leftClasses.setdefault(class1Record, lg)
    lg.glyphs.append(leftGlyph)
    self.allLeftClasses.setdefault("class_%s_%s" % (loop, lg.class1Record), lg.glyphs)

I don't know; if my assessment is correct, then this should be broken for every font. But apparently that's not the case. I haven't debugged it.

Issues that only show up in badly-constructed fonts:

  1. The code reads glyph- and class-based subtables separately. This is a problem if a class-based subtable processes a left-glyph that also shows up in a glyph-based subtable that comes later.

  2. If two subtables of the same kind both cover the same glyph pair, the first one should win, but the way the code is written, the last one wins. That's easy to fix, just reverse the subtable order at the end of getPairPos().

  3. In getClassPairs(), the code iterates over all glyphs defined in ClassDef1. However, if there's a glyph in ClassDef1 that is NOT in Coverage, that glyph should not be processed. So, better to intersect the classes with coverage first. This function from varLib might come handy (copy it; I'll move it somewhere proper later):

https://github.com/fonttools/fonttools/blob/86549315fdab659cfc536d0af7f2d2a56da176d5/Lib/fontTools/varLib/merger.py#L295

Now I noticed that I should intersect classes with allGlyphs in that function as well.

Thanks @behdad! I will have a look.

Fixed _ClassDef_invert(): fonttools/fonttools#939