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

New GF check: Notdef glyphs conform to the best standard design, the rect with diagonals #4770

Open
davelab6 opened this issue Jun 20, 2024 · 20 comments

Comments

@davelab6
Copy link
Contributor

davelab6 commented Jun 20, 2024

Observed behaviour

Someone at a major hardware vendor reported to me that some fonts (unclear which in GF collection) have funky glyph drawings encoded in the notdef character. Fun ones include a QR code for a page on the foundry website telling them to commission glyph set extensions, things that relate to "missing" or "redacted" concepts and the theme of the typeface, or more fresh designs of the classic notdef designs that relate more closely to the typeface styles itself.

The problem with those, for the rationale here, is that readers can not unambiguously decipher when they are getting back a notdef; not only human users but also OCR robot users :)

The classic designs are shown in https://learn.microsoft.com/en-us/typography/opentype/spec/recom#glyph-0-the-notdef-glyph and I think the best design is the rectangle with diagonals. The vendor person showed me their analysis which found a large collection of popular CJK fonts all using that design with no exceptions - only small variety of W:H proportions.

I also think it ought to be consistently singular in W:H and stroke width, in all styles of a family (similar to the original Euro symbol ;) I think variation within a family is OK, and I'm not ready to impose a single design on all GF families, but I expect that in future it may be that text engines ignore the notdef glyphs in fonts to get better uniformity.

Expected behaviour

I would like a GF check that WARNs when GF families do not have a 5 contour notdef design (the rectangle with the two diagonal lines, the 1 outer contour and then the 4 counters on each side).

@felipesanches
Copy link
Collaborator

Instead of creating a new check, (in the spirit of issue #4735), I think this should be an additional validation on com.google.fonts/check/mandatory_glyphs:

@check(
    id="com.google.fonts/check/mandatory_glyphs",
    rationale="""
        The OpenType specification v1.8.2 recommends that the first glyph is the
        '.notdef' glyph without a codepoint assigned and with a drawing:

        The .notdef glyph is very important for providing the user feedback
        that a glyph is not found in the font. This glyph should not be left
        without an outline as the user will only see what looks like a space
        if a glyph is missing and not be aware of the active font’s limitation.

        https://docs.microsoft.com/en-us/typography/opentype/spec/recom#glyph-0-the-notdef-glyph

        Pre-v1.8, it was recommended that fonts should also contain 'space', 'CR'
        and '.null' glyphs. This might have been relevant for MacOS 9 applications.
    """,
    proposal="legacy:check/046",
)

@davelab6
Copy link
Contributor Author

@felipesanches good suggestion :)

This is the design I mentioned, as "a 5 contour notdef design", but there are a few other things that the vendor person has pointed out about the geometry of this glyph design which can be used in a check to ensure it is what we want:

Screenshot 2024-06-20 at 10 26 00 PM
  • Total 5 paths
  • Total 16 points
    • 1 path with 4 points
    • 4 paths with 3 points

Additionally, the glyph design has some interesting properties for the bounding boxes of the 5 paths:

Screenshot 2024-06-20 at 10 30 10 PM
  • 1 path contains 4 paths
  • 2 wide aspect ratio contained; paths are non-overlapping
  • 2 tall aspect ratio contained; paths are also non-overlapping

While I had noted "it ought to be consistently singular in W:H and stroke width, in all styles of a family", an exception to that is with italic styles, since those are typically slanted, but an unslanted notdef glyph will perhaps collide with adjacent glyphs (like /H/notdef/H/). The bounding boxes are interesting in this case because they are robust against slanting and weight stress:

Screenshot 2024-06-20 at 10 30 13 PM

This leaves a nice number of things that are straightforward to check with Python code:

  • gid = 0
  • glyphname = .notdef
  • Total point count = 16
  • Total path count = 5
  • 1 path with 4 points
  • That 1 path fully contains the other 4 paths
  • 4 other paths each with 3 points
  • 2 of those 4 have a "wide aspect ratio" bounding box, and their contained paths are non-overlapping
  • The other 2 of those 4 have a "tall aspect ratio" bounding box, and their contained paths are also non-overlapping

Finally, for the rationale, this design is expected by Google Fonts because it is

  • according with the OpenType Spec
  • widely used in CJK fonts
  • visually distinctive and instantly recognizable due to decades of usage
  • has a small footprint in terms of glyph outline data
  • is easy to validate automatically

