Home | History | Annotate | Download | only in pdf
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkPDFFont_DEFINED
     11 #define SkPDFFont_DEFINED
     12 
     13 #include "SkAdvancedTypefaceMetrics.h"
     14 #include "SkBitSet.h"
     15 #include "SkPDFTypes.h"
     16 #include "SkTDArray.h"
     17 #include "SkThread.h"
     18 #include "SkTypeface.h"
     19 
     20 class SkPaint;
     21 class SkPDFCatalog;
     22 class SkPDFFont;
     23 
     24 class SkPDFGlyphSet : SkNoncopyable {
     25 public:
     26     SkPDFGlyphSet();
     27 
     28     void set(const uint16_t* glyphIDs, int numGlyphs);
     29     bool has(uint16_t glyphID) const;
     30     void merge(const SkPDFGlyphSet& usage);
     31     void exportTo(SkTDArray<uint32_t>* glyphIDs) const;
     32 
     33 private:
     34     SkBitSet fBitSet;
     35 };
     36 
     37 class SkPDFGlyphSetMap : SkNoncopyable {
     38 public:
     39     struct FontGlyphSetPair {
     40         FontGlyphSetPair(SkPDFFont* font, SkPDFGlyphSet* glyphSet);
     41 
     42         SkPDFFont* fFont;
     43         SkPDFGlyphSet* fGlyphSet;
     44     };
     45 
     46     SkPDFGlyphSetMap();
     47     ~SkPDFGlyphSetMap();
     48 
     49     class F2BIter {
     50     public:
     51         explicit F2BIter(const SkPDFGlyphSetMap& map);
     52         const FontGlyphSetPair* next() const;
     53         void reset(const SkPDFGlyphSetMap& map);
     54 
     55     private:
     56         const SkTDArray<FontGlyphSetPair>* fMap;
     57         mutable int fIndex;
     58     };
     59 
     60     void merge(const SkPDFGlyphSetMap& usage);
     61     void reset();
     62 
     63     void noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
     64                         int numGlyphs);
     65 
     66 private:
     67     SkPDFGlyphSet* getGlyphSetForFont(SkPDFFont* font);
     68 
     69     SkTDArray<FontGlyphSetPair> fMap;
     70 };
     71 
     72 
     73 /** \class SkPDFFont
     74     A PDF Object class representing a font.  The font may have resources
     75     attached to it in order to embed the font.  SkPDFFonts are canonicalized
     76     so that resource deduplication will only include one copy of a font.
     77     This class uses the same pattern as SkPDFGraphicState, a static weak
     78     reference to each instantiated class.
     79 */
     80 class SkPDFFont : public SkPDFDict {
     81     SK_DECLARE_INST_COUNT(SkPDFFont)
     82 public:
     83     virtual ~SkPDFFont();
     84 
     85     virtual void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
     86                               SkTSet<SkPDFObject*>* newResourceObjects);
     87 
     88     /** Returns the typeface represented by this class. Returns NULL for the
     89      *  default typeface.
     90      */
     91     SkTypeface* typeface();
     92 
     93     /** Returns the font type represented in this font.  For Type0 fonts,
     94      *  returns the type of the decendant font.
     95      */
     96     virtual SkAdvancedTypefaceMetrics::FontType getType();
     97 
     98     /** Returns true if this font encoding supports glyph IDs above 255.
     99      */
    100     virtual bool multiByteGlyphs() const = 0;
    101 
    102     /** Returns true if the machine readable licensing bits allow embedding.
    103      */
    104     bool canEmbed() const;
    105 
    106     /** Returns true if the machine readable licensing bits allow subsetting.
    107      */
    108     bool canSubset() const;
    109 
    110     /** Return true if this font has an encoding for the passed glyph id.
    111      */
    112     bool hasGlyph(uint16_t glyphID);
    113 
    114     /** Convert (in place) the input glyph IDs into the font encoding.  If the
    115      *  font has more glyphs than can be encoded (like a type 1 font with more
    116      *  than 255 glyphs) this method only converts up to the first out of range
    117      *  glyph ID.
    118      *  @param glyphIDs       The input text as glyph IDs.
    119      *  @param numGlyphs      The number of input glyphs.
    120      *  @return               Returns the number of glyphs consumed.
    121      */
    122     int glyphsToPDFFontEncoding(uint16_t* glyphIDs, int numGlyphs);
    123 
    124     /** Get the font resource for the passed typeface and glyphID. The
    125      *  reference count of the object is incremented and it is the caller's
    126      *  responsibility to unreference it when done.  This is needed to
    127      *  accommodate the weak reference pattern used when the returned object
    128      *  is new and has no other references.
    129      *  @param typeface  The typeface to find.
    130      *  @param glyphID   Specify which section of a large font is of interest.
    131      */
    132     static SkPDFFont* GetFontResource(SkTypeface* typeface, uint16_t glyphID);
    133 
    134     /** Subset the font based on usage set. Returns a SkPDFFont instance with
    135      *  subset.
    136      *  @param usage  Glyph subset requested.
    137      *  @return       NULL if font does not support subsetting, a new instance
    138      *                of SkPDFFont otherwise.
    139      */
    140     virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage);
    141 
    142 protected:
    143     // Common constructor to handle common members.
    144     SkPDFFont(SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
    145               SkPDFDict* relatedFontDescriptor);
    146 
    147     // Accessors for subclass.
    148     SkAdvancedTypefaceMetrics* fontInfo();
    149     void setFontInfo(SkAdvancedTypefaceMetrics* info);
    150     uint16_t firstGlyphID() const;
    151     uint16_t lastGlyphID() const;
    152     void setLastGlyphID(uint16_t glyphID);
    153 
    154     // Add object to resource list.
    155     void addResource(SkPDFObject* object);
    156 
    157     // Accessors for FontDescriptor associated with this object.
    158     SkPDFDict* getFontDescriptor();
    159     void setFontDescriptor(SkPDFDict* descriptor);
    160 
    161     // Add common entries to FontDescriptor.
    162     bool addCommonFontDescriptorEntries(int16_t defaultWidth);
    163 
    164     /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
    165      *  including the passed glyphID.
    166      */
    167     void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
    168 
    169     // Generate ToUnicode table according to glyph usage subset.
    170     // If subset is NULL, all available glyph ids will be used.
    171     void populateToUnicodeTable(const SkPDFGlyphSet* subset);
    172 
    173     // Create instances of derived types based on fontInfo.
    174     static SkPDFFont* Create(SkAdvancedTypefaceMetrics* fontInfo,
    175                              SkTypeface* typeface, uint16_t glyphID,
    176                              SkPDFDict* relatedFontDescriptor);
    177 
    178     static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
    179 
    180 private:
    181     class FontRec {
    182     public:
    183         SkPDFFont* fFont;
    184         uint32_t fFontID;
    185         uint16_t fGlyphID;
    186 
    187         // A fGlyphID of 0 with no fFont always matches.
    188         bool operator==(const FontRec& b) const;
    189         FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
    190     };
    191 
    192     SkAutoTUnref<SkTypeface> fTypeface;
    193 
    194     // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
    195     // this will be a subset if the font has more than 255 glyphs.
    196     uint16_t fFirstGlyphID;
    197     uint16_t fLastGlyphID;
    198     SkAutoTUnref<SkAdvancedTypefaceMetrics> fFontInfo;
    199     SkTDArray<SkPDFObject*> fResources;
    200     SkAutoTUnref<SkPDFDict> fDescriptor;
    201 
    202     SkAdvancedTypefaceMetrics::FontType fFontType;
    203 
    204     // This should be made a hash table if performance is a problem.
    205     static SkTDArray<FontRec>& CanonicalFonts();
    206     static SkBaseMutex& CanonicalFontsMutex();
    207     typedef SkPDFDict INHERITED;
    208 };
    209 
    210 #endif
    211