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