-
Notifications
You must be signed in to change notification settings - Fork 51
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
Support brace and bracket layers #468
Comments
I'm looking into bracket layers as Designspace has that covered by
It turns out to be a bit of an impedance mismatch, as Glyphs.app's bracket layers are, well, layers and a Designspace document works on whole glyphs. So for handling case 1 when round-tripping to UFO, glyphsLib would have to extract the brace layers into their own glyphs and turn them into layers again on round-tripping back. Another problem would be switching a single master (https://glyphsapp.com/tutorials/alternating-glyph-shapes -> "Switching Only One Master"), where for case 2 and 3 we'd need to copy the unchanged master layer to its own glyph to create an artificial case 1 again, but take care to delete it again when going to .glyphs after making sure it's the same as the actual layer (or turning it into an actual case 1). Looking at https://glyphsapp.com/tutorials/alternating-glyph-shapes-with-multiple-axes, the "Rename Glyphs" parameter seems to be easier to translate into Designspace rules. So maybe it's possible to forego extra bracket layer logic and instead try to express it in "Rename Glyphs" terms... The problem being that this mechanism is meant to be just for one particular instance, so you'd have to insert it into all instances. And go the other way, too... |
Brace layers now supported in master. |
Bracket layers now supported in master. |
@madig are all three kinds of bracket layers that you mentioned above supported? And what about conditional substitutions along multiple axes? How do you do that in Glyphs right now, and how do we implement this in glyphsLib? |
Just the first kind. Bracket layers currently support only the first defined axis and you can only define cross-over points, not start--end ranges. |
(posting below my reply to @davelab6's asking about the status of current support for brace and bracket layers in fontmake and glyphsLib, in case anybody is interested) TLDR: For VF, brace is done, bracket is mostly done; for static instances, neither is done, but there's a workaround. For Variable Fonts, Glyphs' brace layers are currently supported by fontmake. FontTools varLib already supports "sparse" masters (at least for TTF; CFF2 is in the making). GlyphsLib can convert the brace layers into Designspace layer sources; the layers then get compiled into master TTFs that contain only these intermediate glyphs, and finally varLib computes deltas accordingly. As for the the "bracket" layers: varLib and designspaceLib for some time now have supported conditional substition rules (FeatureVariations subtables in GSUB). @madig added support to glyphsLib for converting bracket layers into equivalent DS rules that gets compiled by varLib into FeatureVariations tables and "rvrn" features. Like the original feature in Glyphs.app, the support in glyphsLib is limited to one axis only -- whereas DS rules allow all kinds of conditions along multiple axes. But unlike the original bracket feature, glyphsLib does not support yet two variants of the bracket trick, described in the "Alternating glyph shapes" blog post as "Switching Only One Master" and "Reverse Bracket Layer". These should not be difficult to implement. For generating static instances however, these intermediate masters (brace) and conditional rules (bracket) are not currently supported by fontmake. Finally there is a way to overcome the problem with static instances and sparse masters and conditional rules: one could build a VF first and then use However I am not sure yet if that's a viable approach to recommend in the long run in all cases. Leaving aside the fact that some minor post-processing of the mutated instances is needed (e.g. the name table doesn't reflect the instance style name, but that can be fixed); building static instances usually implies removing the overlaps before converting the cubic curves to quadratic individually (i.e. not compatibly) for each UFO. The resulting fonts are usually a bit smaller (quadratic splines can use less points as they don't need to maintain compatibility across masters); and have less rendering glitches in legacy platforms. We could have mutator optionally run skia-pathops to remove the overlaps from the generated instance TTF or OTF fonts. Note that this will also render any manual TrueType hinting in the variable font useless because the point indexes change after removing the overlap. I think interpolating font sources (in addition to font binaries) will still be a valid use case for a while, so we will have to deal with this some point. Or maybe this will fade out as variable font technology becomes the norm, and instantiating from VF binary fully covers the old use cases. I hope I answered your question. |
I'm curious why not add the dependency, if it already does what we want? |
Also todo: support bracketed glyphs as components Imagine a glyph |
I think this (alternate layers with components) is all implemented now, right? |
this has to be a regression because it definitely used to work before.. /cc @simoncozens @schriftgestalt @madig @khaledhosny |
I don't understand the semantics of having more than one layer at the same location. What's that supposed to do? |
Are you using Glyphs 2 or 3? If using Glyphs 3, have you marked those layers as "intermediate"?
I think the problem is that the corresponding intermediate layers (at same location) across different glyphs are being assigned different source.layer attributes in the generated designspace so they appear to varLib as multiple sources at the same locations (invalid) whereas the expectation is that intermediate layers from different glyphs all get merged into the same UFO sparse layer associated with a single DS source. |
I think this is the same issue as #851 |
there's a pending PR from @kontur that tries to fix this #902 another hack that @arrowtype could try in the meantime is to manually rename the intermediate layers within the UI before these get marked as "intermediate" (after which their underlying name [initially just the current date/time] can't be edited any more from the UI), such that each corresponding intermediate layer in different glyphs gets assigned the same layer.name as expected. The name doesn't actually matter as long as it's the same for layers at the same location. |
Ah, nice, thanks! Yes, it looks like this is the same issue, and it appears that the PR would address it (I haven't read any code or tested the PR, though). For now, the workaround of naming layers before marking them as "intermediate" is good to know about. Thanks again! |
Thanks to Behdad's recent efforts on sparse masters, we could now support brace layers. This is probably an issue for multiple layers of the stack. I'll start here because glyphsLib needs to output something. I think this ties into fonttools/fonttools#1308.
designspaceLib supports substitution rules (https://github.com/fonttools/fonttools/blob/master/Lib/fontTools/designspaceLib/__init__.py#L140) to support bracket layers. How should brace layers/sparse masters be supported? For every brace layer, make a new source entry with the appropriate location and set
layerName
to the name of the brace layer? If e.g. there was a brace layer fore
namedMedium {465 100}
inMyFont_Th.ufo
:What already works is using a complete UFO (without feature file) as a sparse master, as I wrote here: googlefonts/fontmake#477 (comment).
There's an example declaration for bracket layers at https://github.com/fonttools/fonttools/blob/master/Lib/fontTools/designspaceLib/__init__.py#L141. Will have to understand those better before including them in the example here.
The text was updated successfully, but these errors were encountered: