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

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

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