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

axisregistry: Axis order of user defined axes #2702

Open
m4rc1e opened this issue Sep 28, 2020 · 24 comments
Open

axisregistry: Axis order of user defined axes #2702

m4rc1e opened this issue Sep 28, 2020 · 24 comments

Comments

@m4rc1e
Copy link
Collaborator

m4rc1e commented Sep 28, 2020

I'm currently working on a tool which will update a designspace's instances based on our axis registry. Have we established an order yet for the user defined axes e.g CASL, GRAD etc?

For registered axes, we have the following order:
opsz wdth wght ital e.g 12pt Condensed Black Italic

If we don't have an order, shall we just sort the user axes alphabetically?

For variable fonts we currently only include the wght and ital axes in the fvar instances so this request isn't relevant. However, for the static fonts, this info is important since a family which is constructed from multiple axes should be split into many different sibling families. If we take a look at Literata's static fonts we can see that it consists of four different families. Same situation for Fraunces as well.

@davelab6
Copy link
Member

davelab6 commented Sep 28, 2020

How do designSpace instances go into fvar and STAT and static fonts is indeed something we need to better define :)

This will need to be a superset of the axis registry fallbacks, because those have to be limited because of the combinatory explosion. I'm guessing we will get min, default, max, or default, mid, max/min, so only 3, for most user axes. But I know designers will want to include more named instances than that. Handjet's element shape axis is a great example, but opsz probably also has this issue.

The problem with sorting them alphabetically by axis tag is that eg XPRN would sort late but by axis label Expression would sort early.

