Closed simoncozens closed 3 years ago
Sounds like a good job for a documented key for glyph.lib.
Yup, perfect for #124
Isn't it possible for a glyph to be more than one of these categories? For example a `
could be used as a stand alone base glyph or it could be part of a compose sequence and used as combining mark, no?
No.
At least not in OpenType, anyway; a glyph has one entry in the GlyphClassDef table.
Hm, I thought I saw a font that was built that way, but it might not have built from UFO sources either. In any event I can't find it right now. I suppose there could have been extraa scripting involved in the build process too.
Where is the GlyphClassDef
information coming from in the compiled OpenType font if it's not in the UFO glyph? Since it's evidently coming from somewhere this sounds like a potential case of data duplication. It may still be appropriate for a glyph.lib
key to store, but if it's data duplication that can be derived from somewhere it definitely should be relegated to a custom lib key, not part of the UFO spec.
It'd come in from the table GDEF { ... }
statement in the feature file. But if the information was in the UFO glyphs files, it should be build from there instead.
AFAIK: makeOTF will construct the GDEF table from a font's features if there isn't an explicit GDEF table in the feature code. I'm assuming that fontMake does the same thing.
Yes, this as part of the glyph's lib makes a lot of sense.
Indeed, fontmake will construct the GDEF table from the features, but it will also construct one from the glyph’s category if the source file provided is a Glyphs.app file with that glyph.category
information.
@moyogo Is that bit of data something that currently gets lost in a round trip from Glyphs.app → UFO → Glyphs.app?
when converting from .glypsh to UFO, glyphsLib contructs GDEF GlyphClassDef in the UFO's features.fea based on the GlyphData.xml properties or the glyph.category overrides. feaLib will use the GDEF from the features.fea, if present. Otherwise, like makeotf, it generates a GDEF table based on the way glyphs are used (as marks, ligatures or bases) in the GPOS lookups, as the Adobe FEA spec recommends to do
When Glyphs.app exports to UFO, glyph category data is lost - because there's nowhere to put it. (This is precisely what motivated this issue...)
Besides Glyphs.app, the other font editors that store the glyph category at the glyph object level are FontLab Studio 5, FontLab VI and 7, and FontForge.
Is that bit of data something that currently gets lost in a round trip from Glyphs.app → UFO → Glyphs.app?
@alerque If glyph.category is defined, it is stored in the glyph.lib["com.schriftgestaltung.Glyphs.category"]
, which is preserved both ways.
If it is not defined, like @anthrotype said, that data can also come from GlyphData.xml when the source is a Glyphs.app file but then it’s only in the GDEF definition in the UFO and only really roundtrips in the GDEF definition.
@simoncozens Glyphs.app could put it in glyph.lib["com.schriftgestaltung.Glyphs.category"]
. Fontmake will use that.
Fontmake will use that.
As a temporary solution, I mean. This should be standardized and there seems to be a consensus for it.
glyph category data is lost
i think glyphsLib puts it in the glyph.lib under some private key
i think glyphsLib puts it in the glyph.lib under some private key
glyphsLib may do, Glyphs.app export does not currently do that.
Is Glyphs category the same as GDEF classes? Glyphs derives the later from the former, but they are not equivalent, so what is requested here, though useful on its own, wouldn’t change much for round-trip conversion.
Besides Glyphs.app, the other font editors that store the glyph category at the glyph object level are FontLab Studio 5, FontLab VI and 7, and FontForge.
Glyphs.app could put it in glyph.lib["com.schriftgestaltung.Glyphs.category"]. Fontmake will use that.
Thanks @moyogo.
While a standardized generic glyphs.lib
key and documented mini-spec would be a good start, this is sounding more and more like something that may be a good candidate for eventually promoting to the UFO spec.
@alerque That's the idea of public keys and mini-spec: trial in a public key with a mini-spec, once use and consensus has been achieved, promote to full spec.
I'm happy to write the mini-spec for this but would appreciate a pointer for how best to write one for glif-level data.
@simoncozens Let's get the plumbing for mini-specs put in, then I think it'll be easy to sort out.
OK, I'm going to start doing the following in my tools:
glyph.lib["public.opentypeCategory"]
will be one of base
, ligature
or mark
.glyph._lib["com.schriftgestaltung.Glyphs.category"] = gslayer.parent.category
.glyph._lib["com.schriftgestaltung.Glyphs.subcategory"] = gslayer.parent.subcategory
.
I'll spec it out when we have the mechanism for creating mini-specs.
glyph.lib["public.opentypeCategory"] will be one of base, ligature or mark
note that all the openType*
prefixed attributes in https://unifiedfontobject.org/versions/ufo3/fontinfo.plist/ are spelled out with camelCase, not opentype
all-lowercase
Thanks. Let's make it public.openTypeCategory
then. (urgh.)
also, not advisable to start using a lib key named public.*
before this has made it into the official spec
Please also remember GDEF's LigatureCaretByPos
, which is relevant for interpolating instances as I have just found out in a project with that stuff written out in feature files 😣
Please also remember GDEF's
LigatureCaretByPos
, which is relevant for interpolating instances as I have just found out in a project with that stuff written out in feature files 😣
@madig Isn’t this handled by the Ligature Caret part of the glif spec?
Ah! I completely forgot about that, thanks.
It is done!
I just realized this should have maybe been a font.lib rather than glyph.lib key, to better vibe with the plan to take Unicode values out of glyphs. Oh well.
If it's really a mistake it would be a lot easier to correct now while any projects implementing it have the code fresh in their minds than years from now when the debt has been accruing awhile.
If there's a strong preference for it I don’t mind the change.
@simoncozens would that work for you?
Yeah, no problem. So would that mean there’s a dictionary mapping glyph names to categories under lib?
I think so, like the postscriptNames
thing.
Apropos, category etc. are also "global" in Glyphs.app in that they're stored glyph level rather than layer (UFO glyph) level.
OK.
Does the following work:
This key is used to define the category of the glyphs to be used, for example, as glyph class in the [OpenType GDEF Glyph Class Definition Table]. The glyph classes or categories are stored in a dictionary keyed by one of base
, mark
, ligature
or component
. Each category is an array of glyph name strings. This data is optional.
<key>public.openTypeCategory</key>
<dict>
<key>base</key>
<array>
<string>A</string>
<string>B</string>
</array>
<key>mark</key>
<array>
<string>acutecomb</string>
</array>
<key>ligature</key>
<array>
<string>f_f</string>
</array>
</dict>
Which is more common: to look up the category of a glyph, or to look up all glyphs of a certain category? I would assume the former (but I don't know for sure), and in that case I'd think the opposite mapping makes more sense: glyph name as key, category as value.
Agree with Just: a glyph->category mapping is more common.
OK. I can open a pull request with the following:
This key is used to define the category of the glyphs to be used, for example, as glyph class in the [OpenType GDEF Glyph Class Definition Table]. The categories are stored in a dictionary keyed by glyph name, each value must be one of base
, mark
, ligature
or component
. This data is optional.
<key>public.openTypeCategory</key>
<dict>
<key>A</key>
<string>base</string>
<key>B</key>
<string>base</string>
<key>f_f</key>
<string>ligature</string>
<key>acutecomb</key>
<string>mark</string>
</dict>
I would like to have a structured way to know whether a glyph is base, mark or ligature, without having to parse and deconstruct a GDEF table from the features file. This is a property of the glyph and could be added as an element on a .glif file. This is obviously related to #87 but has smaller scope.