Bug 258877

Summary: Fallback font chosen over NotoColorEmoji when U+FE0F emoji variation selector is present
Product: WebKit Reporter: Cosimo Lupo <cosimo>
Component: TextAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Normal CC: cosimo, d-r, mmaxfield, rsheeter, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari 16   
Hardware: Unspecified   
OS: macOS 13   
Attachments:
Description Flags
Test HTML pages and fonts reproducing the bug none

Description Cosimo Lupo 2023-07-05 03:43:13 PDT
Created attachment 466932 [details]
Test HTML pages and fonts reproducing the bug

Using Safari 16.5 on the latest macOS Ventura 13.4, if you go to https://fonts.google.com/noto/specimen/Noto+Color+Emoji/glyphs you'll notice that several glyphs from the Noto Color Emoji font appear as .notdef glyph, sometimes multiple .notdefs for a single emoji. The same page displays correctly on Chrome or Firefox.

The issue was originally reported at https://github.com/googlefonts/noto-emoji/issues/428

In the "Glyphs" specimen page of Google Fonts which displays all the glyphs in a font, the `font-family` property is specified like this:

  font-family: NotoColorEmoji, Tofu;

The so-called "Tofu" font is a special fallback font that contains a cmap subtable format 13 that maps all the unicode codepoints to a rectangular glyph in the style of a .notdef; its purpose is to make it visible whenever a font is missing a given character.

The problem with Safari is that, for all the emoji sequences that contain the U+FE0F variation selector (used to request emoji presentation for emojis that can be represented as either black-and-white or colorful), it prefers to use this "Tofu" fallback font instead of NotoColorEmoji. However, this does NOT happen if the Tofu font is omitted and NotoColorEmoji is the only font listed in font-family property. In this case, Safari displays all emoji sequences correctly, including those containing U+FE0F.
E.g. try to modify the font-family from the Inspector by removing the Tofu font, and then all the emoji sequences will work as intended.

The NotoColorEmoji font is a hybrid font containing both OT-SVG table (which macOS and Safari support) and COLRv1 table, but this issue is not about color tables per se, but about font fallback and font segmentation in Safari, for this font does work in Safari and only breaks when followed in the fallback chain by a font like Tofu.ttf. 
Similarly, the font works fine when installed system-wide and used in apps like TextEdit to display the emojis.
Finally, the exact same issue with font fallback in Safari also occurs when using the "Noto Color Emoji SVG" produced independently by Adobe which contains only an OT-SVG table: https://github.com/adobe-fonts/noto-emoji-svg

I have attached a zip file containing the latest NotoColorEmoji font (downloaded from https://fonts.google.com/noto/specimen/Noto+Color+Emoji), and two static HTML pages containing all the sequences that use emoji presentation selector; the test pages only differ in whether the Tofu fallback font is listed or not in the font-family style attribute. The zip also includes the Tofu.ttf font that Google Fonts uses, in case it may be useful for debugging.

A few things to note:

- Noto Color Emoji has no glyph for U+FE0F, does not contain a direct mapping for character U+FE0F in the normal format4/format12 cmap subtables; U+FE0F only appears in the format14 cmap subtable when the emoji variation sequences are listed; Noto Color Emoji only contains color glyphs, no black and white, thus its format14 cmap subtable selects the colorful variants as the default presentation.
- Since there isn't any uniFE0F glyph in the font, its emoji sequences -- that are composed via GSUB "ccmp" feature as ligature substitutions -- do not contain U+FE0F at all (even when the canonical sequences do).
- Tofu.ttf contains one glyph only that is mapped to all the Unicode characters, including U+FE0F.

I have tried a few things, such as adding a uniFE0F glyph mapped to U+FE0F in cmap 4/12, or stripping the format14 subtable entirely, but nothing worked. The only thing that worked was to remove Tofu.ttf from font-family, or hacking it such that it does not map U+FE0F (which defeats the purpose of a "fallback" font...).

Please let me know if you require additional information.
Thank you in advance for taking a look.
Comment 1 Radar WebKit Bug Importer 2023-07-12 03:44:18 PDT
<rdar://problem/112130785>