blob: 00dcb95a6a8ceb2a981ebc3ef085b3c8c8b41f4b [file] [log] [blame]
vandebo@chromium.org28be72b2010-11-11 21:37:00 +00001/*
vandebo@chromium.org2a22e102011-01-25 21:01:34 +00002 * Copyright (C) 2011 Google Inc.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkPDFFont_DEFINED
18#define SkPDFFont_DEFINED
19
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +000020#include "SkAdvancedTypefaceMetrics.h"
vandebo@chromium.org6504cfd2011-07-23 20:22:53 +000021#include "SkBitSet.h"
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000022#include "SkPDFTypes.h"
23#include "SkTDArray.h"
24#include "SkThread.h"
vandebo@chromium.org6504cfd2011-07-23 20:22:53 +000025#include "SkTypeface.h"
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000026
27class SkPaint;
vandebo@chromium.org6504cfd2011-07-23 20:22:53 +000028class SkPDFCatalog;
29class SkPDFFont;
30
31class SkPDFGlyphSet : public SkNoncopyable {
32public:
33 SkPDFGlyphSet();
34
35 void set(const uint16_t* glyphIDs, int numGlyphs);
36 bool has(uint16_t glyphID) const;
37 void merge(const SkPDFGlyphSet& usage);
38
39private:
40 SkBitSet fBitSet;
41};
42
43class SkPDFGlyphSetMap : public SkNoncopyable {
44public:
45 struct FontGlyphSetPair {
46 FontGlyphSetPair(SkPDFFont* font, SkPDFGlyphSet* glyphSet);
47
48 SkPDFFont* fFont;
49 SkPDFGlyphSet* fGlyphSet;
50 };
51
52 SkPDFGlyphSetMap();
53 ~SkPDFGlyphSetMap();
54
55 class F2BIter {
56 public:
57 F2BIter(const SkPDFGlyphSetMap& map);
58 FontGlyphSetPair* next() const;
59 void reset(const SkPDFGlyphSetMap& map);
60
61 private:
62 const SkTDArray<FontGlyphSetPair>* fMap;
63 mutable int fIndex;
64 };
65
66 void merge(const SkPDFGlyphSetMap& usage);
67 void reset();
68
69 void noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
70 int numGlyphs);
71
72private:
73 SkPDFGlyphSet* getGlyphSetForFont(SkPDFFont* font);
74
75 SkTDArray<FontGlyphSetPair> fMap;
76};
77
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000078
79/** \class SkPDFFont
80 A PDF Object class representing a font. The font may have resources
81 attached to it in order to embed the font. SkPDFFonts are canonicalized
82 so that resource deduplication will only include one copy of a font.
83 This class uses the same pattern as SkPDFGraphicState, a static weak
84 reference to each instantiated class.
85*/
86class SkPDFFont : public SkPDFDict {
87public:
vandebo@chromium.org3509f052011-05-30 20:52:33 +000088 SK_API virtual ~SkPDFFont();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000089
vandebo@chromium.org3509f052011-05-30 20:52:33 +000090 SK_API virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000091
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +000092 /** Returns the typeface represented by this class. Returns NULL for the
93 * default typeface.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000094 */
vandebo@chromium.org3509f052011-05-30 20:52:33 +000095 SK_API SkTypeface* typeface();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000096
vandebo@chromium.orgf0ec2662011-05-29 05:55:42 +000097 /** Returns the font type represented in this font. For Type0 fonts,
98 * returns the type of the decendant font.
99 */
vandebo@chromium.org6504cfd2011-07-23 20:22:53 +0000100 SK_API virtual SkAdvancedTypefaceMetrics::FontType getType();
101
102 /** Returns true if this font encoding supports glyph IDs above 255.
103 */
104 SK_API virtual bool multiByteGlyphs() const = 0;
vandebo@chromium.orgf0ec2662011-05-29 05:55:42 +0000105
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000106 /** Return true if this font has an encoding for the passed glyph id.
107 */
vandebo@chromium.org3509f052011-05-30 20:52:33 +0000108 SK_API bool hasGlyph(uint16_t glyphID);
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000109
vandebo@chromium.org01294102011-02-28 19:52:18 +0000110 /** Convert (in place) the input glyph IDs into the font encoding. If the
111 * font has more glyphs than can be encoded (like a type 1 font with more
112 * than 255 glyphs) this method only converts up to the first out of range
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000113 * glyph ID.
114 * @param glyphIDs The input text as glyph IDs.
115 * @param numGlyphs The number of input glyphs.
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000116 * @return Returns the number of glyphs consumed.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000117 */
vandebo@chromium.org3509f052011-05-30 20:52:33 +0000118 SK_API size_t glyphsToPDFFontEncoding(uint16_t* glyphIDs, size_t numGlyphs);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000119
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +0000120 /** Get the font resource for the passed typeface and glyphID. The
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000121 * reference count of the object is incremented and it is the caller's
122 * responsibility to unreference it when done. This is needed to
123 * accommodate the weak reference pattern used when the returned object
124 * is new and has no other references.
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +0000125 * @param typeface The typeface to find.
126 * @param glyphID Specify which section of a large font is of interest.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000127 */
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000128 SK_API static SkPDFFont* GetFontResource(SkTypeface* typeface,
vandebo@chromium.org3509f052011-05-30 20:52:33 +0000129 uint16_t glyphID);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000130
vandebo@chromium.org6504cfd2011-07-23 20:22:53 +0000131 /** Subset the font based on usage set. Returns a SkPDFFont instance with
132 * subset.
133 * @param usage Glyph subset requested.
134 * @return NULL if font does not support subsetting, a new instance
135 * of SkPDFFont otherwise.
136 */
137 SK_API virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage);
138
139protected:
140 // Common constructor to handle common members.
141 SkPDFFont(SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
142 uint16_t glyphID, bool descendantFont);
143
144 // Accessors for subclass.
145 SkAdvancedTypefaceMetrics* fontInfo();
146 uint16_t firstGlyphID() const;
147 uint16_t lastGlyphID() const;
148 void setLastGlyphID(uint16_t glyphID);
149
150 // Add object to resource list.
151 void addResource(SkPDFObject* object);
152
153 // Accessors for FontDescriptor associated with this object.
154 SkPDFDict* getFontDescriptor();
155 void setFontDescriptor(SkPDFDict* descriptor);
156
157 // Add common entries to FontDescriptor.
158 bool addCommonFontDescriptorEntries(int16_t defaultWidth);
159
160 /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
161 * including the passed glyphID.
162 */
163 void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
164
165 // Generate ToUnicode table according to glyph usage subset.
166 // If subset is NULL, all available glyph ids will be used.
167 void populateToUnicodeTable(const SkPDFGlyphSet* subset);
168
169 // Create instances of derived types based on fontInfo.
170 static SkPDFFont* Create(SkAdvancedTypefaceMetrics* fontInfo,
171 SkTypeface* typeface, uint16_t glyphID,
172 SkPDFDict* fontDescriptor);
173
174 static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
175
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000176private:
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000177 class FontRec {
178 public:
179 SkPDFFont* fFont;
180 uint32_t fFontID;
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000181 uint16_t fGlyphID;
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000182
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000183 // A fGlyphID of 0 with no fFont always matches.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000184 bool operator==(const FontRec& b) const;
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000185 FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000186 };
187
vandebo@chromium.org6504cfd2011-07-23 20:22:53 +0000188 SkRefPtr<SkTypeface> fTypeface;
189
190 // The glyph IDs accessible with this font. For Type1 (non CID) fonts,
191 // this will be a subset if the font has more than 255 glyphs.
192 uint16_t fFirstGlyphID;
193 uint16_t fLastGlyphID;
194 // The font info is only kept around after construction for large
195 // Type1 (non CID) fonts that need multiple "fonts" to access all glyphs.
196 SkRefPtr<SkAdvancedTypefaceMetrics> fFontInfo;
197 SkTDArray<SkPDFObject*> fResources;
198 SkRefPtr<SkPDFDict> fDescriptor;
199
200 SkAdvancedTypefaceMetrics::FontType fFontType;
201
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000202 // This should be made a hash table if performance is a problem.
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000203 static SkTDArray<FontRec>& CanonicalFonts();
204 static SkMutex& CanonicalFontsMutex();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000205};
206
207#endif