Changeset 239915 in webkit


Ignore:
Timestamp:
Jan 13, 2019 11:59:00 PM (5 years ago)
Author:
Carlos Garcia Campos
Message:

[FreeType] Support emoji modifiers
https://bugs.webkit.org/show_bug.cgi?id=177040

Reviewed by Myles C. Maxfield.

Source/WebCore:

The problem only happens with emojis having the zero with joiner (U+200D) in the sequence. The sequence is
broken because createAndFillGlyphPage() in Font.cpp overwrites zero with joiner with zero width space (U+200B),
but the emoji font actually supports zero with joiner. This patch moves the control characters override from
createAndFillGlyphPage() to GlyphPage::fill() only for FreeType based ports. This way we can do the override
only for the cases where the code point is not supported by the font.

  • platform/graphics/Font.cpp:

(WebCore::overrideControlCharacters): Helper function to override the control characters.
(WebCore::createAndFillGlyphPage): Call overrideControlCharacters() only when not using FreeType.

  • platform/graphics/freetype/GlyphPageTreeNodeFreeType.cpp:

(WebCore::GlyphPage::fill): Use zero width space as fallback when the font doesn't support characters with
Default_Ignorable Unicode property.

LayoutTests:

Mark several emoji tests as passing now.

  • platform/gtk/TestExpectations:
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r239905 r239915  
     12019-01-13  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [FreeType] Support emoji modifiers
     4        https://bugs.webkit.org/show_bug.cgi?id=177040
     5
     6        Reviewed by Myles C. Maxfield.
     7
     8        Mark several emoji tests as passing now.
     9
     10        * platform/gtk/TestExpectations:
     11
    1122019-01-13  Antti Koivisto  <antti@apple.com>
    213
  • trunk/LayoutTests/platform/gtk/TestExpectations

    r239830 r239915  
    37813781fast/text/emoji-gender-2-8.html [ Pass ]
    37823782fast/text/emoji-gender-2-9.html [ Pass ]
     3783fast/text/emoji-gender-3.html [ Pass ]
     3784fast/text/emoji-gender-4.html [ Pass ]
     3785fast/text/emoji-gender-5.html [ Pass ]
     3786fast/text/emoji-gender-6.html [ Pass ]
     3787fast/text/emoji-gender-8.html [ Pass ]
     3788fast/text/emoji-gender-9.html [ Pass ]
    37833789fast/text/emoji-gender.html [ Pass ]
    37843790fast/text/emoji-gender-fe0f-3.html [ Pass ]
  • trunk/Source/WebCore/ChangeLog

    r239913 r239915  
     12019-01-13  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [FreeType] Support emoji modifiers
     4        https://bugs.webkit.org/show_bug.cgi?id=177040
     5
     6        Reviewed by Myles C. Maxfield.
     7
     8        The problem only happens with emojis having the zero with joiner (U+200D) in the sequence. The sequence is
     9        broken because createAndFillGlyphPage() in Font.cpp overwrites zero with joiner with zero width space (U+200B),
     10        but the emoji font actually supports zero with joiner. This patch moves the control characters override from
     11        createAndFillGlyphPage() to GlyphPage::fill() only for FreeType based ports. This way we can do the override
     12        only for the cases where the code point is not supported by the font.
     13
     14        * platform/graphics/Font.cpp:
     15        (WebCore::overrideControlCharacters): Helper function to override the control characters.
     16        (WebCore::createAndFillGlyphPage): Call overrideControlCharacters() only when not using FreeType.
     17        * platform/graphics/freetype/GlyphPageTreeNodeFreeType.cpp:
     18        (WebCore::GlyphPage::fill): Use zero width space as fallback when the font doesn't support characters with
     19        Default_Ignorable Unicode property.
     20
    1212019-01-13  Dan Bernstein  <mitz@apple.com>
    222
  • trunk/Source/WebCore/platform/graphics/Font.cpp

    r239822 r239915  
    264264}
    265265
     266#if !USE(FREETYPE)
     267static void overrideControlCharacters(Vector<UChar>& buffer, unsigned start, unsigned end)
     268{
     269    auto overwriteCodePoints = [&](unsigned minimum, unsigned maximum, UChar newCodePoint) {
     270        unsigned begin = std::max(start, minimum);
     271        unsigned complete = std::min(end, maximum);
     272        for (unsigned i = begin; i < complete; ++i) {
     273            ASSERT(codePointSupportIndex(i));
     274            buffer[i - start] = newCodePoint;
     275        }
     276    };
     277
     278    auto overwriteCodePoint = [&](UChar codePoint, UChar newCodePoint) {
     279        ASSERT(codePointSupportIndex(codePoint));
     280        if (codePoint >= start && codePoint < end)
     281            buffer[codePoint - start] = newCodePoint;
     282    };
     283
     284    // Code points 0x0 - 0x20 and 0x7F - 0xA0 are control character and shouldn't render. Map them to ZERO WIDTH SPACE.
     285    overwriteCodePoints(0x0, 0x20, zeroWidthSpace);
     286    overwriteCodePoints(0x7F, 0xA0, zeroWidthSpace);
     287    overwriteCodePoint(softHyphen, zeroWidthSpace);
     288    overwriteCodePoint('\n', space);
     289    overwriteCodePoint('\t', space);
     290    overwriteCodePoint(noBreakSpace, space);
     291    overwriteCodePoint(narrowNoBreakSpace, zeroWidthSpace);
     292    overwriteCodePoint(leftToRightMark, zeroWidthSpace);
     293    overwriteCodePoint(rightToLeftMark, zeroWidthSpace);
     294    overwriteCodePoint(leftToRightEmbed, zeroWidthSpace);
     295    overwriteCodePoint(rightToLeftEmbed, zeroWidthSpace);
     296    overwriteCodePoint(leftToRightOverride, zeroWidthSpace);
     297    overwriteCodePoint(rightToLeftOverride, zeroWidthSpace);
     298    overwriteCodePoint(leftToRightIsolate, zeroWidthSpace);
     299    overwriteCodePoint(rightToLeftIsolate, zeroWidthSpace);
     300    overwriteCodePoint(zeroWidthNonJoiner, zeroWidthSpace);
     301    overwriteCodePoint(zeroWidthJoiner, zeroWidthSpace);
     302    overwriteCodePoint(popDirectionalFormatting, zeroWidthSpace);
     303    overwriteCodePoint(popDirectionalIsolate, zeroWidthSpace);
     304    overwriteCodePoint(firstStrongIsolate, zeroWidthSpace);
     305    overwriteCodePoint(objectReplacementCharacter, zeroWidthSpace);
     306    overwriteCodePoint(zeroWidthNoBreakSpace, zeroWidthSpace);
     307}
     308#endif
     309
    266310static RefPtr<GlyphPage> createAndFillGlyphPage(unsigned pageNumber, const Font& font)
    267311{
     
    277321
    278322    unsigned start = GlyphPage::startingCodePointInPageNumber(pageNumber);
    279     unsigned end = start + glyphPageSize;
    280323    Vector<UChar> buffer(glyphPageSize * 2 + 2);
    281324    unsigned bufferLength;
     
    286329            buffer[i] = start + i;
    287330
    288         // Code points 0x0 - 0x20 and 0x7F - 0xA0 are control character and shouldn't render. Map them to ZERO WIDTH SPACE.
    289         auto overwriteCodePoints = [&](unsigned minimum, unsigned maximum, UChar newCodePoint) {
    290             unsigned begin = std::max(start, minimum);
    291             unsigned complete = std::min(end, maximum);
    292             for (unsigned i = begin; i < complete; ++i) {
    293                 ASSERT(codePointSupportIndex(i));
    294                 buffer[i - start] = newCodePoint;
    295             }
    296         };
    297 
    298         auto overwriteCodePoint = [&](UChar codePoint, UChar newCodePoint) {
    299             ASSERT(codePointSupportIndex(codePoint));
    300             if (codePoint >= start && codePoint < end)
    301                 buffer[codePoint - start] = newCodePoint;
    302         };
    303 
    304         overwriteCodePoints(0x0, 0x20, zeroWidthSpace);
    305         overwriteCodePoints(0x7F, 0xA0, zeroWidthSpace);
    306         overwriteCodePoint(softHyphen, zeroWidthSpace);
    307         overwriteCodePoint('\n', space);
    308         overwriteCodePoint('\t', space);
    309         overwriteCodePoint(noBreakSpace, space);
    310         overwriteCodePoint(narrowNoBreakSpace, zeroWidthSpace);
    311         overwriteCodePoint(leftToRightMark, zeroWidthSpace);
    312         overwriteCodePoint(rightToLeftMark, zeroWidthSpace);
    313         overwriteCodePoint(leftToRightEmbed, zeroWidthSpace);
    314         overwriteCodePoint(rightToLeftEmbed, zeroWidthSpace);
    315         overwriteCodePoint(leftToRightOverride, zeroWidthSpace);
    316         overwriteCodePoint(rightToLeftOverride, zeroWidthSpace);
    317         overwriteCodePoint(leftToRightIsolate, zeroWidthSpace);
    318         overwriteCodePoint(rightToLeftIsolate, zeroWidthSpace);
    319         overwriteCodePoint(zeroWidthNonJoiner, zeroWidthSpace);
    320         overwriteCodePoint(zeroWidthJoiner, zeroWidthSpace);
    321         overwriteCodePoint(popDirectionalFormatting, zeroWidthSpace);
    322         overwriteCodePoint(popDirectionalIsolate, zeroWidthSpace);
    323         overwriteCodePoint(firstStrongIsolate, zeroWidthSpace);
    324         overwriteCodePoint(objectReplacementCharacter, zeroWidthSpace);
    325         overwriteCodePoint(zeroWidthNoBreakSpace, zeroWidthSpace);
     331#if !USE(FREETYPE)
     332        overrideControlCharacters(buffer, start, start + glyphPageSize);
     333#endif
    326334    } else {
    327335        bufferLength = glyphPageSize * 2;
  • trunk/Source/WebCore/platform/graphics/freetype/GlyphPageTreeNodeFreeType.cpp

    r200129 r239915  
    3434#include "CairoUtilities.h"
    3535#include "Font.h"
     36#include "FontCascade.h"
    3637#include "UTF16UChar32Iterator.h"
    3738#include <cairo-ft.h>
     
    5960            break;
    6061
    61         Glyph glyph = FcFreeTypeCharIndex(face, character);
     62        Glyph glyph = FcFreeTypeCharIndex(face, FontCascade::treatAsSpace(character) ? space : character);
     63        // If the font doesn't support a Default_Ignorable character, replace it with zero with space.
     64        if (!glyph && u_hasBinaryProperty(character, UCHAR_DEFAULT_IGNORABLE_CODE_POINT))
     65            glyph = FcFreeTypeCharIndex(face, zeroWidthSpace);
     66
    6267        if (!glyph)
    6368            setGlyphForIndex(i, 0);
Note: See TracChangeset for help on using the changeset viewer.