Closed madig closed 3 years ago
mind that the markFeatureWriter behaves differently when a GDEF with GlyphClassDefs is found in the feature file. So that the order in which you run the feature writers may influence the result.
When GDEF is not present, the mark-ness of a glyph is guessed by the presence of _
-prefixed attaching anchors (i.e. with an accompanying non-_
-prefixed anchor somewhere else); ligature-ness is guessed with the presence of base anchors with _1
, _2
etc. suffixes (IIRC), etc. This in turn makes so that feaLib builder will generate a GDEF table based on the way glyphs are used in GPOS mark lookups: e.g. if a glyph is used as a mark, it gets mark category, etc.
When a GDEF is present, the explicit categories will limit the pool of glyphs that the mark feature writer is going to use. So if a glyph is not marked as "Mark" it'll be ignored even if it may have some attaching anchors. And that GDEF definition will be compiled verbatim by feaLib builder later in the pipeline.
so in general, you want to run that GDEF writer before the mark feature writer (like currently the GDEF generation happens in glyphsLib before the ufo2ft mark feature writer)
another approach could be that you teach the mark feature writer about these new public.openTypeCategory key, so that they have the same effect of an explicit GDEF table override in the features.fea.
Then you only add a LigatureCaretsFeatureWriter or something to handle the carets only
@madig Feel free to steal from: https://github.com/arrowtype/recursive/blob/948937aa33b1b04713627475e4ad75cb3e5cadf1/mastering/utils.py#L156. Though, it's likely not robust enough. @anthrotype's idea of teaching the mark feature writer about the openTypeCategory keys is a good one.
Ligature carets are easy, that code above assumes left to right, so you'd want to order on the caret number, but the idea is there.
Yes, the mark feature writer should use openTypeCategories, that's why it was added ;-) In case of disagreement between a GDEF glyph class definitions and openTypeCategories for a glyph, the GDEF in feature code should probably be preferred.
I don't think the GDEF should be written before the mark feature writer runs.
base
or ligature
and should not propage ligature anchors to those with openTypeCategories base
or mark
.base
or mark
.If a glyph has anchors that would make it base, mark or ligature, before or after anchor propagation, but it should not be in lookups that would classify it in one of those GDEF mark glyph class: set its openTypeCategories value to the desired value. The propagate anchors filter should not copy anchors that would change its class from openTypeCategories. The mark feature writer should not use that glyph in those lookups.
If a glyph doesn't have anchors that would place it in lookups defining its GDEF glyph class, before or after anchor propagation, but it should be in one of those classes for lookups with ignoreBasesGlyphs/Ligatures/Marks: set its openTypeCategories value.
I've opened https://github.com/googlefonts/ufo2ft/pull/480 to add a GDEF Feature Writer.
Storing GDEF information in features.fea is possible and done today but is also very much annoying. One, it needs separate maintenance and two, it instance interpolation is not made to interpolate feature files, so ligature caret positions are taken from the default source.
The UFO spec now allows to generate a complete GDEF at compile time:
So, someone needs to sit down and write a GDEF writer for ufo2ft. Since it runs after all (anchor propagation) filters, we might not even need to store any categories, or only when you want to override something somewhere. GDEF generation is already done by code in glyphsLib, so that can be used as a start.