Closed Bug 1971053 Opened 1 month ago Closed 1 month ago

Regression in font glyph selection involving emoji presentation and color fonts

Categories

(Core :: Layout: Text and Fonts, defect)

Firefox 139
defect

Tracking

()

RESOLVED FIXED
141 Branch
Tracking Status
firefox-esr140 --- fixed
firefox140 --- fixed
firefox141 --- fixed

People

(Reporter: rqou00, Assigned: jfkthame)

References

Details

Attachments

(9 files)

Attached file Emerald.ttf

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:139.0) Gecko/20100101 Firefox/139.0

Steps to reproduce:

I was recently experimenting with making an OpenType font which uses some "advanced" OpenType features, and it was working perfectly fine in a previous version of Firefox (probably version 138?) but stopped working after updating to version 139. It continues to work correctly in Chrome 139.0.7219.3 (on MacOS).

To reproduce, either visit my blog page which embeds the font ( https://arcanenibble.github.io/a-quick-introduction-to-opentype.html ), or download the font TTF file and test page from my GitHub repository: https://github.com/ArcaneNibble/pokefont

I've also attached the font file to this bug for convenience

Actual results:

On my laptop, the following things happen:

  • In the blog post, the text "L‍v100" (L ZWJ v 1 0 0) ends up choosing a fallback font for the "100" glyphs, even though the font definitely contains the glyphs for 1 and 0. Using the inspector to delete the ZWJ causes the correct glyphs to be chosen.
  • In the blog post, all occurrences of U+2642 MALE SIGN and U+2640 FEMALE SIGN use a fallback font even though Emerald.ttf contains glyphs for the characters.
  • In the test.html file, U+2642 MALE SIGN and U+2665 BLACK HEART SUIT use a fallback font.
  • In the test.html file, under the heading "Japanese auto-fullwidth", U+2B06 UPWARDS BLACK ARROW chooses a fallback font in the first instance (with lang="ja") but correctly chooses the glyph from Emerald.ttf in the second instance (without a lang attribute)
  • In the test.html file, under the heading "Japanese auto-fullwidth", the "0123" characters choose a fallback font. This continues to happen if I use the inspector to modify the contents down to <p>あ 0123</p>. Deleting the あ character finally results in choosing the correct glyphs for 0123.

On my Android phone which is currently still running 139.0b10 (build #2016091495), the behavior is slightly different:

  • In the blog post, the "L‍v100" text continues to choose the wrong font for the "100" digits.
  • In the blog post, the U+2642 MALE SIGN and U+2640 FEMALE SIGN only use an incorrect fallback font inside the lang="ja" span. All other instances appear correctly.
  • In the test.html file, U+2665 BLACK HEART SUIT and most instances of U+2642 MALE SIGN appear correctly.
  • In the test.html file, under the heading "Japanese auto-fullwidth", U+2B06 UPWARDS BLACK ARROW and U+2642 MALE SIGN continue to be incorrect.
  • In the test.html file, under the heading "Japanese auto-fullwidth", the "0123" characters continue to be incorrect.

Expected results:

All glyphs should be chosen from Emerald.ttf

I don't know which of the many OpenType features I've been experimenting with are actually related to this bug, but the Emerald.ttf is "unusual" compared to a "normal" Latin-script body text font because it uses:

  • COLR/CPAL color layers (despite not being an emoji font)
  • (nonstandard) Unicode Variation Selectors on non-CJK characters
  • nonstandard ZWJ sequences
  • required ligatures (rlig)
  • language-dependent GSUB

The Bugbug bot thinks this bug should belong to the 'Core::Layout: Text and Fonts' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Layout: Text and Fonts
Product: Firefox → Core

It sounds like this is an issue of font selection priorities, where Firefox is preferring to use a font without COLR/CPAL glyphs for character codes that do not have the Unicode emoji-presentation property by default.

To encourage the browser to use the "color" glyphs even for characters that by default have text-style presentation, try setting font-variant-emoji: emoji on your .emerald class. Does that help?

Flags: needinfo?(rqou00)

Indeed, adding font-variant-emoji: emoji does fix the issue, but only after enabling layout.css.font-variant-emoji.enabled in about:config. This won't work on a default install of the browser.

I also confirmed that removing COLR/CPAL tables from my font will work around the glyph selection issue (but obviously results in no color). All of the GSUB shenanigans seem to be unrelated.

However, this generally feels like an awkward workaround? I have explicitly selected a particular font to use, and this font doesn't make a conceptual distinction between "emoji" and any other codepoint (yet it uses color throughout). I don't think the browser should be overriding this choice?

Flags: needinfo?(rqou00)

The current (139.0.1) behavior with font-variant-emoji unset also seems quite inconsistent when it comes to digits (which I didn't know had emoji variation sequences until now), in a manner which also feels like a bug:

  • the sequence "0123456789" renders with color. Adding an explicit font-variant-emoji: text also does not get rid of the color or force a fallback (i.e. it does not change anything).
  • the sequence "あ0123456789" causes the "あ" to render with color and "0123456789" to use a fallback

It feels like the current heuristic is not appropriate for artistically colorful fonts which are not "emoji fonts"?

Apologies for the spam, but whatever was changed in this glyph selection logic manages to break fonts such as Nabla (a prototypical "not emoji" artistic color font, https://fonts.google.com/specimen/Nabla/tester ) in a way that is extremely inconsistent. In a contenteditable div such as the Google font tester, the exact sequence in which text is input (including via copy-pasting) affects whether a fallback font gets used for digits. I will be attaching a screen recording of this.

Yes, digits are problematic because (perhaps counter-intuitively) they have the Emoji property in Unicode (see https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt). This is because they may function as the "base" character of an emoji sequence like <U+0031, U+FE0F, U+20E3>, which displays as 1️⃣.

This means that they are subject to the browser's attempt to respect emoji-presentation options for characters that may have either a text-style (traditional monochrome glyph) or emoji-style (full-color) presentation.

Having said that, your examples do seem to be showing some surprising/inconsistent behavior, and we should try to understand exactly what's happening there. Comment 9 is particularly odd... I can reproduce similar behavior here, so I'll try to look into it.

Summary: Regression in font glyph selection when "advanced" features are used → Regression in font glyph selection involving emoji presentation and color fonts
Duplicate of this bug: 1971148

The inconsistency seen here (as described in comment 9, and in the additional report in bug 1971148) occurs because there's a difference in font-selection behavior between the code-path used for 8-bit vs 16-bit text runs. When the text is stored internally in 8-bit form (no characters beyond U+00FF are present in the content fragment), we use a simplified path, and the digits get rendered with the requested font; but the 16-bit code path, which attempts to take into consideration a lot more issues of emoji characters, combining characters, Unicode ignorables, etc., is forcing the digits to use a non-color font, which is not the desired result here.

Just cleaning up the gfxFontGroup constructor; no functional change.

Assignee: nobody → jfkthame
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Pushed by jkew@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/71256f504209 https://hg.mozilla.org/integration/autoland/rev/fcbafd88ab56 patch 1 - Minor cleanup in gfxFontGroup. r=layout-reviewers,emilio https://github.com/mozilla-firefox/firefox/commit/ab3609bbe30c https://hg.mozilla.org/integration/autoland/rev/1d8eb67711af patch 2 - Prefer to use the specified font from CSS for potentially-emoji characters unless a specific presentation is explicitly requested. r=layout-reviewers,emilio
Severity: -- → S3
Status: ASSIGNED → RESOLVED
Closed: 1 month ago
Resolution: --- → FIXED
Target Milestone: --- → 141 Branch

Is it too late to get a backport for Firefox 140?

Just cleaning up the gfxFontGroup constructor; no functional change.

Original Revision: https://phabricator.services.mozilla.com/D253739

Attachment #9495103 - Flags: approval-mozilla-beta?
Attachment #9495104 - Flags: approval-mozilla-beta?

firefox-beta Uplift Approval Request

  • User impact if declined: incorrect font selection in some cases when attempting to use color fonts
  • Code covered by automated testing: yes
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing: see comment 9; also bug 1971148
  • Risk associated with taking this patch: low
  • Explanation of risk level: adjusted font-selection heuristics only affects characters with Emoji property; test coverage extended to verify behavior
  • String changes made/needed: none
  • Is Android affected?: yes

Changed the beta uplift request over to release since Fx140 is no longer in beta.
This could maybe ship in a later Fx140 build (RC/dot release)

Attachment #9495103 - Flags: approval-mozilla-beta? → approval-mozilla-release?
Attachment #9495104 - Flags: approval-mozilla-beta? → approval-mozilla-release?
QA Whiteboard: [qa-triage-done-c142/b141]
Attachment #9495103 - Flags: approval-mozilla-release? → approval-mozilla-release+
Attachment #9495104 - Flags: approval-mozilla-release? → approval-mozilla-release+

:jfkthame, could you consider an ESR140 uplift request here?
We're just at the start of a new ESR cycle and could take it for 140.1esr

Flags: needinfo?(jfkthame)
Flags: needinfo?(jfkthame)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: