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 |