Add some new emoji with modifiers and new sequence.
authorenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Aug 2015 15:15:40 +0000 (15:15 +0000)
committerenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Aug 2015 15:15:40 +0000 (15:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148202
rdar://problem/21849857

Reviewed by Sam Weinig.

Source/WebCore:

Adding support for some new emoji with modifiers and
one new emoji sequence.

* platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::characterRangeCodePath):
* platform/text/CharacterProperties.h:
(WebCore::isEmojiGroupCandidate):
(WebCore::isEmojiModifier):
* platform/text/TextBreakIterator.cpp:
(WebCore::cursorMovementIterator):

LayoutTests:

Updated test to reflect the changes.

* editing/deleting/delete-emoji-expected.txt:
* editing/deleting/delete-emoji.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189024 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/editing/deleting/delete-emoji-expected.txt
LayoutTests/editing/deleting/delete-emoji.html
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/FontCascade.cpp
Source/WebCore/platform/text/CharacterProperties.h
Source/WebCore/platform/text/TextBreakIterator.cpp

index 7b2166e..c0304d6 100644 (file)
@@ -1,3 +1,16 @@
+2015-08-27  Enrica Casucci  <enrica@apple.com>
+
+        Add some new emoji with modifiers and new sequence.
+        https://bugs.webkit.org/show_bug.cgi?id=148202
+        rdar://problem/21849857
+
+        Reviewed by Sam Weinig.
+
+        Updated test to reflect the changes.
+
+        * editing/deleting/delete-emoji-expected.txt:
+        * editing/deleting/delete-emoji.html:
+
 2015-08-27  Dean Jackson  <dino@apple.com>
 
         Initial infrastructure of media controls testing
index 15d8557..5f3720e 100644 (file)
@@ -1,38 +1,65 @@
 This test verifies that emoji groups and emoji with variations are deleted correctly
 
 Dump of markup 1:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»<#selection-caret>
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»βœπŸΎβ›ΉπŸΎπŸ–πŸΎπŸ–•πŸΎπŸ€˜πŸΎπŸ•΅πŸΎπŸ•΄πŸΎπŸ‹πŸΎπŸ‘β€πŸ—¨<#selection-caret>
 "
 
 Dump of markup 2:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»βœπŸΎβ›ΉπŸΎπŸ–πŸΎπŸ–•πŸΎπŸ€˜πŸΎπŸ•΅πŸΎπŸ•΄πŸΎπŸ‹πŸΎ<#selection-caret>"
 
 Dump of markup 3:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»βœπŸΎβ›ΉπŸΎπŸ–πŸΎπŸ–•πŸΎπŸ€˜πŸΎπŸ•΅πŸΎπŸ•΄πŸΎ<#selection-caret>"
 
 Dump of markup 4:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»βœπŸΎβ›ΉπŸΎπŸ–πŸΎπŸ–•πŸΎπŸ€˜πŸΎπŸ•΅πŸΎ<#selection-caret>"
 
 Dump of markup 5:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»βœπŸΎβ›ΉπŸΎπŸ–πŸΎπŸ–•πŸΎπŸ€˜πŸΎ<#selection-caret>"
 
 Dump of markup 6:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»βœπŸΎβ›ΉπŸΎπŸ–πŸΎπŸ–•πŸΎ<#selection-caret>"
 
 Dump of markup 7:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»βœπŸΎβ›ΉπŸΎπŸ–πŸΎ<#selection-caret>"
 
 Dump of markup 8:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎ<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»βœπŸΎβ›ΉπŸΎ<#selection-caret>"
 
 Dump of markup 9:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»βœπŸΎ<#selection-caret>"
 
 Dump of markup 10:
-| "πŸ‘¦πŸ»πŸ‘¦πŸΎ<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨β˜οΈπŸ»<#selection-caret>"
 
 Dump of markup 11:
