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