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

Make sparse sources explicit #11

Open
arrowtype opened this issue Oct 4, 2021 · 6 comments
Open

Make sparse sources explicit #11

arrowtype opened this issue Oct 4, 2021 · 6 comments

Comments

@arrowtype
Copy link

Often, I will a small number of sources to cover a wide range of style, e.g. weight. This works well for 95% of the glyphs in the designspace, but some need touch-ups somewhere in the middle of their interpolation. A good way to do this is via "sparse" sources which just contain a few glyphs, but not all glyphs, and (unless otherwise intended) no kerning or feature data. However, this process is a bit cumbersome and not very standardized, so it would be great to make more explicit in future versions of the DesignSpace spec.

@madig
Copy link
Collaborator

madig commented Oct 6, 2021

I agree that this is fiddly currently. Can you please list the gotchas that you stumbled over? Since sparsity is basically shoehorning UFOs into something they weren't made for, I'm not very clear on how to improve things...

@arrowtype
Copy link
Author

Thanks, @madig! First off, I’m very glad everything here exists, and I’m just hoping that it can be better for new & experienced users in the future.

Since sparsity is basically shoehorning UFOs into something they weren't made for

Serious question: were UFOs really made for interpolation at all? My understanding of it is that UFOs are mostly made to store single font sources and related data in a flexible way, and the designspace is what binds them together in a way that allows interpolation.

Can you please list the gotchas that you stumbled over?

Sure! Specific friction points I’ve encountered include:

  • No explicit way of labeling sources as "sparse" within designspace, so I end up relying on file name conventions (literally including the substring sparse in the UFO directory name) in order to use that info in Python build scripts.
  • There is the font lib key com.github.googlei18n.ufo2ft.featureWriters which has to be added to a UFO to tell fontmake not to use the kerning data in it. (I guess I could be using this in my own build scripts, rather than relying on file naming conventions.) This is a little bit hard to know about, and adding lib keys is confusing to do for the first time. Sparse / Partial Masters and Anchors googlefonts/fontmake#607
    • If this lib key is missing from a UFO, fontmake treats missing kerning as "zero" kerning for everything when building static fonts, which is a definite gotcha – it's possible to make a variable font with missing kerning where sparse sources are located. No kerning in instances googlefonts/fontmake#625
  • If I wanted to add specific "sparse" kerning with sparse sources, I'm not quite sure how I would do that... I guess I would have to interpolate kerning data for that location, then just edit it for the glyphs I want to effect. But, this is burdensome, when I really just want to add a kerning tweak for small cases ... and actually, it doesn't work to build this in FontMake. But, I definitely don't want to take on kerning for a whole additional source location when 99.9% of that kerning should always simply be interpolated.

I'm not sure how much of this can be handled in designspaces, but I think/hope that being able to specify sparse sources explicitly would help in getting tools to expect it and support it more directly.

@madig
Copy link
Collaborator

madig commented Oct 7, 2021

were UFOs really made for interpolation at all?

I don't think so, which is why you have these impedance mismatches :)

No explicit way of labeling sources as "sparse" within designspace

Yes, use the layer attribute on a source element. Fontmake won't compile features then. It is indeed hairy to correct kerning and other interpolating data, sparse masters are only really made to correct stuff in graphical glyph data. You'd have to fiddle with the OTL data I guess...

@belluzj
Copy link
Collaborator

belluzj commented Oct 13, 2021

I think we should handle this in V5 in the following way:

  • if you take a designspace v4 and just replace the version number at the top with 5.0, then it keeps working exactly the same way as before (despite/including the non-intuitive behaviour that @arrowtype mentions)
  • however now that you're version 5, you have the option to add XML elements to your <source> element to define better the intended behaviour of that UFO within the designspace (i.e. should the kerning be used? etc.)

I think MutatorMath was able to do that kind of stuff already so we should re-use the existing tags whenever possible, and change the spec to say that it should work also in varLib

image

@arrowtype
Copy link
Author

No explicit way of labeling sources as "sparse" within designspace

Yes, use the layer attribute on a source element. Fontmake won't compile features then.

At least as far as the designspace spec goes, this doesn’t really seem very explicit. The entire definition I can find is:

layerName: string. The name of the layer in the source to look for outline data. Default None which means foreground.

The fact that FontMake skips features where layerName is specified is probably good, but a user wouldn’t necessarily expect that from simply reading a source descriptor or the DS spec, unless they already knew that detail about FontMake.

Beyond that, using a specified layer feels more like a workaround than a user-centric solution. Ideally, I would imagine that a goal of the designspace v5 should be to make it simpler for new designers to add design nuance to interpolation. I’m sure that the layer approach works really well for some projects, but it doesn’t strike me as the best possible way forward for future projects. Of course, I could be wrong, but I’ve written about this view in more detail in this comment. My perspective boils down to:

  • Designers are used to thinking of "source = master = UFO," so the intuitive thing would be to support UFOs as sparse sources
  • Layers are often used for old drawings or in-process drawings, so relying on a layer as a "source" on its own risks unintended data getting into that layer, or having a layer drawing that is easy to miss when reviewing a design, debugging incompatible drawings, and simply while updating a character’s construction.
  • There is not (as far as I know) a very clear overview of glyphs on a given layer. It’s valuable to be able to open a UFO for a sparse layer, and see exactly which glyphs are included. In RoboFont, one could make a "default set" / group to make a filter view of glyphs with sparse layer drawings, but this would be constantly falling out of sync with glyphs actually in that layer. So, having a separate file to open is very handy:

image

@belluzj’s suggestion seems to be a pretty good one! I am slightly uncertain about the mutedGlyphNames attribute, though. Worst case: would that attribute require every glyph name that isn’t included in a sparse source? I think that it’s probably much better to assume that missing glyphs (or glyphs in the skipExport lib item) should be muted. But, of course, maybe I’m just misunderstanding that attribute.

@weiweihuanghuang
Copy link

weiweihuanghuang commented Oct 16, 2021

I agree with all the above that @arrowtype has outlined, I've run into the exact problems.

What I found most frustrating while working with sparse masters on top of the above is that there wasn't any simple way in a UI level to work with them contextually.

In Glyphs App I can preview an line at a specific instance and work on a sparse master glyph without having to generate an entire instance – but it's still limited.

In Robofont I essentially had to generate an entire UFO and correct the relevant sparse master glyphs, then delete the rest and then shoehorn them back into a master as layers. I haven't used Skateboard so I'm not sure how it works there.

For both workflows, it's really hard trying to keep track of where I had sparse masters like @arrowtype mentioned too.

Another issue I ran into was depending on the position of a sparse master, I often needed to add extra masters to make sure the spaces created by the sparse master were orthogonal – i.e. adding explicit sparse masters at the edge of a designspace even if they weren't necessarily changing the design – otherwise the rest of the interpolation was warped. This meant I had to keep track of which sparse masters were actual design layers and which ones where only necessary for making the designspace work.

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

No branches or pull requests

4 participants