blob: b88401791240d9ae6662b8a00f242c2e4979262d [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
vandebo@chromium.org28be72b2010-11-11 21:37:00 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000010#ifndef SkPDFFont_DEFINED
11#define SkPDFFont_DEFINED
12
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +000013#include "SkAdvancedTypefaceMetrics.h"
vandebo@chromium.org98594282011-07-25 22:34:12 +000014#include "SkBitSet.h"
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000015#include "SkPDFTypes.h"
16#include "SkTDArray.h"
17#include "SkThread.h"
vandebo@chromium.org98594282011-07-25 22:34:12 +000018#include "SkTypeface.h"
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000019
20class SkPaint;
vandebo@chromium.org98594282011-07-25 22:34:12 +000021class SkPDFCatalog;
22class SkPDFFont;
23
24class SkPDFGlyphSet : public 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);
vandebo@chromium.org17e66e22011-07-27 20:59:55 +000031 void exportTo(SkTDArray<uint32_t>* glyphIDs) const;
vandebo@chromium.org98594282011-07-25 22:34:12 +000032
33private:
34 SkBitSet fBitSet;
35};
36
37class SkPDFGlyphSetMap : public 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:
ctguil@chromium.orga5c72342011-08-15 23:55:03 +000051 explicit F2BIter(const SkPDFGlyphSetMap& map);
vandebo@chromium.org98594282011-07-25 22:34:12 +000052 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
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000072
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 {
81public:
vandebo@chromium.org3509f052011-05-30 20:52:33 +000082 SK_API virtual ~SkPDFFont();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000083
vandebo@chromium.org3509f052011-05-30 20:52:33 +000084 SK_API virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000085
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +000086 /** Returns the typeface represented by this class. Returns NULL for the
87 * default typeface.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000088 */
vandebo@chromium.org3509f052011-05-30 20:52:33 +000089 SK_API SkTypeface* typeface();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000090
vandebo@chromium.orgf0ec2662011-05-29 05:55:42 +000091 /** Returns the font type represented in this font. For Type0 fonts,
92 * returns the type of the decendant font.
93 */
vandebo@chromium.org98594282011-07-25 22:34:12 +000094 SK_API virtual SkAdvancedTypefaceMetrics::FontType getType();
95
96 /** Returns true if this font encoding supports glyph IDs above 255.
97 */
98 SK_API virtual bool multiByteGlyphs() const = 0;
vandebo@chromium.orgf0ec2662011-05-29 05:55:42 +000099
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000100 /** Return true if this font has an encoding for the passed glyph id.
101 */
vandebo@chromium.org3509f052011-05-30 20:52:33 +0000102 SK_API bool hasGlyph(uint16_t glyphID);
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000103
vandebo@chromium.org01294102011-02-28 19:52:18 +0000104 /** Convert (in place) the input glyph IDs into the font encoding. If the
105 * font has more glyphs than can be encoded (like a type 1 font with more
106 * than 255 glyphs) this method only converts up to the first out of range
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000107 * glyph ID.
108 * @param glyphIDs The input text as glyph IDs.
109 * @param numGlyphs The number of input glyphs.
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000110 * @return Returns the number of glyphs consumed.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000111 */
vandebo@chromium.org3509f052011-05-30 20:52:33 +0000112 SK_API size_t glyphsToPDFFontEncoding(uint16_t* glyphIDs, size_t numGlyphs);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000113
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +0000114 /** Get the font resource for the passed typeface and glyphID. The
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000115 * reference count of the object is incremented and it is the caller's
116 * responsibility to unreference it when done. This is needed to
117 * accommodate the weak reference pattern used when the returned object
118 * is new and has no other references.
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +0000119 * @param typeface The typeface to find.
120 * @param glyphID Specify which section of a large font is of interest.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000121 */
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000122 SK_API static SkPDFFont* GetFontResource(SkTypeface* typeface,
vandebo@chromium.org3509f052011-05-30 20:52:33 +0000123 uint16_t glyphID);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000124
vandebo@chromium.org98594282011-07-25 22:34:12 +0000125 /** Subset the font based on usage set. Returns a SkPDFFont instance with
126 * subset.
127 * @param usage Glyph subset requested.
128 * @return NULL if font does not support subsetting, a new instance
129 * of SkPDFFont otherwise.
130 */
131 SK_API virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage);
132
133protected:
134 // Common constructor to handle common members.
135 SkPDFFont(SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
136 uint16_t glyphID, bool descendantFont);
137
138 // Accessors for subclass.
139 SkAdvancedTypefaceMetrics* fontInfo();
vandebo@chromium.org37ad8fb2011-08-18 02:38:50 +0000140 void setFontInfo(SkAdvancedTypefaceMetrics* info);
vandebo@chromium.org98594282011-07-25 22:34:12 +0000141 uint16_t firstGlyphID() const;
142 uint16_t lastGlyphID() const;
143 void setLastGlyphID(uint16_t glyphID);
144
145 // Add object to resource list.
146 void addResource(SkPDFObject* object);
147
148 // Accessors for FontDescriptor associated with this object.
149 SkPDFDict* getFontDescriptor();
150 void setFontDescriptor(SkPDFDict* descriptor);
151
152 // Add common entries to FontDescriptor.
153 bool addCommonFontDescriptorEntries(int16_t defaultWidth);
154
155 /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
156 * including the passed glyphID.
157 */
158 void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
159
160 // Generate ToUnicode table according to glyph usage subset.
161 // If subset is NULL, all available glyph ids will be used.
162 void populateToUnicodeTable(const SkPDFGlyphSet* subset);
163
164 // Create instances of derived types based on fontInfo.
165 static SkPDFFont* Create(SkAdvancedTypefaceMetrics* fontInfo,
166 SkTypeface* typeface, uint16_t glyphID,
167 SkPDFDict* fontDescriptor);
168
169 static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
170
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000171private:
vandebo@chromium.org31dcee72011-07-23 21:13:30 +0000172 class FontRec {
173 public:
174 SkPDFFont* fFont;
175 uint32_t fFontID;
176 uint16_t fGlyphID;
177
178 // A fGlyphID of 0 with no fFont always matches.
179 bool operator==(const FontRec& b) const;
180 FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
181 };
vandebo@chromium.org6504cfd2011-07-23 20:22:53 +0000182
vandebo@chromium.org98594282011-07-25 22:34:12 +0000183 SkRefPtr<SkTypeface> fTypeface;
184
185 // The glyph IDs accessible with this font. For Type1 (non CID) fonts,
186 // this will be a subset if the font has more than 255 glyphs.
187 uint16_t fFirstGlyphID;
188 uint16_t fLastGlyphID;
189 // The font info is only kept around after construction for large
190 // Type1 (non CID) fonts that need multiple "fonts" to access all glyphs.
191 SkRefPtr<SkAdvancedTypefaceMetrics> fFontInfo;
192 SkTDArray<SkPDFObject*> fResources;
193 SkRefPtr<SkPDFDict> fDescriptor;
194
195 SkAdvancedTypefaceMetrics::FontType fFontType;
196
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000197 // This should be made a hash table if performance is a problem.
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000198 static SkTDArray<FontRec>& CanonicalFonts();
199 static SkMutex& CanonicalFontsMutex();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000200};
201
202#endif