Kerning single glyphs treated differently?

I’ve had numerous error reports around my kerning scripts, and they all seem to be around the fact that Glyphs 3 now uses glyph ID in GSFont.kerning whereas they were glyph names (and they are glyph names in the saved files, strangely). Is this an intentional change or bug?

I noticed that setKerningForPair, removeKerningForPair etc still uses glyph by name, not ID. Why is it that the new GSFont.kerning gives me glyph IDs despite the file itself saves them by name and G2 was handling them by name too?
Also it seems that the functions around kerning exception have been removed and it seems that I need to write similar ones on my own. Could you confirm if that’s the case?

Font.kerning was always using ids. They are converted to names in the kerning panel and the saved file.
font.setKerningForPair() will accept names.

That’s strange, since this id/name thing caused issues. Whenever I needed to check existing kerning data and use single glyphs (e.g. New Tab with Unlocked Pairs), the scripts started to fail in G3.

I don’t understand the logic of the “New Tab with Unlocked Pairs” script. There are some obvious failures (font.kernDict() is gone).

What is the script supposed to find. Only pairs where there are glyph and class kerning? Or all glyph kerning? Because in both cases I could think of a more direct approach.

The kerningDict() was already fixed. I thought that was it, but it turns out it no longer displayed anything apart from the master names. On further investigation, I noticed that the glyph info had to be passed around more carefully and could no longer be pasted straight to tab text.

The kerningDict() was translating from glyph IDs to name. That might be the issue here.

In that case, what’s the equivalent of font.kerning in G2? It might be smart to align the behaviour on the 2’s side. (sorry for asking basic things, I no longer have access to G2)

Or G3 equivalent of kerningDict(). Actually I prefer this route as I don’t have to worry about conversion.

If you get it to work in Glyphs 3, it should work the same in Glyphs 2.

Again, if you can explain the algorithm a bit, I might be able to suggest a simpler approach.

The algorithm makes two sets of dictionaries. One is group name : [glyph names] and the other is glyph name : group name one, and for both left and right. After that, it starts looking at the kerning data and tries adding pairs that involve single glyphs to a string (it doesn’t pick only the “exceptions” but any pairs that use single glyphs). And because of the kerningDict() /kerning difference, I needed to add a version checker that converts glyph IDs to names.

I still don’t see the benefit of using glyph IDs instead of names when the latter option was taken away in G3, whereas other functions do use names and so does the file format. GSFont.kerning is the only place I need to face glyph IDs regarding kerning at least in my knowledge.

That’s what I though. So you only need the leftGroups and rightGroups, just go though the raw kern dict. All keys that don’t start with an @ are glyph IDs.
so something like

kerning = font.kerning
for masterID in kerning.allKeys():
    masterKerning = kerning[masterID]
    for leftKey in masterKerning.allKeys():
        leftKerning = masterKerning[leftKey]:
        for rightKey in leftKerning.allKeys():
            if leftKey[0] == "@":
                leftGlyph = leftGroups[leftKey][0]
            else:
                leftGlyph = font.glyphForID_(leftKey)
            if rightKey[0] == "@":
                rightGlyph = rightGroups[rightKey][0]
            else:
                rightGlyph = font.glyphForID_(rightKey)
    # and so on
1 Like

Thank you very much, that’s a lot simpler.