-| "πŸ‘¦πŸ»<#selection-caret>"
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ’‹β€πŸ‘¨<#selection-caret>"
 
 Dump of markup 12:
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨πŸ‘©β€β€οΈβ€πŸ’‹β€πŸ‘©<#selection-caret>"
+
+Dump of markup 13:
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©πŸ‘¨β€β€οΈβ€πŸ‘¨<#selection-caret>"
+
+Dump of markup 14:
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦πŸ‘©β€β€οΈβ€πŸ‘©<#selection-caret>"
+
+Dump of markup 15:
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦<#selection-caret>"
+
+Dump of markup 16:
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎπŸ‘¦<#selection-caret>"
+
+Dump of markup 17:
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»πŸ‘¦πŸΎ<#selection-caret>"
+
+Dump of markup 18:
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎπŸ»<#selection-caret>"
+
+Dump of markup 19:
+| "πŸ‘¦πŸ»πŸ‘¦πŸΎ<#selection-caret>"
+
+Dump of markup 20:
+| "πŸ‘¦πŸ»<#selection-caret>"
+
+Dump of markup 21:
 | <br>
index 77b895b..39835ce 100644 (file)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <body>
-<div id="test" contenteditable="true">&#x1F466;&#x1F3FB;&#x1F466;&#x1F3FE;&#x1F3FB;&#x1F466;&#x1F3FE;&#x1F466;&#x1F469;&#x200D;&#x1F469;&#x200D;&#x1F466;&#x1F469;&#x200D;&#x2764;&#xFE0F;&#x200D;&#x1F469;&#x1F468;&#x200D;&#x2764;&#xFE0F;&#x200D;&#x1F468;&#x1F469;&#x200D;&#x2764;&#xFE0F;&#x200D;&#x1F48B;&#x200D;&#x1F469;&#x1F468;&#x200D;&#x2764;&#xFE0F;&#x200D;&#x1F48B;&#x200D;&#x1F468;&#x261D;&#xFE0F;&#x1F3FB;
+<div id="test" contenteditable="true">&#x1F466;&#x1F3FB;&#x1F466;&#x1F3FE;&#x1F3FB;&#x1F466;&#x1F3FE;&#x1F466;&#x1F469;&#x200D;&#x1F469;&#x200D;&#x1F466;&#x1F469;&#x200D;&#x2764;&#xFE0F;&#x200D;&#x1F469;&#x1F468;&#x200D;&#x2764;&#xFE0F;&#x200D;&#x1F468;&#x1F469;&#x200D;&#x2764;&#xFE0F;&#x200D;&#x1F48B;&#x200D;&#x1F469;&#x1F468;&#x200D;&#x2764;&#xFE0F;&#x200D;&#x1F48B;&#x200D;&#x1F468;&#x261D;&#xFE0F;&#x1F3FB;&#x270D;&#x1F3FE;&#x26F9;&#x1F3FE;&#x1F590;&#x1F3FE;&#x1F595;&#x1F3FE;&#x1F918;&#x1F3FE;&#x1F575;&#x1F3FE;&#x1F574;&#x1F3FE;&#x1F3CB;&#x1F3FE;&#x1F441;&#x200D;&#x1F5E8;
 </div>
 <script src="../../resources/dump-as-markup.js"></script>
 <script>
index f5609a6..bfca0c1 100644 (file)
@@ -1,3 +1,22 @@
+2015-08-27  Enrica Casucci  <enrica@apple.com>
+
+        Add some new emoji with modifiers and new sequence.
+        https://bugs.webkit.org/show_bug.cgi?id=148202
+        rdar://problem/21849857
+
+        Reviewed by Sam Weinig.
+
+        Adding support for some new emoji with modifiers and
+        one new emoji sequence.
+
+        * platform/graphics/FontCascade.cpp:
+        (WebCore::FontCascade::characterRangeCodePath):
+        * platform/text/CharacterProperties.h:
+        (WebCore::isEmojiGroupCandidate):
+        (WebCore::isEmojiModifier):
+        * platform/text/TextBreakIterator.cpp:
+        (WebCore::cursorMovementIterator):
+
 2015-08-27  Dean Jackson  <dino@apple.com>
 
         Initial infrastructure of media controls testing
