googlefonts / glyphsLib

A bridge from Glyphs source files (.glyphs) to UFOs
Apache License 2.0
181 stars 51 forks source link

Alternate layers in components #837

Closed emmamarichal closed 1 year ago

emmamarichal commented 1 year ago

Hello!

I have a font that has alternates layers in components (for example, the layers are in the bar used in the dollar, but not in the dollar itself). The designer manages to make it work in his exports (maybe he exports from glyphs: https://github.com/clauseggers/Playfair/pull/38#issuecomment-1335039800), but when I export with gftools builder, it doesn't work.

The solution would be to create layers in each affected glyph, but I wanted to see if it was possible to fix this directly here so it can work with fontmake? It concerns for exemple: E-cy Ereversed-cy Tcedilla tcedilla tcedilla.smcp e-cy ereversed-cy cent dollar

You can find the sources here: https://github.com/emmamarichal/Playfair

Maybe @simoncozens you can take a look? Thank you 🙏 Cheers!

anthrotype commented 1 year ago

I think https://github.com/googlefonts/glyphsLib/pull/538 from a couple years ago was meant to address that.

There's even a test case for it:

https://github.com/googlefonts/glyphsLib/blob/57b44f1ed1aeccc31025c76ee84c07a01909ff54/tests/builder/designspace_gen_test.py#L366-L39

Is it the same issue?

I think @simoncozens touched this code recently in https://github.com/googlefonts/glyphsLib/pull/828 so he may have more insights

anthrotype commented 1 year ago

I think this is the key part:

https://github.com/googlefonts/glyphsLib/blob/f6e9c4a29ce764d34c309caef5118c48c156be36/Lib/glyphsLib/builder/bracket_layers.py#L114-L118

I think the solution is to ensure that all composite glyphs which contain components with bracket (alternate) layers, also have the same alternate layers.

Also see this issue https://github.com/googlefonts/glyphsLib/issues/535

emmamarichal commented 1 year ago

Oh yes I'm sorry I didn't saw these older issues! I'll take a look, thank you!

simoncozens commented 1 year ago

This is not the same issue as the one that the test case fixes (since that test still passes!). In the test case, glyph B uses component A, and B has the appropriate alternate layers defined on it - the same layers as A. In the Playfair situation, the parent glyph does not have the same alternate layer set-up as the component that it uses.

I've got half way to a fix on this. The easy case is where the parent glyph has no alternate layers at all; then you just clone the master layer for each needed component use and either rename (G2) or set attributes (G3; oh, it's so fun having to support both).

The hard case is something like _f_ydieresis.ligature in Playfair, which has its own alternate layers defined, but the component glyph (y) has a different alternate layer setup. Then you have to do interesting box arithmetic to work out which layer to clone.

simoncozens commented 1 year ago

Oh hell. Almost everything working except:

fontmake: Error: In 'sources/Playfair.glyphs' -> 'master_ufo/Playfair.designspace': Generating fonts from Designspace failed: <features>:2961:9: Glyph names must not be longer than 63 characters
In [2]: len("_f_ydieresis.ligature.BRACKET.opsz_5_410.wdth_50_75.wght_690_900")
Out[2]: 64

This is an obvious limitation of using glyph names to signal alternate layer information.

emmamarichal commented 1 year ago

Thanks a lot @simoncozens, the font works well!

schriftgestalt commented 1 year ago

oh, it's so fun having to support both

Why not upgrade everything when reading the file (converting the layer names to attributes) and then you can remove a lot special causing from the rest of the code.