blob: 4f2b27986c04685ca824f8c084550e021c8c0ddb [file] [log] [blame]
edisonn@google.com1be794f2013-06-21 21:43:09 +00001#include "SkPdfFont.h"
edisonn@google.com131d4ee2013-06-26 17:48:12 +00002#include "SkPdfParser.h"
edisonn@google.com1be794f2013-06-21 21:43:09 +00003
edisonn@google.comeee4b652013-06-27 13:22:42 +00004#include "SkStream.h"
5#include "SkTypeface.h"
edisonn@google.com571c70b2013-07-10 17:09:50 +00006#include "SkPdfNativeTokenizer.h"
edisonn@google.comeee4b652013-06-27 13:22:42 +00007
edisonn@google.com1be794f2013-06-21 21:43:09 +00008std::map<std::string, SkPdfStandardFontEntry>& getStandardFonts() {
9 static std::map<std::string, SkPdfStandardFontEntry> gPdfStandardFonts;
10
11 // TODO (edisonn): , vs - ? what does it mean?
12 // TODO (edisonn): MT, PS, Oblique=italic?, ... what does it mean?
13 if (gPdfStandardFonts.empty()) {
edisonn@google.com596d2e22013-07-10 17:44:55 +000014 gPdfStandardFonts["Arial"] = SkPdfStandardFontEntry("Arial", false, false);
15 gPdfStandardFonts["Arial,Bold"] = SkPdfStandardFontEntry("Arial", true, false);
16 gPdfStandardFonts["Arial,BoldItalic"] = SkPdfStandardFontEntry("Arial", true, true);
17 gPdfStandardFonts["Arial,Italic"] = SkPdfStandardFontEntry("Arial", false, true);
18 gPdfStandardFonts["Arial-Bold"] = SkPdfStandardFontEntry("Arial", true, false);
19 gPdfStandardFonts["Arial-BoldItalic"] = SkPdfStandardFontEntry("Arial", true, true);
20 gPdfStandardFonts["Arial-BoldItalicMT"] = SkPdfStandardFontEntry("Arial", true, true);
21 gPdfStandardFonts["Arial-BoldMT"] = SkPdfStandardFontEntry("Arial", true, false);
22 gPdfStandardFonts["Arial-Italic"] = SkPdfStandardFontEntry("Arial", false, true);
23 gPdfStandardFonts["Arial-ItalicMT"] = SkPdfStandardFontEntry("Arial", false, true);
24 gPdfStandardFonts["ArialMT"] = SkPdfStandardFontEntry("Arial", false, false);
25 gPdfStandardFonts["Courier"] = SkPdfStandardFontEntry("Courier New", false, false);
26 gPdfStandardFonts["Courier,Bold"] = SkPdfStandardFontEntry("Courier New", true, false);
27 gPdfStandardFonts["Courier,BoldItalic"] = SkPdfStandardFontEntry("Courier New", true, true);
28 gPdfStandardFonts["Courier,Italic"] = SkPdfStandardFontEntry("Courier New", false, true);
29 gPdfStandardFonts["Courier-Bold"] = SkPdfStandardFontEntry("Courier New", true, false);
30 gPdfStandardFonts["Courier-BoldOblique"] = SkPdfStandardFontEntry("Courier New", true, true);
31 gPdfStandardFonts["Courier-Oblique"] = SkPdfStandardFontEntry("Courier New", false, true);
32 gPdfStandardFonts["CourierNew"] = SkPdfStandardFontEntry("Courier New", false, false);
33 gPdfStandardFonts["CourierNew,Bold"] = SkPdfStandardFontEntry("Courier New", true, false);
34 gPdfStandardFonts["CourierNew,BoldItalic"] = SkPdfStandardFontEntry("Courier New", true, true);
35 gPdfStandardFonts["CourierNew,Italic"] = SkPdfStandardFontEntry("Courier New", false, true);
36 gPdfStandardFonts["CourierNew-Bold"] = SkPdfStandardFontEntry("Courier New", true, false);
37 gPdfStandardFonts["CourierNew-BoldItalic"] = SkPdfStandardFontEntry("Courier New", true, true);
38 gPdfStandardFonts["CourierNew-Italic"] = SkPdfStandardFontEntry("Courier New", false, true);
39 gPdfStandardFonts["CourierNewPS-BoldItalicMT"] = SkPdfStandardFontEntry("Courier New", true, true);
40 gPdfStandardFonts["CourierNewPS-BoldMT"] = SkPdfStandardFontEntry("Courier New", true, false);
41 gPdfStandardFonts["CourierNewPS-ItalicMT"] = SkPdfStandardFontEntry("Courier New", false, true);
42 gPdfStandardFonts["CourierNewPSMT"] = SkPdfStandardFontEntry("Courier New", false, false);
43 gPdfStandardFonts["Helvetica"] = SkPdfStandardFontEntry("Helvetica", false, false);
44 gPdfStandardFonts["Helvetica,Bold"] = SkPdfStandardFontEntry("Helvetica", true, false);
45 gPdfStandardFonts["Helvetica,BoldItalic"] = SkPdfStandardFontEntry("Helvetica", true, true);
46 gPdfStandardFonts["Helvetica,Italic"] = SkPdfStandardFontEntry("Helvetica", false, true);
47 gPdfStandardFonts["Helvetica-Bold"] = SkPdfStandardFontEntry("Helvetica", true, false);
48 gPdfStandardFonts["Helvetica-BoldItalic"] = SkPdfStandardFontEntry("Helvetica", true, true);
49 gPdfStandardFonts["Helvetica-BoldOblique"] = SkPdfStandardFontEntry("Helvetica", true, true);
50 gPdfStandardFonts["Helvetica-Italic"] = SkPdfStandardFontEntry("Helvetica", false, true);
51 gPdfStandardFonts["Helvetica-Oblique"] = SkPdfStandardFontEntry("Helvetica", false, true);
52 gPdfStandardFonts["Times-Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false);
53 gPdfStandardFonts["Times-BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true);
54 gPdfStandardFonts["Times-Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true);
55 gPdfStandardFonts["Times-Roman"] = SkPdfStandardFontEntry("Times New Roman", false, false);
56 gPdfStandardFonts["TimesNewRoman"] = SkPdfStandardFontEntry("Times New Roman", false, false);
57 gPdfStandardFonts["TimesNewRoman,Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false);
58 gPdfStandardFonts["TimesNewRoman,BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true);
59 gPdfStandardFonts["TimesNewRoman,Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true);
60 gPdfStandardFonts["TimesNewRoman-Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false);
61 gPdfStandardFonts["TimesNewRoman-BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true);
62 gPdfStandardFonts["TimesNewRoman-Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true);
63 gPdfStandardFonts["TimesNewRomanPS"] = SkPdfStandardFontEntry("Times New Roman", false, false);
64 gPdfStandardFonts["TimesNewRomanPS-Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false);
65 gPdfStandardFonts["TimesNewRomanPS-BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true);
66 gPdfStandardFonts["TimesNewRomanPS-BoldItalicMT"] = SkPdfStandardFontEntry("Times New Roman", true, true);
67 gPdfStandardFonts["TimesNewRomanPS-BoldMT"] = SkPdfStandardFontEntry("Times New Roman", true, false);
68 gPdfStandardFonts["TimesNewRomanPS-Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true);
69 gPdfStandardFonts["TimesNewRomanPS-ItalicMT"] = SkPdfStandardFontEntry("Times New Roman", false, true);
70 gPdfStandardFonts["TimesNewRomanPSMT"] = SkPdfStandardFontEntry("Times New Roman", false, false);
71 gPdfStandardFonts["Symbol"] = SkPdfStandardFontEntry("Symbol", false, false);
72 gPdfStandardFonts["ZapfDingbats"] = SkPdfStandardFontEntry("ZapfDingbats", false, false);
edisonn@google.com1be794f2013-06-21 21:43:09 +000073
74 // TODO(edisonn): these are hacks. Load Post Script font name.
75 // see FT_Get_Postscript_Name
76 // Font config is not using it, yet.
77 //https://bugs.freedesktop.org/show_bug.cgi?id=18095
edisonn@google.comb857a0c2013-06-25 20:45:40 +000078
edisonn@google.com596d2e22013-07-10 17:44:55 +000079 gPdfStandardFonts["Arial-Black"] = SkPdfStandardFontEntry("Arial", true, false);
80 gPdfStandardFonts["DejaVuSans"] = SkPdfStandardFontEntry("DejaVu Sans", false, false);
81 gPdfStandardFonts["DejaVuSansMono"] = SkPdfStandardFontEntry("DejaVuSans Mono", false, false);
82 gPdfStandardFonts["DejaVuSansMono-Bold"] = SkPdfStandardFontEntry("DejaVuSans Mono", true, false);
83 gPdfStandardFonts["DejaVuSansMono-Oblique"] = SkPdfStandardFontEntry("DejaVuSans Mono", false, true);
84 gPdfStandardFonts["Georgia-Bold"] = SkPdfStandardFontEntry("Georgia", true, false);
85 gPdfStandardFonts["Georgia-BoldItalic"] = SkPdfStandardFontEntry("Georgia", true, true);
86 gPdfStandardFonts["Georgia-Italic"] = SkPdfStandardFontEntry("Georgia", false, true);
87 gPdfStandardFonts["TrebuchetMS"] = SkPdfStandardFontEntry("Trebuchet MS", false, false);
88 gPdfStandardFonts["TrebuchetMS-Bold"] = SkPdfStandardFontEntry("Trebuchet MS", true, false);
89 gPdfStandardFonts["Verdana-Bold"] = SkPdfStandardFontEntry("Verdana", true, false);
90 gPdfStandardFonts["WenQuanYiMicroHei"] = SkPdfStandardFontEntry("WenQuanYi Micro Hei", false, false);
edisonn@google.comb857a0c2013-06-25 20:45:40 +000091
92 // TODO(edisonn): list all phonts available, builf post script name as in pdf spec
93 /*
94 * The PostScript name for the value of BaseFontis determined in one of two ways:
95• Use the PostScript name that is an optional entry in the “name” table of the
96TrueType font itself.
97• In the absence of such an entry in the “name” table, derive a PostScript name
98from the name by which the font is known in the host operating system: on a
99Windows system, it is based on the lfFaceName field in a LOGFONT structure; in
100the Mac OS, it is based on the name of the FONDresource. If the name contains
101any spaces, the spaces are removed.
102If the font in a source document uses a bold or italic style, but there is no font
103data for that style, the host operating system will synthesize the style. In this case,
104a comma and the style name (one of Bold, Italic, or BoldItalic) are appended to the
105font name. For example, for a TrueType font that is a bold variant of the New
106 */
107
108 /*
109 * If the value of Subtype is MMType1.
110• If the PostScript name of the instance contains spaces, the spaces are replaced
111by underscores in the value of BaseFont. For instance, as illustrated in Example
1125.7, the name “MinionMM 366 465 11 ” (which ends with a space character)
113becomes /MinionMM_366_465_11_.
114 */
115
116 // might not work on all oses ?
117 //
118
edisonn@google.com1be794f2013-06-21 21:43:09 +0000119 }
120
121 return gPdfStandardFonts;
122}
123
124SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic) {
125 std::map<std::string, SkPdfStandardFontEntry>& standardFontMap = getStandardFonts();
126
127 SkTypeface* typeface = NULL;
128 if (standardFontMap.find(fontName) != standardFontMap.end()) {
129 SkPdfStandardFontEntry fontData = standardFontMap[fontName];
130
131 // TODO(edisonn): How does the bold/italic specified in standard definition combines with
132 // the one in /font key? use OR for now.
133 bold = bold || fontData.fIsBold;
134 italic = italic || fontData.fIsItalic;
135
136 typeface = SkTypeface::CreateFromName(
137 fontData.fName,
138 SkTypeface::Style((bold ? SkTypeface::kBold : 0) |
139 (italic ? SkTypeface::kItalic : 0)));
140 } else {
141 typeface = SkTypeface::CreateFromName(
142 fontName,
143 SkTypeface::kNormal);
144 }
145
146 if (typeface) {
147 typeface->ref();
148 }
149 return typeface;
150}
151
edisonn@google.com571c70b2013-07-10 17:09:50 +0000152SkPdfFont* SkPdfFont::fontFromFontDescriptor(SkNativeParsedPDF* doc, SkPdfFontDescriptorDictionary* fd, bool loadFromName) {
153 // TODO(edisonn): partial implementation ... also const handling ...
edisonn@google.comeee4b652013-06-27 13:22:42 +0000154 // Only one, at most be available
edisonn@google.com6e49c342013-06-27 20:03:43 +0000155 SkPdfStream* pdfStream = NULL;
edisonn@google.comeee4b652013-06-27 13:22:42 +0000156 if (fd->has_FontFile()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000157 pdfStream = fd->FontFile(doc);
edisonn@google.comeee4b652013-06-27 13:22:42 +0000158 } else if (fd->has_FontFile2()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000159 pdfStream = fd->FontFile2(doc);
edisonn@google.comeee4b652013-06-27 13:22:42 +0000160 } if (fd->has_FontFile3()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000161 pdfStream = fd->FontFile3(doc);
edisonn@google.comeee4b652013-06-27 13:22:42 +0000162 } else {
edisonn@google.com6e49c342013-06-27 20:03:43 +0000163 if (loadFromName) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000164 return fontFromName(doc, fd, fd->FontName(doc).c_str());
edisonn@google.com6e49c342013-06-27 20:03:43 +0000165 }
edisonn@google.comeee4b652013-06-27 13:22:42 +0000166 }
167
edisonn@google.com571c70b2013-07-10 17:09:50 +0000168 unsigned char* uncompressedStream = NULL;
169 size_t uncompressedStreamLength = 0;
edisonn@google.com6e49c342013-06-27 20:03:43 +0000170
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000171 // TODO(edisonn): report warning to be used in testing.
172 if (!pdfStream ||
edisonn@google.com571c70b2013-07-10 17:09:50 +0000173 !pdfStream->GetFilteredStreamRef(&uncompressedStream, &uncompressedStreamLength, doc->allocator()) ||
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000174 !uncompressedStream ||
175 !uncompressedStreamLength) {
edisonn@google.com6e49c342013-06-27 20:03:43 +0000176 return NULL;
177 }
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000178
edisonn@google.com6e49c342013-06-27 20:03:43 +0000179 SkMemoryStream* skStream = new SkMemoryStream(uncompressedStream, uncompressedStreamLength);
180 SkTypeface* face = SkTypeface::CreateFromStream(skStream);
181
182 if (face == NULL) {
183 // TODO(edisonn): report warning to be used in testing.
184 return NULL;
185 }
186
187 face->ref();
188
189 return new SkPdfStandardFont(face);
edisonn@google.comeee4b652013-06-27 13:22:42 +0000190}
191
edisonn@google.com571c70b2013-07-10 17:09:50 +0000192SkPdfFont* fontFromName(SkNativeParsedPDF* doc, SkPdfObject* obj, const char* fontName) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000193 SkTypeface* typeface = SkTypefaceFromPdfStandardFont(fontName, false, false);
194 if (typeface != NULL) {
195 return new SkPdfStandardFont(typeface);
196 }
edisonn@google.comeee4b652013-06-27 13:22:42 +0000197
198 // TODO(edisonn): perf - make a map
edisonn@google.com571c70b2013-07-10 17:09:50 +0000199 for (unsigned int i = 0 ; i < doc->objects(); i++) {
200 SkPdfObject* obj = doc->object(i);
201 if (!obj->isDictionary()) {
202 continue;
203 }
edisonn@google.comab03e682013-06-28 18:51:20 +0000204
edisonn@google.com571c70b2013-07-10 17:09:50 +0000205 SkPdfFontDescriptorDictionary* fd = obj->asDictionary()->asFontDescriptorDictionary();
206
207 if (!fd->valid()) {
208 continue;
209 }
210
211 if (fd->has_FontName() && fd->FontName(doc) == fontName) {
212 SkPdfFont* font = SkPdfFont::fontFromFontDescriptor(doc, fd, false);
213 if (font) {
214 return font;
215 } else {
216 // failed to load font descriptor
217 break;
edisonn@google.comeee4b652013-06-27 13:22:42 +0000218 }
219 }
220 }
221
222 // TODO(edisonn): warning/report issue
edisonn@google.com1be794f2013-06-21 21:43:09 +0000223 return SkPdfFont::Default();
224}
225
edisonn@google.com571c70b2013-07-10 17:09:50 +0000226SkPdfFont* SkPdfFont::fontFromPdfDictionaryOnce(SkNativeParsedPDF* doc, SkPdfFontDictionary* dict) {
227 // TODO(edisonn): keep the type in a smart way in the SkPdfObject
228 // 1) flag, isResolved (1bit): reset at reset, add/remove/update (array) and set(dict)
229 // in a tree like structure, 3-4 bits for all the datatypes inheriting from obj (int, real, ...)
230 // if is a dict, reserveve a few bytes to encode type of dict, and so on like in a tree
231 // issue: type can be determined from context! atribute night be missing/wrong
232 switch (doc->mapper()->mapFontDictionary(dict)) {
233 case kType0FontDictionary_SkPdfObjectType:
234 return fontFromType0FontDictionary(doc, dict->asType0FontDictionary());
235
236 case kTrueTypeFontDictionary_SkPdfObjectType:
237 return fontFromTrueTypeFontDictionary(doc, dict->asTrueTypeFontDictionary());
238
239 case kType1FontDictionary_SkPdfObjectType:
240 return fontFromType1FontDictionary(doc, dict->asType1FontDictionary());
241
242 case kMultiMasterFontDictionary_SkPdfObjectType:
243 return fontFromMultiMasterFontDictionary(doc, dict->asMultiMasterFontDictionary());
244
245 case kType3FontDictionary_SkPdfObjectType:
246 return fontFromType3FontDictionary(doc, dict->asType3FontDictionary());
247
248 default:
249 // TODO(edisonn): report error?
250 return NULL;
251 }
252}
253
254SkPdfFont* SkPdfFont::fontFromPdfDictionary(SkNativeParsedPDF* doc, SkPdfFontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000255 if (dict == NULL) {
256 return NULL; // TODO(edisonn): report default one?
257 }
258
edisonn@google.com571c70b2013-07-10 17:09:50 +0000259 if (dict->data() == NULL) {
260 dict->setData(fontFromPdfDictionaryOnce(doc, dict));
edisonn@google.com1be794f2013-06-21 21:43:09 +0000261 }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000262 return (SkPdfFont*)dict->data();
edisonn@google.com1be794f2013-06-21 21:43:09 +0000263}
264
edisonn@google.com571c70b2013-07-10 17:09:50 +0000265
266
267SkPdfType0Font* SkPdfFont::fontFromType0FontDictionary(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000268 if (dict == NULL) {
269 return NULL; // default one?
270 }
271
edisonn@google.com571c70b2013-07-10 17:09:50 +0000272 return new SkPdfType0Font(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000273}
274
edisonn@google.com571c70b2013-07-10 17:09:50 +0000275SkPdfType1Font* SkPdfFont:: fontFromType1FontDictionary(SkNativeParsedPDF* doc, SkPdfType1FontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000276 if (dict == NULL) {
277 return NULL; // default one?
278 }
279
edisonn@google.com571c70b2013-07-10 17:09:50 +0000280 return new SkPdfType1Font(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000281}
282
edisonn@google.com571c70b2013-07-10 17:09:50 +0000283SkPdfType3Font* SkPdfFont::fontFromType3FontDictionary(SkNativeParsedPDF* doc, SkPdfType3FontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000284 if (dict == NULL) {
285 return NULL; // default one?
286 }
287
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000288
289
edisonn@google.com571c70b2013-07-10 17:09:50 +0000290 return new SkPdfType3Font(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000291}
292
edisonn@google.com571c70b2013-07-10 17:09:50 +0000293SkPdfTrueTypeFont* SkPdfFont::fontFromTrueTypeFontDictionary(SkNativeParsedPDF* doc, SkPdfTrueTypeFontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000294 if (dict == NULL) {
295 return NULL; // default one?
296 }
297
edisonn@google.com571c70b2013-07-10 17:09:50 +0000298 return new SkPdfTrueTypeFont(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000299}
300
edisonn@google.com571c70b2013-07-10 17:09:50 +0000301SkPdfMultiMasterFont* SkPdfFont::fontFromMultiMasterFontDictionary(SkNativeParsedPDF* doc, SkPdfMultiMasterFontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000302 if (dict == NULL) {
303 return NULL; // default one?
304 }
305
edisonn@google.com571c70b2013-07-10 17:09:50 +0000306 return new SkPdfMultiMasterFont(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000307}
308
edisonn@google.com571c70b2013-07-10 17:09:50 +0000309static int skstoi(const SkPdfObject* str) {
310 // TODO(edisonn): report err of it is not a (hex) string
edisonn@google.com1be794f2013-06-21 21:43:09 +0000311 int ret = 0;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000312 for (unsigned int i = 0 ; i < str->len(); i++) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000313 ret = (ret << 8) + ((unsigned char*)str->c_str())[i];
edisonn@google.com1be794f2013-06-21 21:43:09 +0000314 }
315 return ret;
316}
317
edisonn@google.com571c70b2013-07-10 17:09:50 +0000318#define tokenIsKeyword(token,keyword) (token.fType == kKeyword_TokenType && token.fKeywordLength==sizeof(keyword)-1 && strncmp(token.fKeyword, keyword, sizeof(keyword)-1) == 0)
319
320SkPdfToUnicode::SkPdfToUnicode(SkNativeParsedPDF* parsed, SkPdfStream* stream) : fParsed(parsed) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000321 fCMapEncoding = NULL;
322 fCMapEncodingFlag = NULL;
323
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000324 if (stream) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000325 SkPdfNativeTokenizer* tokenizer = fParsed->tokenizerOfStream(stream);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000326 PdfToken token;
327
328 fCMapEncoding = new unsigned short[256 * 256];
329 fCMapEncodingFlag = new unsigned char[256 * 256];
330 for (int i = 0 ; i < 256 * 256; i++) {
331 fCMapEncoding[i] = i;
332 fCMapEncodingFlag[i] = 0;
333 }
334
335 // TODO(edisonn): deal with multibyte character, or longer strings.
336 // Ritght now we deal with up 2 characters, e.g. <0020> but not longer like <00660066006C>
337 //2 beginbfrange
338 //<0000> <005E> <0020>
339 //<005F> <0061> [<00660066> <00660069> <00660066006C>]
340
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000341 while (tokenizer->readToken(&token)) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000342
edisonn@google.com571c70b2013-07-10 17:09:50 +0000343 // TODO(edisonn): perf, macro that would make equal first for token.fKeywordLength with sizeof(keyword), instead od strlen, make sure it is keyword, not a char*
344 if (tokenIsKeyword(token, "begincodespacerange")) {
345 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endcodespacerange")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000346// tokenizer->PutBack(token);
347// tokenizer->readToken(&token);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000348 // TODO(edisonn): check token type! ignore/report errors.
edisonn@google.com571c70b2013-07-10 17:09:50 +0000349 int start = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000350 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000351 int end = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000352 for (int i = start; i <= end; i++) {
353 fCMapEncodingFlag[i] |= 1;
354 }
355 }
356 }
357
edisonn@google.com571c70b2013-07-10 17:09:50 +0000358 if (tokenIsKeyword(token, "beginbfchar")) {
359 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfchar")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000360// tokenizer->PutBack(token);
361// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000362 int from = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000363 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000364 int to = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000365
366 fCMapEncodingFlag[from] |= 2;
367 fCMapEncoding[from] = to;
368 }
369 }
370
edisonn@google.com571c70b2013-07-10 17:09:50 +0000371 if (tokenIsKeyword(token, "beginbfrange")) {
372 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfrange")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000373// tokenizer->PutBack(token);
374// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000375 int start = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000376 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000377 int end = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000378
379
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000380 tokenizer->readToken(&token); // [ or just an array directly?
381// tokenizer->PutBack(token);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000382
edisonn@google.com571c70b2013-07-10 17:09:50 +0000383 // TODO(edisonn): read spec: any string or only hex string?
384 if (token.fType == kObject_TokenType && token.fObject->isAnyString()) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000385// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000386 int value = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000387
388 for (int i = start; i <= end; i++) {
389 fCMapEncodingFlag[i] |= 2;
390 fCMapEncoding[i] = value;
391 value++;
392 // if i != end, verify last byte id not if, ignore/report error
393 }
394
395 // read one string
edisonn@google.com571c70b2013-07-10 17:09:50 +0000396 } else if (token.fType == kObject_TokenType && token.fObject->isArray()) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000397// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000398 for (unsigned int i = 0; i < token.fObject->size(); i++) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000399 fCMapEncodingFlag[start + i] |= 2;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000400 fCMapEncoding[start + i] = skstoi((*token.fObject)[i]);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000401 }
402 // read array
403 }
404
405 //fCMapEncodingFlag[from] = 1;
406 //fCMapEncoding[from] = to;
407 }
408 }
409 }
410 }
411}
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000412
413
edisonn@google.com571c70b2013-07-10 17:09:50 +0000414SkPdfType0Font::SkPdfType0Font(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict) {
415 fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str());
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000416 fEncoding = NULL;
417
418 if (dict->has_Encoding()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000419 if (dict->isEncodingAName(doc)) {
420 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(doc).c_str());
421 } else if (dict->isEncodingAStream(doc)) {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000422 //fEncoding = loadEncodingFromStream(dict->getEncodingAsStream());
423 } else {
424 // TODO(edisonn): error ... warning .. assert?
425 }
426 }
427
428 if (dict->has_ToUnicode()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000429 fToUnicode = new SkPdfToUnicode(doc, dict->ToUnicode(doc));
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000430 }
431}
432
433std::map<std::string, SkPdfEncoding*>& getStandardEncodings() {
434 static std::map<std::string, SkPdfEncoding*> encodings;
435 if (encodings.empty()) {
436 encodings["Identity-H"] = SkPdfIdentityHEncoding::instance();
437 }
438
439 return encodings;
440}
441
442
443SkPdfEncoding* SkPdfEncoding::fromName(const char* name) {
444 SkPdfEncoding* encoding = getStandardEncodings()[name];
445
446#ifdef PDF_TRACE
447 if (encoding == NULL) {
448 printf("Encoding not found: %s\n", name);
449 }
450#endif
451 return encoding;
452}