Snap for 4448085 from 82d8e4166512ebc404f146eb205a93fb03e4f47c to oc-m3-release

Change-Id: Ifdd9f1476f44d59b88bf8798d8d6587226a5bd24
diff --git a/emoji-compat/createfont.py b/emoji-compat/createfont.py
index 81feb48..a6566a0 100755
--- a/emoji-compat/createfont.py
+++ b/emoji-compat/createfont.py
@@ -30,7 +30,7 @@
 - additions/emoji-zwj-sequences.txt: Includes emojis that are not defined in Unicode files, but are
 in the Android font. Resides in framework and currently under external/unicode/.
 
-- ../third_party/unicode/emoji_metadata.txt: The file that includes the id, codepoints, the first
+- data/emoji_metadata.txt: The file that includes the id, codepoints, the first
 Android OS version that the emoji was added (sdkAdded), and finally the first EmojiCompat font
 version that the emoji was added (compatAdded). Updated when the script is executed.
 
@@ -48,6 +48,7 @@
 import contextlib
 import csv
 import hashlib
+import itertools
 import json
 import os
 import shutil
@@ -58,7 +59,9 @@
 ########### UPDATE OR CHECK WHEN A NEW FONT IS BEING GENERATED ###########
 # Last Android SDK Version
 SDK_VERSION = 26
-# metadata version that will be embedded into font.
+# metadata version that will be embedded into font. If there are updates to the font that would
+# cause data/emoji_metadata.txt to change, this integer number should be incremented. This number
+# defines in which EmojiCompat metadata version the emoji is added to the font.
 METADATA_VERSION = 2
 
 ####### main directories where output files are created #######
@@ -491,12 +494,56 @@
         gsub = ttf['GSUB']
         for lookup in gsub.table.LookupList.Lookup:
             for subtable in lookup.SubTable:
-                if hasattr(subtable, 'ligatures'):
-                    for name, ligatures in subtable.ligatures.iteritems():
-                        for ligature in ligatures:
-                            glyph_names = [name] + ligature.Component
-                            codepoints = [glyph_to_codepoint_map[x] for x in glyph_names]
-                            self.update_emoji_data(codepoints, ligature.LigGlyph)
+                if subtable.LookupType == 5:
+                    self.add_gsub_context_subtable(subtable, gsub.table.LookupList,
+                                                   glyph_to_codepoint_map)
+                elif subtable.LookupType == 4:
+                    self.add_gsub_ligature_subtable(subtable, glyph_to_codepoint_map)
+
+    def add_gsub_context_subtable(self, subtable, lookup_list, glyph_to_codepoint_map):
+        """Add substitutions defined as OpenType Context Substitution"""
+        for sub_class_set in subtable.SubClassSet:
+            if sub_class_set:
+                for sub_class_rule in sub_class_set.SubClassRule:
+                    # prepare holder for substitution list. each rule will have a list that is added
+                    # to the subs_list.
+                    subs_list = len(sub_class_rule.SubstLookupRecord) * [None]
+                    for record in sub_class_rule.SubstLookupRecord:
+                        subs_list[record.SequenceIndex] = self.get_substitutions(lookup_list,
+                                                                            record.LookupListIndex)
+                    # create combinations or all lists. the combinations will be filtered by
+                    # emoji_data_map. the first element that contain as a valid glyph will be used
+                    # as the final glyph
+                    combinations = list(itertools.product(*subs_list))
+                    for seq in combinations:
+                        glyph_names = [x["input"] for x in seq]
+                        codepoints = [glyph_to_codepoint_map[x] for x in glyph_names]
+                        outputs = [x["output"] for x in seq if x["output"]]
+                        nonempty_outputs = filter(lambda x: x.strip() , outputs)
+                        if len(nonempty_outputs) == 0:
+                            print("Warning: no output glyph is set for " + str(glyph_names))
+                            continue
+                        elif len(nonempty_outputs) > 1:
+                            print(
+                                "Warning: multiple glyph is set for "
+                                    + str(glyph_names) + ", will use the first one")
+
+                        glyph = nonempty_outputs[0]
+                        self.update_emoji_data(codepoints, glyph)
+
+    def get_substitutions(self, lookup_list, index):
+        result = []
+        for x in lookup_list.Lookup[index].SubTable:
+            for input, output in x.mapping.iteritems():
+                result.append({"input": input, "output": output})
+        return result
+
+    def add_gsub_ligature_subtable(self, subtable, glyph_to_codepoint_map):
+        for name, ligatures in subtable.ligatures.iteritems():
+            for ligature in ligatures:
+                glyph_names = [name] + ligature.Component
+                codepoints = [glyph_to_codepoint_map[x] for x in glyph_names]
+                self.update_emoji_data(codepoints, ligature.LigGlyph)
 
     def write_metadata_json(self, output_json_file_path):
         """Writes the emojis into a json file"""
diff --git a/emoji-compat/font/NotoColorEmojiCompat.ttf b/emoji-compat/font/NotoColorEmojiCompat.ttf
index ac40624..c753258 100644
--- a/emoji-compat/font/NotoColorEmojiCompat.ttf
+++ b/emoji-compat/font/NotoColorEmojiCompat.ttf
Binary files differ
diff --git a/emoji/NotoColorEmoji.ttf b/emoji/NotoColorEmoji.ttf
index 0c2662e..63dda0e 100644
--- a/emoji/NotoColorEmoji.ttf
+++ b/emoji/NotoColorEmoji.ttf
Binary files differ