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 "SkTypeface.h"
18
19class SkPaint;
20class SkPDFCanon;
21class SkPDFObjNumMap;
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    /** Returns the typeface represented by this class. Returns NULL for the
86     *  default typeface.
87     */
88    SkTypeface* typeface();
89
90    /** Returns the font type represented in this font.  For Type0 fonts,
91     *  returns the type of the decendant font.
92     */
93    virtual SkAdvancedTypefaceMetrics::FontType getType();
94
95    /** Returns true if this font encoding supports glyph IDs above 255.
96     */
97    virtual bool multiByteGlyphs() const = 0;
98
99    /** Returns true if the machine readable licensing bits allow embedding.
100     */
101    bool canEmbed() const;
102
103    /** Returns true if the machine readable licensing bits allow subsetting.
104     */
105    bool canSubset() const;
106
107    /** Return true if this font has an encoding for the passed glyph id.
108     */
109    bool hasGlyph(uint16_t glyphID);
110
111    /** Convert (in place) the input glyph IDs into the font encoding.  If the
112     *  font has more glyphs than can be encoded (like a type 1 font with more
113     *  than 255 glyphs) this method only converts up to the first out of range
114     *  glyph ID.
115     *  @param glyphIDs       The input text as glyph IDs.
116     *  @param numGlyphs      The number of input glyphs.
117     *  @return               Returns the number of glyphs consumed.
118     */
119    int glyphsToPDFFontEncoding(uint16_t* glyphIDs, int numGlyphs);
120
121    /** Get the font resource for the passed typeface and glyphID. The
122     *  reference count of the object is incremented and it is the caller's
123     *  responsibility to unreference it when done.  This is needed to
124     *  accommodate the weak reference pattern used when the returned object
125     *  is new and has no other references.
126     *  @param typeface  The typeface to find.
127     *  @param glyphID   Specify which section of a large font is of interest.
128     */
129    static SkPDFFont* GetFontResource(SkPDFCanon* canon,
130                                      SkTypeface* typeface,
131                                      uint16_t glyphID);
132
133    /** Subset the font based on usage set. Returns a SkPDFFont instance with
134     *  subset.
135     *  @param usage  Glyph subset requested.
136     *  @return       NULL if font does not support subsetting, a new instance
137     *                of SkPDFFont otherwise.
138     */
139    virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage);
140
141    enum Match {
142        kExact_Match,
143        kRelated_Match,
144        kNot_Match,
145    };
146    static Match IsMatch(SkPDFFont* existingFont,
147                         uint32_t existingFontID,
148                         uint16_t existingGlyphID,
149                         uint32_t searchFontID,
150                         uint16_t searchGlyphID);
151
152protected:
153    // Common constructor to handle common members.
154    SkPDFFont(const SkAdvancedTypefaceMetrics* fontInfo,
155              SkTypeface* typeface,
156              SkPDFDict* relatedFontDescriptor);
157
158    // Accessors for subclass.
159    const SkAdvancedTypefaceMetrics* fontInfo();
160    void setFontInfo(const SkAdvancedTypefaceMetrics* info);
161    uint16_t firstGlyphID() const;
162    uint16_t lastGlyphID() const;
163    void setLastGlyphID(uint16_t glyphID);
164
165    // Accessors for FontDescriptor associated with this object.
166    SkPDFDict* getFontDescriptor();
167    void setFontDescriptor(SkPDFDict* descriptor);
168
169    // Add common entries to FontDescriptor.
170    bool addCommonFontDescriptorEntries(int16_t defaultWidth);
171
172    /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
173     *  including the passed glyphID.
174     */
175    void adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID);
176
177    // Generate ToUnicode table according to glyph usage subset.
178    // If subset is NULL, all available glyph ids will be used.
179    void populateToUnicodeTable(const SkPDFGlyphSet* subset);
180
181    // Create instances of derived types based on fontInfo.
182    static SkPDFFont* Create(SkPDFCanon* canon,
183                             const SkAdvancedTypefaceMetrics* fontInfo,
184                             SkTypeface* typeface,
185                             uint16_t glyphID,
186                             SkPDFDict* relatedFontDescriptor);
187
188    static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
189
190private:
191    SkAutoTUnref<SkTypeface> fTypeface;
192
193    // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
194    // this will be a subset if the font has more than 255 glyphs.
195    uint16_t fFirstGlyphID;
196    uint16_t fLastGlyphID;
197    SkAutoTUnref<const SkAdvancedTypefaceMetrics> fFontInfo;
198    SkAutoTUnref<SkPDFDict> fDescriptor;
199
200    SkAdvancedTypefaceMetrics::FontType fFontType;
201
202    typedef SkPDFDict INHERITED;
203};
204
205#endif
206