Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write GDEF feature writer #456

Closed
madig opened this issue Feb 2, 2021 · 6 comments · Fixed by #480
Closed

Write GDEF feature writer #456

madig opened this issue Feb 2, 2021 · 6 comments · Fixed by #480

Comments

@madig
Copy link
Collaborator

madig commented Feb 2, 2021

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:

  1. LigatureCaretByPos can be generated from https://github.com/unified-font-object/ufo-spec/blob/gh-pages/versions/ufo3/glyphs/glif.md#ligature-carets (existing issue Add support for building GDEF LigatureCarets from "caret_X" anchors #329)
  2. GlyphClassDef can be generated from https://unifiedfontobject.org/versions/ufo3/glyphs/glif/#publicopentypecategory

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.

@anthrotype
Copy link
Member

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.

@anthrotype
Copy link
Member

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)

@anthrotype
Copy link
Member

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

@benkiel
Copy link
Contributor

benkiel commented Mar 3, 2021

@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.

@moyogo
Copy link
Collaborator

moyogo commented Mar 3, 2021

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.

  • The propagate anchors filter should not propagate mark anchors to glyphs with openTypeCategories base or ligature and should not propage ligature anchors to those with openTypeCategories base or mark.
  • The mark feature writer should use openTypeCategories values just like it does with GDEF if present. It should probably give priority to the GDEF in feature code in case of conflict for a given glyph.
  • A ufo2ft GDEF feature (table) writer can then extend the GDEF glyph class definitions fontTools.feaLib produces from the feature code, after all other feature writers have run.
    It should add glyphs to GDEF glyph class definitions, and not update the ones present, with data from openTypeCategories. It should add glyphs to GDEF ligature carets with data from anchors, except for glyphs with openTypeCategories 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.

@moyogo
Copy link
Collaborator

moyogo commented Mar 5, 2021

I've opened #480 to add a GDEF Feature Writer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants