Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Side by Side Diff: src/pdf/SkPDFFont.cpp

Issue 2244173005: SkPDF: eliminate SkPDFCIDfont class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698