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

Update font metadata #11

Open
probonopd opened this issue May 2, 2020 · 25 comments
Open

Update font metadata #11

probonopd opened this issue May 2, 2020 · 25 comments

Comments

@probonopd
Copy link
Owner

probonopd commented May 2, 2020

http://designwithfontforge.com/en-US/Font_Info_&_Metadata.html contains a section on Font Info & Metadata.

Unfortunately this does not explain what to put where. Many fields, little explanation...

It would be worthwhile to have a pragmatic explanation what to put into which field, from today's "industry best practice" perspective. See below for some questions that may come to mind when being confronted with this dialog for the first time.

@probonopd
Copy link
Owner Author

Font formats seem to be an arcane world, somehow coming straight from the 80s... OS/2 in 2020, and it's apparently still important?

@probonopd
Copy link
Owner Author

probonopd commented May 3, 2020

Looking for a straightforward, concise description of the many different "name" keys and how they all work together to e.g., get font families recognized correctly. I am assuming there must be some best practices for this.

Say we have "Leutkirch Sans Light". Where do we need to put it as "Leutkirch", where as "Leutkirch Sans", where as "LeutkirchSans", where to put the Light (and where not), when to use a "-" as part of the name, etc.

Another point of confusion is whether to include the terms "Roman" (=non-italic, non-oblique) and "Regular" (=non-bold, non-light) in which names.

