Lookup glyph from color emoji font before and after ZWJ.

Unicode recommends that the zwj sequences should be emoji presentation
even if they don't have the proper U+FE0F. Thus always lookup the glyph
for the code point before and after zwj as if they have a U+FE0F
variation selector.

Bug: 30056627
Change-Id: I03958a92337eaba4a8dd9c5be824b2665aa4a103
diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp
index 33418ab..e665615 100644
--- a/libs/minikin/FontCollection.cpp
+++ b/libs/minikin/FontCollection.cpp
@@ -335,18 +335,15 @@
 }
 
 const uint32_t NBSP = 0xa0;
-const uint32_t ZWJ = 0x200c;
-const uint32_t ZWNJ = 0x200d;
+const uint32_t ZWJ = 0x200d;
+const uint32_t ZWNJ = 0x200c;
 const uint32_t HYPHEN = 0x2010;
 const uint32_t NB_HYPHEN = 0x2011;
-const uint32_t FEMALE_SIGN = 0x2640;
-const uint32_t MALE_SIGN = 0x2642;
-const uint32_t STAFF_OF_AESCULAPIUS = 0x2695;
 
 // Characters where we want to continue using existing font run instead of
 // recomputing the best match in the fallback list.
 static const uint32_t stickyWhitelist[] = { '!', ',', '-', '.', ':', ';', '?', NBSP, ZWJ, ZWNJ,
-        HYPHEN, NB_HYPHEN, FEMALE_SIGN, MALE_SIGN, STAFF_OF_AESCULAPIUS };
+        HYPHEN, NB_HYPHEN };
 
 static bool isStickyWhitelisted(uint32_t c) {
     for (size_t i = 0; i < sizeof(stickyWhitelist) / sizeof(stickyWhitelist[0]); i++) {
@@ -432,8 +429,15 @@
         }
 
         if (!shouldContinueRun) {
-            FontFamily* family = getFamilyForChar(ch, isVariationSelector(nextCh) ? nextCh : 0,
+            FontFamily* family;
+            if ((prevCh == ZWJ || nextCh == ZWJ) && isEmoji(ch)) {
+                // Treat emoji before and after ZWJ as emoji presentation.
+                family = getFamilyForChar(ch, EMOJI_STYLE_VS, langListId, variant);
+            } else {
+                family = getFamilyForChar(ch, isVariationSelector(nextCh) ? nextCh : 0,
                     langListId, variant);
+            }
+
             if (utf16Pos == 0 || family != lastFamily) {
                 size_t start = utf16Pos;
                 // Workaround for combining marks and emoji modifiers until we implement
diff --git a/tests/FontCollectionItemizeTest.cpp b/tests/FontCollectionItemizeTest.cpp
index 468b4a2..85d223c 100644
--- a/tests/FontCollectionItemizeTest.cpp
+++ b/tests/FontCollectionItemizeTest.cpp
@@ -1223,7 +1223,7 @@
     EXPECT_EQ(2, runs[0].end);
     EXPECT_EQ(kNoGlyphFont, getFontPath(runs[0]));
 
-    // U+26FA U+FE0E is specified but ColorTextMixedEmojiFont has a variation sequence U+26F9 U+FE0F
+    // U+26FA U+FE0E is specified but ColorTextMixedEmojiFont has a variation sequence U+26FA U+FE0F
     // in its cmap, so ColorTextMixedEmojiFont should be selected instaed of ColorEmojiFont.
     itemize(collection.get(), "U+26FA U+FE0E", kDefaultFontStyle, &runs);
     ASSERT_EQ(1U, runs.size());
@@ -1305,9 +1305,9 @@
     EXPECT_EQ(2, runs[0].end);
     EXPECT_EQ(kNoGlyphFont, getFontPath(runs[0]));
 
-    // U+26F9 U+FE0F is specified but ColorTextMixedEmojiFont has a variation sequence U+26F9 U+FE0F
+    // U+26F8 U+FE0F is specified but ColorTextMixedEmojiFont has a variation sequence U+26F8 U+FE0F
     // in its cmap, so ColorTextMixedEmojiFont should be selected instaed of ColorEmojiFont.
-    itemize(collection.get(), "U+26F9 U+FE0F", kDefaultFontStyle, &runs);
+    itemize(collection.get(), "U+26F8 U+FE0F", kDefaultFontStyle, &runs);
     ASSERT_EQ(1U, runs.size());
     EXPECT_EQ(0, runs[0].start);
     EXPECT_EQ(2, runs[0].end);
@@ -1396,4 +1396,10 @@
     EXPECT_EQ(0, runs[0].start);
     EXPECT_EQ(4, runs[0].end);
     EXPECT_EQ(kColorEmojiFont, getFontPath(runs[0]));
+
+    itemize(collection.get(), "U+26F9 U+200D U+2695", kDefaultFontStyle, &runs);
+    ASSERT_EQ(1U, runs.size());
+    EXPECT_EQ(0, runs[0].start);
+    EXPECT_EQ(3, runs[0].end);
+    EXPECT_EQ(kColorEmojiFont, getFontPath(runs[0]));
 }
diff --git a/tests/data/ColorEmojiFont.ttf b/tests/data/ColorEmojiFont.ttf
index eee1c37..ecc4b9e 100644
--- a/tests/data/ColorEmojiFont.ttf
+++ b/tests/data/ColorEmojiFont.ttf
Binary files differ
diff --git a/tests/data/ColorEmojiFont.ttx b/tests/data/ColorEmojiFont.ttx
index 5e16574..69b5666 100644
--- a/tests/data/ColorEmojiFont.ttx
+++ b/tests/data/ColorEmojiFont.ttx
@@ -147,7 +147,7 @@
       <map code="0x203C" name="defaultGlyph" /> <!-- Text Default -->
       <map code="0x231B" name="defaultGlyph" /> <!-- Emoji Default -->
       <map code="0x23E9" name="defaultGlyph" /> <!-- Emoji Default -->
-      <map code="0x26F9" name="defaultGlyph" /> <!-- U+26F9 U+FE0F is in ColorTextMixedEmojiFont.ttf -->
+      <map code="0x26F8" name="defaultGlyph" /> <!-- U+26F8 U+FE0F is in ColorTextMixedEmojiFont.ttf -->
       <map code="0x261D" name="defaultGlyph" />
       <map code="0x1F3FD" name="defaultGlyph" />
 
@@ -158,10 +158,11 @@
       <map code="0x262E" name="defaultGlyph" />
       <map code="0x262F" name="defaultGlyph" />
 
-      <!--For FontCollectionItemizeTest,.itemize_genderBalancedEmoji -->
+      <!--For FontCollectionItemizeTest.itemize_genderBalancedEmoji -->
       <map code="0x1F469" name="defaultGlyph" />
       <map code="0x1F373" name="defaultGlyph" />
       <map code="0x200D" name="defaultGlyph" />
+      <map code="0x26F9" name="defaultGlyph" />
       <map code="0x2695" name="defaultGlyph" />
 
       <!-- U+2640, U+2642 are reserved for FontCollectionTest.newEmojiTest -->
diff --git a/tests/data/ColorTextMixedEmojiFont.ttf b/tests/data/ColorTextMixedEmojiFont.ttf
index 57ee330..7f60925 100644
--- a/tests/data/ColorTextMixedEmojiFont.ttf
+++ b/tests/data/ColorTextMixedEmojiFont.ttf
Binary files differ
diff --git a/tests/data/ColorTextMixedEmojiFont.ttx b/tests/data/ColorTextMixedEmojiFont.ttx
index 461210b..f74cfd0 100644
--- a/tests/data/ColorTextMixedEmojiFont.ttx
+++ b/tests/data/ColorTextMixedEmojiFont.ttx
@@ -145,7 +145,7 @@
     <tableVersion version="0"/>
     <cmap_format_14 format="14" platformID="0" platEncID="5" length="40" numVarSelectorRecords="2">
       <map uvs="0xFE0E" uv="0x26FA" name="Emoji1" />
-      <map uvs="0xFE0F" uv="0x26F9" name="Emoji2" />
+      <map uvs="0xFE0F" uv="0x26F8" name="Emoji2" />
     </cmap_format_14>
   </cmap>
 
diff --git a/tests/data/TextEmojiFont.ttf b/tests/data/TextEmojiFont.ttf
index 6a5e9d9..21ac987 100644
--- a/tests/data/TextEmojiFont.ttf
+++ b/tests/data/TextEmojiFont.ttf
Binary files differ
diff --git a/tests/data/TextEmojiFont.ttx b/tests/data/TextEmojiFont.ttx
index eb49422..66247b6 100644
--- a/tests/data/TextEmojiFont.ttx
+++ b/tests/data/TextEmojiFont.ttx
@@ -165,6 +165,7 @@
       <!-- For FontCollectionTest.newEmojiTest -->
       <map code="0x2640" name="defaultGlyph" />
       <map code="0x2642" name="defaultGlyph" />
+      <map code="0x26F9" name="defaultGlyph" />
 
     </cmap_format_4>
     <cmap_format_14 format="14" platformID="0" platEncID="5" length="40" numVarSelectorRecords="2">