| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkData.h" | 8 #include "SkData.h" |
| 9 #include "SkGlyphCache.h" | 9 #include "SkGlyphCache.h" |
| 10 #include "SkPaint.h" | 10 #include "SkPaint.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 #endif | 68 #endif |
| 69 | 69 |
| 70 private: | 70 private: |
| 71 #ifdef SK_DEBUG | 71 #ifdef SK_DEBUG |
| 72 bool fPopulated; | 72 bool fPopulated; |
| 73 #endif | 73 #endif |
| 74 bool populate(const SkPDFGlyphSet* subset); | 74 bool populate(const SkPDFGlyphSet* subset); |
| 75 typedef SkPDFDict INHERITED; | 75 typedef SkPDFDict INHERITED; |
| 76 }; | 76 }; |
| 77 | 77 |
| 78 class SkPDFCIDFont final : public SkPDFFont { | |
| 79 public: | |
| 80 SkPDFCIDFont(sk_sp<const SkAdvancedTypefaceMetrics> info, | |
| 81 sk_sp<SkTypeface> typeface, | |
| 82 SkAdvancedTypefaceMetrics::FontType fontType, | |
| 83 const SkPDFGlyphSet* subset); | |
| 84 virtual ~SkPDFCIDFont(); | |
| 85 | |
| 86 private: | |
| 87 bool populate(const SkPDFGlyphSet* subset); | |
| 88 bool addFontDescriptor(int16_t defaultWidth, | |
| 89 const SkTDArray<uint32_t>* subset); | |
| 90 }; | |
| 91 | |
| 92 class SkPDFType1Font final : public SkPDFFont { | 78 class SkPDFType1Font final : public SkPDFFont { |
| 93 public: | 79 public: |
| 94 SkPDFType1Font(sk_sp<const SkAdvancedTypefaceMetrics> info, | 80 SkPDFType1Font(sk_sp<const SkAdvancedTypefaceMetrics> info, |
| 95 sk_sp<SkTypeface> typeface, | 81 sk_sp<SkTypeface> typeface, |
| 96 uint16_t glyphID, | 82 uint16_t glyphID, |
| 97 sk_sp<SkPDFDict> relatedFontDescriptor); | 83 sk_sp<SkPDFDict> relatedFontDescriptor); |
| 98 virtual ~SkPDFType1Font(); | 84 virtual ~SkPDFType1Font(); |
| 99 | 85 |
| 100 private: | 86 private: |
| 101 bool populate(int16_t glyphID); | 87 bool populate(int16_t glyphID); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 if (range->fEndId == range->fStartId) { | 158 if (range->fEndId == range->fStartId) { |
| 173 range->fType = AdvanceMetric::kRange; | 159 range->fType = AdvanceMetric::kRange; |
| 174 } | 160 } |
| 175 newLength = 1; | 161 newLength = 1; |
| 176 } | 162 } |
| 177 SkASSERT(range->fAdvance.count() >= newLength); | 163 SkASSERT(range->fAdvance.count() >= newLength); |
| 178 range->fAdvance.setCount(newLength); | 164 range->fAdvance.setCount(newLength); |
| 179 zeroWildcardsInRange(range); | 165 zeroWildcardsInRange(range); |
| 180 } | 166 } |
| 181 | 167 |
| 182 | 168 /** Retrieve advance data for glyphs. Used by the PDF backend. */ |
| 183 /** Retrieve advance data for glyphs. Used by the PDF backend. | |
| 184 @param num_glyphs Total number of glyphs in the given font. | |
| 185 @param glyphIDs For per-glyph info, specify subset of the | |
| 186 font by giving glyph ids. Each integer | |
| 187 represents a glyph id. Passing nullptr | |
| 188 means all glyphs in the font. | |
| 189 @param glyphIDsCount Number of elements in subsetGlyphIds. | |
| 190 Ignored if glyphIDs is nullptr. | |
| 191 */ | |
| 192 // TODO(halcanary): this function is complex enough to need its logic | 169 // TODO(halcanary): this function is complex enough to need its logic |
| 193 // tested with unit tests. On the other hand, I want to do another | 170 // tested with unit tests. On the other hand, I want to do another |
| 194 // round of re-factoring before figuring out how to mock this. | 171 // round of re-factoring before figuring out how to mock this. |
| 195 // TODO(halcanary): this function should be combined with | 172 // TODO(halcanary): this function should be combined with |
| 196 // composeAdvanceData() so that we don't need to produce a linked list | 173 // composeAdvanceData() so that we don't need to produce a linked list |
| 197 // of intermediate values. Or we could make the intermediate value | 174 // of intermediate values. Or we could make the intermediate value |
| 198 // something other than a linked list. | 175 // something other than a linked list. |
| 199 static void get_glyph_widths(SkSinglyLinkedList<AdvanceMetric>* glyphWidths, | 176 static void set_glyph_widths(SkTypeface* typeface, |
| 200 int num_glyphs, | 177 const SkPDFGlyphSet* subset, |
| 201 const uint32_t* subsetGlyphIDs, | 178 SkSinglyLinkedList<AdvanceMetric>* glyphWidths) { |
| 202 uint32_t subsetGlyphIDsLength, | 179 SkPaint tmpPaint; |
| 203 SkGlyphCache* glyphCache) { | 180 tmpPaint.setHinting(SkPaint::kNo_Hinting); |
| 181 tmpPaint.setTypeface(sk_ref_sp(typeface)); |
| 182 tmpPaint.setTextSize((SkScalar)typeface->getUnitsPerEm()); |
| 183 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); |
| 184 SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr); |
| 185 SkASSERT(glyphCache.get()); |
| 186 |
| 204 // Assuming that on average, the ASCII representation of an advance plus | 187 // Assuming that on average, the ASCII representation of an advance plus |
| 205 // a space is 8 characters and the ASCII representation of a glyph id is 3 | 188 // a space is 8 characters and the ASCII representation of a glyph id is 3 |
| 206 // characters, then the following cut offs for using different range types | 189 // characters, then the following cut offs for using different range types |
| 207 // apply: | 190 // apply: |
| 208 // The cost of stopping and starting the range is 7 characers | 191 // The cost of stopping and starting the range is 7 characers |
| 209 // a. Removing 4 0's or don't care's is a win | 192 // a. Removing 4 0's or don't care's is a win |
| 210 // The cost of stopping and starting the range plus a run is 22 | 193 // The cost of stopping and starting the range plus a run is 22 |
| 211 // characters | 194 // characters |
| 212 // b. Removing 3 repeating advances is a win | 195 // b. Removing 3 repeating advances is a win |
| 213 // c. Removing 2 repeating advances and 3 don't cares is a win | 196 // c. Removing 2 repeating advances and 3 don't cares is a win |
| 214 // When not currently in a range the cost of a run over a range is 16 | 197 // When not currently in a range the cost of a run over a range is 16 |
| 215 // characaters, so: | 198 // characaters, so: |
| 216 // d. Removing a leading 0/don't cares is a win because it is omitted | 199 // d. Removing a leading 0/don't cares is a win because it is omitted |
| 217 // e. Removing 2 repeating advances is a win | 200 // e. Removing 2 repeating advances is a win |
| 218 | 201 |
| 202 int num_glyphs = typeface->countGlyphs(); |
| 203 |
| 219 AdvanceMetric* prevRange = nullptr; | 204 AdvanceMetric* prevRange = nullptr; |
| 220 int16_t lastAdvance = kInvalidAdvance; | 205 int16_t lastAdvance = kInvalidAdvance; |
| 221 int repeatedAdvances = 0; | 206 int repeatedAdvances = 0; |
| 222 int wildCardsInRun = 0; | 207 int wildCardsInRun = 0; |
| 223 int trailingWildCards = 0; | 208 int trailingWildCards = 0; |
| 224 uint32_t subsetIndex = 0; | |
| 225 | 209 |
| 226 // Limit the loop count to glyph id ranges provided. | 210 // Limit the loop count to glyph id ranges provided. |
| 227 int firstIndex = 0; | |
| 228 int lastIndex = num_glyphs; | 211 int lastIndex = num_glyphs; |
| 229 if (subsetGlyphIDs) { | 212 if (subset) { |
| 230 firstIndex = static_cast<int>(subsetGlyphIDs[0]); | 213 while (!subset->has(lastIndex - 1) && lastIndex > 0) { |
| 231 lastIndex = | 214 --lastIndex; |
| 232 static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1; | 215 } |
| 233 } | 216 } |
| 234 AdvanceMetric curRange(firstIndex); | 217 AdvanceMetric curRange(0); |
| 235 | 218 |
| 236 for (int gId = firstIndex; gId <= lastIndex; gId++) { | 219 for (int gId = 0; gId <= lastIndex; gId++) { |
| 237 int16_t advance = kInvalidAdvance; | 220 int16_t advance = kInvalidAdvance; |
| 238 if (gId < lastIndex) { | 221 if (gId < lastIndex) { |
| 239 // Get glyph id only when subset is nullptr, or the id is in subset. | 222 if (!subset || 0 == gId || subset->has(gId)) { |
| 240 SkASSERT(!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength && | |
| 241 static_cast<uint32_t>(gId) <= subsetGlyphIDs[subsetIndex])); | |
| 242 if (!subsetGlyphIDs || | |
| 243 (subsetIndex < subsetGlyphIDsLength && | |
| 244 static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) { | |
| 245 advance = (int16_t)glyphCache->getGlyphIDAdvance(gId).fAdvanceX; | 223 advance = (int16_t)glyphCache->getGlyphIDAdvance(gId).fAdvanceX; |
| 246 ++subsetIndex; | |
| 247 } else { | 224 } else { |
| 248 advance = kDontCareAdvance; | 225 advance = kDontCareAdvance; |
| 249 } | 226 } |
| 250 } | 227 } |
| 251 if (advance == lastAdvance) { | 228 if (advance == lastAdvance) { |
| 252 repeatedAdvances++; | 229 repeatedAdvances++; |
| 253 trailingWildCards = 0; | 230 trailingWildCards = 0; |
| 254 } else if (advance == kDontCareAdvance) { | 231 } else if (advance == kDontCareAdvance) { |
| 255 wildCardsInRun++; | 232 wildCardsInRun++; |
| 256 trailingWildCards++; | 233 trailingWildCards++; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 return; // https://crbug.com/567031 | 291 return; // https://crbug.com/567031 |
| 315 } | 292 } |
| 316 } else { | 293 } else { |
| 317 FinishRange(&curRange, lastIndex - 1, AdvanceMetric::kRange); | 294 FinishRange(&curRange, lastIndex - 1, AdvanceMetric::kRange); |
| 318 glyphWidths->emplace_back(std::move(curRange)); | 295 glyphWidths->emplace_back(std::move(curRange)); |
| 319 } | 296 } |
| 320 } | 297 } |
| 321 | 298 |
| 322 //////////////////////////////////////////////////////////////////////////////// | 299 //////////////////////////////////////////////////////////////////////////////// |
| 323 | 300 |
| 324 | |
| 325 // scale from em-units to base-1000, returning as a SkScalar | 301 // scale from em-units to base-1000, returning as a SkScalar |
| 326 SkScalar from_font_units(SkScalar scaled, uint16_t emSize) { | 302 SkScalar from_font_units(SkScalar scaled, uint16_t emSize) { |
| 327 if (emSize == 1000) { | 303 if (emSize == 1000) { |
| 328 return scaled; | 304 return scaled; |
| 329 } else { | 305 } else { |
| 330 return SkScalarMulDiv(scaled, 1000, emSize); | 306 return SkScalarMulDiv(scaled, 1000, emSize); |
| 331 } | 307 } |
| 332 } | 308 } |
| 333 | 309 |
| 334 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) { | 310 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) { |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 } | 612 } |
| 637 | 613 |
| 638 void SkPDFFont::setLastGlyphID(uint16_t glyphID) { | 614 void SkPDFFont::setLastGlyphID(uint16_t glyphID) { |
| 639 fLastGlyphID = glyphID; | 615 fLastGlyphID = glyphID; |
| 640 } | 616 } |
| 641 | 617 |
| 642 void SkPDFFont::setFontDescriptor(sk_sp<SkPDFDict> descriptor) { | 618 void SkPDFFont::setFontDescriptor(sk_sp<SkPDFDict> descriptor) { |
| 643 fDescriptor = std::move(descriptor); | 619 fDescriptor = std::move(descriptor); |
| 644 } | 620 } |
| 645 | 621 |
| 646 bool SkPDFFont::addCommonFontDescriptorEntries(int16_t defaultWidth) { | 622 static void add_common_font_descriptor_entries(SkPDFDict* descriptor, |
| 647 if (fDescriptor.get() == nullptr) { | 623 const SkAdvancedTypefaceMetrics&
metrics, |
| 648 return false; | 624 int16_t defaultWidth) { |
| 649 } | 625 const uint16_t emSize = metrics.fEmSize; |
| 650 | 626 descriptor->insertName("FontName", metrics.fFontName); |
| 651 const uint16_t emSize = fFontInfo->fEmSize; | 627 descriptor->insertInt("Flags", (size_t)(metrics.fStyle | kPdfSymbolic)); |
| 652 | 628 descriptor->insertScalar("Ascent", |
| 653 fDescriptor->insertName("FontName", fFontInfo->fFontName); | 629 scaleFromFontUnits(metrics.fAscent, emSize)); |
| 654 fDescriptor->insertInt("Flags", (size_t)(fFontInfo->fStyle | kPdfSymbolic)); | 630 descriptor->insertScalar("Descent", |
| 655 fDescriptor->insertScalar("Ascent", | 631 scaleFromFontUnits(metrics.fDescent, emSize)); |
| 656 scaleFromFontUnits(fFontInfo->fAscent, emSize)); | 632 descriptor->insertScalar("StemV", |
| 657 fDescriptor->insertScalar("Descent", | 633 scaleFromFontUnits(metrics.fStemV, emSize)); |
| 658 scaleFromFontUnits(fFontInfo->fDescent, emSize)); | 634 descriptor->insertScalar("CapHeight", |
| 659 fDescriptor->insertScalar("StemV", | 635 scaleFromFontUnits(metrics.fCapHeight, emSize)); |
| 660 scaleFromFontUnits(fFontInfo->fStemV, emSize)); | 636 descriptor->insertInt("ItalicAngle", metrics.fItalicAngle); |
| 661 | 637 descriptor->insertObject( |
| 662 fDescriptor->insertScalar("CapHeight", | 638 "FontBBox", makeFontBBox(metrics.fBBox, metrics.fEmSize)); |
| 663 scaleFromFontUnits(fFontInfo->fCapHeight, emSize)); | |
| 664 fDescriptor->insertInt("ItalicAngle", fFontInfo->fItalicAngle); | |
| 665 fDescriptor->insertObject( | |
| 666 "FontBBox", makeFontBBox(fFontInfo->fBBox, fFontInfo->fEmSize)); | |
| 667 | |
| 668 if (defaultWidth > 0) { | 639 if (defaultWidth > 0) { |
| 669 fDescriptor->insertScalar("MissingWidth", | 640 descriptor->insertScalar("MissingWidth", |
| 670 scaleFromFontUnits(defaultWidth, emSize)); | 641 scaleFromFontUnits(defaultWidth, emSize)); |
| 671 } | 642 } |
| 672 return true; | |
| 673 } | 643 } |
| 674 | 644 |
| 675 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) { | 645 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) { |
| 676 // Single byte glyph encoding supports a max of 255 glyphs. | 646 // Single byte glyph encoding supports a max of 255 glyphs. |
| 677 fFirstGlyphID = glyphID - (glyphID - 1) % 255; | 647 fFirstGlyphID = glyphID - (glyphID - 1) % 255; |
| 678 if (fLastGlyphID > fFirstGlyphID + 255 - 1) { | 648 if (fLastGlyphID > fFirstGlyphID + 255 - 1) { |
| 679 fLastGlyphID = fFirstGlyphID + 255 - 1; | 649 fLastGlyphID = fFirstGlyphID + 255 - 1; |
| 680 } | 650 } |
| 681 } | 651 } |
| 682 | 652 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 | 689 |
| 720 #ifdef SK_DEBUG | 690 #ifdef SK_DEBUG |
| 721 void SkPDFType0Font::emitObject(SkWStream* stream, | 691 void SkPDFType0Font::emitObject(SkWStream* stream, |
| 722 const SkPDFObjNumMap& objNumMap, | 692 const SkPDFObjNumMap& objNumMap, |
| 723 const SkPDFSubstituteMap& substitutes) const { | 693 const SkPDFSubstituteMap& substitutes) const { |
| 724 SkASSERT(fPopulated); | 694 SkASSERT(fPopulated); |
| 725 return INHERITED::emitObject(stream, objNumMap, substitutes); | 695 return INHERITED::emitObject(stream, objNumMap, substitutes); |
| 726 } | 696 } |
| 727 #endif | 697 #endif |
| 728 | 698 |
| 729 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) { | |
| 730 insertName("Subtype", "Type0"); | |
| 731 insertName("BaseFont", this->getFontInfo()->fFontName); | |
| 732 insertName("Encoding", "Identity-H"); | |
| 733 | |
| 734 sk_sp<SkPDFCIDFont> newCIDFont( | |
| 735 sk_make_sp<SkPDFCIDFont>(this->refFontInfo(), | |
| 736 this->refTypeface(), | |
| 737 this->getType(), | |
| 738 subset)); | |
| 739 auto descendantFonts = sk_make_sp<SkPDFArray>(); | |
| 740 descendantFonts->appendObjRef(std::move(newCIDFont)); | |
| 741 this->insertObject("DescendantFonts", std::move(descendantFonts)); | |
| 742 | |
| 743 this->populateToUnicodeTable(subset); | |
| 744 | |
| 745 SkDEBUGCODE(fPopulated = true); | |
| 746 return true; | |
| 747 } | |
| 748 | |
| 749 /////////////////////////////////////////////////////////////////////////////// | |
| 750 // class SkPDFCIDFont | |
| 751 /////////////////////////////////////////////////////////////////////////////// | |
| 752 | |
| 753 SkPDFCIDFont::SkPDFCIDFont(sk_sp<const SkAdvancedTypefaceMetrics> info, | |
| 754 sk_sp<SkTypeface> typeface, | |
| 755 SkAdvancedTypefaceMetrics::FontType fontType, | |
| 756 const SkPDFGlyphSet* subset) | |
| 757 : SkPDFFont(std::move(info), std::move(typeface), nullptr, | |
| 758 fontType , /* multiByteGlyphs = */ true) { | |
| 759 this->populate(subset); | |
| 760 } | |
| 761 | |
| 762 SkPDFCIDFont::~SkPDFCIDFont() {} | |
| 763 | |
| 764 #ifdef SK_SFNTLY_SUBSETTER | 699 #ifdef SK_SFNTLY_SUBSETTER |
| 765 // if possible, make no copy. | 700 // if possible, make no copy. |
| 766 static sk_sp<SkData> stream_to_data(std::unique_ptr<SkStreamAsset> stream) { | 701 static sk_sp<SkData> stream_to_data(std::unique_ptr<SkStreamAsset> stream) { |
| 767 SkASSERT(stream); | 702 SkASSERT(stream); |
| 768 (void)stream->rewind(); | 703 (void)stream->rewind(); |
| 769 SkASSERT(stream->hasLength()); | 704 SkASSERT(stream->hasLength()); |
| 770 size_t size = stream->getLength(); | 705 size_t size = stream->getLength(); |
| 771 if (const void* base = stream->getMemoryBase()) { | 706 if (const void* base = stream->getMemoryBase()) { |
| 772 SkData::ReleaseProc proc = | 707 SkData::ReleaseProc proc = |
| 773 [](const void*, void* ctx) { delete (SkStream*)ctx; }; | 708 [](const void*, void* ctx) { delete (SkStream*)ctx; }; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 auto subsetStream = sk_make_sp<SkPDFStream>( | 742 auto subsetStream = sk_make_sp<SkPDFStream>( |
| 808 SkData::MakeWithProc( | 743 SkData::MakeWithProc( |
| 809 subsetFont, subsetFontSize, | 744 subsetFont, subsetFontSize, |
| 810 [](const void* p, void*) { delete[] (unsigned char*)p; }, | 745 [](const void* p, void*) { delete[] (unsigned char*)p; }, |
| 811 nullptr)); | 746 nullptr)); |
| 812 subsetStream->dict()->insertInt("Length1", subsetFontSize); | 747 subsetStream->dict()->insertInt("Length1", subsetFontSize); |
| 813 return subsetStream; | 748 return subsetStream; |
| 814 } | 749 } |
| 815 #endif // SK_SFNTLY_SUBSETTER | 750 #endif // SK_SFNTLY_SUBSETTER |
| 816 | 751 |
| 817 bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, | 752 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) { |
| 818 const SkTDArray<uint32_t>* subset) { | 753 SkASSERT(this->canEmbed()); |
| 754 SkASSERT(this->getFontInfo()); |
| 755 const SkAdvancedTypefaceMetrics& metrics = *(this->getFontInfo()); |
| 756 SkAdvancedTypefaceMetrics::FontType type = this->getType(); |
| 757 SkTypeface* face = this->typeface(); |
| 758 SkASSERT(face); |
| 759 const char* name = metrics.fFontName.c_str(); |
| 760 |
| 819 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); | 761 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); |
| 820 setFontDescriptor(descriptor); | 762 add_common_font_descriptor_entries(descriptor.get(), metrics, 0); |
| 821 if (!addCommonFontDescriptorEntries(defaultWidth)) { | 763 switch (type) { |
| 822 this->insertObjRef("FontDescriptor", std::move(descriptor)); | |
| 823 return false; | |
| 824 } | |
| 825 SkASSERT(this->canEmbed()); | |
| 826 | |
| 827 switch (getType()) { | |
| 828 case SkAdvancedTypefaceMetrics::kTrueType_Font: { | 764 case SkAdvancedTypefaceMetrics::kTrueType_Font: { |
| 829 int ttcIndex; | 765 int ttcIndex; |
| 830 std::unique_ptr<SkStreamAsset> fontAsset( | 766 std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex)
); |
| 831 this->typeface()->openStream(&ttcIndex)); | |
| 832 SkASSERT(fontAsset); | 767 SkASSERT(fontAsset); |
| 833 if (!fontAsset) { | 768 if (!fontAsset) { |
| 834 return false; | 769 return false; |
| 835 } | 770 } |
| 836 size_t fontSize = fontAsset->getLength(); | 771 size_t fontSize = fontAsset->getLength(); |
| 837 SkASSERT(fontSize > 0); | 772 SkASSERT(fontSize > 0); |
| 838 if (fontSize == 0) { | 773 if (fontSize == 0) { |
| 839 return false; | 774 return false; |
| 840 } | 775 } |
| 841 | 776 |
| 842 #ifdef SK_SFNTLY_SUBSETTER | 777 #ifdef SK_SFNTLY_SUBSETTER |
| 843 if (this->canSubset() && subset) { | 778 if (this->canSubset() && subset) { |
| 844 const char* name = this->getFontInfo()->fFontName.c_str(); | 779 // Generate glyph id array. in format needed by sfntly |
| 780 SkTDArray<uint32_t> glyphIDs; |
| 781 if (subset) { |
| 782 if (!subset->has(0)) { |
| 783 glyphIDs.push(0); // Always include glyph 0. |
| 784 } |
| 785 subset->exportTo(&glyphIDs); |
| 786 } |
| 845 sk_sp<SkPDFObject> subsetStream = get_subset_font_stream( | 787 sk_sp<SkPDFObject> subsetStream = get_subset_font_stream( |
| 846 std::move(fontAsset), *subset, name); | 788 std::move(fontAsset), glyphIDs, name); |
| 847 if (subsetStream) { | 789 if (subsetStream) { |
| 848 descriptor->insertObjRef("FontFile2", std::move(subsetStream
)); | 790 descriptor->insertObjRef("FontFile2", std::move(subsetStream
)); |
| 849 break; | 791 break; |
| 850 } | 792 } |
| 851 // If subsetting fails, fall back to original font data. | 793 // If subsetting fails, fall back to original font data. |
| 852 fontAsset.reset(this->typeface()->openStream(&ttcIndex)); | 794 fontAsset.reset(face->openStream(&ttcIndex)); |
| 853 } | 795 } |
| 854 #endif // SK_SFNTLY_SUBSETTER | 796 #endif // SK_SFNTLY_SUBSETTER |
| 855 auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontAsset)
); | 797 auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontAsset)
); |
| 856 fontStream->dict()->insertInt("Length1", fontSize); | 798 fontStream->dict()->insertInt("Length1", fontSize); |
| 857 descriptor->insertObjRef("FontFile2", std::move(fontStream)); | 799 descriptor->insertObjRef("FontFile2", std::move(fontStream)); |
| 858 break; | 800 break; |
| 859 } | 801 } |
| 860 case SkAdvancedTypefaceMetrics::kCFF_Font: | |
| 861 case SkAdvancedTypefaceMetrics::kType1CID_Font: { | 802 case SkAdvancedTypefaceMetrics::kType1CID_Font: { |
| 862 std::unique_ptr<SkStreamAsset> fontData( | 803 std::unique_ptr<SkStreamAsset> fontData(face->openStream(nullptr)); |
| 863 this->typeface()->openStream(nullptr)); | |
| 864 SkASSERT(fontData); | 804 SkASSERT(fontData); |
| 865 SkASSERT(fontData->getLength() > 0); | 805 SkASSERT(fontData->getLength() > 0); |
| 866 if (!fontData || 0 == fontData->getLength()) { | 806 if (!fontData || 0 == fontData->getLength()) { |
| 867 return false; | 807 return false; |
| 868 } | 808 } |
| 869 auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontData))
; | 809 auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontData))
; |
| 870 if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) { | 810 fontStream->dict()->insertName("Subtype", "CIDFontType0c"); |
| 871 fontStream->dict()->insertName("Subtype", "Type1C"); | |
| 872 } else { | |
| 873 fontStream->dict()->insertName("Subtype", "CIDFontType0c"); | |
| 874 } | |
| 875 descriptor->insertObjRef("FontFile3", std::move(fontStream)); | 811 descriptor->insertObjRef("FontFile3", std::move(fontStream)); |
| 876 break; | 812 break; |
| 877 } | 813 } |
| 878 default: | 814 default: |
| 879 SkASSERT(false); | 815 SkASSERT(false); |
| 880 } | 816 } |
| 881 this->insertObjRef("FontDescriptor", std::move(descriptor)); | |
| 882 return true; | |
| 883 } | |
| 884 | 817 |
| 885 void set_glyph_widths(SkTypeface* tf, | 818 auto newCIDFont = sk_make_sp<SkPDFDict>("Font"); |
| 886 const SkTDArray<uint32_t>* glyphIDs, | 819 newCIDFont->insertObjRef("FontDescriptor", std::move(descriptor)); |
| 887 SkSinglyLinkedList<AdvanceMetric>* dst) { | 820 newCIDFont->insertName("BaseFont", name); |
| 888 SkPaint tmpPaint; | |
| 889 tmpPaint.setHinting(SkPaint::kNo_Hinting); | |
| 890 tmpPaint.setTypeface(sk_ref_sp(tf)); | |
| 891 tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm()); | |
| 892 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); | |
| 893 SkAutoGlyphCache autoGlyphCache(tmpPaint, &props, nullptr); | |
| 894 if (!glyphIDs || glyphIDs->isEmpty()) { | |
| 895 get_glyph_widths(dst, tf->countGlyphs(), nullptr, 0, autoGlyphCache.get(
)); | |
| 896 } else { | |
| 897 get_glyph_widths(dst, tf->countGlyphs(), glyphIDs->begin(), | |
| 898 glyphIDs->count(), autoGlyphCache.get()); | |
| 899 } | |
| 900 } | |
| 901 | 821 |
| 902 sk_sp<const SkAdvancedTypefaceMetrics> SkPDFFont::GetFontMetricsWithGlyphNames( | 822 if (type == SkAdvancedTypefaceMetrics::kType1CID_Font) { |
| 903 SkTypeface* typeface, uint32_t* glyphs, uint32_t glyphsCount) { | 823 newCIDFont->insertName("Subtype", "CIDFontType0"); |
| 904 return sk_sp<const SkAdvancedTypefaceMetrics>( | 824 } else if (type == SkAdvancedTypefaceMetrics::kTrueType_Font) { |
| 905 typeface->getAdvancedTypefaceMetrics( | 825 newCIDFont->insertName("Subtype", "CIDFontType2"); |
| 906 SkTypeface::kGlyphNames_PerGlyphInfo, glyphs, glyphsCount)); | 826 newCIDFont->insertName("CIDToGIDMap", "Identity"); |
| 907 } | |
| 908 | |
| 909 sk_sp<const SkAdvancedTypefaceMetrics> SkPDFFont::GetFontMetricsWithToUnicode( | |
| 910 SkTypeface* typeface, uint32_t* glyphs, uint32_t glyphsCount) { | |
| 911 return sk_sp<const SkAdvancedTypefaceMetrics>( | |
| 912 typeface->getAdvancedTypefaceMetrics( | |
| 913 SkTypeface::kToUnicode_PerGlyphInfo, glyphs, glyphsCount)); | |
| 914 } | |
| 915 | |
| 916 bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) { | |
| 917 // Generate new font metrics with advance info for true type fonts. | |
| 918 // Generate glyph id array. | |
| 919 SkTDArray<uint32_t> glyphIDs; | |
| 920 if (subset) { | |
| 921 if (!subset->has(0)) { | |
| 922 glyphIDs.push(0); // Always include glyph 0. | |
| 923 } | |
| 924 subset->exportTo(&glyphIDs); | |
| 925 } | |
| 926 if (this->getType() == SkAdvancedTypefaceMetrics::kTrueType_Font) { | |
| 927 uint32_t* glyphs = (glyphIDs.count() == 0) ? nullptr : glyphIDs.begin(); | |
| 928 uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0; | |
| 929 sk_sp<const SkAdvancedTypefaceMetrics> fontMetrics = | |
| 930 SkPDFFont::GetFontMetricsWithGlyphNames(this->typeface(), glyphs, gl
yphsCount); | |
| 931 this->setFontInfo(std::move(fontMetrics)); | |
| 932 this->addFontDescriptor(0, &glyphIDs); | |
| 933 } else { | |
| 934 // Other CID fonts | |
| 935 addFontDescriptor(0, nullptr); | |
| 936 } | |
| 937 | |
| 938 insertName("BaseFont", this->getFontInfo()->fFontName); | |
| 939 | |
| 940 if (getType() == SkAdvancedTypefaceMetrics::kType1CID_Font) { | |
| 941 insertName("Subtype", "CIDFontType0"); | |
| 942 } else if (getType() == SkAdvancedTypefaceMetrics::kTrueType_Font) { | |
| 943 insertName("Subtype", "CIDFontType2"); | |
| 944 insertName("CIDToGIDMap", "Identity"); | |
| 945 } else { | 827 } else { |
| 946 SkASSERT(false); | 828 SkASSERT(false); |
| 947 } | 829 } |
| 948 | 830 |
| 949 auto sysInfo = sk_make_sp<SkPDFDict>(); | 831 auto sysInfo = sk_make_sp<SkPDFDict>(); |
| 950 sysInfo->insertString("Registry", "Adobe"); | 832 sysInfo->insertString("Registry", "Adobe"); |
| 951 sysInfo->insertString("Ordering", "Identity"); | 833 sysInfo->insertString("Ordering", "Identity"); |
| 952 sysInfo->insertInt("Supplement", 0); | 834 sysInfo->insertInt("Supplement", 0); |
| 953 this->insertObject("CIDSystemInfo", std::move(sysInfo)); | 835 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); |
| 954 | 836 |
| 955 SkSinglyLinkedList<AdvanceMetric> tmpMetrics; | 837 SkSinglyLinkedList<AdvanceMetric> tmpMetrics; |
| 956 set_glyph_widths(this->typeface(), &glyphIDs, &tmpMetrics); | 838 set_glyph_widths(face, subset, &tmpMetrics); |
| 957 int16_t defaultWidth = 0; | 839 int16_t defaultWidth = 0; |
| 958 uint16_t emSize = (uint16_t)this->getFontInfo()->fEmSize; | 840 uint16_t emSize = (uint16_t)this->getFontInfo()->fEmSize; |
| 959 sk_sp<SkPDFArray> widths = composeAdvanceData(tmpMetrics, emSize, &defaultWi
dth); | 841 sk_sp<SkPDFArray> widths = composeAdvanceData(tmpMetrics, emSize, &defaultWi
dth); |
| 960 if (widths->size()) { | 842 if (widths->size()) { |
| 961 this->insertObject("W", std::move(widths)); | 843 newCIDFont->insertObject("W", std::move(widths)); |
| 962 } | 844 } |
| 963 | 845 |
| 964 this->insertScalar( | 846 newCIDFont->insertScalar( |
| 965 "DW", scaleFromFontUnits(defaultWidth, emSize)); | 847 "DW", scaleFromFontUnits(defaultWidth, emSize)); |
| 848 |
| 849 |
| 850 //////////////////////////////////////////////////////////////////////////// |
| 851 |
| 852 this->insertName("Subtype", "Type0"); |
| 853 this->insertName("BaseFont", metrics.fFontName); |
| 854 this->insertName("Encoding", "Identity-H"); |
| 855 auto descendantFonts = sk_make_sp<SkPDFArray>(); |
| 856 descendantFonts->appendObjRef(std::move(newCIDFont)); |
| 857 this->insertObject("DescendantFonts", std::move(descendantFonts)); |
| 858 this->populateToUnicodeTable(subset); |
| 859 SkDEBUGCODE(fPopulated = true); |
| 966 return true; | 860 return true; |
| 967 } | 861 } |
| 968 | 862 |
| 863 sk_sp<const SkAdvancedTypefaceMetrics> SkPDFFont::GetFontMetricsWithToUnicode( |
| 864 SkTypeface* typeface, uint32_t* glyphs, uint32_t glyphsCount) { |
| 865 return sk_sp<const SkAdvancedTypefaceMetrics>( |
| 866 typeface->getAdvancedTypefaceMetrics( |
| 867 SkTypeface::kToUnicode_PerGlyphInfo, glyphs, glyphsCount)); |
| 868 } |
| 869 |
| 870 |
| 969 /////////////////////////////////////////////////////////////////////////////// | 871 /////////////////////////////////////////////////////////////////////////////// |
| 970 // class SkPDFType1Font | 872 // class SkPDFType1Font |
| 971 /////////////////////////////////////////////////////////////////////////////// | 873 /////////////////////////////////////////////////////////////////////////////// |
| 972 | 874 |
| 973 SkPDFType1Font::SkPDFType1Font(sk_sp<const SkAdvancedTypefaceMetrics> info, | 875 SkPDFType1Font::SkPDFType1Font(sk_sp<const SkAdvancedTypefaceMetrics> info, |
| 974 sk_sp<SkTypeface> typeface, | 876 sk_sp<SkTypeface> typeface, |
| 975 uint16_t glyphID, | 877 uint16_t glyphID, |
| 976 sk_sp<SkPDFDict> relatedFontDescriptor) | 878 sk_sp<SkPDFDict> relatedFontDescriptor) |
| 977 : SkPDFFont(std::move(info), | 879 : SkPDFFont(std::move(info), |
| 978 std::move(typeface), | 880 std::move(typeface), |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1003 if (!fontData) { | 905 if (!fontData) { |
| 1004 return false; | 906 return false; |
| 1005 } | 907 } |
| 1006 SkASSERT(this->canEmbed()); | 908 SkASSERT(this->canEmbed()); |
| 1007 auto fontStream = sk_make_sp<SkPDFStream>(std::move(fontData)); | 909 auto fontStream = sk_make_sp<SkPDFStream>(std::move(fontData)); |
| 1008 fontStream->dict()->insertInt("Length1", header); | 910 fontStream->dict()->insertInt("Length1", header); |
| 1009 fontStream->dict()->insertInt("Length2", data); | 911 fontStream->dict()->insertInt("Length2", data); |
| 1010 fontStream->dict()->insertInt("Length3", trailer); | 912 fontStream->dict()->insertInt("Length3", trailer); |
| 1011 descriptor->insertObjRef("FontFile", std::move(fontStream)); | 913 descriptor->insertObjRef("FontFile", std::move(fontStream)); |
| 1012 | 914 |
| 915 SkASSERT(this->getFontInfo()); |
| 916 add_common_font_descriptor_entries(descriptor.get(), |
| 917 *this->getFontInfo(), |
| 918 defaultWidth); |
| 1013 this->insertObjRef("FontDescriptor", std::move(descriptor)); | 919 this->insertObjRef("FontDescriptor", std::move(descriptor)); |
| 1014 | 920 return true; |
| 1015 return addCommonFontDescriptorEntries(defaultWidth); | |
| 1016 } | 921 } |
| 1017 | 922 |
| 1018 bool SkPDFType1Font::populate(int16_t glyphID) { | 923 bool SkPDFType1Font::populate(int16_t glyphID) { |
| 1019 this->insertName("Subtype", "Type1"); | 924 this->insertName("Subtype", "Type1"); |
| 1020 this->insertName("BaseFont", this->getFontInfo()->fFontName); | 925 this->insertName("BaseFont", this->getFontInfo()->fFontName); |
| 1021 adjustGlyphRangeForSingleByteEncoding(glyphID); | 926 adjustGlyphRangeForSingleByteEncoding(glyphID); |
| 1022 SkGlyphID firstGlyphID = this->firstGlyphID(); | 927 SkGlyphID firstGlyphID = this->firstGlyphID(); |
| 1023 SkGlyphID lastGlyphID = this->lastGlyphID(); | 928 SkGlyphID lastGlyphID = this->lastGlyphID(); |
| 1024 | 929 |
| 1025 // glyphCount not including glyph 0 | 930 // glyphCount not including glyph 0 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1284 } | 1189 } |
| 1285 return *canon->fCanEmbedTypeface.set(id, canEmbed); | 1190 return *canon->fCanEmbedTypeface.set(id, canEmbed); |
| 1286 } | 1191 } |
| 1287 | 1192 |
| 1288 void SkPDFFont::drop() { | 1193 void SkPDFFont::drop() { |
| 1289 fTypeface = nullptr; | 1194 fTypeface = nullptr; |
| 1290 fFontInfo = nullptr; | 1195 fFontInfo = nullptr; |
| 1291 fDescriptor = nullptr; | 1196 fDescriptor = nullptr; |
| 1292 this->SkPDFDict::drop(); | 1197 this->SkPDFDict::drop(); |
| 1293 } | 1198 } |
| OLD | NEW |