Revert of SkPDF: hand SfntlyWrapper::SubsetFont() ttcIndex, not fontName. (patchset...
authorhalcanary <halcanary@google.com>
Tue, 30 Aug 2016 18:58:52 +0000 (11:58 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 30 Aug 2016 18:58:52 +0000 (11:58 -0700)
Reason for revert:
forgot to roll sfntly in android!

Original issue's description:
> SkPDF: hand SfntlyWrapper::SubsetFont() ttcIndex, not fontName.
>
> Also, minor code refactoring.
> GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2258233002
>
> Committed: https://skia.googlesource.com/skia/+/fce190647285423bf36c44bca09db78a6af30f9f

TBR=bungeman@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review-Url: https://codereview.chromium.org/2296683004

src/pdf/SkPDFFont.cpp

index 8b316b1..93f4833 100644 (file)
@@ -136,6 +136,12 @@ static bool can_embed(const SkAdvancedTypefaceMetrics& metrics) {
     return !SkToBool(metrics.fFlags & SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag);
 }
 
+#ifdef SK_PDF_USE_SFNTLY
+static bool can_subset(const SkAdvancedTypefaceMetrics& metrics) {
+    return !SkToBool(metrics.fFlags & SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag);
+}
+#endif
+
 const SkAdvancedTypefaceMetrics* SkPDFFont::GetMetrics(SkTypeface* typeface,
                                                        SkPDFCanon* canon) {
     SkASSERT(typeface);
@@ -295,34 +301,35 @@ static sk_sp<SkData> stream_to_data(std::unique_ptr<SkStreamAsset> stream) {
     size_t size = stream->getLength();
     if (const void* base = stream->getMemoryBase()) {
         SkData::ReleaseProc proc =
-            [](const void*, void* ctx) { delete (SkStreamAsset*)ctx; };
+            [](const void*, void* ctx) { delete (SkStream*)ctx; };
         return SkData::MakeWithProc(base, size, proc, stream.release());
     }
     return SkData::MakeFromStream(stream.get(), size);
 }
 
-static sk_sp<SkPDFStream> get_subset_font_stream(
+static sk_sp<SkPDFObject> get_subset_font_stream(
         std::unique_ptr<SkStreamAsset> fontAsset,
-        const SkBitSet& glyphUsage,
-        int ttcIndex) {
-    // Generate glyph id array in format needed by sfntly.
-    // TODO(halcanary): sfntly should take a more compact format.
-    SkTDArray<unsigned> subset;
-    if (!glyphUsage.has(0)) {
-        subset.push(0);  // Always include glyph 0.
-    }
-    glyphUsage.exportTo(&subset);
+        const SkTDArray<uint32_t>& subset,
+        const char* fontName) {
+    // sfntly requires unsigned int* to be passed in,
+    // as far as we know, unsigned int is equivalent
+    // to uint32_t on all platforms.
+    static_assert(sizeof(unsigned) == sizeof(uint32_t), "");
+
+    // TODO(halcanary): Use ttcIndex, not fontName.
 
     unsigned char* subsetFont{nullptr};
-    sk_sp<SkData> fontData(stream_to_data(std::move(fontAsset)));
-    int subsetFontSize = SfntlyWrapper::SubsetFont(ttcIndex,
-                                                   fontData->bytes(),
-                                                   fontData->size(),
-                                                   subset.begin(),
-                                                   subset.count(),
-                                                   &subsetFont);
-    fontData.reset();
-    subset.reset();
+    int subsetFontSize{0};
+    {
+        sk_sp<SkData> fontData(stream_to_data(std::move(fontAsset)));
+        subsetFontSize =
+            SfntlyWrapper::SubsetFont(fontName,
+                                      fontData->bytes(),
+                                      fontData->size(),
+                                      subset.begin(),
+                                      subset.count(),
+                                      &subsetFont);
+    }
     SkASSERT(subsetFontSize > 0 || subsetFont == nullptr);
     if (subsetFontSize < 1) {
         return nullptr;
@@ -348,65 +355,76 @@ void SkPDFType0Font::getFontSubset(SkPDFCanon* canon) {
     SkAdvancedTypefaceMetrics::FontType type = this->getType();
     SkTypeface* face = this->typeface();
     SkASSERT(face);
+    const SkString& name = metrics.fFontName;
 
     auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor");
     add_common_font_descriptor_entries(descriptor.get(), metrics, 0);
+    switch (type) {
+        case SkAdvancedTypefaceMetrics::kTrueType_Font: {
+            int ttcIndex;
+            std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex));
+            SkASSERT(fontAsset);
+            if (!fontAsset) {
+                return;
+            }
+            size_t fontSize = fontAsset->getLength();
+            SkASSERT(fontSize > 0);
+            if (fontSize == 0) {
+                return;
+            }
 
-    int ttcIndex;
-    std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex));
-    size_t fontSize = fontAsset ? fontAsset->getLength() : 0;
-    SkASSERT(fontAsset);
-    SkASSERT(fontSize > 0);
-    if (fontSize > 0) {
-        switch (type) {
-            case SkAdvancedTypefaceMetrics::kTrueType_Font: {
-                #ifdef SK_PDF_USE_SFNTLY
-                if (!SkToBool(metrics.fFlags &
-                              SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag)) {
-                    sk_sp<SkPDFStream> subsetStream = get_subset_font_stream(
-                            std::move(fontAsset), this->glyphUsage(), ttcIndex);
-                    if (subsetStream) {
-                        descriptor->insertObjRef("FontFile2", std::move(subsetStream));
-                        break;
-                    }
-                    // If subsetting fails, fall back to original font data.
-                    fontAsset.reset(face->openStream(&ttcIndex));
-                    SkASSERT(fontAsset);
-                    SkASSERT(fontAsset->getLength() == fontSize);
-                    if (!fontAsset || fontAsset->getLength() == 0) { break; }
+        #ifdef SK_PDF_USE_SFNTLY
+            if (can_subset(metrics)) {
+                // Generate glyph id array. in format needed by sfntly
+                SkTDArray<uint32_t> glyphIDs;
+                if (!this->glyphUsage().has(0)) {
+                    glyphIDs.push(0);  // Always include glyph 0.
+                }
+                this->glyphUsage().exportTo(&glyphIDs);
+                sk_sp<SkPDFObject> subsetStream = get_subset_font_stream(
+                        std::move(fontAsset), glyphIDs, name.c_str());
+                if (subsetStream) {
+                    descriptor->insertObjRef("FontFile2", std::move(subsetStream));
+                    break;
                 }
-                #endif  // SK_PDF_USE_SFNTLY
-                auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontAsset));
-                fontStream->dict()->insertInt("Length1", fontSize);
-                descriptor->insertObjRef("FontFile2", std::move(fontStream));
-                break;
+                // If subsetting fails, fall back to original font data.
+                fontAsset.reset(face->openStream(&ttcIndex));
             }
-            case SkAdvancedTypefaceMetrics::kType1CID_Font: {
-                auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontAsset));
-                fontStream->dict()->insertName("Subtype", "CIDFontType0C");
-                descriptor->insertObjRef("FontFile3", std::move(fontStream));
-                break;
+        #endif  // SK_PDF_USE_SFNTLY
+            auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontAsset));
+            fontStream->dict()->insertInt("Length1", fontSize);
+            descriptor->insertObjRef("FontFile2", std::move(fontStream));
+            break;
+        }
+        case SkAdvancedTypefaceMetrics::kType1CID_Font: {
+            std::unique_ptr<SkStreamAsset> fontData(face->openStream(nullptr));
+            SkASSERT(fontData);
+            SkASSERT(fontData->getLength() > 0);
+            if (!fontData || 0 == fontData->getLength()) {
+                return;
             }
-            default:
-                SkASSERT(false);
+            auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontData));
+            fontStream->dict()->insertName("Subtype", "CIDFontType0c");
+            descriptor->insertObjRef("FontFile3", std::move(fontStream));
+            break;
         }
+        default:
+            SkASSERT(false);
     }
 
     auto newCIDFont = sk_make_sp<SkPDFDict>("Font");
     newCIDFont->insertObjRef("FontDescriptor", std::move(descriptor));
-    newCIDFont->insertName("BaseFont", metrics.fFontName);
+    newCIDFont->insertName("BaseFont", name);
 
-    switch (type) {
-        case SkAdvancedTypefaceMetrics::kType1CID_Font:
-            newCIDFont->insertName("Subtype", "CIDFontType0");
-            break;
-        case SkAdvancedTypefaceMetrics::kTrueType_Font:
-            newCIDFont->insertName("Subtype", "CIDFontType2");
-            newCIDFont->insertName("CIDToGIDMap", "Identity");
-            break;
-        default:
-            SkASSERT(false);
+    if (type == SkAdvancedTypefaceMetrics::kType1CID_Font) {
+        newCIDFont->insertName("Subtype", "CIDFontType0");
+    } else if (type == SkAdvancedTypefaceMetrics::kTrueType_Font) {
+        newCIDFont->insertName("Subtype", "CIDFontType2");
+        newCIDFont->insertName("CIDToGIDMap", "Identity");
+    } else {
+        SkASSERT(false);
     }
+
     auto sysInfo = sk_make_sp<SkPDFDict>();
     sysInfo->insertString("Registry", "Adobe");
     sysInfo->insertString("Ordering", "Identity");