unified-font-object / ufo-spec

The official Unified Font Object specification source files.
http://unifiedfontobject.org
175 stars 30 forks source link

Support for storing glyph category #146

Closed simoncozens closed 3 years ago

simoncozens commented 4 years ago

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.

LettError commented 4 years ago

Sounds like a good job for a documented key for glyph.lib.

justvanrossum commented 4 years ago

Yup, perfect for #124

alerque commented 4 years ago

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?

simoncozens commented 4 years ago

No.

simoncozens commented 4 years ago

At least not in OpenType, anyway; a glyph has one entry in the GlyphClassDef table.

alerque commented 4 years ago

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.

simoncozens commented 4 years ago

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.

benkiel commented 4 years ago

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.

moyogo commented 4 years ago

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.

alerque commented 4 years ago

@moyogo Is that bit of data something that currently gets lost in a round trip from Glyphs.app → UFO → Glyphs.app?

anthrotype commented 4 years ago

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

simoncozens commented 4 years ago

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

moyogo commented 4 years ago

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.

moyogo commented 4 years ago

Fontmake will use that.

As a temporary solution, I mean. This should be standardized and there seems to be a consensus for it.

anthrotype commented 4 years ago

glyph category data is lost

i think glyphsLib puts it in the glyph.lib under some private key

simoncozens commented 4 years ago

i think glyphsLib puts it in the glyph.lib under some private key

glyphsLib may do, Glyphs.app export does not currently do that.

khaledhosny commented 4 years ago

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.

alerque commented 4 years ago

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.

benkiel commented 4 years ago

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

simoncozens commented 4 years ago

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.

benkiel commented 4 years ago

@simoncozens Let's get the plumbing for mini-specs put in, then I think it'll be easy to sort out.

simoncozens commented 4 years ago

OK, I'm going to start doing the following in my tools:

anthrotype commented 4 years ago

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

simoncozens commented 4 years ago

Thanks. Let's make it public.openTypeCategory then. (urgh.)

anthrotype commented 4 years ago

also, not advisable to start using a lib key named public.* before this has made it into the official spec

madig commented 3 years ago

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 😣

moyogo commented 3 years ago

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?

madig commented 3 years ago

Ah! I completely forgot about that, thanks.

simoncozens commented 3 years ago

It is done!

madig commented 3 years ago

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.

alerque commented 3 years ago

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.

moyogo commented 3 years ago

If there's a strong preference for it I don’t mind the change.

@simoncozens would that work for you?

simoncozens commented 3 years ago

Yeah, no problem. So would that mean there’s a dictionary mapping glyph names to categories under lib?

madig commented 3 years ago

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.

moyogo commented 3 years ago

OK.

Does the following work:

public.openTypeCategory

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>
justvanrossum commented 3 years ago

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.

simoncozens commented 3 years ago

Agree with Just: a glyph->category mapping is more common.

moyogo commented 3 years ago

OK. I can open a pull request with the following:

public.openTypeCategory

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>