index 8fd1bde..3695942 100644 (file)
@@ -751,7 +751,7 @@ FontCascade::CodePath FontCascade::characterRangeCodePath(const UChar* character
             if (supplementaryCharacter <= 0x1F1FF)
                 return Complex;
 
-            if (supplementaryCharacter >= 0x1F466 && supplementaryCharacter <= 0x1F469) {
+            if (supplementaryCharacter == 0x1F441 || supplementaryCharacter == 0x1F5E8 || (supplementaryCharacter >= 0x1F466 && supplementaryCharacter <= 0x1F469)) {
                 previousCharacterIsEmojiGroupCandidate = true;
                 continue;
             }
index 00d0faf..774b635 100644 (file)
@@ -30,7 +30,8 @@ namespace WebCore {
 
 static inline bool isEmojiGroupCandidate(UChar32 character)
 {
-    return (character >= 0x1F466 && character <= 0x1F469) || character == 0x2764 || character == 0x1F48B;
+    return (character >= 0x1F466 && character <= 0x1F469) || character == 0x2764 || character == 0x1F48B
+        || character == 0x1F441 || character == 0x1F5E8;
 }
 
 static inline bool isEmojiModifier(UChar32 character)
index 73b4d55..504953f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2015 Apple Inc. All rights reserved.
  * Copyright (C) 2007-2009 Torch Mobile, Inc.
  *
  * This library is free software; you can redistribute it and/or
 #include "UTextProviderUTF16.h"
 #include <mutex>
 #include <wtf/Atomics.h>
-#include <wtf/Lock.h>
 #include <wtf/text/StringView.h>
 
+// FIXME: This needs a better name
+#define ADDITIONAL_EMOJI_SUPPORT ((PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100))
+
 namespace WebCore {
 
 // Iterator initialization
@@ -210,19 +212,34 @@ TextBreakIterator* cursorMovementIterator(StringView string)
         "$RI      = [\\U0001F1E6-\\U0001F1FF];" // Emoji regional indicators
         "$ZWJ     = \\u200D;"               // Zero width joiner
         "$EmojiVar = [\\uFE0F];"            // Emoji-style variation selector
+#if ADDITIONAL_EMOJI_SUPPORT
+        "$EmojiForSeqs = [\\u2764 \\U0001F441 \\U0001F466-\\U0001F469 \\U0001F48B \\U0001F5E8];" // Emoji that participate in ZWJ sequences
+        "$EmojiForMods = [\\u261D \\u270A-\\u270D \\U0001F385 \\U0001F3C3-\\U0001F3C4 \\U0001F3C7 \\U0001F3CA \\U0001F442-\\U0001F443 \\U0001F446-\\U0001F450 \\U0001F466-\\U0001F469 \\U0001F46E-\\U0001F478 \\U0001F47C \\U0001F481-\\U0001F483 \\U0001F485-\\U0001F487 \\U0001F4AA \\U0001F590 \\U0001F595 \\U0001F596 \\U0001F645-\\U0001F647 \\U0001F64B-\\U0001F64F \\U0001F6A3 \\U0001F6B4-\\U0001F6B6 \\U0001F6C0 \\U0001F918] ;" // Emoji that take Fitzpatrick modifiers
+#else
         "$EmojiForSeqs = [\\u2764 \\U0001F466-\\U0001F469 \\U0001F48B];" // Emoji that participate in ZWJ sequences
         "$EmojiForMods = [\\u261D \\u270A-\\u270C \\U0001F385 \\U0001F3C3-\\U0001F3C4 \\U0001F3C7 \\U0001F3CA \\U0001F442-\\U0001F443 \\U0001F446-\\U0001F450 \\U0001F466-\\U0001F469 \\U0001F46E-\\U0001F478 \\U0001F47C \\U0001F481-\\U0001F483 \\U0001F485-\\U0001F487 \\U0001F4AA \\U0001F596 \\U0001F645-\\U0001F647 \\U0001F64B-\\U0001F64F \\U0001F6A3 \\U0001F6B4-\\U0001F6B6 \\U0001F6C0] ;" // Emoji that take Fitzpatrick modifiers
+#endif
         "$EmojiMods = [\\U0001F3FB-\\U0001F3FF];" // Fitzpatrick modifiers
         "!!chain;"
+#if ADDITIONAL_EMOJI_SUPPORT
+        "!!RINoChain;"
+#endif
         "!!forward;"
         "$CR $LF;"
         "$L ($L | $V | $LV | $LVT);"
         "($LV | $V) ($V | $T);"
         "($LVT | $T) $T;"
+#if ADDITIONAL_EMOJI_SUPPORT
+        "$RI $RI $Extend* / $RI;"
+        "$RI $RI $Extend*;"
+        "[^$Control $CR $LF] $Extend;"
+        "[^$Control $CR $LF] $SpacingMark;"
+#else
         "[^$Control $CR $LF] $Extend;"
         "[^$Control $CR $LF] $SpacingMark;"
         "$RI $RI / $RI;"
         "$RI $RI;"
+#endif
         "$Hin0 $HinV $Hin1;"               // Devanagari Virama (forward)
         "$Ben0 $BenV $Ben1;"               // Bengali Virama (forward)
         "$Pan0 $PanV $Pan1;"               // Gurmukhi Virama (forward)
@@ -238,10 +255,17 @@ TextBreakIterator* cursorMovementIterator(StringView string)
         "($L | $V | $LV | $LVT) $L;"
         "($V | $T) ($LV | $V);"
         "$T ($LVT | $T);"
+#if ADDITIONAL_EMOJI_SUPPORT
+        "$Extend* $RI $RI / $Extend* $RI $RI;"
+        "$Extend* $RI $RI;"
+        "$Extend      [^$Control $CR $LF];"
+        "$SpacingMark [^$Control $CR $LF];"
+#else
         "$Extend      [^$Control $CR $LF];"
         "$SpacingMark [^$Control $CR $LF];"
         "$RI $RI / $RI $RI;"
         "$RI $RI;"
+#endif
         "$Hin1 $HinV $Hin0;"               // Devanagari Virama (backward)
         "$Ben1 $BenV $Ben0;"               // Bengali Virama (backward)
         "$Pan1 $PanV $Pan0;"               // Gurmukhi Virama (backward)
@@ -252,10 +276,19 @@ TextBreakIterator* cursorMovementIterator(StringView string)
         "$Mal1 $MalV $Mal0;"               // Malayalam Virama (backward)
         "$EmojiForSeqs $ZWJ;"              // Don't break in emoji ZWJ sequences
         "$EmojiMods $EmojiVar? $EmojiForMods;" // Don't break between relevant emoji (possibly with variation selector) and Fitzpatrick modifier
+#if ADDITIONAL_EMOJI_SUPPORT
+        "!!safe_reverse;"
+        "$RI $RI+;"
+        "[$EmojiVar $EmojiMods]+ $EmojiForMods;"
+        "!!safe_forward;"
+        "$RI $RI+;"
+        "$EmojiForMods [$EmojiVar $EmojiMods]+;";
+#else
         "[$EmojiVar $EmojiMods]+ $EmojiForMods;"
         "$EmojiForMods [$EmojiVar $EmojiMods]+;"
         "!!safe_reverse;"
         "!!safe_forward;";
+#endif
     static TextBreakIterator* staticCursorMovementIterator = initializeIteratorWithRules(kRules);
 #else // PLATFORM(IOS)
     // Use the special Thai character break iterator for all locales
@@ -402,6 +435,7 @@ static const char* uax14AssignmentsAfter =
     "$PO = [[:LineBreak = Postfix_Numeric:] - $PO_SUB];"
     "$PR = [[:LineBreak = Prefix_Numeric:] - $PR_SUB];"
     "$QU = [:LineBreak = Quotation:];"
+    "$RI = [\\U0001F1E6-\\U0001F1FF];"
     "$SA = [:LineBreak = Complex_Context:];"
     "$SG = [:LineBreak = Surrogate:];"
     "$SP = [:LineBreak = Space:];"
@@ -411,8 +445,13 @@ static const char* uax14AssignmentsAfter =
     "$ZW = [:LineBreak = ZWSpace:];"
     "$ZWJ = \\u200D;"
     "$EmojiVar = \\uFE0F;"
+#if ADDITIONAL_EMOJI_SUPPORT
+    "$EmojiForSeqs = [\\u2764 \\U0001F441 \\U0001F466-\\U0001F469 \\U0001F48B \\U0001F5E8];"
+    "$EmojiForMods = [\\u261D \\u270A-\\u270D \\U0001F385 \\U0001F3C3-\\U0001F3C4 \\U0001F3C7 \\U0001F3CA \\U0001F442-\\U0001F443 \\U0001F446-\\U0001F450 \\U0001F466-\\U0001F469 \\U0001F46E-\\U0001F478 \\U0001F47C \\U0001F481-\\U0001F483 \\U0001F485-\\U0001F487 \\U0001F4AA \\U0001F590 \\U0001F595 \\U0001F596 \\U0001F645-\\U0001F647 \\U0001F64B-\\U0001F64F \\U0001F6A3 \\U0001F6B4-\\U0001F6B6 \\U0001F6C0 \\U0001F918] ;" // Emoji that take Fitzpatrick modifiers
+#else
     "$EmojiForSeqs = [\\u2764 \\U0001F466-\\U0001F469 \\U0001F48B];"
     "$EmojiForMods = [\\u261D \\u270A-\\u270C \\U0001F385 \\U0001F3C3-\\U0001F3C4 \\U0001F3C7 \\U0001F3CA \\U0001F442-\\U0001F443 \\U0001F446-\\U0001F450 \\U0001F466-\\U0001F469 \\U0001F46E-\\U0001F478 \\U0001F47C \\U0001F481-\\U0001F483 \\U0001F485-\\U0001F487 \\U0001F4AA \\U0001F596 \\U0001F645-\\U0001F647 \\U0001F64B-\\U0001F64F \\U0001F6A3 \\U0001F6B4-\\U0001F6B6 \\U0001F6C0] ;" // Emoji that take Fitzpatrick modifiers
+#endif
     "$EmojiMods = [\\U0001F3FB-\\U0001F3FF];"
     "$dictionary = [:LineBreak = Complex_Context:];"
     "$ALPlus = [$AL $AI $SA $SG $XX];"
@@ -440,6 +479,7 @@ static const char* uax14AssignmentsAfter =
     "$POcm = $PO $CM*;"
     "$PRcm = $PR $CM*;"
     "$QUcm = $QU $CM*;"
+    "$RIcm = $QU $CM*;"
     "$SYcm = $SY $CM*;"
     "$WJcm = $WJ $CM*;";
 
@@ -558,6 +598,9 @@ static const char* uax14Forward =
     "($ALcm | $HLcm | $NUcm) $OPcm;"
     "$CM+ $OPcm;"
     "$CPcm ($ALcm | $HLcm | $NUcm);"
+#if ADDITIONAL_EMOJI_SUPPORT
+    "$RIcm $RIcm;"
+#endif
     "$EmojiForMods $EmojiVar? $EmojiMods;";
 
 static const char* uax14Reverse =
@@ -586,6 +629,9 @@ static const char* uax14Reverse =
     "$CM+ $PO;"
     "$CM+ $PR;"
     "$CM+ $QU;"
+#if ADDITIONAL_EMOJI_SUPPORT
+    "$CM+ $RI;"
+#endif
     "$CM+ $SY;"
     "$CM+ $WJ;"
     "$CM+;"
@@ -654,6 +700,9 @@ static const char* uax14Reverse =
     "$CM* ($ALPlus | $HL) $CM* $IS;"
     "$CM* $OP $CM* ($ALPlus | $HL | $NU);"
     "$CM* ($ALPlus | $HL | $NU) $CM* $CP;"
+#if ADDITIONAL_EMOJI_SUPPORT
+    "$CM* $RI $CM* $RI;"
+#endif
     "$EmojiMods $EmojiVar? $EmojiForMods;";
 
 static const char* uax14SafeForward =