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

STAT AxisNameID must be greater than 255. Why? #433

Closed
justvanrossum opened this issue Jun 7, 2020 · 18 comments
Closed

STAT AxisNameID must be greater than 255. Why? #433

justvanrossum opened this issue Jun 7, 2020 · 18 comments

Comments

@justvanrossum
Copy link

The AxisNameID is required to be greater than 255. This is odd, or at least not intuitively understandable. Can this restriction be elaborated on, or, even better, be lifted?

See also khaledhosny/ots#210 and fonttools/fonttools#1985


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

@anthrotype
Copy link

anthrotype commented Jun 8, 2020

yes, I concur with Just this is weird, especially as the AxisValues' valueNameID are allowed to below 256:

Defined name IDs, such as name IDs 2, 17 or 22, can be used if those have the appropriate string for an axis value. Otherwise, name IDs must be greater than 255 and less than 32768.

https://docs.microsoft.com/en-us/typography/opentype/spec/stat#axis-value-tables

@anthrotype
Copy link

Hm, perhaps I can see why the restriction >= 255 would apply to STAT axes names but not to axis value names. The former match the fvar axes names, which similarly must be >= 255; whereas the latter may overlap with one of the default style names in the < 256 range.

@justvanrossum
Copy link
Author

Ah, and the fvar restriction comes from the Apple spec. Equally odd, and similarly doesn't seem to apply to name IDs for named instances.

@PeterConstable
Copy link

There's a rationale for this restriction: These are vendor-determined name IDs. If a vendor were to use, say, name ID 26, and then tomorrow name ID was given a formal definition within the spec, then that would break existing fonts in the wild. Name IDs 0 to 255 are reserved for formal definition in the spec. It's been that way since forever. This is explained in the 'name' table chapter:

"Name IDs 26 to 255, inclusive, are reserved for future standard names. Name IDs 256 to 32767, inclusive, are reserved for font-specific names such as those referenced by a font’s layout features."

@PeterConstable
Copy link

In the case of named instances in the 'fvar' table, it could be reasonable to use name ID 2 or 17 for a given named instance. The 'fvar' spec spells this out:

"Values of 2 or 17 can be used; otherwise, values must be greater than 255 and less than 32768. The values 2 or 17 should only be used if the named instance corresponds to the font’s default instance."

@justvanrossum
Copy link
Author

justvanrossum commented Jun 8, 2020

Thanks for clarifying.

I understand the reservation of name IDs 26 to 255, but that's not what this is about. I'm looking at a variable font that is Italic, has a nameID = 2 that is 'Italic', and has a STAT axis named 'Italic'. There should be no reason that the axis name could not be shared with nameID = 2.

@justvanrossum
Copy link
Author

(I now see that my question was not phrased precisely: I should have mentioned it was about sharing name IDs.)

@PeterConstable
Copy link

Axis values have the same restriction as for named instances:

"Defined name IDs, such as name IDs 2, 17 or 22, can be used if those have the appropriate string for an axis value. Otherwise, name IDs must be greater than 255 and less than 32768."

But I see you're talking about the axis name. I don't think there'd be any case besides "Italic" in which an axis name is likely to have the same value as a spec-defined name ID.

@justvanrossum
Copy link
Author

But I see you're talking about the axis name. I don't think there'd be any case besides "Italic" in which an axis name is likely to have the same value as a spec-defined name ID.

Who knows, but the restriction as worded is arbitrary and unnecessary, caused an OTS warning, and made me write a substantial patch to fonttools to rectify :)

Vendor-determined name IDs could very generally be defined as: must be greater than or equal to 256 and less than 32768, or can share a formally defined name ID if the name contents happen to be the same.

@PeterConstable
Copy link

Fair enough. There would still be a conformance constraint that name IDs 26, 27... (assuming OT 1.8.3) could not be used. One could abuse a name ID 0 .. 25 for an axis name string, but that's pretty unlikely.

@justvanrossum
Copy link
Author

