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