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 SkTypeface&, 47 const SkAdvancedTypefaceMetrics&); 48 static void GetType1GlyphNames(const SkTypeface&, SkString*); 49 IsMultiByte(SkAdvancedTypefaceMetrics::FontType type)50 static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) { 51 return type == SkAdvancedTypefaceMetrics::kType1CID_Font || 52 type == SkAdvancedTypefaceMetrics::kTrueType_Font; 53 } 54 55 /** Returns true if this font encoding supports glyph IDs above 255. 56 */ multiByteGlyphs()57 bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); } 58 59 /** Return true if this font has an encoding for the passed glyph id. 60 */ hasGlyph(SkGlyphID gid)61 bool hasGlyph(SkGlyphID gid) { 62 return (gid >= this->firstGlyphID() && gid <= this->lastGlyphID()) || gid == 0; 63 } 64 65 /** Convert the input glyph ID into the font encoding. */ glyphToPDFFontEncoding(SkGlyphID gid)66 SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const { 67 if (this->multiByteGlyphs() || gid == 0) { 68 return gid; 69 } 70 SkASSERT(gid >= this->firstGlyphID() && gid <= this->lastGlyphID()); 71 SkASSERT(this->firstGlyphID() > 0); 72 return gid - this->firstGlyphID() + 1; 73 } 74 noteGlyphUsage(SkGlyphID glyph)75 void noteGlyphUsage(SkGlyphID glyph) { 76 SkASSERT(this->hasGlyph(glyph)); 77 fGlyphUsage.set(glyph); 78 } 79 indirectReference()80 SkPDFIndirectReference indirectReference() const { return fIndirectReference; } 81 82 /** Get the font resource for the passed typeface and glyphID. The 83 * reference count of the object is incremented and it is the caller's 84 * responsibility to unreference it when done. This is needed to 85 * accommodate the weak reference pattern used when the returned object 86 * is new and has no other references. 87 * @param typeface The typeface to find, not nullptr. 88 * @param glyphID Specify which section of a large font is of interest. 89 */ 90 static SkPDFFont* GetFontResource(SkPDFDocument* doc, 91 const SkGlyph* glyphs, 92 SkTypeface* typeface); 93 94 /** Gets SkAdvancedTypefaceMetrics, and caches the result. 95 * @param typeface can not be nullptr. 96 * @return nullptr only when typeface is bad. 97 */ 98 static const SkAdvancedTypefaceMetrics* GetMetrics(const SkTypeface* typeface, 99 SkPDFDocument* canon); 100 101 static const std::vector<SkUnichar>& GetUnicodeMap(const SkTypeface* typeface, 102 SkPDFDocument* canon); 103 104 static void PopulateCommonFontDescriptor(SkPDFDict* descriptor, 105 const SkAdvancedTypefaceMetrics&, 106 uint16_t emSize, 107 int16_t defaultWidth); 108 109 void emitSubset(SkPDFDocument*) const; 110 111 /** 112 * Return false iff the typeface has its NotEmbeddable flag set. 113 * typeface is not nullptr 114 */ 115 static bool CanEmbedTypeface(SkTypeface*, SkPDFDocument*); 116 firstGlyphID()117 SkGlyphID firstGlyphID() const { return fGlyphUsage.firstNonZero(); } lastGlyphID()118 SkGlyphID lastGlyphID() const { return fGlyphUsage.lastGlyph(); } glyphUsage()119 const SkPDFGlyphUse& glyphUsage() const { return fGlyphUsage; } refTypeface()120 sk_sp<SkTypeface> refTypeface() const { return fTypeface; } 121 122 private: 123 sk_sp<SkTypeface> fTypeface; 124 SkPDFGlyphUse fGlyphUsage; 125 SkPDFIndirectReference fIndirectReference; 126 SkAdvancedTypefaceMetrics::FontType fFontType; 127 128 SkPDFFont(sk_sp<SkTypeface>, 129 SkGlyphID firstGlyphID, 130 SkGlyphID lastGlyphID, 131 SkAdvancedTypefaceMetrics::FontType fontType, 132 SkPDFIndirectReference indirectReference); 133 // The glyph IDs accessible with this font. For Type1 (non CID) fonts, 134 // this will be a subset if the font has more than 255 glyphs. 135 136 SkPDFFont() = delete; 137 SkPDFFont(const SkPDFFont&) = delete; 138 SkPDFFont& operator=(const SkPDFFont&) = delete; 139 }; 140 141 #endif 142