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

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: rebase 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(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
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
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
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
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
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
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
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 }
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