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

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

Issue 2232283003: Revert of SkPDF: Subset Type3 (fallback) font (Closed) Base URL: https://skia.googlesource.com/skia.git@SkPDF_next3
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') | src/pdf/SkPDFTypes.cpp » ('j') | 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 AdvanceMetric(const AdvanceMetric&) = delete; 53 AdvanceMetric(const AdvanceMetric&) = delete;
54 AdvanceMetric& operator=(const AdvanceMetric&) = delete; 54 AdvanceMetric& operator=(const AdvanceMetric&) = delete;
55 }; 55 };
56 56
57 class SkPDFType0Font final : public SkPDFFont { 57 class SkPDFType0Font final : public SkPDFFont {
58 public: 58 public:
59 SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, 59 SkPDFType0Font(const SkAdvancedTypefaceMetrics* info,
60 SkTypeface* typeface); 60 SkTypeface* typeface);
61 virtual ~SkPDFType0Font(); 61 virtual ~SkPDFType0Font();
62 bool multiByteGlyphs() const override { return true; } 62 bool multiByteGlyphs() const override { return true; }
63 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override; 63 SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage) override;
64 #ifdef SK_DEBUG 64 #ifdef SK_DEBUG
65 void emitObject(SkWStream*, 65 void emitObject(SkWStream*,
66 const SkPDFObjNumMap&, 66 const SkPDFObjNumMap&,
67 const SkPDFSubstituteMap&) const override; 67 const SkPDFSubstituteMap&) const override;
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
(...skipping 27 matching lines...) Expand all
101 private: 101 private:
102 bool populate(int16_t glyphID); 102 bool populate(int16_t glyphID);
103 bool addFontDescriptor(int16_t defaultWidth); 103 bool addFontDescriptor(int16_t defaultWidth);
104 }; 104 };
105 105
106 class SkPDFType3Font final : public SkPDFFont { 106 class SkPDFType3Font final : public SkPDFFont {
107 public: 107 public:
108 SkPDFType3Font(const SkAdvancedTypefaceMetrics* info, 108 SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
109 SkTypeface* typeface, 109 SkTypeface* typeface,
110 uint16_t glyphID); 110 uint16_t glyphID);
111 virtual ~SkPDFType3Font() {} 111 virtual ~SkPDFType3Font();
112 void emitObject(SkWStream*,
113 const SkPDFObjNumMap&,
114 const SkPDFSubstituteMap&) const override {
115 SkDEBUGFAIL("should call getFontSubset!");
116 }
117 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override;
118 bool multiByteGlyphs() const override { return false; } 112 bool multiByteGlyphs() const override { return false; }
113
114 private:
115 bool populate(uint16_t glyphID);
119 }; 116 };
120 117
121 /////////////////////////////////////////////////////////////////////////////// 118 ///////////////////////////////////////////////////////////////////////////////
122 // File-Local Functions 119 // File-Local Functions
123 /////////////////////////////////////////////////////////////////////////////// 120 ///////////////////////////////////////////////////////////////////////////////
124 121
125 const int16_t kInvalidAdvance = SK_MinS16; 122 const int16_t kInvalidAdvance = SK_MinS16;
126 const int16_t kDontCareAdvance = SK_MinS16 + 1; 123 const int16_t kDontCareAdvance = SK_MinS16 + 1;
127 124
128 static void stripUninterestingTrailingAdvancesFromRange( 125 static void stripUninterestingTrailingAdvancesFromRange(
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 return SkScalarMulDiv(scaled, 1000, emSize); 328 return SkScalarMulDiv(scaled, 1000, emSize);
332 } 329 }
333 } 330 }
334 331
335 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) { 332 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) {
336 return from_font_units(SkIntToScalar(val), emSize); 333 return from_font_units(SkIntToScalar(val), emSize);
337 } 334 }
338 335
339 336
340 void setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box, 337 void setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box,
341 SkDynamicMemoryWStream* content) { 338 SkWStream* content) {
342 // Specify width and bounding box for the glyph. 339 // Specify width and bounding box for the glyph.
343 SkPDFUtils::AppendScalar(width, content); 340 SkPDFUtils::AppendScalar(width, content);
344 content->writeText(" 0 "); 341 content->writeText(" 0 ");
345 content->writeDecAsText(box.fLeft); 342 content->writeDecAsText(box.fLeft);
346 content->writeText(" "); 343 content->writeText(" ");
347 content->writeDecAsText(box.fTop); 344 content->writeDecAsText(box.fTop);
348 content->writeText(" "); 345 content->writeText(" ");
349 content->writeDecAsText(box.fRight); 346 content->writeDecAsText(box.fRight);
350 content->writeText(" "); 347 content->writeText(" ");
351 content->writeDecAsText(box.fBottom); 348 content->writeDecAsText(box.fBottom);
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 fontMetrics.reset( 552 fontMetrics.reset(
556 typeface->getAdvancedTypefaceMetrics(info, nullptr, 0)); 553 typeface->getAdvancedTypefaceMetrics(info, nullptr, 0));
557 } 554 }
558 555
559 SkPDFFont* font = SkPDFFont::Create(canon, fontMetrics.get(), typeface, 556 SkPDFFont* font = SkPDFFont::Create(canon, fontMetrics.get(), typeface,
560 glyphID, relatedFontDescriptor); 557 glyphID, relatedFontDescriptor);
561 canon->addFont(font, fontID, font->fFirstGlyphID); 558 canon->addFont(font, fontID, font->fFirstGlyphID);
562 return font; 559 return font;
563 } 560 }
564 561
565 sk_sp<SkPDFObject> SkPDFFont::getFontSubset(const SkPDFGlyphSet*) { 562 SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) {
566 return nullptr; // Default: no support. 563 return nullptr; // Default: no support.
567 } 564 }
568 565
569 SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info, 566 SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info,
570 SkTypeface* typeface, 567 SkTypeface* typeface,
571 SkPDFDict* relatedFontDescriptor) 568 SkPDFDict* relatedFontDescriptor)
572 : SkPDFDict("Font") 569 : SkPDFDict("Font")
573 , fTypeface(ref_or_default(typeface)) 570 , fTypeface(ref_or_default(typeface))
574 , fFirstGlyphID(1) 571 , fFirstGlyphID(1)
575 , fLastGlyphID(info ? info->fLastGlyphID : 0) 572 , fLastGlyphID(info ? info->fLastGlyphID : 0)
576 , fFontInfo(SkSafeRef(info)) 573 , fFontInfo(SkSafeRef(info))
577 , fDescriptor(SkSafeRef(relatedFontDescriptor)) 574 , fDescriptor(SkSafeRef(relatedFontDescriptor)) {
578 , fFontType((!info || info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster _FontFlag) 575 if (info == nullptr ||
579 ? SkAdvancedTypefaceMetrics::kOther_Font 576 info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag) {
580 : info->fType) { 577 fFontType = SkAdvancedTypefaceMetrics::kOther_Font;
581 if (0 == fLastGlyphID) { 578 } else {
582 SkAutoResolveDefaultTypeface face(typeface); 579 fFontType = info->fType;
583 fLastGlyphID = SkToU16(face->countGlyphs() - 1);
584 } 580 }
585 } 581 }
586 582
587 // static 583 // static
588 SkPDFFont* SkPDFFont::Create(SkPDFCanon* canon, 584 SkPDFFont* SkPDFFont::Create(SkPDFCanon* canon,
589 const SkAdvancedTypefaceMetrics* info, 585 const SkAdvancedTypefaceMetrics* info,
590 SkTypeface* typeface, 586 SkTypeface* typeface,
591 uint16_t glyphID, 587 uint16_t glyphID,
592 SkPDFDict* relatedFontDescriptor) { 588 SkPDFDict* relatedFontDescriptor) {
593 SkAdvancedTypefaceMetrics::FontType type = 589 SkAdvancedTypefaceMetrics::FontType type =
594 info ? info->fType : SkAdvancedTypefaceMetrics::kOther_Font; 590 info ? info->fType : SkAdvancedTypefaceMetrics::kOther_Font;
595 SkAdvancedTypefaceMetrics::FontFlags flags = 591
596 info ? info->fFlags : SkAdvancedTypefaceMetrics::kEmpty_FontFlag; 592 if (info && (info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag )) {
597 if (SkToBool(flags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag)) {
598 return new SkPDFType3Font(info, typeface, glyphID); 593 return new SkPDFType3Font(info, typeface, glyphID);
599 } 594 }
600 switch (type) { 595 if (type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
601 case SkAdvancedTypefaceMetrics::kType1CID_Font: 596 type == SkAdvancedTypefaceMetrics::kTrueType_Font) {
602 case SkAdvancedTypefaceMetrics::kTrueType_Font: 597 SkASSERT(relatedFontDescriptor == nullptr);
603 SkASSERT(relatedFontDescriptor == nullptr); 598 return new SkPDFType0Font(info, typeface);
604 SkASSERT(info != nullptr);
605 return new SkPDFType0Font(info, typeface);
606 case SkAdvancedTypefaceMetrics::kType1_Font:
607 SkASSERT(info != nullptr);
608 return new SkPDFType1Font(info, typeface, glyphID, relatedFontDescri ptor);
609 case SkAdvancedTypefaceMetrics::kCFF_Font:
610 SkASSERT(info != nullptr);
611 // fallthrough
612 case SkAdvancedTypefaceMetrics::kOther_Font:
613 return new SkPDFType3Font(info, typeface, glyphID);
614 } 599 }
615 SkDEBUGFAIL("invalid SkAdvancedTypefaceMetrics::FontType"); 600 if (type == SkAdvancedTypefaceMetrics::kType1_Font) {
616 return nullptr; 601 return new SkPDFType1Font(info, typeface, glyphID, relatedFontDescriptor );
602 }
603
604 SkASSERT(type == SkAdvancedTypefaceMetrics::kCFF_Font ||
605 type == SkAdvancedTypefaceMetrics::kOther_Font);
606
607 return new SkPDFType3Font(info, typeface, glyphID);
617 } 608 }
618 609
619 const SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() { 610 const SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() {
620 return fFontInfo.get(); 611 return fFontInfo.get();
621 } 612 }
622 613
623 void SkPDFFont::setFontInfo(const SkAdvancedTypefaceMetrics* info) { 614 void SkPDFFont::setFontInfo(const SkAdvancedTypefaceMetrics* info) {
624 if (info == nullptr || info == fFontInfo.get()) { 615 if (info == nullptr || info == fFontInfo.get()) {
625 return; 616 return;
626 } 617 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, SkTypeface * typeface) 696 SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, SkTypeface * typeface)
706 : SkPDFFont(info, typeface, nullptr) { 697 : SkPDFFont(info, typeface, nullptr) {
707 SkDEBUGCODE(fPopulated = false); 698 SkDEBUGCODE(fPopulated = false);
708 if (!canSubset()) { 699 if (!canSubset()) {
709 this->populate(nullptr); 700 this->populate(nullptr);
710 } 701 }
711 } 702 }
712 703
713 SkPDFType0Font::~SkPDFType0Font() {} 704 SkPDFType0Font::~SkPDFType0Font() {}
714 705
715 sk_sp<SkPDFObject> SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) { 706 SkPDFFont* SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) {
716 if (!canSubset()) { 707 if (!canSubset()) {
717 return nullptr; 708 return nullptr;
718 } 709 }
719 auto newSubset = sk_make_sp<SkPDFType0Font>(fontInfo(), typeface()); 710 SkPDFType0Font* newSubset = new SkPDFType0Font(fontInfo(), typeface());
720 newSubset->populate(subset); 711 newSubset->populate(subset);
721 return newSubset; 712 return newSubset;
722 } 713 }
723 714
724 #ifdef SK_DEBUG 715 #ifdef SK_DEBUG
725 void SkPDFType0Font::emitObject(SkWStream* stream, 716 void SkPDFType0Font::emitObject(SkWStream* stream,
726 const SkPDFObjNumMap& objNumMap, 717 const SkPDFObjNumMap& objNumMap,
727 const SkPDFSubstituteMap& substitutes) const { 718 const SkPDFSubstituteMap& substitutes) const {
728 SkASSERT(fPopulated); 719 SkASSERT(fPopulated);
729 return INHERITED::emitObject(stream, objNumMap, substitutes); 720 return INHERITED::emitObject(stream, objNumMap, substitutes);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 return true; 871 return true;
881 } 872 }
882 873
883 void set_glyph_widths(SkTypeface* tf, 874 void set_glyph_widths(SkTypeface* tf,
884 const SkTDArray<uint32_t>* glyphIDs, 875 const SkTDArray<uint32_t>* glyphIDs,
885 SkSinglyLinkedList<AdvanceMetric>* dst) { 876 SkSinglyLinkedList<AdvanceMetric>* dst) {
886 SkPaint tmpPaint; 877 SkPaint tmpPaint;
887 tmpPaint.setHinting(SkPaint::kNo_Hinting); 878 tmpPaint.setHinting(SkPaint::kNo_Hinting);
888 tmpPaint.setTypeface(sk_ref_sp(tf)); 879 tmpPaint.setTypeface(sk_ref_sp(tf));
889 tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm()); 880 tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm());
890 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); 881 SkAutoGlyphCache autoGlyphCache(tmpPaint, nullptr, nullptr);
891 SkAutoGlyphCache autoGlyphCache(tmpPaint, &props, nullptr);
892 if (!glyphIDs || glyphIDs->isEmpty()) { 882 if (!glyphIDs || glyphIDs->isEmpty()) {
893 get_glyph_widths(dst, tf->countGlyphs(), nullptr, 0, autoGlyphCache.get( )); 883 get_glyph_widths(dst, tf->countGlyphs(), nullptr, 0, autoGlyphCache.get( ));
894 } else { 884 } else {
895 get_glyph_widths(dst, tf->countGlyphs(), glyphIDs->begin(), 885 get_glyph_widths(dst, tf->countGlyphs(), glyphIDs->begin(),
896 glyphIDs->count(), autoGlyphCache.get()); 886 glyphIDs->count(), autoGlyphCache.get());
897 } 887 }
898 } 888 }
899 889
900 sk_sp<const SkAdvancedTypefaceMetrics> SkPDFFont::GetFontMetricsWithGlyphNames( 890 sk_sp<const SkAdvancedTypefaceMetrics> SkPDFFont::GetFontMetricsWithGlyphNames(
901 SkTypeface* typeface, uint32_t* glyphs, uint32_t glyphsCount) { 891 SkTypeface* typeface, uint32_t* glyphs, uint32_t glyphsCount) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 // glyphCount not including glyph 0 1010 // glyphCount not including glyph 0
1021 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID; 1011 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID;
1022 SkASSERT(glyphCount > 0 && glyphCount <= 255); 1012 SkASSERT(glyphCount > 0 && glyphCount <= 255);
1023 this->insertInt("FirstChar", (size_t)0); 1013 this->insertInt("FirstChar", (size_t)0);
1024 this->insertInt("LastChar", (size_t)glyphCount); 1014 this->insertInt("LastChar", (size_t)glyphCount);
1025 { 1015 {
1026 SkPaint tmpPaint; 1016 SkPaint tmpPaint;
1027 tmpPaint.setHinting(SkPaint::kNo_Hinting); 1017 tmpPaint.setHinting(SkPaint::kNo_Hinting);
1028 tmpPaint.setTypeface(sk_ref_sp(this->typeface())); 1018 tmpPaint.setTypeface(sk_ref_sp(this->typeface()));
1029 tmpPaint.setTextSize((SkScalar)this->typeface()->getUnitsPerEm()); 1019 tmpPaint.setTextSize((SkScalar)this->typeface()->getUnitsPerEm());
1030 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); 1020 SkAutoGlyphCache glyphCache(tmpPaint, nullptr, nullptr);
1031 SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr);
1032 auto widths = sk_make_sp<SkPDFArray>(); 1021 auto widths = sk_make_sp<SkPDFArray>();
1033 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX; 1022 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX;
1034 const uint16_t emSize = this->fontInfo()->fEmSize; 1023 const uint16_t emSize = this->fontInfo()->fEmSize;
1035 widths->appendScalar(from_font_units(advance, emSize)); 1024 widths->appendScalar(from_font_units(advance, emSize));
1036 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) { 1025 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) {
1037 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX; 1026 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX;
1038 widths->appendScalar(from_font_units(advance, emSize)); 1027 widths->appendScalar(from_font_units(advance, emSize));
1039 } 1028 }
1040 this->insertObject("Widths", std::move(widths)); 1029 this->insertObject("Widths", std::move(widths));
1041 } 1030 }
(...skipping 16 matching lines...) Expand all
1058 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); 1047 auto encoding = sk_make_sp<SkPDFDict>("Encoding");
1059 encoding->insertObject("Differences", std::move(encDiffs)); 1048 encoding->insertObject("Differences", std::move(encDiffs));
1060 this->insertObject("Encoding", std::move(encoding)); 1049 this->insertObject("Encoding", std::move(encoding));
1061 return true; 1050 return true;
1062 } 1051 }
1063 1052
1064 /////////////////////////////////////////////////////////////////////////////// 1053 ///////////////////////////////////////////////////////////////////////////////
1065 // class SkPDFType3Font 1054 // class SkPDFType3Font
1066 /////////////////////////////////////////////////////////////////////////////// 1055 ///////////////////////////////////////////////////////////////////////////////
1067 1056
1068 namespace { 1057 SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
1069 // returns [0, first, first+1, ... last-1, last] 1058 SkTypeface* typeface,
1070 struct SingleByteGlyphIdIterator { 1059 uint16_t glyphID)
1071 SingleByteGlyphIdIterator(SkGlyphID first, SkGlyphID last) 1060 : SkPDFFont(info, typeface, nullptr) {
1072 : fFirst(first), fLast(last) { 1061 this->populate(glyphID);
1073 SkASSERT(fFirst > 0);
1074 SkASSERT(fLast >= first);
1075 }
1076 struct Iter {
1077 void operator++() {
1078 fCurrent = (0 == fCurrent) ? fFirst : fCurrent + 1;
1079 }
1080 // This is an input_iterator
1081 SkGlyphID operator*() const { return (SkGlyphID)fCurrent; }
1082 bool operator!=(const Iter& rhs) const {
1083 return fCurrent != rhs.fCurrent;
1084 }
1085 Iter(SkGlyphID f, int c) : fFirst(f), fCurrent(c) {}
1086 private:
1087 const SkGlyphID fFirst;
1088 int fCurrent; // must be int to make fLast+1 to fit
1089 };
1090 Iter begin() const { return Iter(fFirst, 0); }
1091 Iter end() const { return Iter(fFirst, (int)fLast + 1); }
1092 private:
1093 const SkGlyphID fFirst;
1094 const SkGlyphID fLast;
1095 };
1096 } 1062 }
1097 1063
1098 static void add_type3_font_info(SkPDFDict* font, 1064 SkPDFType3Font::~SkPDFType3Font() {}
1099 SkTypeface* typeface, 1065
1100 SkScalar emSize, 1066 bool SkPDFType3Font::populate(uint16_t glyphID) {
1101 const SkPDFGlyphSet* subset,
1102 SkGlyphID firstGlyphID,
1103 SkGlyphID lastGlyphID) {
1104 SkASSERT(lastGlyphID >= firstGlyphID);
1105 SkPaint paint; 1067 SkPaint paint;
1106 paint.setHinting(SkPaint::kNo_Hinting); 1068 paint.setTypeface(sk_ref_sp(this->typeface()));
1107 paint.setTypeface(sk_ref_sp(typeface)); 1069 paint.setTextSize(1000);
1108 paint.setTextSize(emSize);
1109 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); 1070 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
1110 SkAutoGlyphCache cache(paint, &props, nullptr); 1071 SkAutoGlyphCache autoCache(paint, &props, nullptr);
1072 SkGlyphCache* cache = autoCache.getCache();
1073 // If fLastGlyphID isn't set (because there is not fFontInfo), look it up.
1074 if (lastGlyphID() == 0) {
1075 setLastGlyphID(cache->getGlyphCount() - 1);
1076 }
1111 1077
1112 font->insertName("Subtype", "Type3"); 1078 adjustGlyphRangeForSingleByteEncoding(glyphID);
1113 // Flip about the x-axis and scale by 1/emSize. 1079
1080 insertName("Subtype", "Type3");
1081 // Flip about the x-axis and scale by 1/1000.
1114 SkMatrix fontMatrix; 1082 SkMatrix fontMatrix;
1115 fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize)); 1083 fontMatrix.setScale(SkScalarInvert(1000), -SkScalarInvert(1000));
1116 font->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix)); 1084 this->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix));
1117 1085
1118 auto charProcs = sk_make_sp<SkPDFDict>(); 1086 auto charProcs = sk_make_sp<SkPDFDict>();
1119 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); 1087 auto encoding = sk_make_sp<SkPDFDict>("Encoding");
1120 1088
1121 auto encDiffs = sk_make_sp<SkPDFArray>(); 1089 auto encDiffs = sk_make_sp<SkPDFArray>();
1122 // length(firstGlyphID .. lastGlyphID) == lastGlyphID - firstGlyphID + 1 1090 encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
1123 // plus 1 for glyph 0; 1091 encDiffs->appendInt(1);
1124 SkASSERT(firstGlyphID > 0);
1125 SkASSERT(lastGlyphID >= firstGlyphID);
1126 int glyphCount = lastGlyphID - firstGlyphID + 2;
1127 // one other entry for the index of first glyph.
1128 encDiffs->reserve(glyphCount + 1);
1129 encDiffs->appendInt(0); // index of first glyph
1130 1092
1131 auto widthArray = sk_make_sp<SkPDFArray>(); 1093 auto widthArray = sk_make_sp<SkPDFArray>();
1132 widthArray->reserve(glyphCount);
1133 1094
1134 SkIRect bbox = SkIRect::MakeEmpty(); 1095 SkIRect bbox = SkIRect::MakeEmpty();
1096 for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
1097 SkString characterName;
1098 characterName.printf("gid%d", gID);
1099 encDiffs->appendName(characterName.c_str());
1135 1100
1136 sk_sp<SkPDFStream> emptyStream; 1101 const SkGlyph& glyph = cache->getGlyphIDMetrics(gID);
1137 for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID)) { 1102 widthArray->appendScalar(SkFloatToScalar(glyph.fAdvanceX));
1138 bool skipGlyph = subset && gID != 0 && !subset->has(gID); 1103 SkIRect glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop,
1139 SkString characterName; 1104 glyph.fWidth, glyph.fHeight);
1140 SkScalar advance = 0.0f; 1105 bbox.join(glyphBBox);
1141 SkIRect glyphBBox; 1106
1142 if (skipGlyph) { 1107 SkDynamicMemoryWStream content;
1143 characterName.set("g0"); 1108 setGlyphWidthAndBoundingBox(SkFloatToScalar(glyph.fAdvanceX), glyphBBox,
1144 } else { 1109 &content);
1145 characterName.printf("g%X", gID); 1110 const SkPath* path = cache->findPath(glyph);
1146 const SkGlyph& glyph = cache->getGlyphIDMetrics(gID); 1111 if (path) {
1147 advance = SkFloatToScalar(glyph.fAdvanceX); 1112 SkPDFUtils::EmitPath(*path, paint.getStyle(), &content);
1148 glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop, 1113 SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(),
1149 glyph.fWidth, glyph.fHeight); 1114 &content);
1150 bbox.join(glyphBBox);
1151 const SkPath* path = cache->findPath(glyph);
1152 if (path && !path->isEmpty()) {
1153 SkDynamicMemoryWStream content;
1154 setGlyphWidthAndBoundingBox(SkFloatToScalar(glyph.fAdvanceX), gl yphBBox,
1155 &content);
1156 SkPDFUtils::EmitPath(*path, SkPaint::kFill_Style, &content);
1157 SkPDFUtils::PaintPath(SkPaint::kFill_Style, path->getFillType(),
1158 &content);
1159 charProcs->insertObjRef(
1160 characterName, sk_make_sp<SkPDFStream>(
1161 std::unique_ptr<SkStreamAsset>(content.detachAsStrea m())));
1162 } else {
1163 if (!emptyStream) {
1164 emptyStream = sk_make_sp<SkPDFStream>(
1165 std::unique_ptr<SkStreamAsset>(
1166 new SkMemoryStream((size_t)0)));
1167 }
1168 charProcs->insertObjRef(characterName, emptyStream);
1169 }
1170 } 1115 }
1171 encDiffs->appendName(characterName.c_str()); 1116 charProcs->insertObjRef(
1172 widthArray->appendScalar(advance); 1117 characterName, sk_make_sp<SkPDFStream>(
1118 std::unique_ptr<SkStreamAsset>(content.detachAsStream()) ));
1173 } 1119 }
1174 1120
1175 encoding->insertObject("Differences", std::move(encDiffs)); 1121 encoding->insertObject("Differences", std::move(encDiffs));
1176 font->insertInt("FirstChar", 0); 1122
1177 font->insertInt("LastChar", lastGlyphID - firstGlyphID + 1); 1123 this->insertObject("CharProcs", std::move(charProcs));
1178 /* FontBBox: "A rectangle expressed in the glyph coordinate 1124 this->insertObject("Encoding", std::move(encoding));
1179 system, specifying the font bounding box. This is the smallest 1125
1180 rectangle enclosing the shape that would result if all of the 1126 this->insertObject("FontBBox", makeFontBBox(bbox, 1000));
1181 glyphs of the font were placed with their origins coincident and 1127 this->insertInt("FirstChar", 1);
1182 then filled." */ 1128 this->insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1);
1183 auto fontBBox = sk_make_sp<SkPDFArray>(); 1129 this->insertObject("Widths", std::move(widthArray));
1184 fontBBox->reserve(4); 1130 this->insertName("CIDToGIDMap", "Identity");
1185 fontBBox->appendInt(bbox.left()); 1131
1186 fontBBox->appendInt(bbox.bottom()); 1132 this->populateToUnicodeTable(nullptr);
1187 fontBBox->appendInt(bbox.right()); 1133 return true;
1188 fontBBox->appendInt(bbox.top());
1189 font->insertObject("FontBBox", std::move(fontBBox));
1190 font->insertName("CIDToGIDMap", "Identity");
1191 sk_sp<const SkAdvancedTypefaceMetrics> metrics;
1192 if (subset) {
1193 SkTDArray<uint32_t> subsetList;
1194 for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID )) {
1195 if (gID == 0 || subset->has(gID)) { // Always include glyph 0.
1196 subsetList.push(0);
1197 }
1198 }
1199 subset->exportTo(&subsetList);
1200 metrics = SkPDFFont::GetFontMetricsWithToUnicode(typeface, subsetList.be gin(),
1201 subsetList.count());
1202 } else {
1203 metrics = SkPDFFont::GetFontMetricsWithToUnicode(typeface, nullptr, 0);
1204 }
1205 font->insertObjRef("ToUnicode",
1206 SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode,
1207 subset,
1208 false,
1209 firstGlyphID,
1210 lastGlyphID));
1211 font->insertObject("Widths", std::move(widthArray));
1212 font->insertObject("Encoding", std::move(encoding));
1213 font->insertObject("CharProcs", std::move(charProcs));
1214 } 1134 }
1215 1135
1216 SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
1217 SkTypeface* typeface,
1218 uint16_t glyphID)
1219 : SkPDFFont(info, typeface, nullptr) {
1220 // If fLastGlyphID isn't set (because there is not fFontInfo), look it up.
1221 this->setLastGlyphID(SkToU16(typeface->countGlyphs() - 1));
1222 this->adjustGlyphRangeForSingleByteEncoding(glyphID);
1223 }
1224
1225 sk_sp<SkPDFObject> SkPDFType3Font::getFontSubset(const SkPDFGlyphSet* usage) {
1226 // All fonts are subset before serialization.
1227 // TODO(halcanary): all fonts should follow this pattern.
1228 auto font = sk_make_sp<SkPDFDict>("Font");
1229 const SkAdvancedTypefaceMetrics* info = this->fontInfo();
1230 uint16_t emSize = info && info->fEmSize > 0 ? info->fEmSize : 1000;
1231 add_type3_font_info(font.get(), this->typeface(), (SkScalar)emSize, usage,
1232 this->firstGlyphID(), this->lastGlyphID());
1233 return font;
1234 }
1235
1236
1237 ////////////////////////////////////////////////////////////////////////////////
1238
1239 SkPDFFont::Match SkPDFFont::IsMatch(SkPDFFont* existingFont, 1136 SkPDFFont::Match SkPDFFont::IsMatch(SkPDFFont* existingFont,
1240 uint32_t existingFontID, 1137 uint32_t existingFontID,
1241 uint16_t existingGlyphID, 1138 uint16_t existingGlyphID,
1242 uint32_t searchFontID, 1139 uint32_t searchFontID,
1243 uint16_t searchGlyphID) { 1140 uint16_t searchGlyphID) {
1244 if (existingFontID != searchFontID) { 1141 if (existingFontID != searchFontID) {
1245 return SkPDFFont::kNot_Match; 1142 return SkPDFFont::kNot_Match;
1246 } 1143 }
1247 if (existingGlyphID == 0 || searchGlyphID == 0) { 1144 if (existingGlyphID == 0 || searchGlyphID == 0) {
1248 return SkPDFFont::kExact_Match; 1145 return SkPDFFont::kExact_Match;
(...skipping 26 matching lines...) Expand all
1275 } 1172 }
1276 return *canon->fCanEmbedTypeface.set(id, canEmbed); 1173 return *canon->fCanEmbedTypeface.set(id, canEmbed);
1277 } 1174 }
1278 1175
1279 void SkPDFFont::drop() { 1176 void SkPDFFont::drop() {
1280 fTypeface = nullptr; 1177 fTypeface = nullptr;
1281 fFontInfo = nullptr; 1178 fFontInfo = nullptr;
1282 fDescriptor = nullptr; 1179 fDescriptor = nullptr;
1283 this->SkPDFDict::drop(); 1180 this->SkPDFDict::drop();
1284 } 1181 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | src/pdf/SkPDFTypes.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698