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/SkTypeface.h" 12 #include "include/core/SkTypes.h" 13 #include "src/core/SkAdvancedTypefaceMetrics.h" 14 #include "src/core/SkStrikeCache.h" 15 #include "src/pdf/SkPDFGlyphUse.h" 16 #include "src/pdf/SkPDFTypes.h" 17 18 #include <vector> 19 20 class SkPDFDocument; 21 class SkString; 22 23 /** \class SkPDFFont 24 A PDF Object class representing a font. The font may have resources 25 attached to it in order to embed the font. SkPDFFonts are canonicalized 26 so that resource deduplication will only include one copy of a font. 27 This class uses the same pattern as SkPDFGraphicState, a static weak 28 reference to each instantiated class. 29 */ 30 class SkPDFFont { 31 public: 32 ~SkPDFFont(); 33 SkPDFFont(SkPDFFont&&); 34 SkPDFFont& operator=(SkPDFFont&&); 35 36 /** Returns the typeface represented by this class. Returns nullptr for the 37 * default typeface. 38 */ typeface()39 SkTypeface* typeface() const { return fTypeface.get(); } 40 41 /** Returns the font type represented in this font. For Type0 fonts, 42 * returns the type of the descendant font. 43 */ getType()44 SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; } 45 46 static SkAdvancedTypefaceMetrics::FontType FontType(const SkAdvancedTypefaceMetrics&); 47 static void GetType1GlyphNames(const SkTypeface&, SkString*); 48 IsMultiByte(SkAdvancedTypefaceMetrics::FontType type)49 static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) { 50 return type == SkAdvancedTypefaceMetrics::kType1CID_Font || 51 type == SkAdvancedTypefaceMetrics::kTrueType_Font; 52 } 53 54 /** Returns true if this font encoding supports glyph IDs above 255. 55 */ multiByteGlyphs()56 bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); } 57 58 /** Return true if this font has an encoding for the passed glyph id. 59 */ hasGlyph(SkGlyphID gid)60 bool hasGlyph(SkGlyphID gid) { 61 return (gid >= this->firstGlyphID() && gid <= this->lastGlyphID()) || gid == 0; 62 } 63 64 /** Convert the input glyph ID into the font encoding. */ glyphToPDFFontEncoding(SkGlyphID gid)65 SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const { 66 if (this->multiByteGlyphs() || gid == 0) { 67 return gid; 68 } 69 SkASSERT(gid >= this->firstGlyphID() && gid <= this->lastGlyphID()); 70 SkASSERT(this->firstGlyphID() > 0); 71 return gid - this->firstGlyphID() + 1; 72 } 73 noteGlyphUsage(SkGlyphID glyph)74 void noteGlyphUsage(SkGlyphID glyph) { 75 SkASSERT(this->hasGlyph(glyph)); 76 fGlyphUsage.set(glyph); 77 } 78 indirectReference()79 SkPDFIndirectReference indirectReference() const { return fIndirectReference; } 80 81 /** Get the font resource for the passed typeface and glyphID. The 82 * reference count of the object is incremented and it is the caller's 83 * responsibility to unreference it when done. This is needed to 84 * accommodate the weak reference pattern used when the returned object 85 * is new and has no other references. 86 * @param typeface The typeface to find, not nullptr. 87 * @param glyphID Specify which section of a large font is of interest. 88 */ 89 static SkPDFFont* GetFontResource(SkPDFDocument* doc, 90 const SkGlyph* glyphs, 91 SkTypeface* typeface); 92 93 /** Gets SkAdvancedTypefaceMetrics, and caches the result. 94 * @param typeface can not be nullptr. 95 * @return nullptr only when typeface is bad. 96 */ 97 static const SkAdvancedTypefaceMetrics* GetMetrics(const SkTypeface* typeface, 98 SkPDFDocument* canon); 99 100 static const std::vector<SkUnichar>& GetUnicodeMap(const SkTypeface* typeface, 101 SkPDFDocument* canon); 102 103 static void PopulateCommonFontDescriptor(SkPDFDict* descriptor, 104 const SkAdvancedTypefaceMetrics&, 105 uint16_t emSize, 106 int16_t defaultWidth); 107 108 void emitSubset(SkPDFDocument*) const; 109 110 /** 111 * Return false iff the typeface has its NotEmbeddable flag set. 112 * typeface is not nullptr 113 */ 114 static bool CanEmbedTypeface(SkTypeface*, SkPDFDocument*); 115 firstGlyphID()116 SkGlyphID firstGlyphID() const { return fGlyphUsage.firstNonZero(); } lastGlyphID()117 SkGlyphID lastGlyphID() const { return fGlyphUsage.lastGlyph(); } glyphUsage()118 const SkPDFGlyphUse& glyphUsage() const { return fGlyphUsage; } refTypeface()119 sk_sp<SkTypeface> refTypeface() const { return fTypeface; } 120 121 private: 122 sk_sp<SkTypeface> fTypeface; 123 SkPDFGlyphUse fGlyphUsage; 124 SkPDFIndirectReference fIndirectReference; 125 SkAdvancedTypefaceMetrics::FontType fFontType; 126 127 SkPDFFont(sk_sp<SkTypeface>, 128 SkGlyphID firstGlyphID, 129 SkGlyphID lastGlyphID, 130 SkAdvancedTypefaceMetrics::FontType fontType, 131 SkPDFIndirectReference indirectReference); 132 // The glyph IDs accessible with this font. For Type1 (non CID) fonts, 133 // this will be a subset if the font has more than 255 glyphs. 134 135 SkPDFFont() = delete; 136 SkPDFFont(const SkPDFFont&) = delete; 137 SkPDFFont& operator=(const SkPDFFont&) = delete; 138 }; 139 140 #endif 141