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 |