1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 #ifndef SkPDFFont_DEFINED 8 #define SkPDFFont_DEFINED 9 10 #include "include/core/SkRefCnt.h" 11 #include "include/core/SkScalar.h" 12 #include "include/core/SkTypes.h" 13 #include "src/base/SkUTF.h" 14 #include "src/core/SkAdvancedTypefaceMetrics.h" 15 #include "src/core/SkStrikeSpec.h" 16 #include "src/core/SkTHash.h" 17 #include "src/pdf/SkPDFGlyphUse.h" 18 #include "src/pdf/SkPDFTypes.h" 19 20 #include <cstdint> 21 #include <vector> 22 23 class SkDescriptor; 24 class SkFont; 25 class SkGlyph; 26 class SkPaint; 27 class SkPDFDocument; 28 class SkPDFFont; 29 class SkString; 30 class SkTypeface; 31 32 class SkPDFStrikeSpec { 33 public: 34 SkPDFStrikeSpec(SkStrikeSpec, SkScalar em); 35 36 const SkStrikeSpec fStrikeSpec; 37 const SkScalar fUnitsPerEM; 38 }; 39 40 class SkPDFStrike : public SkRefCnt { 41 public: 42 /** Make or return an existing SkPDFStrike, canonicalizing for resource de-duplication. 43 * The SkPDFStrike is owned by the SkPDFDocument. 44 */ 45 static sk_sp<SkPDFStrike> Make(SkPDFDocument* doc, const SkFont&, const SkPaint&); 46 47 const SkPDFStrikeSpec fPath; 48 const SkPDFStrikeSpec fImage; 49 const bool fHasMaskFilter; 50 SkPDFDocument* fDoc; 51 skia_private::THashMap<SkGlyphID, SkPDFFont> fFontMap; 52 53 /** Get the font resource for the glyph. 54 * The returned SkPDFFont is owned by the SkPDFStrike. 55 * @param glyph The glyph of interest 56 */ 57 SkPDFFont* getFontResource(const SkGlyph* glyph); 58 59 struct Traits { 60 static const SkDescriptor& GetKey(const sk_sp<SkPDFStrike>& strike); 61 static uint32_t Hash(const SkDescriptor& descriptor); 62 }; 63 private: 64 SkPDFStrike(SkPDFStrikeSpec path, SkPDFStrikeSpec image, bool hasMaskFilter, SkPDFDocument*); 65 }; 66 67 /** \class SkPDFFont 68 A PDF Object class representing a PDF Font. SkPDFFont are owned by an SkPDFStrike. 69 */ 70 class SkPDFFont { 71 public: 72 ~SkPDFFont(); 73 SkPDFFont(SkPDFFont&&); 74 SkPDFFont& operator=(SkPDFFont&&) = delete; 75 76 /** Returns the font type represented in this font. For Type0 fonts, 77 * returns the type of the descendant font. 78 */ getType()79 SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; } 80 81 static SkAdvancedTypefaceMetrics::FontType FontType(const SkPDFStrike&, 82 const SkAdvancedTypefaceMetrics&); 83 static void GetType1GlyphNames(const SkTypeface&, SkString*); 84 IsMultiByte(SkAdvancedTypefaceMetrics::FontType type)85 static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) { 86 return type == SkAdvancedTypefaceMetrics::kType1CID_Font || 87 type == SkAdvancedTypefaceMetrics::kTrueType_Font || 88 type == SkAdvancedTypefaceMetrics::kCFF_Font; 89 } 90 91 /** Returns true if this font encoding supports glyph IDs above 255. 92 */ multiByteGlyphs()93 bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); } 94 95 /** Return true if this font has an encoding for the passed glyph id. 96 */ hasGlyph(SkGlyphID gid)97 bool hasGlyph(SkGlyphID gid) { 98 return (gid >= this->firstGlyphID() && gid <= this->lastGlyphID()) || gid == 0; 99 } 100 101 /** Convert the input glyph ID into the font encoding. */ glyphToPDFFontEncoding(SkGlyphID gid)102 SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const { 103 if (this->multiByteGlyphs() || gid == 0) { 104 return gid; 105 } 106 SkASSERT(gid >= this->firstGlyphID() && gid <= this->lastGlyphID()); 107 SkASSERT(this->firstGlyphID() > 0); 108 return gid - this->firstGlyphID() + 1; 109 } 110 noteGlyphUsage(SkGlyphID glyph)111 void noteGlyphUsage(SkGlyphID glyph) { 112 SkASSERT(this->hasGlyph(glyph)); 113 fGlyphUsage.set(glyph); 114 } 115 indirectReference()116 SkPDFIndirectReference indirectReference() const { return fIndirectReference; } 117 118 /** Gets SkAdvancedTypefaceMetrics, and caches the result. 119 * @param typeface can not be nullptr. 120 * @return nullptr only when typeface is bad. 121 */ 122 static const SkAdvancedTypefaceMetrics* GetMetrics(const SkTypeface& typeface, 123 SkPDFDocument* canon); 124 125 static const std::vector<SkUnichar>& GetUnicodeMap(const SkTypeface& typeface, 126 SkPDFDocument* canon); 127 static skia_private::THashMap<SkGlyphID, SkString>& GetUnicodeMapEx( 128 const SkTypeface& typeface, SkPDFDocument* canon); 129 130 static void PopulateCommonFontDescriptor(SkPDFDict* descriptor, 131 const SkAdvancedTypefaceMetrics&, 132 uint16_t emSize, 133 int16_t defaultWidth); 134 135 void emitSubset(SkPDFDocument*) const; 136 137 /** Return false iff the typeface has its NotEmbeddable flag set. */ 138 static bool CanEmbedTypeface(const SkTypeface&, SkPDFDocument*); 139 firstGlyphID()140 SkGlyphID firstGlyphID() const { return fGlyphUsage.firstNonZero(); } lastGlyphID()141 SkGlyphID lastGlyphID() const { return fGlyphUsage.lastGlyph(); } glyphUsage()142 const SkPDFGlyphUse& glyphUsage() const { return fGlyphUsage; } 143 strike()144 const SkPDFStrike& strike() const { return *fStrike; } 145 146 private: 147 const SkPDFStrike* fStrike; 148 SkPDFGlyphUse fGlyphUsage; 149 SkPDFIndirectReference fIndirectReference; 150 SkAdvancedTypefaceMetrics::FontType fFontType; 151 152 SkPDFFont(const SkPDFStrike*, 153 SkGlyphID firstGlyphID, 154 SkGlyphID lastGlyphID, 155 SkAdvancedTypefaceMetrics::FontType fontType, 156 SkPDFIndirectReference indirectReference); 157 // The glyph IDs accessible with this font. For Type1 (non CID) fonts, 158 // this will be a subset if the font has more than 255 glyphs. 159 160 SkPDFFont() = delete; 161 SkPDFFont(const SkPDFFont&) = delete; 162 SkPDFFont& operator=(const SkPDFFont&) = delete; 163 friend class SkPDFStrike; 164 }; 165 166 #endif 167