With Bold, it gets even more complex. Where to put the word "Bold", is it part of the title (name) or is it a property of the font (like what is known today as a "tag")? What about "Semi Bold" (or is it "SemiBold"?) then? (Most text processing applications have buttons for italic, bold, bold italic but not for e.g. light, semi bold, etc. - is this a leftover from the early 80s? What good is it for? Why hasn't it been eliminated a long time ago? Does clicking the "bold" button do the same thing as selecting the font which has "Bold" as part of its name? Is this consistent for all fonts or is the answer still "it depends"?)

In which cases does "Demi" have to be used instead of "Semibold"? Is there an authoritative lookup table of such equivalent names?

Then there is abbreviations. In some places you will find "Bold Italic", in some places "BoldItalic", and in some places "BolIta". What goes where and how do we know? Is "Light" supposed to be abbreviated as "Lt" or "Lig"? Is Italic supposed to be "It" or "Ita"? Why does e.g., Adobe use "SourceSerifPro-SemiboldIt.otf" where one is a very long unabbreviated word and the other is abbreviated?

Then there is capitalization. Is it "SemiBold" or "Semibold"? "Extralight" or "ExtraLight"?

Then there is numbers that are supposed to describe weight. The Frutiger numbering system ("55", "65",...), the Linotype numbering system - these are apparently part of the font name rather than metadata. And there is metadata for the same thing, usually three-digit ints (400, 600,..) - these are apparently not part of the font name but metadata.

Also, sometimes the font foundry name seems to sneak into font names, but also in an apparently inconsistent way. There is "Univers LT 55 Oblique" and "Univers 56 Oblique" (with and without "LT" which probably is meant to stand for "Linotype").

Is there a clear definite description, ideally one that covers both otf and ttf as it is used (and as is best practice) today (as opposed to the days when OS/2 was still a thing)?

FontLab seem to have invented their own terminology (PSN | TFN | TSN | SGN | SLN) which makes things even more complex since their terminology is not part of neither what UFO3 nor Adobe are using.

The whole situation seems to be such a huge mess (legacy, or "technical debt", piled up over decades) that one needs long-winded threads that are started out of noble intentions but are so confusing that you don't even want to start reading them.

To make this pragmatic, what exactly do we need to put into all the values that have "name" as part of their keys?

me@host:~/font-leutkirch$ cat source/SeN-CL.ufo/fontinfo.plist | grep -i name | cut -d ">" -f 2 | cut -d "<" -f 1
familyName
styleName
styleMapFamilyName
styleMapStyleName
openTypeNameVersion
openTypeNameUniqueID
openTypeNamePreferredFamilyName
openTypeNamePreferredSubfamilyName
postscriptFontName
postscriptFullName
postscriptWeightName

@probonopd
Copy link
Owner Author

probonopd commented May 3, 2020

Saying "best practice" probably means looking at how Adobe is doing things.

Unfortunately, they seem not to be working from UFO3 (which appears to be the emerging standard for open source based workflows) but their own set of tools.

Especially relevant seems to be FontMenuNameDB. Here is the example for Source Serif Pro.

Seemingly that file only covers a fraction of the whole naming complexity, with other parts of the metadata coming in from other files with no immediately visible relationship between them.

How does this translate to the fields in UFO3?

@probonopd
Copy link
Owner Author

probonopd commented May 3, 2020

Right now we have:

me@host:~/font-leutkirch$ grep -r styleName -C 2

source/SeN-CM.ufo/fontinfo.plist-    <key>familyName</key>
source/SeN-CM.ufo/fontinfo.plist-    <string>LeutkirchSans CM</string>
source/SeN-CM.ufo/fontinfo.plist:    <key>styleName</key>
source/SeN-CM.ufo/fontinfo.plist-    <string>CM</string>
source/SeN-CM.ufo/fontinfo.plist-    <key>styleMapFamilyName</key>
--
source/SeN-CL.ufo/fontinfo.plist-    <key>familyName</key>
source/SeN-CL.ufo/fontinfo.plist-    <string>LeutkirchSans CL</string>
source/SeN-CL.ufo/fontinfo.plist:    <key>styleName</key>
source/SeN-CL.ufo/fontinfo.plist-    <string>CL</string>
source/SeN-CL.ufo/fontinfo.plist-    <key>styleMapFamilyName</key>
--
source/SeN-CEB.ufo/fontinfo.plist-    <key>familyName</key>
source/SeN-CEB.ufo/fontinfo.plist-    <string>LeutkirchSans CEB</string>
source/SeN-CEB.ufo/fontinfo.plist:    <key>styleName</key>
source/SeN-CEB.ufo/fontinfo.plist-    <string>CEB</string>
source/SeN-CEB.ufo/fontinfo.plist-    <key>styleMapFamilyName</key>
--
source/SeN-CBL.ufo/fontinfo.plist-    <key>familyName</key>
source/SeN-CBL.ufo/fontinfo.plist-    <string>LeutkirchSans CBL</string>
source/SeN-CBL.ufo/fontinfo.plist:    <key>styleName</key>
source/SeN-CBL.ufo/fontinfo.plist-    <string>CBL</string>
source/SeN-CBL.ufo/fontinfo.plist-    <key>styleMapFamilyName</key>
--
source/SeN-CB.ufo/fontinfo.plist-    <key>familyName</key>
source/SeN-CB.ufo/fontinfo.plist-    <string>LeutkirchSans CB</string>
source/SeN-CB.ufo/fontinfo.plist:    <key>styleName</key>
source/SeN-CB.ufo/fontinfo.plist-    <string>CB</string>
source/SeN-CB.ufo/fontinfo.plist-    <key>styleMapFamilyName</key>

Which seems to be different from what most fonts are using. Hence the quest to find out what to put into which UFO3 fields according to "industry best practice".

@probonopd
Copy link
Owner Author

probonopd commented May 3, 2020

Here is what Adobe is using, based on SourceSerifPro-SemiboldIt.otf opened in FontForge:

adobe1

adobe2

This is what FontForge converts this to when exported as UFO3:

    <key>familyName</key>
    <string>Source Serif Pro</string>

    <key>styleName</key>
    <string>SemiboldIt</string>

    <key>styleMapFamilyName</key>
    <string>Source Serif Pro Semibold Italic</string>

    <key>styleMapStyleName</key>
    <string>italic</string>

    <key>openTypeNameVersion</key>
    <string>Version 3.001;hotconv 1.0.111;makeotfexe 2.5.65597</string>

    <key>openTypeNameUniqueID</key>
    <string>3.001;ADBO;SourceSerifPro-SemiboldIt;ADOBE</string>

    <key>openTypeNamePreferredFamilyName</key>
    <string>Source Serif Pro</string>

    <key>openTypeNamePreferredSubfamilyName</key>
    <string>Semibold Italic</string>

    <key>postscriptFontName</key>
    <string>SourceSerifPro-SemiboldIt</string>

    <key>postscriptFullName</key>
    <string>Source Serif Pro Semibold Italic</string>

    <key>postscriptWeightName</key>
    <string>Demi</string>

Can we assume this to be "industry best practice"?

@probonopd
Copy link
Owner Author

probonopd commented May 3, 2020

To be pragmatic, here is a table with what I could figure out so far (please double-check!) and what I am struggling with. Maybe this is useful for other font projects wondering the same things, too.

UFO3 field CL CM CB CEB CBL
familyName Leutkirch Sans Leutkirch Sans Leutkirch Sans Leutkirch Sans Leutkirch Sans
styleName Light ?
Question 1 below
Bold ?
Question 2 below
Black
styleMapFamilyName Leutkirch Sans Light ?
Question 3 below
Leutkirch Sans Bold ?
Question 4 below
Leutkirch Sans Black
styleMapStyleName
Question 5 below
? ? ? ? ?
openTypeNameVersion
Question 6 below
? ? ? ? ?
openTypeNameUniqueID
Question 7 below
? ? ? ? ?
openTypeNamePreferredFamilyName
Question 8 below
Leutkirch Sans Leutkirch Sans Leutkirch Sans Leutkirch Sans Leutkirch Sans
openTypeNamePreferredSubfamilyName
Question 9 below
? ? ? ? ?
postscriptFontName
Question 10 below
LeutkirchSans-Light ? LeutkirchSans-Bold ? LeutkirchSans-Black
postscriptFullName
Question 11 below
Leutkirch Sans Light ? Leutkirch Sans Bold ? Leutkirch Sans Black
postscriptWeightName
Question 12 below
? ? ? ? ?

Question 1

Which one is industry best practice and why?

  • Book
  • Medium
  • Regular

Question 2

  • Extra Bold
  • Extrabold
  • ExtraBold

Note that in the case of Source Serif Pro Semibold Italic, styleName has SemiboldIt. Is there industry best practice for what gets abbreviated and how? Is there any technical need to abbreviate anything anymore nowadays?

Question 3

Which one is industry best practice and why?

  • Leutkirch Sans
  • Leutkirch Sans Normal
  • Leutkirch Sans Regular
  • Leutkirch Sans Roman

Question 4

Which is industry best practice and why?

  • Leutkirch Sans ExtraBold
  • Leutkirch Sans Extrabold
  • Leutkirch Sans Extra Bold

Question 5

What to put here? Source Serif Pro Semibold Italic has just italic there.

Question 6

Should openTypeNameVersion be auto-populated by the tools being used?

Question 7

Should openTypeNameUniqueID be auto-populated by the tools being used?

Question 8

Should openTypeNamePreferredFamilyName be the same as familyName nowadays? In which cases should they be different?

Question 9

Should openTypeNamePreferredSubfamilyName be the same as styleName nowadays? In which cases should they be different? Note that in the case of Source Serif Pro Semibold Italic, openTypeNamePreferredSubfamilyName has "Semibold Italic" whereas styleName has SemiboldIt

Question 10

Should postscriptFontName always be constructed by taking familyName, replacing " " with "_", appending "-", appending styleName?

Question 11

Should postscriptFullName always be the same as styleMapFamilyName?

Question 12

Apparently postscriptWeightName expects different names than openTypeNamePreferredSubfamilyName. Note that in the case of Source Serif Pro Semibold Italic, postscriptWeightName has "Demi". Is there a lookup table to know what is expected here?

@ctrlcctrlv
Copy link

Let me try to answer your questions:

First of all, you are using UFO conventions, so please see http://unifiedfontobject.org/versions/ufo3/fontinfo.plist/ , e.g. section "Name Record Format" and then https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids to match the IDs there to see what the spec actually says about each.

Q1

(OT Name ID 17)

It is wrong to think of there as being an "industry best practice" for this. Medium and Regular are typographically different, a font can have both a Regular weight and a Medium weight, or both a Book and Regular. I'd go with Regular, but there's no wrong answer here.

Q2

(OT Name ID 17)

"Extra Bold" is best. There is no need to abbreviate anything. When you see abbreviations or lack of spaces, you are almost always seeing some intermediary program just getting them from the PostScript font name, which had limitations. These limitations are usually still respected, as ancient programs choke on them, but actually the format has evolved to the point where they ought to be relaxed from errors to warnings as many foundries, especially CJK ones, ignore them. See fontforge/fontforge#3941.

Q3

(OT Name ID 1)

Name IDs 1 and 2 are used to inform more basic programs, especially word processors, et cetera, of which of the four "regular", "bold", "italic", or "bold italic" your font corresponds to.

See e.g. https://robofont.com/documentation/how-tos/setting-font-names/#2-style-linked-sub-families for a good example:

    MyFamily
    ├── Regular
    ├── Italic
    ├── Bold
    └── Bold Italic

    MyFamily Light
    ├── Regular
    └── Italic

    MyFamily Black
    ├── Regular
    └── Italic

So, the correct answer is, it depends on how many styles there are. If you have only two, a bold and a regular, correct answer is Leutkirch Sans. You should lay out your font styles like above...if you have a light, it must be Leutkirch Sans Light.

Q4

(OT Name ID 1)

Leutkirch Sans Extra Bold

Q5

(OT Name ID 2)

Yes. It should be, for maximum compatibility, always one of regular, italic, bold, or bold italic, regardless of whether the font is Light or Extrabold.

Q6

(OT Name ID 5)

Yes and no. You should provide a version for your fonts, but tools often populate extra information. String must always begin with e.g. Version 99.0, but may have a semicolon followed by any other version info, I believe ttfautohint and fontlint put their version info here?

Q7

(OT Name ID 3)

The story of this UniqueID and XUID is very frustrating. Both fields are essentially junk now, no serious tools use it. See Yannis Haralambous, Fonts & Encodings, p. 658–659 for a treatment of this subject. XUID "organization IDs" were assigned by Adobe, but as of 2016 Adobe recommends against using them.

Auto-population is therefore fine, but these fields shouldn't be relied on to be unique. See Q10 for what should be relied on instead.

Q8

(OT Name ID 16)

Yes, although UFO specification is agnostic.

Q9

(OT Name ID 17)

Abbreviation certainly has same cause as Q2. They shouldn't ever need to be different, just Adobe's tools sometimes favor the PostScript name as it's not out-of-spec to do so.

Q10

(OT Name ID 6)

No, not always, but most of the time. To-spec PostScript font names cannot contain Unicode, but many CJK fonts have Unicode names. So, they often have an OT 16 like 예 산세 리프 but a PostScript name like YeSans-Regular.

PostScript font names should always be unique, in many modern systems, the PS font name serves the purpose the defunct XUID/UID used to serve. Apple cautions:

If two fonts are installed with the same PostScript name, OS X treats them as duplicates and only one will be available for use.

Fontconfig, AFAIK, does the same.

Q11

(CFF /FullName)

No, it should be the same as openTypeNamePreferredFamilyName plus openTypeNamePreferredSubfamilyName, which should be the same as familyName and styleName. The UFO specification provides that if it's missing, that's how it ought to be made, and there is no reason I know of to deviate from this.

Q12

(CFF /Weight)

The reason it might be different is that it's in sync with OS/2 openTypeOS2WeightClass, but that's an integer. See for example "OS/2 Weight Class" names in FontForge, compared to the OpenType spec's names, they are slightly different capitalization, one has parenthesis and the other doesn't, and so on.

So, the UFO3 spec is saying to put a string "in sync" with an integer, which is a bit absurd and probably a spec bug.

Since this field is so old, it can literally contain anything. I'd match it up to the strings FontForge uses, and assume most programs will prefer OT ID 17 over it.

@probonopd
Copy link
Owner Author

probonopd commented May 3, 2020

Thanks a ton @ctrlcctrlv - this is really helpful.

So this is what I will go with. Turns out to be way more orderly than what I had anticipated.

UFO3 field CL CM CB CEB CBL
familyName Leutkirch Sans Leutkirch Sans Leutkirch Sans Leutkirch Sans Leutkirch Sans
styleName Light Regular Bold Extra Bold Black
styleMapFamilyName Leutkirch Sans Light Leutkirch Sans Leutkirch Sans Leutkirch Sans Extra Bold Leutkirch Sans Black
styleMapStyleName regular regular bold bold bold
openTypeNameVersion Version 0.1 Version 0.1 Version 0.1 Version 0.1 Version 0.1
openTypeNameUniqueID Leutkirch Sans Light Leutkirch Sans Regular Leutkirch Sans Bold Leutkirch Sans Extra Bold Leutkirch Sans Black
openTypeNamePreferredFamilyName Leutkirch Sans Leutkirch Sans Leutkirch Sans Leutkirch Sans Leutkirch Sans
openTypeNamePreferredSubfamilyName Light Regular Bold Extra Bold Black
postscriptFontName LeutkirchSans-Light LeutkirchSans-Regular LeutkirchSans-Bold LeutkirchSans-ExtraBold LeutkirchSans-Black
postscriptFullName Leutkirch Sans Light Leutkirch Sans Regular Leutkirch Sans Bold Leutkirch Sans Extra Bold Leutkirch Sans Black
postscriptWeightName Light Regular Bold Extra Bold Black

Again, thanks for your help.

Anyone, please comment in this ticket if you think I did not follow best practices anywhere.

@probonopd probonopd removed the help wanted Extra attention is needed label May 3, 2020
@nim-nim
Copy link

nim-nim commented May 5, 2020

Saying "best practice" probably means looking at how Adobe is doing things.

Best practice means reading the OpenType spec and applying strictly all its recommendations.

Anyway, here is a short summary. It all starts by defining clean target font family and font style values.

  1. choose a font family name free of usual font keywords. For example Black/Heavy are weight keywords, it’s a real bad idea to name a family that includes those.

GOOD:

  • Foo

BAD:

  • Play Book
  • Darker Black
  • So Heavy

LESS BAD (but probably breaks somewhere):

  • Heavy Metal

Microsoft listed quite a lot of those in their key WPF whitepaper, that served as base for later OpenType spec evolutions

https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/02/24/90/36/WPF%20Font%20Selection%20Model.pdf

All the design of name ID 21 & 22 and later of CSS4 font attributes and the default variable OpenType axes can be traced to the analysis detailed in this document.

  1. limit your styles to Width Weight Slant differences. If you need other variations, start a new font family.

Width Weight Slant correspond to the default OpenType variable axes. Any other kind of style variation won’t map correctly to variable font naming.

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

If you feel adventurous, you can play with optical sizing (the 4th default variable axis). But, it is so new and badly defined even OpenType spec authors admit they only included it in the hope some clear conventions would emerge.

  1. write your styles as Width Weight Slant space-separated keyword triplets. That’s the only ordering compatible with OpenType Name ID 1 & 2 legacy limitations.

GOOD:

  • Condensed Bold Italic

BAD:

  • Bold Condensed

See also
https://docs.microsoft.com/fr-ca/typography/opentype/spec/namesmp

  1. By convention, default Width Weight Slant values are not stated in style, except when they are all the default value. In that case you use the magic Regular default style.

GOOD:

  • Condensed Bold Italic
  • Condensed Italic
  • Bold
  • Regular

BAD:

  • Condensed Regular Italic
  • Regular Italic
  • Normal (not used in real fonts, even though it appears instead of Regular in some documents)
  1. When your Width Weight Slant values approximate standard values, use the official OpenType/CSS keyword, do not invent another one, do not refer to obscure Renaissance practices no one cares about nowadays.

https://www.w3.org/TR/css-fonts-4/#font-stretch-prop
https://www.w3.org/TR/css-fonts-4/#font-weight-prop
https://www.w3.org/TR/css-fonts-4/#font-style-prop
https://docs.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass
https://docs.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass

GOOD:

  • Condensed

BAD:

  • Narrow

(Arial Narrow antedates modern Width conventions & specifications.)

  1. Conversely, if you do need a Width Weigth Slant value different from the ones defined in the spec, do use a non-standard keyword, do not repurpose a standard keyword to mean something else.

  2. Use Cased keywords without spaces, ie SemiBold not Semi Bold. The W3C missed the boat here, they cleaned up the wording of the OpenType spec nicely in CSS, except here.

SemiBold seems more common than DemiBold or Semi-Bold

Contrary to what @ctrlcctrlv wrote using spaces in style keywords badly breaks software that attempts to read and understand your style values. The Microsoft WPF whitepaper details the level of complexity induced by non regular style naming. It’s a fascinating (if sick) read, if you are interested in this kind of thing.

Once you have a clean target family/style pair you can put them in Name ID 16 & 17 and derive all the other Name IDs from those following the rules set down in
https://docs.microsoft.com/en-us/typography/opentype/otspec182/name#name-ids

For example:

  • Name ID 4 (full name) should be constructed as Name ID 16 (family) space Name ID 17 (style), except when style = Regular in which case Regular is omitted from full name the same way it is omitted from style except when needed to avoid an empty string

  • Name ID 1 & 2 are the same thing as Name ID 16 & 17, except that back when they were defined styles were limited to RBBI. So for any style that matches RBBI, Name ID 1 & 2 = Name ID 16 & 17, and for others, you only keep the RBBI parts of Name ID 17 in Name ID 2, and move the rest to the end of Name ID 1. If everything moves to Name ID 1, Name ID 2 becomes Regular the usual way to avoid an empty string.

    That‘s why the Width Weight Slant ordering matters, it’s the only way to get a Name ID 4 (full name) that matches both Name ID 1 & 2 and Name ID 16 & 17, and keep some consistency between apps that read Name ID 1 & 2, apps that read Name ID 4, and apps that read ID 16 & 17.

    https://docs.microsoft.com/fr-ca/typography/opentype/spec/namesmp
    showcases that backwards compatibility naming mechanism.

  • Name ID 21 & 22 are a way to patch Name ID 16 & 17 when you made mistakes here in the past (it’s a spec correction because some font makers invented lots of stupid things in Name ID 17, that broke font-using apps. Name ID 21 & 22 are Name ID 16 & 17 with sanity rules added. You do not need those if you are careful in the naming you use in 16 & 17).

  • PostScript did not allow spaces in naming and had other character limitations (Times New Roman would not have been possible in PostScript). Nowadays Name ID 6 is a transliteration of Name ID 4, replacing spaces with hyphens, and replacing non-ASCII symbols with the closest ASCII approximations

And so on. The OpenType spec is pretty thorough on how each naming layer is constructed, as long as you remember that in OpenType speak “it would be nice to” means “you should really really do this unless you want to break apps”, and the spec was amended for a long time (for example Name ID 4 rules forget to state relationship to Name ID 21 & 22, because those were added later. You need to remember that the part of the spec that states 21 & 22 are the same thing than 16 & 17, means that every time you saw 16 & 17 in the rest of the spec, that means 16 & 17 or 21 & 22 if defined).

@nim-nim
Copy link

nim-nim commented May 5, 2020

Also, for a long time you could put whatever garbage you wanted as width or weight numeric values, apps mostly ignored those.

That changes with the introduction of OpenType variable axes. The values are actually used to coordinate the various styles, and take precedence over the style namings (because, variable fonts permit more width weight slant values than previous OpenType formats, so it was not possible anymore to restrict processing to standard style keywords).

That‘s why CSS4 dropped the rounding of standard keywords to specific values (as was done before).

To quote the specification of the OpenType variable weight axis:

The Width axis can be used as a variation axis within a variable font. It can also be used within a STAT table in non-variable fonts within a family that has width variants to provide a complete characterization of a font in relation to its family within the STAT table.

Variable numeric axis values can also be set in non variable OpenType font (in the usual euphemistic way the spec is written, that means you bloody well should set those if you can, even in non variable fonts).

And that continues with

The Width axis uses a scale that correlates with but is different from the scale used for the usWidthClass field of the OS/2 table.

Translation: and you should bloody well make sure the values set in OS/2 tables are consistent with the values you set or someone else will eventually set in STAT, before things break.

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

Other variable axes definitions contain similar wording in the spec.

@ctrlcctrlv
Copy link

The WPF whitepaper is not the standard. OT 17 shouldn't be "read and understood"...just sorted according to OS/2 value.

@probonopd
Copy link
Owner Author

probonopd commented May 5, 2020

Thank you very much for your detailed answers everyone - turns out what I hoped were questions with straightforward answers is really a complex can of worms.

Maybe it would really be worth a chapter in the "Design with FontForge" book, fontforge/designwithfontforge.com#202.

@nim-nim
Copy link

nim-nim commented May 6, 2020

The WPF whitepaper is not the standard.

Of course it is not the standard. It’s a research paper written by the Microsoft fonts team. However Microsoft are co-editors of the Opentype spec, and they apply everything they learn in research to the spec. A lot of later (now current) OpenType spec changes can not be understood without reading this whitepaper. 80% of what’s in OpenType variable axes today is the clear continuation of WWS (making WWS continuous axes, not discrete values) and the WPF whitepaper explains WWS objectives much better than the short paragraphs that ended up in the spec.

The remaining default variable axis, optical sizing, can not be traced to the WPF whitepaper, and (surprise!), it’s a thorough mess right now.

OT 17 shouldn't be "read and understood"...just sorted according to OS/2 value.

Except apps do need to read style:

  • a large pool of existing fonts have garbage in their OS/2 values (easy to understand: font maker customers see the style names in font lists, they do not see the OS/2 values, it’s easier to sneak defects in the OS/2 layer without the customer understanding why the font behaves in strange way in apps, and to blame the app side for its “bugs”).

  • the whole CSS pre-variable font mechanism asks users to select fonts using style keywords (and, it is mightily inconvenient for users when those do not match what the font file declared in its naming layers).

  • free desktop side (Linux/Android), the font management layer, fontconfig, will generate weight values from style naming values, not the reverse (that will need changing to properly support variable fonts; it WILL expose a lot of previously work-arounded OS/2 metadata errors in existing font files)

  • the whole WPF whitepaper, is a thoroughly documented testament to the lengths apps will go to try to parse style names

  • OpenType even added Name ID 21 & 22 to force font makers to produce parseable style names, and remove the usual font maker excuse of “already made the mistake, too late to change anything without breaking existing userbase” (generic argument to refuse to fix anything since any fix, to provide value, will change something). Some font makers were even putting song verses in Name ID 17 to defend their inalienable “right” to produce garbage font metadata! Thus the official OpenType spec compromise is “if you insist on putting non-standard unparseable strings in Name ID 16 & 17, you get to add clean parseable strings in Name ID 21 & 22” (and apps that care about parseable regular naming, ie most real-world apps, will just ignore your funky Name ID 16 & 17 in that case).

I’m pretty sure that one key reason Microsoft invested in variable fonts in the OpenType spec, is that variable fonts can not work without clean metadata in font files, so even if variable fonts remain marginal app side (as is the case today), they are forcing font makers to clean up their act both regarding numeric metadata values, and string naming metadata values. Without the first, you can not select an arbitrary point on the variable axis. Without the second, transition from traditional non variable font names to variable instance names breaks.

Microsoft is historically an app company. Their contributions to the OpenType spec always aim first and foremost to make fonts files useful to the apps that are the company moneymaker. The other OpenType key editor, Adobe, has a thriving font business, and will care a lot less about the app side. They are as ready to earn money with app-unfriendly font files as the next font maker. They will accept to do very strange things in their own apps (things that the average app author will never do) to avoid fixing the font files they already sold in the past.

@ctrlcctrlv
Copy link

You're right about one thing, OT name IDs 21 & 22 are stricter.

And it is genuinely useful to have them.

That doesn't mean you're right about the conventions around OT ID 17.

@ctrlcctrlv
Copy link

By the way, Microsoft's own documentation reads, for ID 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.)

I understand your frustrations with the format. How could I not, I contribute to FontForge. But you're simply wrong that it's invalid to have spaces there...

@nim-nim
Copy link

nim-nim commented May 7, 2020

@ctrlcctrlv I'm not stating that Name ID 17 (or Name ID 22) can not have spaces, I am stating that the Width Weight Slant keywords in Name ID 17 (or Name ID 22) should not have spaces. The keywords are themselves space-separated.

None of the spec canonical “good” examples use keywords with spaces. Be it in the text you quoted, in https://docs.microsoft.com/fr-ca/typography/opentype/spec/namesmp, or elsewhere.

Name ID 17 was initially very weakly specified, because its initial objective was to lift the limitations of Name ID 2. So, it started with “Name ID 2, without constrains”. The spec authors could not imagine at that time how font makers would take advantage of the “without constrains” bit to invent app-breaking ID 17 strings (remember, pre ID 17 world was RBBI, no room for garbage here).

When Microsoft actually tried to use ID 17 in its apps, and audited the vast pool of font files out there, they had a “what were they thinking” moment. And then they proceeded to add ID 21 22 to the spec, and published the WPF whitepaper to detail with actual parser algorithms why free-for-all ID 17 did not work for apps in practice, and needed fixing (either directly in ID 17 or indirectly via ID 22). I also strongly suspect that Adobe was among the pro-eminents font makers that had produced app-breaking font files, and ID 22 was invented to avoid embarrassing Adobe. Otherwise Adobe customers could have complained Adobe had sold them non-compliant OpenType files.

That’s why the spec is very elliptic on WWS and name ID 17 & 22, and the WPF whitepaper serves as main documentation here. That is also probably one reason Microsoft Office is still stuck in RBBI land.

Franckly, I don’t understand why you’re insisting here that Name ID 17s that contain spaces in their Width Weight Slant keywords are “right”:

I know that many people font maker side took it bad when Microsoft stated they were doing it wrong and amended the OpenType spec to add WWS restrictions, but let’s stop being childish here, @probonopd asked for best practices, not loopholes that can be used to justify producing broken font files. The specified best practice in the OpenType spec is WWS, both in the spec wording, and in the spec examples. And, even if the spec had not written it down, OpenType variable formats use WWS as default axes, so non WWS naming will not transition to OpenType variable.

(Again, excepting Optical Sizing, which is not a WWS concept, and is woefully under-specified, be it in the spec or elsewhere).

@probonopd
Copy link
Owner Author

probonopd commented May 7, 2020

OTM Light has a Consistency Checker which complains about this font:

consistency

These are the different messages that can be produced with the OTF Light Consistency Checker and which should possibly be considered when writing the "industry best practice" guide on font name metadata:

  • The Font Subfamily name distiguishes the font in a group with the same Font Family name (name ID 1). This is assumed to address style (italic, oblique) and weight (light, bold, black, etc.). A font with no particular differences in weight or style should have the string "Regular" stored in this position.
  • No OTF guideline information available about Font Subfamily names with Platform ID/Language ID other than 3/1033 (Microsoft, English (American)) or 1/0 (Macintosh, English).
  • The Full font name should be a combination of strings 1 and 2. - Exception 1: if the font is "Regular" as indicated in string 2, then use only the family name contained in string 1. - Exception 2: for Microsoft platform strings for CFF * OpenType fonts the Full font name string must be identical to the PostScript FontName in the CFF Name INDEX.
  • Version string should begin with the syntax 'Version .' (upper case, lower case, or mixed, with a space between "Version" and the number). The string must contain a version number of the following form: one or more digits (0-9) of value less than 65,535, followed by a period, followed by one or more digits of value less than 65,535. Any character other than a digit will terminate the minor number. A character such as ";" is helpful to separate different pieces of version information.
  • The PostScript name string must be no longer than 63 characters, and restricted to the printable ASCII subset, codes 33 through 126, except for the 10 characters '{}<>/%'. OpenType fonts which include a name with name ID of 6 shall include identical names for the two (Platform;Encoding;Language) sets (1;0;0) (Macintosh;Roman;English) and (3;1;1033) (Microsoft;Unicode;English(American)) In CFF OpenType fonts, these two name strings must also be identical to the font name as stored in the CFF's Name INDEX.
  • This PostScript name string does not fit the OTF guidelines because it's longer than 63 characters.
  • This PostScript name string does not fit the OTF guidelines because it's not restricted to the permitted character subset.
  • This Macintosh PostScript name string does not fit the OTF guidelines because the respective Microsoft PostScript name string does not exist.
  • This Macintosh PostScript name string does not fit the OTF guidelines because it differs from the respective Microsoft PostScript name string.
  • This Microsoft PostScript name string does not fit the OTF guidelines because the respective Macintosh PostScript name string does not exist.
  • This Microsoft PostScript name string does not fit the OTF guidelines because it differs from the respective Macintosh PostScript name string.
  • This PostScript name string does not fit the OTF guidelines because it's none of the required (Platform;Encoding;Language) sets.
  • This PostScript name string does not fit the OTF guidelines because it differs from the CFF PostScript FontName.
  • This Trademark string does not fit the OTF guidelines because it exactly matches the copyright notice in the name ID 0 string.

@probonopd probonopd reopened this May 7, 2020
@ctrlcctrlv
Copy link

@nim-nim Actually we have no disagreement. I just misunderstood you. I thought you meant ID 17 should read SemiboldItalic and not Semibold Italic. I agree Semi Bold Italic is bad practice, although not out-of-spec.

@probonopd
Copy link
Owner Author

To be honest, the output of OTM Light is cryptic to me. What is wrong about the line that it has marked red, and which field in UFO3 does this correspond to? (Maybe I should really ask this question to the OTM Light developers, but possibly someone more knowledgeable than me can make more sense of that dialog box.)

@ctrlcctrlv
Copy link

I think it's complaining about OT ID 1, but both RoboFont's devs and I disagree with what they're saying.

@ctrlcctrlv
Copy link

Oh and it seems like they list the exceptions right there, but their program isn't considering them. I would take the output with a grain of salt.

@probonopd
Copy link
Owner Author

Note to self, https://glyphsapp.com/tutorials/naming is a long writeup on naming which we also might to consider if we ever turn this into some generic documentation/checker.

@probonopd
Copy link
Owner Author

Dr. Jürgen Willrodt in OpenType Status 2009 https://www.youtube.com/watch?v=29jQAZ-H6Wk (around 21:40) gives information on font naming and basically confirms that it is a mess ("there is no hope this will get better")...

@nim-nim
Copy link

nim-nim commented May 9, 2020

It is a mess but it is getting better due to pressure from web and module devs (the W3C did not give up and removed all the excuses built-in the OpenType spec in the CSS spec, so careless font makers see the web/mobile market go to others).

@nim-nim
Copy link

nim-nim commented May 9, 2020

See also
https://blogs.adobe.com/typblography/typotechnica2007/Font%20names.pdf

By 2009 the general clean up had just started and many believed garbage as usual in metadata would continue forever.

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

3 participants