@simoncozens
Copy link
Collaborator

I think in this case it's looking at something very different (design not just existence) so a separate check is fine. In fact, the idea that we need to do different code in different profiles is a good indicator that it should be a separate check.

@vv-monsalve
Copy link
Collaborator

vv-monsalve commented Jun 21, 2024

I would like a GF check that WARNs when GF families do not have a 5 contour notdef design (the rectangle with the two diagonal lines, the 1 outer contour and then the 4 counters on each side).

How to reconcile this expectation with the fact that our UI actually uses a different shape, one that could fall into the "creative" category?

This is the one used there

image

Jua-Whoowahan-Brothers

@davelab6
Copy link
Contributor Author

davelab6 commented Jun 21, 2024

2 wide aspect ratio contained; paths are non-overlapping
2 tall aspect ratio contained; paths are also non-overlapping

Also: Aspect Ratio = width / height, so:

  • "wide aspect ratio” is an aspect ratio greater than 1
  • "tall aspect ratio" is an aspect ratio less than 1

How to reconcile this expectation with the fact that our UI actually uses a different shape, one that could fall into the "creative" category?

I will file an internal bug report ;)

@vv-monsalve
Copy link
Collaborator

I like creativity, though!

@khaledhosny
Copy link
Contributor

but I expect that in future it may be that text engines ignore the notdef glyphs in fonts to get better uniformity.

That is already the case in Firefox and Pango, they both ignore the .notdef glyph in the font and show a hex box of the codepoint of the character.

@moyogo
Copy link
Contributor

moyogo commented Jun 22, 2024

GF could remove .notdef and let ufo2ft draw it.

@davelab6
Copy link
Contributor Author

@vv-monsalve I can connect you to the vendor person if you would like :)

@moyogo Is that a Builder feature for @simoncozens ?

@simoncozens
Copy link
Collaborator

We could write a ufo2ft filter and let the builder call it. And yes, we probably should.

@simoncozens
Copy link
Collaborator

Incidentally flag this up as yet another "things we want a font compiler to do that not everyone wants a font compiler to do."

@felipesanches
Copy link
Collaborator

Incidentally flag this up as yet another "things we want a font compiler to do that not everyone wants a font compiler to do."

FontBakery's concept of a profile should be adopted on font editors and font compilers as well

@moyogo
Copy link
Contributor

moyogo commented Jun 23, 2024

GF could remove .notdef and let ufo2ft draw it.

We could write a ufo2ft filter

utfo2ft.outlineCompiler will draw a .notdef when there is none.

@simoncozens
Copy link
Collaborator

It does, but not the one we want.

@moyogo
Copy link
Contributor

moyogo commented Jun 24, 2024

It does, but not the one we want.

It sounds like it’s not the one ufo2ft should draw either.

@rimas-kudelis
Copy link
Contributor

I'd just like to point out that the OpenType spec, linked in the initial post here, actually shows three different example variations of .notdef, all equally acceptable:

image

Why would you demand exactly one specific shape?

Also, the idea of removing the glyph if it exists and then replacing it with another automatically inserted glyph sounds a bit weird to me, because such process would most likely disregard font properties like it's typical character weight, width, height etc.

@felipesanches
Copy link
Collaborator

In my opinion, .notdef should be treated is a manner similar to a standardized road sign: formalized and extremely clear to recognize. It's purpose is to indicate a font problem (the font is "broken" for the purpose of rendering this specific piece of text).

So, I believe that having a single design that is widely recognized is better than having a design that blends well with the rest of the glyphs in the font.

For that reason, I think the "cute" tofu-like glyph used on Google Fonts UI was perhaps a nice touch, but still a mistake.

@rimas-kudelis
Copy link
Contributor

I'm not talking about cute tofu-like glyphs. I'm talking about rectangles which aren't cute at all and are already recognized well enough.

@felipesanches
Copy link
Collaborator

Why would you demand exactly one specific shape?

@davelab6 said:

  • "I'm not ready to impose a single design on all GF families" <-- but warning is a reasonable first step towards that.
  • "I would like a GF check that WARNs" <-- this means the warning would be restricted to Google Fonts; meaning it is (at least initially) proposed as a vendor-specific profile decision.

@rimas-kudelis
Copy link
Contributor

Okay, that is fair enough.

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

7 participants