Changeset 179567 in webkit


Ignore:
Timestamp:
Feb 3, 2015 1:37:56 PM (9 years ago)
Author:
enrica@apple.com
Message:

Additional emoji support.
https://bugs.webkit.org/show_bug.cgi?id=141047
rdar://problem/19045135

Reviewed by Darin Adler.

Source/WebCore:

Adds support for emoji modifiers and group emoji.

Test: editing/deleting/delete-emoji.html

  • platform/graphics/FontCascade.cpp:

(WebCore::FontCascade::characterRangeCodePath):

  • platform/text/TextBreakIterator.cpp:

(WebCore::cursorMovementIterator):

  • rendering/RenderText.cpp:

(WebCore::isEmojiGroupCandidate):
(WebCore::isEmojiModifier):
(WebCore::RenderText::previousOffsetForBackwardDeletion):

LayoutTests:

  • editing/deleting/delete-emoji.html: Added.
  • editing/deleting/delete-emoji-expected.txt: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r179566 r179567  
     12015-02-02  Enrica Casucci  <enrica@apple.com>
     2
     3        Additional emoji support.
     4        https://bugs.webkit.org/show_bug.cgi?id=141047
     5        rdar://problem/19045135
     6
     7        Reviewed by Darin Adler.
     8
     9        * editing/deleting/delete-emoji.html: Added.
     10        * editing/deleting/delete-emoji-expected.txt: Added.
     11
    1122015-02-03  Brent Fulgham  <bfulgham@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r179565 r179567  
     12015-02-02  Enrica Casucci  <enrica@apple.com>
     2
     3        Additional emoji support.
     4        https://bugs.webkit.org/show_bug.cgi?id=141047
     5        rdar://problem/19045135
     6
     7        Reviewed by Darin Adler.
     8
     9        Adds support for emoji modifiers and group emoji.
     10
     11        Test: editing/deleting/delete-emoji.html
     12
     13        * platform/graphics/FontCascade.cpp:
     14        (WebCore::FontCascade::characterRangeCodePath):
     15        * platform/text/TextBreakIterator.cpp:
     16        (WebCore::cursorMovementIterator):
     17        * rendering/RenderText.cpp:
     18        (WebCore::isEmojiGroupCandidate):
     19        (WebCore::isEmojiModifier):
     20        (WebCore::RenderText::previousOffsetForBackwardDeletion):
     21
    1222015-02-03  Jer Noble  <jer.noble@apple.com>
    223
  • trunk/Source/WebCore/platform/graphics/FontCascade.cpp

    r179368 r179567  
    641641    // list of ranges.
    642642    CodePath result = Simple;
     643    bool previousCharacterIsEmojiGroupCandidate = false;
    643644    for (unsigned i = 0; i < len; i++) {
    644645        const UChar c = characters[i];
     646        if (c == zeroWidthJoiner && previousCharacterIsEmojiGroupCandidate)
     647            return Complex;
     648       
     649        previousCharacterIsEmojiGroupCandidate = false;
    645650        if (c < 0x2E5) // U+02E5 through U+02E9 (Modifier Letters : Tone letters) 
    646651            continue;
     
    763768                return Complex;
    764769
     770            if (supplementaryCharacter >= 0x1F466 && supplementaryCharacter <= 0x1F469) {
     771                previousCharacterIsEmojiGroupCandidate = true;
     772                continue;
     773            }
    765774            if (supplementaryCharacter < 0xE0100) // U+E0100 through U+E01EF Unicode variation selectors.
    766775                continue;
  • trunk/Source/WebCore/platform/text/TextBreakIterator.cpp

    r176473 r179567  
    208208        "$Mal1    = [\\u0D15-\\u0D39];"    // Malayalam Letter A,...,Ha
    209209        "$RI      = [\\U0001F1E6-\\U0001F1FF];" // Emoji regional indicators
     210        "$ZWJ     = \\u200D;"               // Zero width joiner
     211        "$EmojiForModsAndSeqs = [\\U0001F466-\\U0001F469];" // Emoji that take Fitzpatrick modifiers AND participate in ZWJ sequences
     212        "$EmojiForModsOnly = [\\u261D \\u270A-\\u270C \\U0001F385 \\U0001F3C3-\\U0001F3C4 \\U0001F3C7 \\U0001F3CA \\U0001F442-\\U0001F443 \\U0001F446-\\U0001F450 \\U0001F46E-\\U0001F478 \\U0001F47C \\U0001F481-\\U0001F483 \\U0001F485-\\U0001F487 \\U0001F4AA \\U0001F645-\\U0001F647 \\U0001F64B-\\U0001F64F \\U0001F6B4-\\U0001F6B6 \\U0001F6C0];" // Emoji that take Fitzpatrick modifiers
     213        "$EmojiMods = [\\U0001F3FB-\\U0001F3FF];" // Fitzpatrick modifiers
    210214        "!!chain;"
    211215        "!!forward;"
     
    226230        "$Kan0 $KanV $Kan1;"               // Kannada Virama (forward)
    227231        "$Mal0 $MalV $Mal1;"               // Malayalam Virama (forward)
     232        "$ZWJ $EmojiForModsAndSeqs;"       // Don't break in emoji ZWJ sequences
     233        "[$EmojiForModsAndSeqs $EmojiForModsOnly] $EmojiMods;" // Don't break between relevant emoji and Fitzpatrick modifier
    228234        "!!reverse;"
    229235        "$LF $CR;"
     
    243249        "$Kan1 $KanV $Kan0;"               // Kannada Virama (backward)
    244250        "$Mal1 $MalV $Mal0;"               // Malayalam Virama (backward)
     251        "$EmojiForModsAndSeqs $ZWJ;"       // Don't break in emoji ZWJ sequences
     252        "$EmojiMods [$EmojiForModsAndSeqs $EmojiForModsOnly];" // Don't break between relevant emoji and Fitzpatrick modifier
    245253        "!!safe_reverse;"
    246254        "!!safe_forward;";
     
    398406    "$XX = [:LineBreak = Unknown:];"
    399407    "$ZW = [:LineBreak = ZWSpace:];"
     408    "$ZWJ = \\u200D;"
     409    "$EmojiForModsAndSeqs = [\\U0001F466-\\U0001F469];"
     410    "$EmojiForModsOnly = [\\u261D \\u270A-\\u270C \\U0001F385 \\U0001F3C3-\\U0001F3C4 \\U0001F3C7 \\U0001F3CA \\U0001F442-\\U0001F443 \\U0001F446-\\U0001F450 \\U0001F46E-\\U0001F478 \\U0001F47C \\U0001F481-\\U0001F483 \\U0001F485-\\U0001F487 \\U0001F4AA \\U0001F645-\\U0001F647 \\U0001F64B-\\U0001F64F \\U0001F6B4-\\U0001F6B6 \\U0001F6C0];"
     411    "$EmojiMods = [\\U0001F3FB-\\U0001F3FF];"
    400412    "$dictionary = [:LineBreak = Complex_Context:];"
    401413    "$ALPlus = [$AL $AI $SA $SG $XX];"
     
    474486    "$CAN_CM $CM* [$SP $ZW];"
    475487    "$CM+ [$SP $ZW];"
     488    "[$EmojiForModsAndSeqs $EmojiMods] $ZWJ $EmojiForModsAndSeqs;"
    476489    "$CAN_CM $CM+;"
    477490    "$CM+;"
     
    540553    "($ALcm | $HLcm | $NUcm) $OPcm;"
    541554    "$CM+ $OPcm;"
    542     "$CPcm ($ALcm | $HLcm | $NUcm);";
     555    "$CPcm ($ALcm | $HLcm | $NUcm);"
     556    "[$EmojiForModsAndSeqs $EmojiForModsOnly] $EmojiMods;";
    543557
    544558static const char* uax14Reverse =
     
    578592    "[$SP $ZW] [$LB4NonBreaks-$CM];"
    579593    "[$SP $ZW] $CM+ $CAN_CM;"
     594    "$EmojiForModsAndSeqs $ZWJ [$EmojiForModsAndSeqs $EmojiMods];"
    580595    "$CM+ $CAN_CM;"
    581596    "$CM* $WJ $CM* $CAN_CM;"
     
    634649    "$CM* ($ALPlus | $HL) $CM* $IS;"
    635650    "$CM* $OP $CM* ($ALPlus | $HL | $NU);"
    636     "$CM* ($ALPlus | $HL | $NU) $CM* $CP;";
     651    "$CM* ($ALPlus | $HL | $NU) $CM* $CP;"
     652    "$EmojiMods [$EmojiForModsAndSeqs $EmojiForModsOnly];";
    637653
    638654static const char* uax14SafeForward =
  • trunk/Source/WebCore/rendering/RenderText.cpp

    r178940 r179567  
    14221422};
    14231423
    1424 inline bool isHangulLVT(UChar32 character)
     1424static inline bool isHangulLVT(UChar32 character)
    14251425{
    14261426    return (character - HANGUL_SYLLABLE_START) % HANGUL_JONGSEONG_COUNT;
    14271427}
    14281428
    1429 inline bool isMark(UChar32 c)
    1430 {
    1431     int8_t charType = u_charType(c);
     1429static inline bool isMark(UChar32 character)
     1430{
     1431    int8_t charType = u_charType(character);
    14321432    return charType == U_NON_SPACING_MARK || charType == U_ENCLOSING_MARK || charType == U_COMBINING_SPACING_MARK;
    14331433}
    14341434
    1435 inline bool isRegionalIndicator(UChar32 c)
     1435static inline bool isRegionalIndicator(UChar32 character)
    14361436{
    14371437    // National flag emoji each consists of a pair of regional indicator symbols.
    1438     return 0x1F1E6 <= c && c <= 0x1F1FF;
     1438    return 0x1F1E6 <= character && character <= 0x1F1FF;
     1439}
     1440
     1441static inline bool isEmojiGroupCandidate(UChar32 character)
     1442{
     1443    return character >= 0x1F466 && character <= 0x1F469;
     1444}
     1445
     1446static inline bool isEmojiModifier(UChar32 character)
     1447{
     1448    return character >= 0x1F3FB && character <= 0x1F3FF;
    14391449}
    14401450
     
    14481458    UChar32 character;
    14491459    bool sawRegionalIndicator = false;
     1460    bool sawEmojiGroupCandidate = false;
     1461    bool sawEmojiModifier = false;
     1462   
    14501463    while (current > 0) {
    14511464        if (U16_IS_TRAIL(text[--current]))
     
    14551468
    14561469        UChar32 character = text.characterStartingAt(current);
     1470
     1471        if (sawEmojiGroupCandidate) {
     1472            sawEmojiGroupCandidate = false;
     1473            if (character == zeroWidthJoiner)
     1474                continue;
     1475            // We could have two emoji group candidates without a joiner in between.
     1476            // Those should not be treated as a group.
     1477            U16_FWD_1_UNSAFE(text, current);
     1478            break;
     1479        }
     1480
     1481        if (sawEmojiModifier) {
     1482            if (isEmojiModifier(character))
     1483                U16_FWD_1_UNSAFE(text, current);
     1484            break;
     1485        }
    14571486
    14581487        if (sawRegionalIndicator) {
     
    14721501        if (isRegionalIndicator(character)) {
    14731502            sawRegionalIndicator = true;
     1503            continue;
     1504        }
     1505       
     1506        if (isEmojiModifier(character)) {
     1507            sawEmojiModifier = true;
     1508            continue;
     1509        }
     1510
     1511        if (isEmojiGroupCandidate(character)) {
     1512            sawEmojiGroupCandidate = true;
    14741513            continue;
    14751514        }
Note: See TracChangeset for help on using the changeset viewer.