From 8e3f54d51930f0c2f3bebf163ee7754b69080ae8 Mon Sep 17 00:00:00 2001 From: halcanary Date: Tue, 30 Aug 2016 11:58:52 -0700 Subject: [PATCH] Revert of SkPDF: hand SfntlyWrapper::SubsetFont() ttcIndex, not fontName. (patchset #3 id:40001 of https://codereview.chromium.org/2258233002/ ) 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 | 148 ++++++++++++++++++++++++++++---------------------- 1 file changed, 83 insertions(+), 65 deletions(-) diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp index 8b316b1..93f4833 100644 --- a/src/pdf/SkPDFFont.cpp +++ b/src/pdf/SkPDFFont.cpp @@ -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 stream_to_data(std::unique_ptr 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 get_subset_font_stream( +static sk_sp get_subset_font_stream( std::unique_ptr 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 subset; - if (!glyphUsage.has(0)) { - subset.push(0); // Always include glyph 0. - } - glyphUsage.exportTo(&subset); + const SkTDArray& 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 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 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("FontDescriptor"); add_common_font_descriptor_entries(descriptor.get(), metrics, 0); + switch (type) { + case SkAdvancedTypefaceMetrics::kTrueType_Font: { + int ttcIndex; + std::unique_ptr 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 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 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 glyphIDs; + if (!this->glyphUsage().has(0)) { + glyphIDs.push(0); // Always include glyph 0. + } + this->glyphUsage().exportTo(&glyphIDs); + sk_sp 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(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(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(std::move(fontAsset)); + fontStream->dict()->insertInt("Length1", fontSize); + descriptor->insertObjRef("FontFile2", std::move(fontStream)); + break; + } + case SkAdvancedTypefaceMetrics::kType1CID_Font: { + std::unique_ptr fontData(face->openStream(nullptr)); + SkASSERT(fontData); + SkASSERT(fontData->getLength() > 0); + if (!fontData || 0 == fontData->getLength()) { + return; } - default: - SkASSERT(false); + auto fontStream = sk_make_sp(std::move(fontData)); + fontStream->dict()->insertName("Subtype", "CIDFontType0c"); + descriptor->insertObjRef("FontFile3", std::move(fontStream)); + break; } + default: + SkASSERT(false); } auto newCIDFont = sk_make_sp("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(); sysInfo->insertString("Registry", "Adobe"); sysInfo->insertString("Ordering", "Identity"); -- 2.7.4