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
20class SkPaint;
21class SkPDFCatalog;
22class SkPDFFont;
23
24class SkPDFGlyphSet : SkNoncopyable {
25public:
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
33private:
34    SkBitSet fBitSet;
35};
36
37class SkPDFGlyphSetMap : SkNoncopyable {
38public:
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
66private:
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*/
80class SkPDFFont : public SkPDFDict {
81    SK_DECLARE_INST_COUNT(SkPDFFont)
82public:
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
142protected:
143    // Common constructor to handle common members.
144    SkPDFFont(const SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
145              SkPDFDict* relatedFontDescriptor);
146
147    // Accessors for subclass.
148    const SkAdvancedTypefaceMetrics* fontInfo();
149    void setFontInfo(const 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(uint16_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(const 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
180private:
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<const 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