googlefonts / ufo2ft

A bridge from UFOs to FontTools objects (and therefore, OTFs and TTFs).
MIT License
151 stars 43 forks source link

Alternate layers / FeatureVariations glyphs not taking part in mark attachment #730

Closed simoncozens closed 1 year ago

simoncozens commented 1 year ago

I just noticed that although my base layers in a variable Oriya font were attaching nicely in a blwm mark-to-mark feature, alternate layers were not:

oriya

This turns out to be because we build a mark filtering class for mark features like so:

https://github.com/googlefonts/ufo2ft/blob/0f123a791c62ccd09ad41992f6cd52ed21858bc2/Lib/ufo2ft/featureWriters/markFeatureWriter.py#L678-L679

where include is something like this:

https://github.com/googlefonts/ufo2ft/blob/0f123a791c62ccd09ad41992f6cd52ed21858bc2/Lib/ufo2ft/featureWriters/markFeatureWriter.py#L828-L831

However:

In [10]: lookupName
Out[10]: 'blwm_mark2mark_bottom'

In [11]: include
Out[11]: <function ufo2ft.featureWriters.markFeatureWriter.MarkFeatureWriter._makeFeatures.<locals>.isAbvm(glyphName)>

In [12]: include("lVocalicMatra-oriya")
Out[12]: True

In [13]: include("lVocalicMatra-oriya.BRACKET.varAlt01")
Out[13]: False

lVocalicMatra-oriya is included in the glyph set because it has a Unicode encoded codepoint pointing to an abvm-using script; and anything reachable by GSUB substitutions from that codepoint is also included:

https://github.com/googlefonts/ufo2ft/blob/0f123a791c62ccd09ad41992f6cd52ed21858bc2/Lib/ufo2ft/featureWriters/markFeatureWriter.py#L878-L883

But (and here I'm guessing slightly but it's a reasonable guess) lVocalicMatra-oriya.BRACKET.varAlt01 is only reachable by feature variations, so is not included, so does not take part in mark attachment.

I think the fix here is that either compileGSUB or classifyGlyphs or both need to know more about feature variations.

simoncozens commented 1 year ago

Oh wait. That's not possible, because feature variations only exist in the designspace and we're compiling UFOs; there's no link between lVocalicMatra-oriya and lVocalicMatra-oriya.BRACKET.varAlt01 in the UFO.

Score another one for "you can't build a variable font by treating UFOs as independent fonts".