diff options
author | halcanary <halcanary@google.com> | 2016-08-30 11:58:52 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-08-30 11:58:52 -0700 |
commit | 8e3f54d51930f0c2f3bebf163ee7754b69080ae8 (patch) | |
tree | 5e68dd942aa1d0a5a245a265231b009fd046a527 /src/pdf | |
parent | 4f0a23a8d54f5eb0fdacfff7c109b9045b548978 (diff) |
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
Diffstat (limited to 'src/pdf')
-rw-r--r-- | src/pdf/SkPDFFont.cpp | 148 |
1 files changed, 83 insertions, 65 deletions
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp index 8b316b116e..93f48332d8 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<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"); |