[webkit-changes] [WebKit/WebKit] 3f69e1: REGRESSION: Emoji characters are sometimes drawn i...

Myles C. Maxfield noreply at github.com
Sun Jul 16 01:36:53 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 3f69e13f0317394affb24ab40d881b92f2f1299d
      https://github.com/WebKit/WebKit/commit/3f69e13f0317394affb24ab40d881b92f2f1299d
  Author: Myles C. Maxfield <mmaxfield at apple.com>
  Date:   2023-07-16 (Sun, 16 Jul 2023)

  Changed paths:
    A LayoutTests/fast/text/emoji-style-expected.html
    A LayoutTests/fast/text/emoji-style.html
    M Source/WTF/wtf/BitVector.h
    M Source/WTF/wtf/PlatformHave.h
    M Source/WTF/wtf/unicode/CharacterNames.h
    M Source/WebCore/PAL/pal/cf/CoreTextSoftLink.cpp
    M Source/WebCore/PAL/pal/cf/CoreTextSoftLink.h
    M Source/WebCore/platform/graphics/Font.cpp
    M Source/WebCore/platform/graphics/Font.h
    M Source/WebCore/platform/graphics/FontCascade.cpp
    M Source/WebCore/platform/graphics/FontCascade.h
    M Source/WebCore/platform/graphics/FontCascadeFonts.cpp
    M Source/WebCore/platform/graphics/FontCascadeFonts.h
    M Source/WebCore/platform/graphics/GlyphPage.h
    M Source/WebCore/platform/graphics/SystemFallbackFontCache.cpp
    M Source/WebCore/platform/graphics/SystemFallbackFontCache.h
    M Source/WebCore/platform/graphics/cairo/FontCairo.cpp
    M Source/WebCore/platform/graphics/coretext/FontCascadeCoreText.cpp
    M Source/WebCore/platform/graphics/coretext/FontCoreText.cpp
    M Source/WebCore/platform/graphics/coretext/GlyphPageCoreText.cpp
    M Source/WebCore/platform/graphics/freetype/GlyphPageTreeNodeFreeType.cpp
    M Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp
    M Source/WebCore/platform/graphics/win/GlyphPageTreeNodeCairoWin.cpp
    M Source/WebCore/platform/text/TextFlags.h

  Log Message:
  -----------
  REGRESSION: Emoji characters are sometimes drawn in text style erroneously
https://bugs.webkit.org/show_bug.cgi?id=259139
rdar://111411175

Reviewed by Cameron McCormack.

In WebKit, we weren't treating emoji deliberately at all. We were treating them like any other
character - falling back to the first font in the fallback list that supports them. This is a
problem because there are some fonts (like STIXTwo) which support emoji code points, but
aren't colorful like emoji should be. In particular, on macOS, STIXTwo is earlier in the
platform's default font cascade list than Apple Color Emoji, so some emoji characters were being
rendered in text style, not emoji style.

The fix for this is to treat emoji deliberately. This patch adds two classification functions:
- One that classifies a character as either "RequireText", "RequireEmoji" or "NoPreference"
- One that classifies a glyph in a font as either color or not

When we perform font fallback for a particular character, we can make sure that if the
character requires emoji style, that it is being rendered with a color glyph (and vice-versa
for characters that require text style - of which there are none right now, but the yet-to-
be-implemented `font-variant-emoji` property would create this situation). If the glyph from
the fallback font isn't compatible with the character, then the solution is to just keep
falling back to another font. If we get to the end of the list, we ask the platform to produce
a font for us, and we pass it a variation selector which indicates which kind of glyph/font
we need.

The first classification works by just asking Unicode (ICU) whether the character has the
Emoji_Presentation property. The second classification works by creating a bitmap of all the
glyphs at font creation time, which can then be queried at font fallback time.

