/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkPDFFont_DEFINED #define SkPDFFont_DEFINED #include "SkAdvancedTypefaceMetrics.h" #include "SkBitSet.h" #include "SkGlyphCache.h" #include "SkPDFTypes.h" #include "SkTDArray.h" #include "SkTypeface.h" class SkPDFCanon; class SkPDFFont; /** \class SkPDFFont A PDF Object class representing a font. The font may have resources attached to it in order to embed the font. SkPDFFonts are canonicalized so that resource deduplication will only include one copy of a font. This class uses the same pattern as SkPDFGraphicState, a static weak reference to each instantiated class. */ class SkPDFFont : public SkPDFDict { public: ~SkPDFFont() override; /** Returns the typeface represented by this class. Returns nullptr for the * default typeface. */ SkTypeface* typeface() const { return fTypeface.get(); } /** Returns the font type represented in this font. For Type0 fonts, * returns the type of the decendant font. */ SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; } static SkAdvancedTypefaceMetrics::FontType FontType(const SkAdvancedTypefaceMetrics&); static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) { return type == SkAdvancedTypefaceMetrics::kType1CID_Font || type == SkAdvancedTypefaceMetrics::kTrueType_Font; } static SkExclusiveStrikePtr MakeVectorCache(SkTypeface*, int* sizeOut); /** Returns true if this font encoding supports glyph IDs above 255. */ bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); } /** Return true if this font has an encoding for the passed glyph id. */ bool hasGlyph(SkGlyphID gid) { return (gid >= fFirstGlyphID && gid <= fLastGlyphID) || gid == 0; } /** Convert the input glyph ID into the font encoding. */ SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const { if (this->multiByteGlyphs() || gid == 0) { return gid; } SkASSERT(gid >= fFirstGlyphID && gid <= fLastGlyphID); SkASSERT(fFirstGlyphID > 0); return gid - fFirstGlyphID + 1; } void noteGlyphUsage(SkGlyphID glyph) { SkASSERT(this->hasGlyph(glyph)); fGlyphUsage.set(glyph); } /** Get the font resource for the passed typeface and glyphID. The * reference count of the object is incremented and it is the caller's * responsibility to unreference it when done. This is needed to * accommodate the weak reference pattern used when the returned object * is new and has no other references. * @param typeface The typeface to find, not nullptr. * @param glyphID Specify which section of a large font is of interest. */ static sk_sp GetFontResource(SkPDFCanon* canon, SkTypeface* typeface, SkGlyphID glyphID); /** Gets SkAdvancedTypefaceMetrics, and caches the result. * @param typeface can not be nullptr. * @return nullptr only when typeface is bad. */ static const SkAdvancedTypefaceMetrics* GetMetrics(SkTypeface* typeface, SkPDFCanon* canon); /** Subset the font based on current usage. * Must be called before emitObject(). */ virtual void getFontSubset(SkPDFCanon*) = 0; /** * Return false iff the typeface has its NotEmbeddable flag set. * typeface is not nullptr */ static bool CanEmbedTypeface(SkTypeface*, SkPDFCanon*); protected: // Common constructor to handle common members. struct Info { sk_sp fTypeface; SkGlyphID fFirstGlyphID; SkGlyphID fLastGlyphID; SkAdvancedTypefaceMetrics::FontType fFontType; }; SkPDFFont(Info); SkGlyphID firstGlyphID() const { return fFirstGlyphID; } SkGlyphID lastGlyphID() const { return fLastGlyphID; } const SkBitSet& glyphUsage() const { return fGlyphUsage; } sk_sp refTypeface() const { return fTypeface; } void drop() override; private: sk_sp fTypeface; SkBitSet fGlyphUsage; // The glyph IDs accessible with this font. For Type1 (non CID) fonts, // this will be a subset if the font has more than 255 glyphs. const SkGlyphID fFirstGlyphID; const SkGlyphID fLastGlyphID; const SkAdvancedTypefaceMetrics::FontType fFontType; typedef SkPDFDict INHERITED; }; #endif