I don't agree with the "pretty unlikely" assessment, as it's an actual use case that made me discover that the font I'm working on doesn't conform to the spec...

Of course the range 26..255 is reserved, there's no questioning that.

It makes everything (implementations as well as the spec itself) more complicated to rule out the reuse of nameID < 256 in some cases, explicitly make exceptions for nameID 2, 17 and 22 in some other cases. It could just say something like: vendor-determined name records may use formally defined nameIDs if their contents would match, else they should use values >= 256 and < 32768.

Example: if a font family would be named "Bold", there should be no reason for an fvar named instance to not use name ID 1, yet that's currently prohibited.

@PeterConstable
Copy link

You've misunderstood what I meant by "abuse a name ID 0 .. 25". For example, suppose my font has TrueType outline data, and I consider CID irrelevant. I could decide to use name ID 20 for the axis name "Weight" (or for some other purpose, like an 'ss01' display string). That would be abusing that name ID. That's the kind of thing I'm saying is unlikely.

I think your suggestion to allow exceptions in the cases of name IDs 2, 17 and 22. (22 was left out in discussion of fvar, probably on the rationale that STAT more or less makes 21/22 obsolete.)

If constraints were relaxed beyond that to 'may use formally defined nameIDs if their contents would match', then — hypothetically — I could decide that my axis name "Weight" matches nameID 20 because I'm not using nameID 20 otherwise (i.e., abusing nameID 20). But that hypothetical is probably unlikely. IOW, potential risk is low. So even your more relaxed constraint may be OK.

@PeterCon
Copy link
Collaborator

The constraint should be relaxed along the lines Just suggested.

@PeterCon PeterCon assigned PeterCon and unassigned PeterCon Aug 25, 2020
@PeterCon
Copy link
Collaborator

Currently:
axis name:

The axisNameID field ... must be greater than 255 and less than 32768.

axis value:

Each format includes a valueNameID field, which references a display string to be associated with the numeric axis value or combination of axis values. Defined name IDs, such as name IDs 2, 17 or 22, can be used if those have the appropriate string for an axis value. Otherwise, name IDs must be greater than 255 and less than 32768.

@PeterCon
Copy link
Collaborator

Fixed for next version:

The axisNameID field provides a name ID that can be used to obtain strings from the 'name' table that can be used to refer to the axis in application user interfaces. A defined name ID can be used if strings for that name ID have the appropriate string for an axis name. Otherwise, name IDs must be greater than 255 and less than 32768.

@behdad
Copy link

behdad commented Sep 20, 2020

I wrote this to someone a few weeks back:

name table has two functions:

  1. to store family, style, etc. Those are referenced by pre-allocated nameIDs. To allow for future expansion, nameIDs up to 255 are reserved for this purpose,
  2. to store arbitrary strings as needed by other tables.

There's no reason that, if a table, eg. a GSUB feature, needs to store a string to happens to match one of the string for family, style, etc, that the same nameID cannot be reused. Indeed, fonttools does that these days. But because of the bogus requirement encoded in the spec, OTS was rejecting those.

In summary: the requirement is bogus and not necessary, and disallows real optimizations and makes compiler and validator code more complicated for no reason.

@PeterConstable
Copy link

Which requirement? The old text? The proposed revision (already supplied above)? Something else?

@behdad
Copy link

behdad commented Sep 21, 2020

Which requirement? The old text? The proposed revision (already supplied above)? Something else?

I was talking, in general, about any table other than name table talking about what is allowed and what is not. The proposed:

A defined name ID can be used if strings for that name ID have the appropriate string for an axis name. Otherwise, name IDs must be greater than 255 and less than 32768.

is technically correct but redundant: "if strings for that name ID have the appropriate string for an axis name" is a given. If strings for that name ID do not have the appropriate string for an axis name, then the font will be incorrect. So specifying this tautology is redundant. Even more so when it's repeated in multiple places.

@PeterCon PeterCon added this to the OpenType 1.8.4 milestone Nov 17, 2020
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

5 participants