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

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-12 (Friday) 10:20:16 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 } 515 }
513 516
514 return numGlyphs; 517 return numGlyphs;
515 } 518 }
516 519
517 // static 520 // static
518 SkPDFFont* SkPDFFont::GetFontResource(SkPDFCanon* canon, 521 SkPDFFont* SkPDFFont::GetFontResource(SkPDFCanon* canon,
519 SkTypeface* typeface, 522 SkTypeface* typeface,
520 uint16_t glyphID) { 523 uint16_t glyphID) {
521 SkASSERT(canon); 524 SkASSERT(canon);
522 SkAutoResolveDefaultTypeface autoResolve(typeface); 525 const uint32_t fontID = SkTypeface::UniqueID(typeface);
523 typeface = autoResolve.get();
524 const uint32_t fontID = typeface->uniqueID();
525
526 SkPDFFont* relatedFont; 526 SkPDFFont* relatedFont;
527 if (SkPDFFont* pdfFont = canon->findFont(fontID, glyphID, &relatedFont)) { 527 if (SkPDFFont* pdfFont = canon->findFont(fontID, glyphID, &relatedFont)) {
528 return SkRef(pdfFont); 528 return SkRef(pdfFont);
529 } 529 }
530 530 SkAutoResolveDefaultTypeface autoResolve(typeface);
531 typeface = autoResolve.get();
532 SkASSERT(typeface);
533 int glyphCount = typeface->countGlyphs();
534 if (glyphCount < 1 || // typeface lacks even a NOTDEF glyph.
535 glyphCount > 1 + SK_MaxU16 || // invalid glyphCount
536 glyphID >= glyphCount) { // invalid glyph
537 return nullptr;
538 }
531 sk_sp<const SkAdvancedTypefaceMetrics> fontMetrics; 539 sk_sp<const SkAdvancedTypefaceMetrics> fontMetrics;
532 SkPDFDict* relatedFontDescriptor = nullptr; 540 SkPDFDict* relatedFontDescriptor = nullptr;
533 if (relatedFont) { 541 if (relatedFont) {
534 fontMetrics.reset(SkSafeRef(relatedFont->fontInfo())); 542 fontMetrics.reset(SkSafeRef(relatedFont->fontInfo()));
535 relatedFontDescriptor = relatedFont->getFontDescriptor(); 543 relatedFontDescriptor = relatedFont->getFontDescriptor();
536 544
537 // This only is to catch callers who pass invalid glyph ids. 545 // This only is to catch callers who pass invalid glyph ids.
538 // If glyph id is invalid, then we will create duplicate entries 546 // If glyph id is invalid, then we will create duplicate entries
539 // for TrueType fonts. 547 // for TrueType fonts.
540 SkAdvancedTypefaceMetrics::FontType fontType = 548 SkAdvancedTypefaceMetrics::FontType fontType =
(...skipping 11 matching lines...) Expand all
552 fontMetrics.reset( 560 fontMetrics.reset(
553 typeface->getAdvancedTypefaceMetrics(info, nullptr, 0)); 561 typeface->getAdvancedTypefaceMetrics(info, nullptr, 0));
554 } 562 }
555 563
556 SkPDFFont* font = SkPDFFont::Create(canon, fontMetrics.get(), typeface, 564 SkPDFFont* font = SkPDFFont::Create(canon, fontMetrics.get(), typeface,
557 glyphID, relatedFontDescriptor); 565 glyphID, relatedFontDescriptor);
558 canon->addFont(font, fontID, font->fFirstGlyphID); 566 canon->addFont(font, fontID, font->fFirstGlyphID);
559 return font; 567 return font;
560 } 568 }
561 569
562 SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) { 570 sk_sp<SkPDFObject> SkPDFFont::getFontSubset(const SkPDFGlyphSet*) {
563 return nullptr; // Default: no support. 571 return nullptr; // Default: no support.
564 } 572 }
565 573
574 // TODO: take a sk_sp<SkAdvancedTypefaceMetrics> and sk_sp<SkTypeface>
566 SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info, 575 SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info,
567 SkTypeface* typeface, 576 SkTypeface* typeface,
568 SkPDFDict* relatedFontDescriptor) 577 SkPDFDict* relatedFontDescriptor)
569 : SkPDFDict("Font") 578 : SkPDFDict("Font")
570 , fTypeface(ref_or_default(typeface)) 579 , fTypeface(ref_or_default(typeface))
571 , fFirstGlyphID(1) 580 , fFirstGlyphID(1)
572 , fLastGlyphID(info ? info->fLastGlyphID : 0) 581 , fLastGlyphID(info ? info->fLastGlyphID : 0)
573 , fFontInfo(SkSafeRef(info)) 582 , fFontInfo(SkSafeRef(info))
574 , fDescriptor(SkSafeRef(relatedFontDescriptor)) { 583 , fDescriptor(SkSafeRef(relatedFontDescriptor))
575 if (info == nullptr || 584 , fFontType((!info || info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster _FontFlag)
576 info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag) { 585 ? SkAdvancedTypefaceMetrics::kOther_Font
577 fFontType = SkAdvancedTypefaceMetrics::kOther_Font; 586 : info->fType) {
578 } else { 587 SkASSERT(fTypeface);
579 fFontType = info->fType; 588 if (0 == fLastGlyphID) {
589 fLastGlyphID = SkToU16(fTypeface->countGlyphs() - 1);
580 } 590 }
581 } 591 }
582 592
583 // static 593 // static
584 SkPDFFont* SkPDFFont::Create(SkPDFCanon* canon, 594 SkPDFFont* SkPDFFont::Create(SkPDFCanon* canon,
585 const SkAdvancedTypefaceMetrics* info, 595 const SkAdvancedTypefaceMetrics* info,
586 SkTypeface* typeface, 596 SkTypeface* typeface,
587 uint16_t glyphID, 597 uint16_t glyphID,
588 SkPDFDict* relatedFontDescriptor) { 598 SkPDFDict* relatedFontDescriptor) {
589 SkAdvancedTypefaceMetrics::FontType type = 599 SkAdvancedTypefaceMetrics::FontType type =
590 info ? info->fType : SkAdvancedTypefaceMetrics::kOther_Font; 600 info ? info->fType : SkAdvancedTypefaceMetrics::kOther_Font;
591 601 SkAdvancedTypefaceMetrics::FontFlags flags =
592 if (info && (info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag )) { 602 info ? info->fFlags : SkAdvancedTypefaceMetrics::kEmpty_FontFlag;
603 if (SkToBool(flags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag)) {
593 return new SkPDFType3Font(info, typeface, glyphID); 604 return new SkPDFType3Font(info, typeface, glyphID);
594 } 605 }
595 if (type == SkAdvancedTypefaceMetrics::kType1CID_Font || 606 switch (type) {
596 type == SkAdvancedTypefaceMetrics::kTrueType_Font) { 607 case SkAdvancedTypefaceMetrics::kType1CID_Font:
597 SkASSERT(relatedFontDescriptor == nullptr); 608 case SkAdvancedTypefaceMetrics::kTrueType_Font:
598 return new SkPDFType0Font(info, typeface); 609 SkASSERT(relatedFontDescriptor == nullptr);
610 SkASSERT(info != nullptr);
611 return new SkPDFType0Font(info, typeface);
612 case SkAdvancedTypefaceMetrics::kType1_Font:
613 SkASSERT(info != nullptr);
614 return new SkPDFType1Font(info, typeface, glyphID, relatedFontDescri ptor);
615 case SkAdvancedTypefaceMetrics::kCFF_Font:
616 SkASSERT(info != nullptr);
617 // fallthrough
618 case SkAdvancedTypefaceMetrics::kOther_Font:
619 return new SkPDFType3Font(info, typeface, glyphID);
599 } 620 }
600 if (type == SkAdvancedTypefaceMetrics::kType1_Font) { 621 SkDEBUGFAIL("invalid SkAdvancedTypefaceMetrics::FontType");
601 return new SkPDFType1Font(info, typeface, glyphID, relatedFontDescriptor ); 622 return nullptr;
602 }
603
604 SkASSERT(type == SkAdvancedTypefaceMetrics::kCFF_Font ||
605 type == SkAdvancedTypefaceMetrics::kOther_Font);
606
607 return new SkPDFType3Font(info, typeface, glyphID);
608 } 623 }
609 624
610 const SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() { 625 const SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() {
611 return fFontInfo.get(); 626 return fFontInfo.get();
612 } 627 }
613 628
614 void SkPDFFont::setFontInfo(const SkAdvancedTypefaceMetrics* info) { 629 void SkPDFFont::setFontInfo(const SkAdvancedTypefaceMetrics* info) {
615 if (info == nullptr || info == fFontInfo.get()) { 630 if (info == nullptr || info == fFontInfo.get()) {
616 return; 631 return;
617 } 632 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, SkTypeface * typeface) 711 SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, SkTypeface * typeface)
697 : SkPDFFont(info, typeface, nullptr) { 712 : SkPDFFont(info, typeface, nullptr) {
698 SkDEBUGCODE(fPopulated = false); 713 SkDEBUGCODE(fPopulated = false);
699 if (!canSubset()) { 714 if (!canSubset()) {
700 this->populate(nullptr); 715 this->populate(nullptr);
701 } 716 }
702 } 717 }
703 718
704 SkPDFType0Font::~SkPDFType0Font() {} 719 SkPDFType0Font::~SkPDFType0Font() {}
705 720
706 SkPDFFont* SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) { 721 sk_sp<SkPDFObject> SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) {
707 if (!canSubset()) { 722 if (!canSubset()) {
708 return nullptr; 723 return nullptr;
709 } 724 }
710 SkPDFType0Font* newSubset = new SkPDFType0Font(fontInfo(), typeface()); 725 auto newSubset = sk_make_sp<SkPDFType0Font>(fontInfo(), typeface());
711 newSubset->populate(subset); 726 newSubset->populate(subset);
712 return newSubset; 727 return newSubset;
713 } 728 }
714 729
715 #ifdef SK_DEBUG 730 #ifdef SK_DEBUG
716 void SkPDFType0Font::emitObject(SkWStream* stream, 731 void SkPDFType0Font::emitObject(SkWStream* stream,
717 const SkPDFObjNumMap& objNumMap, 732 const SkPDFObjNumMap& objNumMap,
718 const SkPDFSubstituteMap& substitutes) const { 733 const SkPDFSubstituteMap& substitutes) const {
719 SkASSERT(fPopulated); 734 SkASSERT(fPopulated);
720 return INHERITED::emitObject(stream, objNumMap, substitutes); 735 return INHERITED::emitObject(stream, objNumMap, substitutes);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 return true; 886 return true;
872 } 887 }
873 888
874 void set_glyph_widths(SkTypeface* tf, 889 void set_glyph_widths(SkTypeface* tf,
875 const SkTDArray<uint32_t>* glyphIDs, 890 const SkTDArray<uint32_t>* glyphIDs,
876 SkSinglyLinkedList<AdvanceMetric>* dst) { 891 SkSinglyLinkedList<AdvanceMetric>* dst) {
877 SkPaint tmpPaint; 892 SkPaint tmpPaint;
878 tmpPaint.setHinting(SkPaint::kNo_Hinting); 893 tmpPaint.setHinting(SkPaint::kNo_Hinting);
879 tmpPaint.setTypeface(sk_ref_sp(tf)); 894 tmpPaint.setTypeface(sk_ref_sp(tf));
880 tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm()); 895 tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm());
881 SkAutoGlyphCache autoGlyphCache(tmpPaint, nullptr, nullptr); 896 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
897 SkAutoGlyphCache autoGlyphCache(tmpPaint, &props, nullptr);
882 if (!glyphIDs || glyphIDs->isEmpty()) { 898 if (!glyphIDs || glyphIDs->isEmpty()) {
883 get_glyph_widths(dst, tf->countGlyphs(), nullptr, 0, autoGlyphCache.get( )); 899 get_glyph_widths(dst, tf->countGlyphs(), nullptr, 0, autoGlyphCache.get( ));
884 } else { 900 } else {
885 get_glyph_widths(dst, tf->countGlyphs(), glyphIDs->begin(), 901 get_glyph_widths(dst, tf->countGlyphs(), glyphIDs->begin(),
886 glyphIDs->count(), autoGlyphCache.get()); 902 glyphIDs->count(), autoGlyphCache.get());
887 } 903 }
888 } 904 }
889 905
890 sk_sp<const SkAdvancedTypefaceMetrics> SkPDFFont::GetFontMetricsWithGlyphNames( 906 sk_sp<const SkAdvancedTypefaceMetrics> SkPDFFont::GetFontMetricsWithGlyphNames(
891 SkTypeface* typeface, uint32_t* glyphs, uint32_t glyphsCount) { 907 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 1026 // glyphCount not including glyph 0
1011 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID; 1027 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID;
1012 SkASSERT(glyphCount > 0 && glyphCount <= 255); 1028 SkASSERT(glyphCount > 0 && glyphCount <= 255);
1013 this->insertInt("FirstChar", (size_t)0); 1029 this->insertInt("FirstChar", (size_t)0);
1014 this->insertInt("LastChar", (size_t)glyphCount); 1030 this->insertInt("LastChar", (size_t)glyphCount);
1015 { 1031 {
1016 SkPaint tmpPaint; 1032 SkPaint tmpPaint;
1017 tmpPaint.setHinting(SkPaint::kNo_Hinting); 1033 tmpPaint.setHinting(SkPaint::kNo_Hinting);
1018 tmpPaint.setTypeface(sk_ref_sp(this->typeface())); 1034 tmpPaint.setTypeface(sk_ref_sp(this->typeface()));
1019 tmpPaint.setTextSize((SkScalar)this->typeface()->getUnitsPerEm()); 1035 tmpPaint.setTextSize((SkScalar)this->typeface()->getUnitsPerEm());
1020 SkAutoGlyphCache glyphCache(tmpPaint, nullptr, nullptr); 1036 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
1037 SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr);
1021 auto widths = sk_make_sp<SkPDFArray>(); 1038 auto widths = sk_make_sp<SkPDFArray>();
1022 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX; 1039 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX;
1023 const uint16_t emSize = this->fontInfo()->fEmSize; 1040 const uint16_t emSize = this->fontInfo()->fEmSize;
1024 widths->appendScalar(from_font_units(advance, emSize)); 1041 widths->appendScalar(from_font_units(advance, emSize));
1025 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) { 1042 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) {
1026 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX; 1043 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX;
1027 widths->appendScalar(from_font_units(advance, emSize)); 1044 widths->appendScalar(from_font_units(advance, emSize));
1028 } 1045 }
1029 this->insertObject("Widths", std::move(widths)); 1046 this->insertObject("Widths", std::move(widths));
1030 } 1047 }
(...skipping 16 matching lines...) Expand all
1047 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); 1064 auto encoding = sk_make_sp<SkPDFDict>("Encoding");
1048 encoding->insertObject("Differences", std::move(encDiffs)); 1065 encoding->insertObject("Differences", std::move(encDiffs));
1049 this->insertObject("Encoding", std::move(encoding)); 1066 this->insertObject("Encoding", std::move(encoding));
1050 return true; 1067 return true;
1051 } 1068 }
1052 1069
1053 /////////////////////////////////////////////////////////////////////////////// 1070 ///////////////////////////////////////////////////////////////////////////////
1054 // class SkPDFType3Font 1071 // class SkPDFType3Font
1055 /////////////////////////////////////////////////////////////////////////////// 1072 ///////////////////////////////////////////////////////////////////////////////
1056 1073
1074 namespace {
1075 // returns [0, first, first+1, ... last-1, last]
1076 struct SingleByteGlyphIdIterator {
1077 SingleByteGlyphIdIterator(SkGlyphID first, SkGlyphID last)
1078 : fFirst(first), fLast(last) {
1079 SkASSERT(fFirst > 0);
1080 SkASSERT(fLast >= first);
1081 }
1082 struct Iter {
1083 void operator++() {
1084 fCurrent = (0 == fCurrent) ? fFirst : fCurrent + 1;
1085 }
1086 // This is an input_iterator
1087 SkGlyphID operator*() const { return (SkGlyphID)fCurrent; }
1088 bool operator!=(const Iter& rhs) const {
1089 return fCurrent != rhs.fCurrent;
1090 }
1091 Iter(SkGlyphID f, int c) : fFirst(f), fCurrent(c) {}
1092 private:
1093 const SkGlyphID fFirst;
1094 int fCurrent; // must be int to make fLast+1 to fit
1095 };
1096 Iter begin() const { return Iter(fFirst, 0); }
1097 Iter end() const { return Iter(fFirst, (int)fLast + 1); }
1098 private:
1099 const SkGlyphID fFirst;
1100 const SkGlyphID fLast;
1101 };
1102 }
1103
1104 static void add_type3_font_info(SkPDFDict* font,
1105 SkTypeface* typeface,
1106 SkScalar emSize,
1107 const SkPDFGlyphSet* subset,
1108 SkGlyphID firstGlyphID,
1109 SkGlyphID lastGlyphID) {
1110 SkASSERT(lastGlyphID >= firstGlyphID);
1111 SkPaint paint;
1112 paint.setHinting(SkPaint::kNo_Hinting);
1113 paint.setTypeface(sk_ref_sp(typeface));
1114 paint.setTextSize(emSize);
1115 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
1116 SkAutoGlyphCache cache(paint, &props, nullptr);
1117
1118 font->insertName("Subtype", "Type3");
1119 // Flip about the x-axis and scale by 1/emSize.
1120 SkMatrix fontMatrix;
1121 fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize));
1122 font->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix));
1123
1124 auto charProcs = sk_make_sp<SkPDFDict>();
1125 auto encoding = sk_make_sp<SkPDFDict>("Encoding");
1126
1127 auto encDiffs = sk_make_sp<SkPDFArray>();
1128 // length(firstGlyphID .. lastGlyphID) == lastGlyphID - firstGlyphID + 1
1129 // plus 1 for glyph 0;
1130 SkASSERT(firstGlyphID > 0);
1131 SkASSERT(lastGlyphID >= firstGlyphID);
1132 int glyphCount = lastGlyphID - firstGlyphID + 2;
1133 // one other entry for the index of first glyph.
1134 encDiffs->reserve(glyphCount + 1);
1135 encDiffs->appendInt(0); // index of first glyph
1136
1137 auto widthArray = sk_make_sp<SkPDFArray>();
1138 widthArray->reserve(glyphCount);
1139
1140 SkIRect bbox = SkIRect::MakeEmpty();
1141
1142 sk_sp<SkPDFStream> emptyStream;
1143 for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID)) {
1144 bool skipGlyph = subset && gID != 0 && !subset->has(gID);
1145 SkString characterName;
1146 SkScalar advance = 0.0f;
1147 SkIRect glyphBBox;
1148 if (skipGlyph) {
1149 characterName.set("g0");
1150 } else {
1151 characterName.printf("g%X", gID);
1152 const SkGlyph& glyph = cache->getGlyphIDMetrics(gID);
1153 advance = SkFloatToScalar(glyph.fAdvanceX);
1154 glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop,
1155 glyph.fWidth, glyph.fHeight);
1156 bbox.join(glyphBBox);
1157 const SkPath* path = cache->findPath(glyph);
1158 if (path && !path->isEmpty()) {
1159 SkDynamicMemoryWStream content;
1160 setGlyphWidthAndBoundingBox(SkFloatToScalar(glyph.fAdvanceX), gl yphBBox,
1161 &content);
1162 SkPDFUtils::EmitPath(*path, SkPaint::kFill_Style, &content);
1163 SkPDFUtils::PaintPath(SkPaint::kFill_Style, path->getFillType(),
1164 &content);
1165 charProcs->insertObjRef(
1166 characterName, sk_make_sp<SkPDFStream>(
1167 std::unique_ptr<SkStreamAsset>(content.detachAsStrea m())));
1168 } else {
1169 if (!emptyStream) {
1170 emptyStream = sk_make_sp<SkPDFStream>(
1171 std::unique_ptr<SkStreamAsset>(
1172 new SkMemoryStream((size_t)0)));
1173 }
1174 charProcs->insertObjRef(characterName, emptyStream);
1175 }
1176 }
1177 encDiffs->appendName(characterName.c_str());
1178 widthArray->appendScalar(advance);
1179 }
1180
1181 encoding->insertObject("Differences", std::move(encDiffs));
1182 font->insertInt("FirstChar", 0);
1183 font->insertInt("LastChar", lastGlyphID - firstGlyphID + 1);
1184 /* FontBBox: "A rectangle expressed in the glyph coordinate
1185 system, specifying the font bounding box. This is the smallest
1186 rectangle enclosing the shape that would result if all of the
1187 glyphs of the font were placed with their origins coincident and
1188 then filled." */
1189 auto fontBBox = sk_make_sp<SkPDFArray>();
1190 fontBBox->reserve(4);
1191 fontBBox->appendInt(bbox.left());
1192 fontBBox->appendInt(bbox.bottom());
1193 fontBBox->appendInt(bbox.right());
1194 fontBBox->appendInt(bbox.top());
1195 font->insertObject("FontBBox", std::move(fontBBox));
1196 font->insertName("CIDToGIDMap", "Identity");
1197 sk_sp<const SkAdvancedTypefaceMetrics> metrics;
1198 if (subset) {
1199 SkTDArray<uint32_t> subsetList;
1200 for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID )) {
1201 if (gID == 0 || subset->has(gID)) { // Always include glyph 0.
1202 subsetList.push(0);
1203 }
1204 }
1205 subset->exportTo(&subsetList);
1206 metrics = SkPDFFont::GetFontMetricsWithToUnicode(typeface, subsetList.be gin(),
1207 subsetList.count());
1208 } else {
1209 metrics = SkPDFFont::GetFontMetricsWithToUnicode(typeface, nullptr, 0);
1210 }
1211 if (metrics) {
1212 font->insertObjRef("ToUnicode",
1213 SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode,
1214 subset,
1215 false,
1216 firstGlyphID,
1217 lastGlyphID));
1218 }
1219 font->insertObject("Widths", std::move(widthArray));
1220 font->insertObject("Encoding", std::move(encoding));
1221 font->insertObject("CharProcs", std::move(charProcs));
1222 }
1223
1057 SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info, 1224 SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
1058 SkTypeface* typeface, 1225 SkTypeface* typeface,
1059 uint16_t glyphID) 1226 uint16_t glyphID)
1060 : SkPDFFont(info, typeface, nullptr) { 1227 : SkPDFFont(info, typeface, nullptr) {
1061 this->populate(glyphID); 1228 // If fLastGlyphID isn't set (because there is not fFontInfo), look it up.
1229 this->setLastGlyphID(SkToU16(typeface->countGlyphs() - 1));
1230 this->adjustGlyphRangeForSingleByteEncoding(glyphID);
1062 } 1231 }
1063 1232
1064 SkPDFType3Font::~SkPDFType3Font() {} 1233 sk_sp<SkPDFObject> SkPDFType3Font::getFontSubset(const SkPDFGlyphSet* usage) {
1234 // All fonts are subset before serialization.
1235 // TODO(halcanary): all fonts should follow this pattern.
1236 auto font = sk_make_sp<SkPDFDict>("Font");
1237 const SkAdvancedTypefaceMetrics* info = this->fontInfo();
1238 uint16_t emSize = info && info->fEmSize > 0 ? info->fEmSize : 1000;
1239 add_type3_font_info(font.get(), this->typeface(), (SkScalar)emSize, usage,
1240 this->firstGlyphID(), this->lastGlyphID());
1241 return font;
1242 }
1065 1243
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 1244
1078 adjustGlyphRangeForSingleByteEncoding(glyphID); 1245 ////////////////////////////////////////////////////////////////////////////////
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 1246
1136 SkPDFFont::Match SkPDFFont::IsMatch(SkPDFFont* existingFont, 1247 SkPDFFont::Match SkPDFFont::IsMatch(SkPDFFont* existingFont,
1137 uint32_t existingFontID, 1248 uint32_t existingFontID,
1138 uint16_t existingGlyphID, 1249 uint16_t existingGlyphID,
1139 uint32_t searchFontID, 1250 uint32_t searchFontID,
1140 uint16_t searchGlyphID) { 1251 uint16_t searchGlyphID) {
1141 if (existingFontID != searchFontID) { 1252 if (existingFontID != searchFontID) {
1142 return SkPDFFont::kNot_Match; 1253 return SkPDFFont::kNot_Match;
1143 } 1254 }
1144 if (existingGlyphID == 0 || searchGlyphID == 0) { 1255 if (existingGlyphID == 0 || searchGlyphID == 0) {
(...skipping 27 matching lines...) Expand all
1172 } 1283 }
1173 return *canon->fCanEmbedTypeface.set(id, canEmbed); 1284 return *canon->fCanEmbedTypeface.set(id, canEmbed);
1174 } 1285 }
1175 1286
1176 void SkPDFFont::drop() { 1287 void SkPDFFont::drop() {
1177 fTypeface = nullptr; 1288 fTypeface = nullptr;
1178 fFontInfo = nullptr; 1289 fFontInfo = nullptr;
1179 fDescriptor = nullptr; 1290 fDescriptor = nullptr;
1180 this->SkPDFDict::drop(); 1291 this->SkPDFDict::drop();
1181 } 1292 }
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