Regression in font glyph selection involving emoji presentation and color fonts
Categories
(Core :: Layout: Text and Fonts, defect)
Tracking
()
People
(Reporter: rqou00, Assigned: jfkthame)
References
Details
Attachments
(9 files)
175.09 KB,
font/ttf
|
Details | |
153.99 KB,
image/png
|
Details | |
88.67 KB,
image/png
|
Details | |
71.81 KB,
image/png
|
Details | |
6.93 MB,
video/quicktime
|
Details | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
phab-bot
:
approval-mozilla-release+
|
Details | Review |
48 bytes,
text/x-phabricator-request
|
phab-bot
:
approval-mozilla-release+
|
Details | Review |
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 "Lv100" (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 "Lv100" 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
Comment 5•1 month ago
|
||
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.
Assignee | ||
Comment 6•1 month ago
|
||
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?
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?
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.
Reporter | ||
Comment 10•1 month ago
|
||
Assignee | ||
Comment 11•1 month ago
|
||
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.
Assignee | ||
Comment 13•1 month ago
|
||
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.
Assignee | ||
Comment 14•1 month ago
|
||
Just cleaning up the gfxFontGroup constructor; no functional change.
Updated•1 month ago
|
Assignee | ||
Comment 15•1 month ago
|
||
Comment 16•1 month ago
|
||
Assignee | ||
Updated•1 month ago
|
Comment 17•1 month ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/fcbafd88ab56
https://hg.mozilla.org/mozilla-central/rev/1d8eb67711af
Reporter | ||
Comment 18•1 month ago
|
||
Is it too late to get a backport for Firefox 140?
Assignee | ||
Comment 19•1 month ago
|
||
Just cleaning up the gfxFontGroup constructor; no functional change.
Original Revision: https://phabricator.services.mozilla.com/D253739
Updated•1 month ago
|
Assignee | ||
Comment 20•1 month ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D253740
Updated•1 month ago
|
Comment 21•1 month ago
|
||
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
Comment 22•1 month ago
|
||
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)
Updated•1 month ago
|
Updated•1 month ago
|
Updated•24 days ago
|
Updated•16 days ago
|
Updated•16 days ago
|
Updated•16 days ago
|
Comment 23•16 days ago
|
||
uplift |
Comment 24•16 days ago
|
||
: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
Comment 25•12 days ago
|
||
uplift |
Updated•12 days ago
|
Description
•