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
82public:
83    virtual ~SkPDFFont();
84
85    /** Returns the typeface represented by this class. Returns nullptr 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       nullptr 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
152    /**
153     *  Return false iff the typeface has its NotEmbeddable flag set.
154     *  If typeface is NULL, the default typeface is checked.
155     */
156    static bool CanEmbedTypeface(SkTypeface*, SkPDFCanon*);
157
158protected:
159    // Common constructor to handle common members.
160    SkPDFFont(const SkAdvancedTypefaceMetrics* fontInfo,
161              SkTypeface* typeface,
162              SkPDFDict* relatedFontDescriptor);
163
164    // Accessors for subclass.
165    const SkAdvancedTypefaceMetrics* fontInfo();
166    void setFontInfo(const SkAdvancedTypefaceMetrics* info);
167    uint16_t firstGlyphID() const;
168    uint16_t lastGlyphID() const;
169    void setLastGlyphID(uint16_t glyphID);
170
171    // Accessors for FontDescriptor associated with this object.
172    SkPDFDict* getFontDescriptor();
173    void setFontDescriptor(SkPDFDict* descriptor);
174
175    // Add common entries to FontDescriptor.
176    bool addCommonFontDescriptorEntries(int16_t defaultWidth);
177
178    /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
179     *  including the passed glyphID.
180     */
181    void adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID);
182
183    // Generate ToUnicode table according to glyph usage subset.
184    // If subset is nullptr, all available glyph ids will be used.
185    void populateToUnicodeTable(const SkPDFGlyphSet* subset);
186
187    // Create instances of derived types based on fontInfo.
188    static SkPDFFont* Create(SkPDFCanon* canon,
189                             const SkAdvancedTypefaceMetrics* fontInfo,
190                             SkTypeface* typeface,
191                             uint16_t glyphID,
192                             SkPDFDict* relatedFontDescriptor);
193
194    static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
195
196private:
197    SkAutoTUnref<SkTypeface> fTypeface;
198
199    // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
200    // this will be a subset if the font has more than 255 glyphs.
201    uint16_t fFirstGlyphID;
202    uint16_t fLastGlyphID;
203    SkAutoTUnref<const SkAdvancedTypefaceMetrics> fFontInfo;
204    SkAutoTUnref<SkPDFDict> fDescriptor;
205
206    SkAdvancedTypefaceMetrics::FontType fFontType;
207
208    typedef SkPDFDict INHERITED;
209};
210
211#endif
212