English grammar has sorting rules for adjectives (https://qz.com/773738/how-non-english-speakers-are-taught-this-crazy-english-grammar-rule-you-know-but-youve-never-heard-of/ & https://slate.com/culture/2014/08/the-study-of-adjective-order-and-gsssacpm.html & etc etc) and so I believe we ought to have a defined order that is done with respect to that grammar.

The registered axes set needs to account for families with both ital and slnt axes. That is complicated by the fact that the typical slant values are negative, and can be both negative and positive.

Family name (nameid 1) Family Sans 12pt Condensed Black -8deg
Style name (name id 2) Italic
Typographic Family Name (nameid 16) Family Sans 12pt Condensed -8deg
Typographic Style Name (nameid 17) Black Italic

I forget what the WWS nameid 18 (+19?) can do...

@davelab6
Copy link
Member

So I guess a text file with # for comments will be the most simple way to make an ordered list of axes, by label not tag, and there will be at least 8 commented lines to segment the list into these sections, and then a test will be to check that all axes in the registry are listed in the file.

opinion-size-age-shape-colour-origin-material-purpose

@davelab6
Copy link
Member

davelab6 commented Oct 1, 2020

So, this is the order I propose

# opinion


# size
Optical size
Dot Grid


# age


# shape
Casual
Cursive
Dot Shape
Softness
Wonkiness


# colour
Grade


# origin


# material


# purpose
Monospace


# WWS
Weight
Width
Slope

# Italic always goes last
Italic

If defaults are not elided and a 'franken-font' was made with all the axes, it would be like this:

14pt One Dot Linear Roman Default Sharp Normal Normal Normal Regular Upright Roman

Or, with non-default values, like this:

72pt 2x2 Dots Casual Cursive Default Extra Soft Wonky Full Positive Monospace Ultra Expanded Extra Bold -8deg Italic

A more realistic couple of examples of real-world Recursive, Fraunces and Handjet axes:

Recursive Casual Cursive Monospace Extra Bold -8deg Italic

Fraunces 72pt Extra Soft Wonky Extra Bold Italic

However, ArrowType-Recursive-1.065.zip contains RecursiveMonoLnrSt-ExBdItalic.ttf.

So perhaps the Cursive fallback for the 0 value should be Sans not Roman, as that will prevent the 'doubling' of Roman seen in the above example; but since it is elided, perhaps that's OK.

The Default fallback in Dot Shape axis should probably also become Normal to match the others; or, all 'default' and 'normal' and such generics should be avoided.

Anyway, this is as far as I got today, and isn't my final recommendation.

I also said earlier,

I forget what the WWS nameid 18 (+19?) can do...

I looked into this. To recap, https://docs.microsoft.com/en-us/typography/opentype/spec/name lists the nameIDs, and the relevant ones are:

Code Meaning
1 Font Family name. The Font Family name is used in combination with Font Subfamily name (name ID 2), and should be shared among at most four fonts that differ only in weight or style (as described below).This four-way distinction should also be reflected in the OS/2.fsSelection field, using bits 0 and 5.While some platforms or applications do not have this constraint, many existing applications that use this pair of names assume that a Font Family name is shared by at most four fonts that form a font style-linking group: regular, italic (or oblique), bold, and bold italic (or bold oblique). To be compatible with the broadest range of platforms and applications, it is strongly recommended that fonts limit use of Font Family name in this manner.For extended typographic families that includes fonts other than the four basic styles (regular, italic, bold, bold italic), it is strongly recommended that name IDs 16 and 17 be used in fonts to create an extended, typographic grouping. (See examples provided below.)It is also strongly recommended that applications support extended typographic-family groupings using name IDs 16 and 17. Note, in particular, that variable fonts can include a large number of named instances, each of which will use a shared typographic family name (name ID 16) and will have a typographic subfamily name (equivalent to name ID 17). Applications that assume a four-style family grouping based on name IDs 1 and 2 are likely to provide a poor user experience with variable fonts.For fonts within an extended typographic family that fall outside the basic four-way distinction, the distinguishing attributes should be reflected in the Font Family name so that those fonts appear as a separate font family. For example, the Font Family name for the Arial Narrow font is “Arial Narrow”; the Font Family name for the Arial Black font is “Arial Black”. Note that, in such cases, name ID 16 should also be included with a shared name that reflects the full, typographic family.
2 Font Subfamily name. The Font Subfamily name is used in combination with Font Family name (name ID 1), and distinguishes the fonts in a group with the same Font Family name. This should be used for style and weight variants only (as described below).This four-way distinction should also be reflected in the OS/2.fsSelection field, using bits 0 and 5. A font with no distinctive weight or style (e.g. medium weight, not italic, and OS/2.fsSelection bit 6 set) should use the string “Regular” as the Font Subfamily name (for English language).While some platforms or applications do not have this constraint, many existing applications that use this pair of names assume that a Font Family name is shared by at most four fonts that form a font style-linking group, and that Font Subfamily names would reflect one of the four basic styles, regular, italic (or oblique), bold, and bold italic (or bold oblique). To be compatible with the broadest range of platforms and applications, it is strongly recommended that fonts should limit use of Font Family in this manner.For extended typographic families that includes fonts other than the four basic styles (regular, italic, bold, bold italic), it is strongly recommended that name IDs 16 and 17 be used in fonts to create an extended, typographic grouping.Within an extended typographic family that includes fonts beyond regular, bold, italic, or bold italic, distinctions are made in the Font Family name, so that fonts appear to be in separate families. In some cases, this may lead to specifying a Subfamily name of “Regular” for a font that might not otherwise be considered a regular font. For example, the Arial Black font has a Font Family name of “Arial Black” and a Subfamily name of “Regular”. Note that, in such cases, name IDs 16 and 17 should also be included, using a shared value for name ID 16 that reflects the full typographic family, and values for name ID 17 that appropriately reflect the actual design variant of each font.
4 Full font name that reflects all family and relevant subfamily descriptors. The full font name is generally a combination of name IDs 1 and 2, or of name IDs 16 and 17, or a similar human-readable variant.For fonts in extended typographic families (that is, families that include more than regular, italic, bold, and bold italic variants), values for name IDs 1 and 2 are normally chosen to provide compatibility with certain applications that assume a family has at most four style-linked fonts. In that case, some fonts may end up with a Subfamily name (name ID 2) of “Regular” even though the font would not be considered, typographically, a regular font. For such non-regular fonts in which name ID 2 is specified as “Regular”, the “Regular” descriptor would generally be omitted from name ID 4. For example, the Arial Black font has a Font Family name (name ID 1) of “Arial Black” and a Subfamily name (name ID 2) of “Regular”, but has a full font name (name ID 4) of “Arial Black”. Note that name IDs 16 and 17 should also be included in these fonts, and that name ID 4 would typically be a combination of name IDs 16 and 17, without needing any additional qualifications regarding “Regular”.
6 PostScript name for the font; Name ID 6 specifies a string which is used to invoke a PostScript language font that corresponds to this OpenType font. When translated to ASCII, the name string must be no longer than 63 characters and restricted to the printable ASCII subset, codes 33 to 126, except for the 10 characters '[', ']', '(', ')', '{', '}', '<', '>', '/', '%'.In a CFF OpenType font, there is no requirement that this name be the same as the font name in the CFF’s Name INDEX. Thus, the same CFF may be shared among multiple font components in a Font Collection. See the 'name' table section of “Recommendations for OpenType fonts” for additional information.
16 Typographic Family name: The typographic family grouping doesn’t impose any constraints on the number of faces within it, in contrast with the 4-style family grouping (ID 1), which is present both for historical reasons and to express style linking groups. If name ID 16 is absent, then name ID 1 is considered to be the typographic family name. (In earlier versions of the specification, name ID 16 was known as “Preferred Family”.)
17 Typographic Subfamily name: This allows font designers to specify a subfamily name within the typographic family grouping. This string must be unique within a particular typographic family. If it is absent, then name ID 2 is considered to be the typographic subfamily name. (In earlier versions of the specification, name ID 17 was known as “Preferred Subfamily”.)
18 Compatible Full (Macintosh only); On the Macintosh, the menu name is constructed using the FOND resource. This usually matches the Full Name. If you want the name of the font to appear differently than the Full Name, you can insert the Compatible Full Name in ID 18.
20 PostScript CID findfont name; Its presence in a font means that the nameID 6 holds a PostScript font name that is meant to be used with the “composefont” invocation in order to invoke the font in a PostScript interpreter. See the definition of name ID 6.The value held in the name ID 20 string is interpreted as a PostScript font name that is meant to be used with the “findfont” invocation, in order to invoke the font in a PostScript interpreter.When translated to ASCII, this name string must be restricted to the printable ASCII subset, codes 33 through 126, except for the 10 characters: '[', ']', '(', ')', '{', '}', '<', '>', '/', '%'.See “Recommendations for OTF fonts” for additional information
21 WWS Family Name. Used to provide a WWS-conformant family name in case the entries for IDs 16 and 17 do not conform to the WWS model. (That is, in case the entry for ID 17 includes qualifiers for some attribute other than weight, width or slope.) If bit 8 of the fsSelection field is set, a WWS Family Name entry should not be needed and should not be included. Conversely, if an entry for this ID is included, bit 8 should not be set. (See OS/2.fsSelection field for details.) Examples of name ID 21: “Minion Pro Caption” and “Minion Pro Display”. (Name ID 16 would be “Minion Pro” for these examples.)
22 WWS Subfamily Name. Used in conjunction with ID 21, this ID provides a WWS-conformant subfamily name (reflecting only weight, width and slope attributes) in case the entries for IDs 16 and 17 do not conform to the WWS model. As in the case of ID 21, use of this ID should correlate inversely with bit 8 of the fsSelection field being set. Examples of name ID 22: “Semibold Italic”, “Bold Condensed”. (Name ID 17 could be “Semibold Italic Caption”, or “Bold Condensed Display”, for example.)
25 Variations PostScript Name Prefix. If present in a variable font, it may be used as the family prefix in the PostScript Name Generation for Variation Fonts algorithm. The character set is restricted to ASCII-range uppercase Latin letters, lowercase Latin letters, and digits. All name strings for name ID 25 within a font, when converted to ASCII, must be identical. See Adobe Technical Note #5902: “PostScript Name Generation for Variation Fonts” for reasons to include name ID 25 in a font, and for examples. For general information on OpenType Font Variations, see the chapter, OpenType Font Variations Overview.

https://glyphsapp.com/tutorials/naming is also a great explanation of this topic, and has section titled "WWS Names: Name IDs 21 and 22" that well explains:

create separate families with the non-normal names, and put those family names into ID 21, but keep all the weight, width and slope info in ID 22.

So, Name ID 22 is not only for RIBBI names, but for anything that falls into the weight, width or slope category, like Medium Extended Italic or Bold Condensed Oblique.

Family Name Subfamily (Style) Name WWS Family Name (ID 21) WWS Subfamily Name (ID 22)
MyFontFamily Display Light MyFontFamily Display Light
MyFontFamily Display Light Italic MyFontFamily Display Light Italic
MyFontFamily Display Medium Extended MyFontFamily Display Medium Extended
MyFontFamily Display Medium Extended Italic MyFontFamily Display Medium Extended Italic
MyFontFamily Display MyFontFamily Display Regular
MyFontFamily Display Italic MyFontFamily Display Italic
MyFontFamily Display Bold MyFontFamily Display Bold
MyFontFamily Display Bold Italic MyFontFamily Display Bold Italic
MyFontFamily Display Semibold MyFontFamily Display Semibold
MyFontFamily Display Semibold Italic MyFontFamily Display Semibold Italic

It also has these 2 important notes:

Note 1: Inclusion of IDs 21/22 should correlate exactly with the state of OS/2.fsSelection.bit8, if you know what that means. If you don’t, don’t worry, Glyphs takes care of this automatically.

Note 2: For a case like MyFontFamily Compressed, where the style name is purely expressible with WWS, name IDs 21/22 are not required, remember? But actually, the spec does not preclude including IDs 21 and 22, provided this fsSelection bit 8 is set. So if you feel like it and have a lot of time to kill, you can add them everywhere. But really, finish early and have an ice cream instead. If you want to take control of fsSelection bit 8 yourself, add the Has WWS Names parameter to your instance: According to the OpenType specification, this bit indicates that ‘the font has “name” table strings consistent with a weight/width/slope family without requiring use of “name” IDs 21 and 22.’ Keep in mind that this makes sense only if the naming of your font already adheres to the WWS scheme.

I note that WWS is (1) Weight, (2) Width, (3) Slope, not (1) Width, (2) Weight, (3) Slant, as I've seen it ordered/named.

If we do go with the second ordering, that might mean more work to map to MSOT/OFF systems, which seems undesirable.

@davelab6
Copy link
Member

davelab6 commented Oct 1, 2020

If also like to resolve #2701 as the spaces in the particles in my examples are a bit ambiguous.

@davelab6
Copy link
Member

davelab6 commented Oct 1, 2020

There's also some undocumented trick that @twardoch figured out to fix the ordering in Adobe apps

@anthrotype
Copy link
Member

Why do we need to impose a sigle order for the axes names to all google fonts? Can't the font developer decide this for each specific project at hand depending on whatever they think is more important? The ordering of the STAT table's DesignAxes should be enough, I think.

@anthrotype
Copy link
Member

See the AxisRecord.axisOrdering field:

for ordering of descriptors when composing family or face names

https://docs.microsoft.com/en-us/typography/opentype/spec/stat

@davelab6
Copy link
Member

davelab6 commented Oct 1, 2020

Why do we need to impose a single order for the axes names to all google fonts?

For generating static fonts from the list of fallback instances.

See the AxisRecord.axisOrdering field

We'll need to make sure that field matches our registry order. I'll file a fontbakery issuue.

@anthrotype
Copy link
Member

I understand this is for generating static fonts from VFs. What I don't understand is why we have to come up with an artificially general ordering for all the fonts in our library when font naming is, in my view, the responsibility of the font designer and specific to each font project. If that design intent is encoded in the font somewhere (e.g. the STAT axis records' ordering), then the fonttools instancer tool can use it to generate the instances names without needing access to an external, and GF-specific AxisRegistry database.
If we really want to enforce some standard ordering of the axes names (for reasons which I still don't quite understand), we could do for STAT with a fontbakery check, like you suggested.

@m4rc1e
Copy link
Collaborator Author

m4rc1e commented Oct 1, 2020

I understand this is for generating static fonts from VFs

This is my main concern. Imo axis particles should be ordered in a consistent manner when we instantiate static fonts. The existing statics we serve do have an explicit order so we shouldn't be breaking this.

@anthrotype
Copy link
Member

in a consistent manner

consistent with what? With the rest of the other fonts in GF library (i.e. there should be an enforced common ordering across all fonts)? Or consistent with the static fonts that are produced by the font developer alongside a VF (but not from it)?

@m4rc1e
Copy link
Collaborator Author

m4rc1e commented Oct 1, 2020

consistent with what? With the rest of the other fonts in GF library (i.e. there should be an enforced common ordering across all fonts)?

yes and there already is an enforced ordering. You won't ever see "familyName-ItalicBold.ttf", you'll always get "familyName-BoldItalic.ttf". Weight always appears before italic in our collection.

@twardoch
Copy link
Collaborator

twardoch commented Oct 1, 2020

Having worked or interacted wiith many hundreds of type designers (as part of my MyFonts and FontLab work), I can say that the vast majority prefers strong recommendations and will happily follow them.

There may be a handful who will want their own ordering, who are also willing to accept the risk that the font will not work very well on some environments. Most people will follow the publisher/distributor guide — this is the same realm as standardized glyph sets.

Axis ordering is not an area where type designers desperately want their creative freedom.

@twardoch
Copy link
Collaborator

twardoch commented Oct 1, 2020

As a general rule, type designers want freedom when it comes to “numbers”: point coordinates (i.e. the actual glyph design), widths & sidebearings, italic angle, x/caps height, kerning, total line height.

Then, they'll also want some freedom in forming collections: glyph repertoire (beyond minimal sets), kerning class composition, number of OT features.

But they prefer recommendations in anything beyond, esp. font names (except the family name), licenses, glyph names, ways to order items within the said collections, and pretty much everything that influence that their font may work “better” vs. “worse” in existing apps & OSes.

@anthrotype
Copy link
Member

Ok fair enough. I just want to insist that whatever the publisher's recommended ordering, it should be encoded in STAT and the instancer should look at that only, not to an external vendor-specific Axis Registry. If the STAT ordering doesn't match the expected order, it should be fixed in the source, rather than discarded/overwritten.

@twardoch
Copy link
Collaborator

twardoch commented Oct 1, 2020

That's a “management issue”. I mean the question at what level a problem should be fixed. ☺️ But I agree that the earlier (closer to source) the better. Higher-quality sources always mean that less can go wrong on the way.

@twardoch
Copy link
Collaborator

twardoch commented Oct 1, 2020

The really important question is: should wght or wdth come earlier.

Tradition dictates: wght (so: Bold Condensed). That's Adobe-made tradition, which is actually recommended somewhere (I can dig it up).

But the more advanced Adobe tradition for their Pro fonts is "wght wdth ital opsz" (Minion Pro Bold Condensed Italic Caption). Or is it wght wdth opsz ital? Need to check.

In my view, the opposite ordering would be better, because the ordering of particles should guide the user in first separating fonts that you don't mix within the same line, and then leading you to choices where you can combine fonts within a line.

  • opsz is for very different sizes
  • wdth works best of it's the same within the same like or paragraph
  • wght is quite freely mixable within one line or paragraph but still makes a visual disturbance if changed
  • ital is very mixable within one line or paragraph, even for a a single-letter word

Another way of expressing that is that the trait that changes the geometry and color of the entire text more should be ordered earlier.

Not sure how GF currently does it — but I think we should either follow the old Adobe tradition OR adopt a new one (like the one I outlined). Whatever we do (be it as enforcement or recommendation) will impact other makers, so this is a sort of industry-wide decision.

Opinions?

@twardoch
Copy link
Collaborator

twardoch commented Oct 1, 2020

One more approach would be to adopt the general principle I described, but make the exception as a nod to the prevailing tradition, and sort wdth after wght, not before. So: opsz wght wdth ital — and use the “principle” for any axes beyond.

@thlinard
Copy link
Contributor

thlinard commented Oct 1, 2020

But the more advanced Adobe tradition for their Pro fonts is "wght wdth ital opsz" (Minion Pro Bold Condensed Italic Caption). Or is it wght wdth opsz ital? Need to check.

Minion (one big family): Minion Pro, Semibold Cond Italic Display
Minion 3 (4 optical families): Minion 3 Display, Semibold Italic
Minion Variable Concept: Minion Variable Concept, Display Semibold Italic
Myriad Pro: Myriad Pro, Semibold Condensed Italic
Myriad Variable Concept: Myriad Variable Concept, Semibold Condensed Italic

@tiroj
Copy link

tiroj commented Oct 1, 2020

Not sure whether this is relevant, but putting weight and italic axes last makes it convenient to generate name ID 1 and 2 style families consistent with naming of larger family and style groupings.

@arrowtype
Copy link
Collaborator

arrowtype commented Oct 13, 2020

“Purpose” should be higher in the hierarchy, probably second only to the primary family name.

The purpose of a font determines so much about whether a designer should even bother reaching for it; all other considerations of specific styles come after that. Basically, the “Purpose” is a logical sub-family.

For example, Recursive Mono Casual SemiBold is useful in monospace settings. It is not particularly interchangeable for settings which call for proportional type, e.g. Recursive Sans Casual SemiBold.

As another example, stencil fonts are common sibling families to other fonts. But, they are often not really compatible for the same contexts/purposes as their non-stencil counterparts. So, House Industries’ Eames Stencil is basically a separate subfamily from the rest of the Eames collection. Typotheque sets Stencil fonts as separate families, even with systems, e.g. Noctorno Stencil, and within that there are multiple weights. Same for H&Co Peristyle.

Yet another example is Commerical Types Dala family, which has two stencil families (Dala Floda is a serif, while Dala Moa is a Sans), plus a multi-line family, Dala Prisma.

Or, perhaps, this is missing “Category” as a category

Perhaps, “Monospace” is misplaced under “Purpose,” if “Category” and “Purpose” are separate ideas.

“Monospace” and “Stencil” could be called font categories, similar to “Sans” and “Serif.”

When considered like this, it is pretty clear that those terms should immediately follow the primary family name.

And, maybe “Purpose” means something else, such as whether a particularly style is meant for screen/print media or light/dark backgrounds. Then again, often these purposes would still be useful to sort earlier in the decision tree, for less-noisy font menus, so I’m still unsure that putting these close to the end is best.

@felipesanches
Copy link
Collaborator

This is the current status of the STAT table axis ordering on the entire Google Fonts collection:

Captura de Tela 2020-10-23 às 02 46 31

@davelab6
Copy link
Member

I agree i misplaced Monospace. Category seems like a synonym for opinion :)

@arrowtype
Copy link
Collaborator

I suppose if we find it important to map to that grammatical structure, then that might be a way to do it.

One layer of complexity:

A font could contain multiple terms within one name level. For example, there may be a hierarchy within categories (or maybe these are "opinion" or "shape"): Serif / sans-serif / Script would usually come before Monospace / Stencil, as the latter could be maybe layered by onto the former. E.g. there could be a Futura Serif Mono, or a Recursive Script Stencil. I don't think Futura Mono Serif or Recursive Stencil Script make quite as much intuitive sense.

Or maybe "stencil" is a shape name. It isn't so dissimilar from Casual/Linear. In this case, however, it may also need hierarchy within the Shape tier.

Also...

I think opsz may be a "purpose" name. For Recursive, it would make sense to have "Recursive Mono Casual 144pt," but not as much to have "Recursive Mono 144pt Casual", as your first ranking suggested, davelab6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants