Access kerning dict of instance

Hi there!

I’m writing a script to create an instance and access its kerning through interpolatedFont.

My issue is that interpolatedFont.kerning returns an empty dict. If I go to the actual instances panel, select the created instance once and run the script again, it’s now working and returns a valid dict with all the pairs.

Basically it happens if there are already existing instances (active or not).
If I reduce code to a minimum:

master = font.selectedFontMaster
font.instances.append(GSInstance())
instance = font.instances[-1]
instance.name = master.name
instance.axes = master.axes
instance.customParameters['Disable Masters'] = master.name
print  instance.interpolatedFont.kerning

This is working if there are no previously set instances, but will return an empty dict if not (until I go to the instance panel, select the new instance once, and run the script again — minus the append line).

Is this because of the way I’m accessing the instance by index?

Thanks,
J

Try this (in Macro Window):

master = Font.selectedFontMaster
instance = GSInstance()
Font.instances.append(instance)
instance.name = master.name
instance.axes = master.axes
instance.customParameters['Disable Masters'] = master.name
print instance.interpolatedFont.kerning
  1. Use Font instead of font (shortcut for current font in the Macro Window)
  2. See how I assigned instance with a new GSInstance object, and then added it to the list of instances. Then you do not need to find it again afterwards, because you already have a reference to the object.

Hello Rainer!

Thanks for your help.
The result is the same though. I run this on a font without instances = works fine.
I add some instances and run the script and I find myself with an empty dict again.

I can see the kerning data with this script. Are you sure you are accessing the same objects you have set up before?

Why do you need to add a new instance?

You never set the interposition settings. So it might be unable to interpolate.

Yes I am. By the way, the instance is always created just fine and has correct kerning when generated. It’s just that trying to access its kerning dict doesn’t work until I somehow go in the instance panel and select it once, unless it’s the only instance there in which case it works.
I’m trying this on a test font with two masters that have a kerning pair, and one intermediate master that doesn’t have any kerning, but I’ve been testing on several other -real- projects with always the same result.

Georg, I want to add a new instance at the same axes position as an intermediate master, for which said master is disabled. So I can get the kerning from that instance and copy it to my intermediate master — then delete that temporary instance.
Not sure what you mean by me never setting interpolation settings. Isn’t that what instance.axes is for ?

Rainer, to expand on this: if my selectedFontMaster is one of the extreme masters, it works. Obviously I need to remove the Disable Masters custom parameter to get the correct kerning, but it works.
Didn’t try this before because, well, the point is to get the kerning for an intermediate master. So it only happens when I run this on an intermediate master. I’ll admit I have no clue how as to get further to find the issue.

Hi!
Any chance I could get an update on this, or confirmation that there is either a bug or something wrong on my end?

Did you send me the .glyphs file and the exact script you use?

Hi Georg,
The code snippet above is enough to get issue (or Rainers one, that is better written but does exactly the same thing).
I don’t have a particular Glyphs file where the issue happen, I tested on multiple files both at home and at work and I can reproduce the problem everywhere.
You can just take any file you have with two masters and kerning, add an instance as an intermediate master and try to run the snippet above that:

-creates an instance with the axes position of selectedFontMaster (which should be the intermediate master)
-add a custom parameter to disable that master so kerning can interpolate between the two extremes
-try to print the kerning dict

If selectedFontMaster is one of the extreme masters, it works.
If there are no other instances than the one just created by the script, it works.
If selectedFontMaster is an intermediate master AND there are other instances previously set, it will print an empty dict unless I go to the instance panel, select the instance, and try to access dict again.

If generated, instances always have the correct kerning, so its only when trying to access via interpolatedFont I guess?

Any chance I could get a follow up on this? I’ve been scratching my head over this for a while now but whatever I do I can’t get things to work.
The fact that a seemingly very random thing (having to go to the instances panel and manually select the instance) is enough to make the script work makes me think that it has nothing to do with the code.
.
I understand that the use case is very specific so maybe not high on the priority list, but I’d like to at least know if there’s anything I can actually do or if I need to find a workaround.

I assume the problem is that the instance.instanceInterpolations dict is still referencing the disabled master. You may need to trigger its update:

master = Font.selectedFontMaster
instance = GSInstance()
Font.instances.append(instance)
instance.name = master.name
instance.axes = master.axes
instance.customParameters['Disable Masters'] = master.name
instance.updateInterpolationValues() # <-- update the interpolation dict
print instance.interpolatedFont.kerning

Hi Rainer,
Thanks a lot, that was it!

If I understand correctly, since the instanceInterpolation dict is updated with every change to the axes values, it is set before I add the Disable Masters parameter, hence referencing a still active master that has effectively no kerning, right?

So basically I can set my custom parameter before the axes values and the instanceInterpolations dict will update taking that into account (I tried, and it works). Is this a valid option or is there some added advantage to using instance.updateInterpolationValues()?

That’s being on the safe side I guess. Doesn’t hurt in any event.

I see. Thanks for your help Rainer! :pray: