Add Symbol encoding when renaming a font.

GDI will not use a Symbol encoded cmap table if there is no Symbol
encoded name. Always output both Unicode and Symbol names (same data,
different name entries). This fixes test_symbolfont on GDI.

Change-Id: I05dea903b9c3914a852cf31472a19a6a06b274e0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/233079
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Herb Derby <herb@google.com>
diff --git a/src/sfnt/SkOTUtils.cpp b/src/sfnt/SkOTUtils.cpp
index 869fec2..061ceb0 100644
--- a/src/sfnt/SkOTUtils.cpp
+++ b/src/sfnt/SkOTUtils.cpp
@@ -65,18 +65,25 @@
     }
 
     // The required 'name' record types: Family, Style, Unique, Full and PostScript.
-    const SkOTTableName::Record::NameID::Predefined::Value namesToCreate[] = {
+    static constexpr std::array<SkOTTableName::Record::NameID::Predefined::Value, 5> names{{
         SkOTTableName::Record::NameID::Predefined::FontFamilyName,
         SkOTTableName::Record::NameID::Predefined::FontSubfamilyName,
         SkOTTableName::Record::NameID::Predefined::UniqueFontIdentifier,
         SkOTTableName::Record::NameID::Predefined::FullFontName,
         SkOTTableName::Record::NameID::Predefined::PostscriptName,
-    };
-    const int namesCount = SK_ARRAY_COUNT(namesToCreate);
+    }};
+
+    // GDI will not use a Symbol cmap table if there is no Symbol encoded name.
+    static constexpr std::array<SkOTTableName::Record::EncodingID::Windows::Value, 2> encodings{{
+        SkOTTableName::Record::EncodingID::Windows::Symbol,
+        SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2,
+    }};
 
     // Copy the data, leaving out the old name table.
     // In theory, we could also remove the DSIG table if it exists.
-    size_t nameTableLogicalSize = sizeof(SkOTTableName) + (namesCount * sizeof(SkOTTableName::Record)) + (fontNameLen * sizeof(wchar_t));
+    size_t nameTableLogicalSize = sizeof(SkOTTableName)
+                                + (encodings.size() * names.size() * sizeof(SkOTTableName::Record))
+                                + (fontNameLen * sizeof(SK_OT_USHORT));
     size_t nameTablePhysicalSize = (nameTableLogicalSize + 3) & ~3; // Rounded up to a multiple of 4.
 
     size_t oldNameTablePhysicalSize = (SkEndian_SwapBE32(tableEntry.logicalLength) + 3) & ~3; // Rounded up to a multiple of 4.
@@ -108,6 +115,7 @@
         if (oldOffset > oldNameTableOffset) {
             currentEntry->offset = SkEndian_SwapBE32(SkToU32(oldOffset - oldNameTablePhysicalSize));
         }
+
         if (SkOTTableHead::TAG == currentEntry->tag) {
             headTableEntry = currentEntry;
         }
@@ -120,19 +128,22 @@
 
     // Write the new 'name' table after the original font data.
     SkOTTableName* nameTable = reinterpret_cast<SkOTTableName*>(data + originalDataSize);
-    unsigned short stringOffset = sizeof(SkOTTableName) + (namesCount * sizeof(SkOTTableName::Record));
+    unsigned short stringOffset = sizeof(SkOTTableName) + (encodings.size() * names.size() * sizeof(SkOTTableName::Record));
     nameTable->format = SkOTTableName::format_0;
-    nameTable->count = SkEndian_SwapBE16(namesCount);
+    nameTable->count = SkEndian_SwapBE16(encodings.size() * names.size());
     nameTable->stringOffset = SkEndian_SwapBE16(stringOffset);
 
-    SkOTTableName::Record* nameRecords = reinterpret_cast<SkOTTableName::Record*>(data + originalDataSize + sizeof(SkOTTableName));
-    for (int i = 0; i < namesCount; ++i) {
-        nameRecords[i].platformID.value = SkOTTableName::Record::PlatformID::Windows;
-        nameRecords[i].encodingID.windows.value = SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2;
-        nameRecords[i].languageID.windows.value = SkOTTableName::Record::LanguageID::Windows::English_UnitedStates;
-        nameRecords[i].nameID.predefined.value = namesToCreate[i];
-        nameRecords[i].offset = SkEndian_SwapBE16(0);
-        nameRecords[i].length = SkEndian_SwapBE16(SkToU16(fontNameLen * sizeof(wchar_t)));
+    SkOTTableName::Record* nameRecord = reinterpret_cast<SkOTTableName::Record*>(data + originalDataSize + sizeof(SkOTTableName));
+    for (const auto& encoding : encodings) {
+        for (const auto& name : names) {
+            nameRecord->platformID.value = SkOTTableName::Record::PlatformID::Windows;
+            nameRecord->encodingID.windows.value = encoding;
+            nameRecord->languageID.windows.value = SkOTTableName::Record::LanguageID::Windows::English_UnitedStates;
+            nameRecord->nameID.predefined.value = name;
+            nameRecord->offset = SkEndian_SwapBE16(0);
+            nameRecord->length = SkEndian_SwapBE16(SkToU16(fontNameLen * sizeof(SK_OT_USHORT)));
+            ++nameRecord;
+        }
     }
 
     SK_OT_USHORT* nameString = reinterpret_cast<SK_OT_USHORT*>(data + originalDataSize + stringOffset);