Avoid serializing to 'typ1' on Mac.

CoreGraphics does not provide a means to get the original font data for a
CGFont, only the tables. As a result, Skia pieces the font data back
together when requested. The most awkward part of this is choosing the
first four bytes, and the CTFont suggestion seems to often be wrong.

This change doublechecks the selection of 'typ1', prefering to use 'OTTO'
if there are no 'TYP1' or 'CID ' tables. These sorts of fonts are
extremely old and unlikely to be in current use. It appears that CTFont
may report that it has this format if it is an 'OTTO' font with very few
glyphs. If Skia serializes such a font with 'typ1' as the first four
bytes, CoreGraphics will not create a CGFont from the resulting font data.

BUG=chromium:809763,skia:7630

Change-Id: I9979b9f0ebdd27c4ad0903e8ee6237241e755541
Reviewed-on: https://skia-review.googlesource.com/113306
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/resources/fonts/7630.otf b/resources/fonts/7630.otf
new file mode 100644
index 0000000..355d0af
--- /dev/null
+++ b/resources/fonts/7630.otf
Binary files differ
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index ae46664..5d8723b 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -1629,15 +1629,30 @@
     tableTags.setCount(numTables);
     this->getTableTags(tableTags.begin());
 
-    // calc total size for font, save sizes
+    // see if there are any required 'typ1' tables (see Adobe Technical Note #5180)
+    bool couldBeTyp1 = false;
+    constexpr SkFontTableTag TYPE1Tag = SkSetFourByteTag('T', 'Y', 'P', '1');
+    constexpr SkFontTableTag CIDTag = SkSetFourByteTag('C', 'I', 'D', ' ');
+    // get the table sizes and accumulate the total size of the font
     SkTDArray<size_t> tableSizes;
     size_t totalSize = sizeof(SkSFNTHeader) + sizeof(SkSFNTHeader::TableDirectoryEntry) * numTables;
     for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) {
+        if (TYPE1Tag == tableTags[tableIndex] || CIDTag == tableTags[tableIndex]) {
+            couldBeTyp1 = true;
+        }
+
         size_t tableSize = this->getTableSize(tableTags[tableIndex]);
         totalSize += (tableSize + 3) & ~3;
         *tableSizes.append() = tableSize;
     }
 
+    // sometimes CoreGraphics incorrectly thinks a font is kCTFontFormatPostScript
+    // it is exceedingly unlikely that this is the case, so double check
+    // see https://crbug.com/809763
+    if (fontType == SkSFNTHeader::fontType_PostScript::TAG && !couldBeTyp1) {
+        fontType = SkSFNTHeader::fontType_OpenTypeCFF::TAG;
+    }
+
     // reserve memory for stream, and zero it (tables must be zero padded)
     SkMemoryStream* stream = new SkMemoryStream(totalSize);
     char* dataStart = (char*)stream->getMemoryBase();
diff --git a/tests/TypefaceTest.cpp b/tests/TypefaceTest.cpp
index fc81e84..b6b71ae 100644
--- a/tests/TypefaceTest.cpp
+++ b/tests/TypefaceTest.cpp
@@ -94,6 +94,21 @@
     }
 }
 
+DEF_TEST(TypefaceRoundTrip, reporter) {
+    sk_sp<SkTypeface> typeface(MakeResourceAsTypeface("fonts/7630.otf"));
+    if (!typeface) {
+        // Not all SkFontMgr can MakeFromStream().
+        return;
+    }
+
+    int fontIndex;
+    std::unique_ptr<SkStreamAsset> stream(typeface->openStream(&fontIndex));
+
+    sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
+    sk_sp<SkTypeface> typeface2 = fm->makeFromStream(std::move(stream), fontIndex);
+    REPORTER_ASSERT(reporter, typeface2);
+}
+
 DEF_TEST(TypefaceAxes, reporter) {
     std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf"));
     if (!distortable) {