(On the Linux ports, I couldn't figure out how to implement the second classification function.
See https://bugs.webkit.org/show_bug.cgi?id=259205. This means that the first classification
needs to report NoPreference for every character on those ports. We don't want a situation where
a character reports it requires emoji style, but we don't know how to ask a font if it has
colorful glyphs, so we assume no fonts have colorful glyphs, which means no fonts can render
the character.)

Because a particular glyph in a font is either text style or emoji style (and not both),
all the caches _inside_ Font don't need to be updated. The only caches which need to be updated
in this patch is the ones in FontCascadeFonts where different glyphs from different fonts are
combined together into a single data structure.

The test for this patch only tests the characters which Unicode says actually need emoji style.
All the other characters are up to the OS/UA's discretion about whether they should be emoji
or not. For example, iOS renders a bunch of more characters in emoji style than just what's
required by Unicode - but macOS doesn't. I also limited the set of characters from "all the
characters Unicode says need emoji style" to "all the characters Unicode says need emoji style
that macOS renders as text style" so the set isn't super big.

* LayoutTests/fast/text/emoji-style-expected.html: Added.
* LayoutTests/fast/text/emoji-style.html: Added.
* Source/WTF/wtf/BitVector.h:
* Source/WTF/wtf/PlatformHave.h:
* Source/WTF/wtf/unicode/CharacterNames.h:
* Source/WebCore/PAL/pal/cf/CoreTextSoftLink.cpp:
* Source/WebCore/PAL/pal/cf/CoreTextSoftLink.h:
* Source/WebCore/platform/graphics/Font.cpp:
(WebCore::Font::systemFallbackFontForCharacter const):
(WebCore::Font::glyphIsColorGlyph const):
* Source/WebCore/platform/graphics/Font.h:
* Source/WebCore/platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::glyphDataForCharacter const):
* Source/WebCore/platform/graphics/FontCascade.h:
* Source/WebCore/platform/graphics/FontCascadeFonts.cpp:
(WebCore::FontCascadeFonts::glyphDataForSystemFallback):
(WebCore::FontCascadeFonts::glyphDataForVariant):
(WebCore::FontCascadeFonts::glyphDataForCharacter):
(WebCore::FontCascadeFonts::pruneSystemFallbacks):
* Source/WebCore/platform/graphics/FontCascadeFonts.h:
* Source/WebCore/platform/graphics/GlyphPage.h:
(WebCore::GlyphData::GlyphData):
(WebCore::GlyphPage::glyphDataForIndex const):
(WebCore::GlyphPage::glyphForIndex const):
(WebCore::GlyphPage::isColorForIndex const):
(WebCore::GlyphPage::setGlyphForIndex):
* Source/WebCore/platform/graphics/SystemFallbackFontCache.cpp:
(WebCore::SystemFallbackFontCache::systemFallbackFontForCharacter):
* Source/WebCore/platform/graphics/SystemFallbackFontCache.h:
(WebCore::add):
(WebCore::CharacterFallbackMapKey::operator== const): Deleted.
* Source/WebCore/platform/graphics/cairo/FontCairo.cpp:
(WebCore::FontCascade::resolveEmojiPolicy):
* Source/WebCore/platform/graphics/coretext/FontCascadeCoreText.cpp:
(WebCore::FontCascade::resolveEmojiPolicy):
* Source/WebCore/platform/graphics/coretext/FontCoreText.cpp:
(WebCore::Font::platformInit):
* Source/WebCore/platform/graphics/coretext/GlyphPageCoreText.cpp:
(WebCore::GlyphPage::fill):
* Source/WebCore/platform/graphics/freetype/GlyphPageTreeNodeFreeType.cpp:
(WebCore::GlyphPage::fill):
* Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp:
(WebCore::OpenTypeVerticalData::substituteWithVerticalGlyphs const):
* Source/WebCore/platform/graphics/win/GlyphPageTreeNodeCairoWin.cpp:
(WebCore::GlyphPage::fill):
* Source/WebCore/platform/text/TextFlags.h:

Canonical link: https://commits.webkit.org/266089@main




More information about the webkit-changes mailing list