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 
      8 
      9 #ifndef SkPDFFont_DEFINED
     10 #define SkPDFFont_DEFINED
     11 
     12 #include "SkAdvancedTypefaceMetrics.h"
     13 #include "SkBitSet.h"
     14 #include "SkPDFTypes.h"
     15 #include "SkTDArray.h"
     16 #include "SkTypeface.h"
     17 
     18 class SkAutoGlyphCache;
     19 class SkPDFCanon;
     20 class SkPDFFont;
     21 
     22 /** \class SkPDFFont
     23     A PDF Object class representing a font.  The font may have resources
     24     attached to it in order to embed the font.  SkPDFFonts are canonicalized
     25     so that resource deduplication will only include one copy of a font.
     26     This class uses the same pattern as SkPDFGraphicState, a static weak
     27     reference to each instantiated class.
     28 */
     29 class SkPDFFont : public SkPDFDict {
     30 
     31 public:
     32     ~SkPDFFont() override;
     33 
     34     /** Returns the typeface represented by this class. Returns nullptr for the
     35      *  default typeface.
     36      */
     37     SkTypeface* typeface() const { return fTypeface.get(); }
     38 
     39     /** Returns the font type represented in this font.  For Type0 fonts,
     40      *  returns the type of the decendant font.
     41      */
     42     SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; }
     43 
     44     static SkAdvancedTypefaceMetrics::FontType FontType(const SkAdvancedTypefaceMetrics&);
     45 
     46     static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) {
     47         return type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
     48                type == SkAdvancedTypefaceMetrics::kTrueType_Font;
     49     }
     50 
     51     static SkAutoGlyphCache MakeVectorCache(SkTypeface*, int* sizeOut);
     52 
     53     /** Returns true if this font encoding supports glyph IDs above 255.
     54      */
     55     bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); }
     56 
     57     /** Return true if this font has an encoding for the passed glyph id.
     58      */
     59     bool hasGlyph(SkGlyphID gid) {
     60         return (gid >= fFirstGlyphID && gid <= fLastGlyphID) || gid == 0;
     61     }
     62 
     63     /** Convert the input glyph ID into the font encoding.  */
     64     SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const {
     65         if (this->multiByteGlyphs() || gid == 0) {
     66             return gid;
     67         }
     68         SkASSERT(gid >= fFirstGlyphID && gid <= fLastGlyphID);
     69         SkASSERT(fFirstGlyphID > 0);
     70         return gid - fFirstGlyphID + 1;
     71     }
     72 
     73     void noteGlyphUsage(SkGlyphID glyph) {
     74         SkASSERT(this->hasGlyph(glyph));
     75         fGlyphUsage.set(glyph);
     76     }
     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 sk_sp<SkPDFFont> GetFontResource(SkPDFCanon* canon,
     87                                             SkTypeface* typeface,
     88                                             SkGlyphID glyphID);
     89 
     90     /** Gets SkAdvancedTypefaceMetrics, and caches the result.
     91      *  @param typeface can not be nullptr.
     92      *  @return nullptr only when typeface is bad.
     93      */
     94     static const SkAdvancedTypefaceMetrics* GetMetrics(SkTypeface* typeface,
     95                                                        SkPDFCanon* canon);
     96 
     97     /** Subset the font based on current usage.
     98      *  Must be called before emitObject().
     99      */
    100     virtual void getFontSubset(SkPDFCanon*) = 0;
    101 
    102     /**
    103      *  Return false iff the typeface has its NotEmbeddable flag set.
    104      *  typeface is not nullptr
    105      */
    106     static bool CanEmbedTypeface(SkTypeface*, SkPDFCanon*);
    107 
    108 protected:
    109     // Common constructor to handle common members.
    110     struct Info {
    111         sk_sp<SkTypeface> fTypeface;
    112         SkGlyphID fFirstGlyphID;
    113         SkGlyphID fLastGlyphID;
    114         SkAdvancedTypefaceMetrics::FontType fFontType;
    115     };
    116     SkPDFFont(Info);
    117 
    118     SkGlyphID firstGlyphID() const { return fFirstGlyphID; }
    119     SkGlyphID lastGlyphID() const { return fLastGlyphID; }
    120     const SkBitSet& glyphUsage() const { return fGlyphUsage; }
    121     sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
    122 
    123     void drop() override;
    124 
    125 private:
    126     sk_sp<SkTypeface> fTypeface;
    127     SkBitSet fGlyphUsage;
    128 
    129     // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
    130     // this will be a subset if the font has more than 255 glyphs.
    131     const SkGlyphID fFirstGlyphID;
    132     const SkGlyphID fLastGlyphID;
    133     const SkAdvancedTypefaceMetrics::FontType fFontType;
    134 
    135     typedef SkPDFDict INHERITED;
    136 };
    137 
    138 #endif
    139