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