GPOS default feature duplication + complication

In Glyphs 2 every entry in the GPOS script table gets its “own” feature. Glyphs 3 minimises the number of entries in the feature table. But for some reason the script default entries end up with 2 features instead of one. In its most simple case with just one kerning lookup for latn the script and feature tables look like the following. 1 script table entry, with two kerning features pointing to the same lookup:

script table begin
latn	default		 0, 1
script table end

feature table begin
 0	kern	 0
 1	kern	 0
feature table end

Having a few languages and some more lookups:

script table begin
DFLT	default		 0, 2, 4
latn	default		 0, 1, 2, 3, 4
latn	CAT 		 0, 2, 4
latn	MOL 		 0, 2, 4
latn	ROM 		 0, 2, 4
script table end

feature table begin
 0	kern	 0, 1
 1	kern	 1
 2	mark	 2, 3
 3	mark	 3
 4	mkmk	 4
feature table end

The default gets the kern and mark features twice, with the second dropping the first lookup.

And now checking Noto Serif Devanagari (the regular): There is a dist feature with a context rule. Glyphs adds the kerning to this feature.

In Glyphs 2 the context rule is lookup 36 and the kerning is lookup 37. Each script table has its own feature. But only the two features for the default deva and dev2 script table entries have both lookups, the rest have to make do without the kerning of lookup 37. Which is not good.

In Glyphs 3 the kerning is lookup 36 and the context rule 37. The context rule is an x-placement, so it is indeed better to do that after the kerning. The feature table has three dist entries. There are two with the kerning and one entry for the context rule.
The default deva and dev2 script table entries have two dist features. I have not tested if we get both lookups or just the one of the first dist, or the one of the second dist feature. The other script table entries get a feature with the context rule only and miss out on the kerning.
The two default script table entries also get an extra abvm and blwm feature with the second feature missing the first of the six lookups.

Reducing redundancy in langsys->feature table structures to produce the smallest file possible was the goal, yes (more on that below). That is of course best achieved if the algorithm that translates the feature code structure to langsys->feature table structures produces the right output by default with no backtracking etc. It turns out, though, that making sure there are no redundant entries left at all is hard to do this way and that an extra optimisation step would be needed, something we don’t do at this point. So the duplicate entries you see are just algorithmic artefacts for the specific feature code structure you had for that example.

Now’s the tricky part: as said above, the goal in Glyphs 3 was to reduce redundancy in langsys->feature table structures. What you see here is multiple feature tables being created if possible per feature per language system to avoid duplicate lookup contents from table to table, and to allow different language systems to reference them on an as-needed basis. Unfortunately, we’ve learned only recently that this is something that most layout engines won’t handle, so this will be changed in the coming updates. (Fortunately enough, the Glyphs-generated feature code seems not to be affected by this, which also may explain why it hasn’t been reported before.) For now, we’ve simply switched to the old, makeotf-compatible way of doing things (separate feature table for each language system) not to break people’s fonts. Please update to the latest cutting edge version.

That is something I think is a matter of how kerning code is generated in Glyphs 2 for makeotf to handle. Georg would have to chime in to comment on that more, but I assume it’s just insufficient or mismatched script/language declarations at the feature code level.

The way feature code mixes lookups, scripts and languages into so called features is very different to the final GPOS and GSUB, where you have a simple sequence of lookups that is given a meaning by grouping the entries with feature tags and which are given a context with a script/language tag. I interpret your description the Glyphs 3 problem as a difficulty of having to un-mix the one into the other.

The missing kerning is something I do not see as something that me the user can fix. There is a language system entry defining DFLT ( do not know why that is there, but if I remove it I cannot generate a font because it does not like the locl feature ) and there is deva and dev2 as default and with Marathi, Nepali and Sanskrit localisations. The dist feature contains the lookup with the context rule without any script or language code. So it should apply to all that is defined in the LanguageSystem field. And it does. But Glyphs 2 (and 3 in its own way) adds kerning to the default dist feature, but not to those for Marathi, Nepali and Sanskrit. I do not see any way for me to influence that.

I tried following (with Glyphs2):
Change the tag of the context rule to kern. I get a kern feature for all 9, but a dist feature with the kerning only for the two defaults.
If I remove the context rule completely, a dist feature with the kerning only for the two defaults.

My theory is that when there is kerning for a kern feature, everything is OK. But if there is an exception for Indic that moves the kerning to the dist feature, the language entries are left in the cold.

By the way: for dev2 having a kern feature is OK. It is only the old Indic deva and so on that do not support it. Not sure if there are many Windows XP users left…

I tried the 3073. It is a bit confusing trying out all these variants, lots of files with similar names to compare.

First thing to notice is that the GSUB with useExtension has become a lot smaller. Glyphs 3 still cannot do without it. But if I ignore Adobe’s advice to add it to the largest lookups, and add it to the lookups at the end of the GSUB (the last two lookups) the GSUB gets a lot smaller yet.

The GPOS and GSUB changed more than expected. It seems a bit of a mix between the Glyphs 2 version and the previous Glyphs 3 version. The class based context rules have disappeared, but there is still a variation in formats for context rules, that the old MakeOTF lacks.

I tried out the condition keyword for making a feature variation table. I like it and it works. Still to try out how to use it in combination with an avar table.
I tried some kern context rules with the Number Values. That works OK with interpolated instances as far as I can tell. But in a variable font, I do not see a reference to the item variation store in the GPOS, so we get the value of the default master only. I thought to mention it. Maybe it is a bug, maybe it is something on the to do list. It will be useful if it works.

The changes to makeotf-compatible have produced a result that is about to change, which probably means I should wait a while for a new update to arrive to continue my investigations.