blob: a37fec15cc595fa1953e452e5b9cbf54fd9136b9 [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.org98594282011-07-25 22:34:12 +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.org98594282011-07-25 22:34:12 +000025#include "SkTypeface.h"
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000026
27class SkPaint;
vandebo@chromium.org98594282011-07-25 22:34:12 +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);
vandebo@chromium.org17e66e22011-07-27 20:59:55 +000038 void exportTo(SkTDArray<uint32_t>* glyphIDs) const;
vandebo@chromium.org98594282011-07-25 22:34:12 +000039
40private:
41 SkBitSet fBitSet;
42};
43
44class SkPDFGlyphSetMap : public SkNoncopyable {
45public:
46 struct FontGlyphSetPair {
47 FontGlyphSetPair(SkPDFFont* font, SkPDFGlyphSet* glyphSet);
48
49 SkPDFFont* fFont;
50 SkPDFGlyphSet* fGlyphSet;
51 };
52
53 SkPDFGlyphSetMap();
54 ~SkPDFGlyphSetMap();
55
56 class F2BIter {
57 public:
58 F2BIter(const SkPDFGlyphSetMap& map);
59 FontGlyphSetPair* next() const;
60 void reset(const SkPDFGlyphSetMap& map);
61
62 private:
63 const SkTDArray<FontGlyphSetPair>* fMap;
64 mutable int fIndex;
65 };
66
67 void merge(const SkPDFGlyphSetMap& usage);
68 void reset();
69
70 void noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
71 int numGlyphs);
72
73private:
74 SkPDFGlyphSet* getGlyphSetForFont(SkPDFFont* font);
75
76 SkTDArray<FontGlyphSetPair> fMap;
77};
78
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000079
80/** \class SkPDFFont
81 A PDF Object class representing a font. The font may have resources
82 attached to it in order to embed the font. SkPDFFonts are canonicalized
83 so that resource deduplication will only include one copy of a font.
84 This class uses the same pattern as SkPDFGraphicState, a static weak
85 reference to each instantiated class.
86*/
87class SkPDFFont : public SkPDFDict {
88public:
vandebo@chromium.org3509f052011-05-30 20:52:33 +000089 SK_API virtual ~SkPDFFont();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000090
vandebo@chromium.org3509f052011-05-30 20:52:33 +000091 SK_API virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000092
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +000093 /** Returns the typeface represented by this class. Returns NULL for the
94 * default typeface.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000095 */
vandebo@chromium.org3509f052011-05-30 20:52:33 +000096 SK_API SkTypeface* typeface();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +000097
vandebo@chromium.orgf0ec2662011-05-29 05:55:42 +000098 /** Returns the font type represented in this font. For Type0 fonts,
99 * returns the type of the decendant font.
100 */
vandebo@chromium.org98594282011-07-25 22:34:12 +0000101 SK_API virtual SkAdvancedTypefaceMetrics::FontType getType();
102
103 /** Returns true if this font encoding supports glyph IDs above 255.
104 */
105 SK_API virtual bool multiByteGlyphs() const = 0;
vandebo@chromium.orgf0ec2662011-05-29 05:55:42 +0000106
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000107 /** Return true if this font has an encoding for the passed glyph id.
108 */
vandebo@chromium.org3509f052011-05-30 20:52:33 +0000109 SK_API bool hasGlyph(uint16_t glyphID);
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000110
vandebo@chromium.org01294102011-02-28 19:52:18 +0000111 /** 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
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000114 * glyph ID.
115 * @param glyphIDs The input text as glyph IDs.
116 * @param numGlyphs The number of input glyphs.
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000117 * @return Returns the number of glyphs consumed.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000118 */
vandebo@chromium.org3509f052011-05-30 20:52:33 +0000119 SK_API size_t glyphsToPDFFontEncoding(uint16_t* glyphIDs, size_t numGlyphs);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000120
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +0000121 /** Get the font resource for the passed typeface and glyphID. The
vandebo@chromium.org2a22e102011-01-25 21:01:34 +0000122 * 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.
ctguil@chromium.org9db86bb2011-03-04 21:43:27 +0000126 * @param typeface The typeface to find.
127 * @param glyphID Specify which section of a large font is of interest.
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000128 */
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000129 SK_API static SkPDFFont* GetFontResource(SkTypeface* typeface,
vandebo@chromium.org3509f052011-05-30 20:52:33 +0000130 uint16_t glyphID);
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000131
vandebo@chromium.org98594282011-07-25 22:34:12 +0000132 /** Subset the font based on usage set. Returns a SkPDFFont instance with
133 * subset.
134 * @param usage Glyph subset requested.
135 * @return NULL if font does not support subsetting, a new instance
136 * of SkPDFFont otherwise.
137 */
138 SK_API virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage);
139
140protected:
141 // Common constructor to handle common members.
142 SkPDFFont(SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface,
143 uint16_t glyphID, bool descendantFont);
144
145 // Accessors for subclass.
146 SkAdvancedTypefaceMetrics* fontInfo();
147 uint16_t firstGlyphID() const;
148 uint16_t lastGlyphID() const;
149 void setLastGlyphID(uint16_t glyphID);
150
151 // Add object to resource list.
152 void addResource(SkPDFObject* object);
153
154 // Accessors for FontDescriptor associated with this object.
155 SkPDFDict* getFontDescriptor();
156 void setFontDescriptor(SkPDFDict* descriptor);
157
158 // Add common entries to FontDescriptor.
159 bool addCommonFontDescriptorEntries(int16_t defaultWidth);
160
161 /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs,
162 * including the passed glyphID.
163 */
164 void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID);
165
166 // Generate ToUnicode table according to glyph usage subset.
167 // If subset is NULL, all available glyph ids will be used.
168 void populateToUnicodeTable(const SkPDFGlyphSet* subset);
169
170 // Create instances of derived types based on fontInfo.
171 static SkPDFFont* Create(SkAdvancedTypefaceMetrics* fontInfo,
172 SkTypeface* typeface, uint16_t glyphID,
173 SkPDFDict* fontDescriptor);
174
175 static bool Find(uint32_t fontID, uint16_t glyphID, int* index);
176
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000177private:
vandebo@chromium.org31dcee72011-07-23 21:13:30 +0000178 class FontRec {
179 public:
180 SkPDFFont* fFont;
181 uint32_t fFontID;
182 uint16_t fGlyphID;
183
184 // A fGlyphID of 0 with no fFont always matches.
185 bool operator==(const FontRec& b) const;
186 FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID);
187 };
vandebo@chromium.org6504cfd2011-07-23 20:22:53 +0000188
vandebo@chromium.org98594282011-07-25 22:34:12 +0000189 SkRefPtr<SkTypeface> fTypeface;
190
191 // The glyph IDs accessible with this font. For Type1 (non CID) fonts,
192 // this will be a subset if the font has more than 255 glyphs.
193 uint16_t fFirstGlyphID;
194 uint16_t fLastGlyphID;
195 // The font info is only kept around after construction for large
196 // Type1 (non CID) fonts that need multiple "fonts" to access all glyphs.
197 SkRefPtr<SkAdvancedTypefaceMetrics> fFontInfo;
198 SkTDArray<SkPDFObject*> fResources;
199 SkRefPtr<SkPDFDict> fDescriptor;
200
201 SkAdvancedTypefaceMetrics::FontType fFontType;
202
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000203 // This should be made a hash table if performance is a problem.
reed@google.comf6c3ebd2011-07-20 17:20:28 +0000204 static SkTDArray<FontRec>& CanonicalFonts();
205 static SkMutex& CanonicalFontsMutex();
vandebo@chromium.org28be72b2010-11-11 21:37:00 +0000206};
207
208#endif