blob: 2574ce4165acdea9114dece8f2f49d9842170247 [file] [log] [blame]
edisonn@google.com1be794f2013-06-21 21:43:09 +00001#include "SkPdfFont.h"
2
edisonn@google.comeee4b652013-06-27 13:22:42 +00003#include "SkStream.h"
4#include "SkTypeface.h"
edisonn@google.com571c70b2013-07-10 17:09:50 +00005#include "SkPdfNativeTokenizer.h"
edisonn@google.comeee4b652013-06-27 13:22:42 +00006
edisonn@google.com1be794f2013-06-21 21:43:09 +00007std::map<std::string, SkPdfStandardFontEntry>& getStandardFonts() {
8 static std::map<std::string, SkPdfStandardFontEntry> gPdfStandardFonts;
9
10 // TODO (edisonn): , vs - ? what does it mean?
11 // TODO (edisonn): MT, PS, Oblique=italic?, ... what does it mean?
12 if (gPdfStandardFonts.empty()) {
edisonn@google.com596d2e22013-07-10 17:44:55 +000013 gPdfStandardFonts["Arial"] = SkPdfStandardFontEntry("Arial", false, false);
14 gPdfStandardFonts["Arial,Bold"] = SkPdfStandardFontEntry("Arial", true, false);
15 gPdfStandardFonts["Arial,BoldItalic"] = SkPdfStandardFontEntry("Arial", true, true);
16 gPdfStandardFonts["Arial,Italic"] = SkPdfStandardFontEntry("Arial", false, true);
17 gPdfStandardFonts["Arial-Bold"] = SkPdfStandardFontEntry("Arial", true, false);
18 gPdfStandardFonts["Arial-BoldItalic"] = SkPdfStandardFontEntry("Arial", true, true);
19 gPdfStandardFonts["Arial-BoldItalicMT"] = SkPdfStandardFontEntry("Arial", true, true);
20 gPdfStandardFonts["Arial-BoldMT"] = SkPdfStandardFontEntry("Arial", true, false);
21 gPdfStandardFonts["Arial-Italic"] = SkPdfStandardFontEntry("Arial", false, true);
22 gPdfStandardFonts["Arial-ItalicMT"] = SkPdfStandardFontEntry("Arial", false, true);
23 gPdfStandardFonts["ArialMT"] = SkPdfStandardFontEntry("Arial", false, false);
24 gPdfStandardFonts["Courier"] = SkPdfStandardFontEntry("Courier New", false, false);
25 gPdfStandardFonts["Courier,Bold"] = SkPdfStandardFontEntry("Courier New", true, false);
26 gPdfStandardFonts["Courier,BoldItalic"] = SkPdfStandardFontEntry("Courier New", true, true);
27 gPdfStandardFonts["Courier,Italic"] = SkPdfStandardFontEntry("Courier New", false, true);
28 gPdfStandardFonts["Courier-Bold"] = SkPdfStandardFontEntry("Courier New", true, false);
29 gPdfStandardFonts["Courier-BoldOblique"] = SkPdfStandardFontEntry("Courier New", true, true);
30 gPdfStandardFonts["Courier-Oblique"] = SkPdfStandardFontEntry("Courier New", false, true);
31 gPdfStandardFonts["CourierNew"] = SkPdfStandardFontEntry("Courier New", false, false);
32 gPdfStandardFonts["CourierNew,Bold"] = SkPdfStandardFontEntry("Courier New", true, false);
33 gPdfStandardFonts["CourierNew,BoldItalic"] = SkPdfStandardFontEntry("Courier New", true, true);
34 gPdfStandardFonts["CourierNew,Italic"] = SkPdfStandardFontEntry("Courier New", false, true);
35 gPdfStandardFonts["CourierNew-Bold"] = SkPdfStandardFontEntry("Courier New", true, false);
36 gPdfStandardFonts["CourierNew-BoldItalic"] = SkPdfStandardFontEntry("Courier New", true, true);
37 gPdfStandardFonts["CourierNew-Italic"] = SkPdfStandardFontEntry("Courier New", false, true);
38 gPdfStandardFonts["CourierNewPS-BoldItalicMT"] = SkPdfStandardFontEntry("Courier New", true, true);
39 gPdfStandardFonts["CourierNewPS-BoldMT"] = SkPdfStandardFontEntry("Courier New", true, false);
40 gPdfStandardFonts["CourierNewPS-ItalicMT"] = SkPdfStandardFontEntry("Courier New", false, true);
41 gPdfStandardFonts["CourierNewPSMT"] = SkPdfStandardFontEntry("Courier New", false, false);
42 gPdfStandardFonts["Helvetica"] = SkPdfStandardFontEntry("Helvetica", false, false);
43 gPdfStandardFonts["Helvetica,Bold"] = SkPdfStandardFontEntry("Helvetica", true, false);
44 gPdfStandardFonts["Helvetica,BoldItalic"] = SkPdfStandardFontEntry("Helvetica", true, true);
45 gPdfStandardFonts["Helvetica,Italic"] = SkPdfStandardFontEntry("Helvetica", false, true);
46 gPdfStandardFonts["Helvetica-Bold"] = SkPdfStandardFontEntry("Helvetica", true, false);
47 gPdfStandardFonts["Helvetica-BoldItalic"] = SkPdfStandardFontEntry("Helvetica", true, true);
48 gPdfStandardFonts["Helvetica-BoldOblique"] = SkPdfStandardFontEntry("Helvetica", true, true);
49 gPdfStandardFonts["Helvetica-Italic"] = SkPdfStandardFontEntry("Helvetica", false, true);
50 gPdfStandardFonts["Helvetica-Oblique"] = SkPdfStandardFontEntry("Helvetica", false, true);
51 gPdfStandardFonts["Times-Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false);
52 gPdfStandardFonts["Times-BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true);
53 gPdfStandardFonts["Times-Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true);
54 gPdfStandardFonts["Times-Roman"] = SkPdfStandardFontEntry("Times New Roman", false, false);
55 gPdfStandardFonts["TimesNewRoman"] = SkPdfStandardFontEntry("Times New Roman", false, false);
56 gPdfStandardFonts["TimesNewRoman,Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false);
57 gPdfStandardFonts["TimesNewRoman,BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true);
58 gPdfStandardFonts["TimesNewRoman,Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true);
59 gPdfStandardFonts["TimesNewRoman-Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false);
60 gPdfStandardFonts["TimesNewRoman-BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true);
61 gPdfStandardFonts["TimesNewRoman-Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true);
62 gPdfStandardFonts["TimesNewRomanPS"] = SkPdfStandardFontEntry("Times New Roman", false, false);
63 gPdfStandardFonts["TimesNewRomanPS-Bold"] = SkPdfStandardFontEntry("Times New Roman", true, false);
64 gPdfStandardFonts["TimesNewRomanPS-BoldItalic"] = SkPdfStandardFontEntry("Times New Roman", true, true);
65 gPdfStandardFonts["TimesNewRomanPS-BoldItalicMT"] = SkPdfStandardFontEntry("Times New Roman", true, true);
66 gPdfStandardFonts["TimesNewRomanPS-BoldMT"] = SkPdfStandardFontEntry("Times New Roman", true, false);
67 gPdfStandardFonts["TimesNewRomanPS-Italic"] = SkPdfStandardFontEntry("Times New Roman", false, true);
68 gPdfStandardFonts["TimesNewRomanPS-ItalicMT"] = SkPdfStandardFontEntry("Times New Roman", false, true);
69 gPdfStandardFonts["TimesNewRomanPSMT"] = SkPdfStandardFontEntry("Times New Roman", false, false);
70 gPdfStandardFonts["Symbol"] = SkPdfStandardFontEntry("Symbol", false, false);
71 gPdfStandardFonts["ZapfDingbats"] = SkPdfStandardFontEntry("ZapfDingbats", false, false);
edisonn@google.com1be794f2013-06-21 21:43:09 +000072
73 // TODO(edisonn): these are hacks. Load Post Script font name.
74 // see FT_Get_Postscript_Name
75 // Font config is not using it, yet.
76 //https://bugs.freedesktop.org/show_bug.cgi?id=18095
edisonn@google.comb857a0c2013-06-25 20:45:40 +000077
edisonn@google.com596d2e22013-07-10 17:44:55 +000078 gPdfStandardFonts["Arial-Black"] = SkPdfStandardFontEntry("Arial", true, false);
79 gPdfStandardFonts["DejaVuSans"] = SkPdfStandardFontEntry("DejaVu Sans", false, false);
80 gPdfStandardFonts["DejaVuSansMono"] = SkPdfStandardFontEntry("DejaVuSans Mono", false, false);
81 gPdfStandardFonts["DejaVuSansMono-Bold"] = SkPdfStandardFontEntry("DejaVuSans Mono", true, false);
82 gPdfStandardFonts["DejaVuSansMono-Oblique"] = SkPdfStandardFontEntry("DejaVuSans Mono", false, true);
83 gPdfStandardFonts["Georgia-Bold"] = SkPdfStandardFontEntry("Georgia", true, false);
84 gPdfStandardFonts["Georgia-BoldItalic"] = SkPdfStandardFontEntry("Georgia", true, true);
85 gPdfStandardFonts["Georgia-Italic"] = SkPdfStandardFontEntry("Georgia", false, true);
86 gPdfStandardFonts["TrebuchetMS"] = SkPdfStandardFontEntry("Trebuchet MS", false, false);
87 gPdfStandardFonts["TrebuchetMS-Bold"] = SkPdfStandardFontEntry("Trebuchet MS", true, false);
88 gPdfStandardFonts["Verdana-Bold"] = SkPdfStandardFontEntry("Verdana", true, false);
89 gPdfStandardFonts["WenQuanYiMicroHei"] = SkPdfStandardFontEntry("WenQuanYi Micro Hei", false, false);
edisonn@google.comb857a0c2013-06-25 20:45:40 +000090
91 // TODO(edisonn): list all phonts available, builf post script name as in pdf spec
92 /*
93 * The PostScript name for the value of BaseFontis determined in one of two ways:
94• Use the PostScript name that is an optional entry in the “name” table of the
95TrueType font itself.
96• In the absence of such an entry in the “name” table, derive a PostScript name
97from the name by which the font is known in the host operating system: on a
98Windows system, it is based on the lfFaceName field in a LOGFONT structure; in
99the Mac OS, it is based on the name of the FONDresource. If the name contains
100any spaces, the spaces are removed.
101If the font in a source document uses a bold or italic style, but there is no font
102data for that style, the host operating system will synthesize the style. In this case,
103a comma and the style name (one of Bold, Italic, or BoldItalic) are appended to the
104font name. For example, for a TrueType font that is a bold variant of the New
105 */
106
107 /*
108 * If the value of Subtype is MMType1.
109• If the PostScript name of the instance contains spaces, the spaces are replaced
110by underscores in the value of BaseFont. For instance, as illustrated in Example
1115.7, the name “MinionMM 366 465 11 ” (which ends with a space character)
112becomes /MinionMM_366_465_11_.
113 */
114
115 // might not work on all oses ?
116 //
117
edisonn@google.com1be794f2013-06-21 21:43:09 +0000118 }
119
120 return gPdfStandardFonts;
121}
122
123SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool italic) {
124 std::map<std::string, SkPdfStandardFontEntry>& standardFontMap = getStandardFonts();
125
126 SkTypeface* typeface = NULL;
127 if (standardFontMap.find(fontName) != standardFontMap.end()) {
128 SkPdfStandardFontEntry fontData = standardFontMap[fontName];
129
130 // TODO(edisonn): How does the bold/italic specified in standard definition combines with
131 // the one in /font key? use OR for now.
132 bold = bold || fontData.fIsBold;
133 italic = italic || fontData.fIsItalic;
134
135 typeface = SkTypeface::CreateFromName(
136 fontData.fName,
137 SkTypeface::Style((bold ? SkTypeface::kBold : 0) |
138 (italic ? SkTypeface::kItalic : 0)));
139 } else {
140 typeface = SkTypeface::CreateFromName(
141 fontName,
142 SkTypeface::kNormal);
143 }
144
145 if (typeface) {
146 typeface->ref();
147 }
148 return typeface;
149}
150
edisonn@google.com571c70b2013-07-10 17:09:50 +0000151SkPdfFont* SkPdfFont::fontFromFontDescriptor(SkNativeParsedPDF* doc, SkPdfFontDescriptorDictionary* fd, bool loadFromName) {
152 // TODO(edisonn): partial implementation ... also const handling ...
edisonn@google.comeee4b652013-06-27 13:22:42 +0000153 // Only one, at most be available
edisonn@google.com6e49c342013-06-27 20:03:43 +0000154 SkPdfStream* pdfStream = NULL;
edisonn@google.comeee4b652013-06-27 13:22:42 +0000155 if (fd->has_FontFile()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000156 pdfStream = fd->FontFile(doc);
edisonn@google.comeee4b652013-06-27 13:22:42 +0000157 } else if (fd->has_FontFile2()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000158 pdfStream = fd->FontFile2(doc);
edisonn@google.comeee4b652013-06-27 13:22:42 +0000159 } if (fd->has_FontFile3()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000160 pdfStream = fd->FontFile3(doc);
edisonn@google.comeee4b652013-06-27 13:22:42 +0000161 } else {
edisonn@google.com6e49c342013-06-27 20:03:43 +0000162 if (loadFromName) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000163 return fontFromName(doc, fd, fd->FontName(doc).c_str());
edisonn@google.com6e49c342013-06-27 20:03:43 +0000164 }
edisonn@google.comeee4b652013-06-27 13:22:42 +0000165 }
166
edisonn@google.com571c70b2013-07-10 17:09:50 +0000167 unsigned char* uncompressedStream = NULL;
168 size_t uncompressedStreamLength = 0;
edisonn@google.com6e49c342013-06-27 20:03:43 +0000169
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000170 // TODO(edisonn): report warning to be used in testing.
171 if (!pdfStream ||
edisonn@google.com571c70b2013-07-10 17:09:50 +0000172 !pdfStream->GetFilteredStreamRef(&uncompressedStream, &uncompressedStreamLength, doc->allocator()) ||
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000173 !uncompressedStream ||
174 !uncompressedStreamLength) {
edisonn@google.com6e49c342013-06-27 20:03:43 +0000175 return NULL;
176 }
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000177
edisonn@google.com6e49c342013-06-27 20:03:43 +0000178 SkMemoryStream* skStream = new SkMemoryStream(uncompressedStream, uncompressedStreamLength);
179 SkTypeface* face = SkTypeface::CreateFromStream(skStream);
180
181 if (face == NULL) {
182 // TODO(edisonn): report warning to be used in testing.
183 return NULL;
184 }
185
186 face->ref();
187
188 return new SkPdfStandardFont(face);
edisonn@google.comeee4b652013-06-27 13:22:42 +0000189}
190
edisonn@google.com571c70b2013-07-10 17:09:50 +0000191SkPdfFont* fontFromName(SkNativeParsedPDF* doc, SkPdfObject* obj, const char* fontName) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000192 SkTypeface* typeface = SkTypefaceFromPdfStandardFont(fontName, false, false);
193 if (typeface != NULL) {
194 return new SkPdfStandardFont(typeface);
195 }
edisonn@google.comeee4b652013-06-27 13:22:42 +0000196
197 // TODO(edisonn): perf - make a map
edisonn@google.com571c70b2013-07-10 17:09:50 +0000198 for (unsigned int i = 0 ; i < doc->objects(); i++) {
199 SkPdfObject* obj = doc->object(i);
200 if (!obj->isDictionary()) {
201 continue;
202 }
edisonn@google.comab03e682013-06-28 18:51:20 +0000203
edisonn@google.com571c70b2013-07-10 17:09:50 +0000204 SkPdfFontDescriptorDictionary* fd = obj->asDictionary()->asFontDescriptorDictionary();
205
206 if (!fd->valid()) {
207 continue;
208 }
209
210 if (fd->has_FontName() && fd->FontName(doc) == fontName) {
211 SkPdfFont* font = SkPdfFont::fontFromFontDescriptor(doc, fd, false);
212 if (font) {
213 return font;
214 } else {
215 // failed to load font descriptor
216 break;
edisonn@google.comeee4b652013-06-27 13:22:42 +0000217 }
218 }
219 }
220
221 // TODO(edisonn): warning/report issue
edisonn@google.com1be794f2013-06-21 21:43:09 +0000222 return SkPdfFont::Default();
223}
224
edisonn@google.com571c70b2013-07-10 17:09:50 +0000225SkPdfFont* SkPdfFont::fontFromPdfDictionaryOnce(SkNativeParsedPDF* doc, SkPdfFontDictionary* dict) {
226 // TODO(edisonn): keep the type in a smart way in the SkPdfObject
227 // 1) flag, isResolved (1bit): reset at reset, add/remove/update (array) and set(dict)
228 // in a tree like structure, 3-4 bits for all the datatypes inheriting from obj (int, real, ...)
229 // if is a dict, reserveve a few bytes to encode type of dict, and so on like in a tree
230 // issue: type can be determined from context! atribute night be missing/wrong
231 switch (doc->mapper()->mapFontDictionary(dict)) {
232 case kType0FontDictionary_SkPdfObjectType:
233 return fontFromType0FontDictionary(doc, dict->asType0FontDictionary());
234
235 case kTrueTypeFontDictionary_SkPdfObjectType:
236 return fontFromTrueTypeFontDictionary(doc, dict->asTrueTypeFontDictionary());
237
238 case kType1FontDictionary_SkPdfObjectType:
239 return fontFromType1FontDictionary(doc, dict->asType1FontDictionary());
240
241 case kMultiMasterFontDictionary_SkPdfObjectType:
242 return fontFromMultiMasterFontDictionary(doc, dict->asMultiMasterFontDictionary());
243
244 case kType3FontDictionary_SkPdfObjectType:
245 return fontFromType3FontDictionary(doc, dict->asType3FontDictionary());
246
247 default:
248 // TODO(edisonn): report error?
249 return NULL;
250 }
251}
252
253SkPdfFont* SkPdfFont::fontFromPdfDictionary(SkNativeParsedPDF* doc, SkPdfFontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000254 if (dict == NULL) {
255 return NULL; // TODO(edisonn): report default one?
256 }
257
edisonn@google.com571c70b2013-07-10 17:09:50 +0000258 if (dict->data() == NULL) {
259 dict->setData(fontFromPdfDictionaryOnce(doc, dict));
edisonn@google.com1be794f2013-06-21 21:43:09 +0000260 }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000261 return (SkPdfFont*)dict->data();
edisonn@google.com1be794f2013-06-21 21:43:09 +0000262}
263
edisonn@google.com571c70b2013-07-10 17:09:50 +0000264
265
266SkPdfType0Font* SkPdfFont::fontFromType0FontDictionary(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000267 if (dict == NULL) {
268 return NULL; // default one?
269 }
270
edisonn@google.com571c70b2013-07-10 17:09:50 +0000271 return new SkPdfType0Font(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000272}
273
edisonn@google.com571c70b2013-07-10 17:09:50 +0000274SkPdfType1Font* SkPdfFont:: fontFromType1FontDictionary(SkNativeParsedPDF* doc, SkPdfType1FontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000275 if (dict == NULL) {
276 return NULL; // default one?
277 }
278
edisonn@google.com571c70b2013-07-10 17:09:50 +0000279 return new SkPdfType1Font(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000280}
281
edisonn@google.com571c70b2013-07-10 17:09:50 +0000282SkPdfType3Font* SkPdfFont::fontFromType3FontDictionary(SkNativeParsedPDF* doc, SkPdfType3FontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000283 if (dict == NULL) {
284 return NULL; // default one?
285 }
286
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000287
288
edisonn@google.com571c70b2013-07-10 17:09:50 +0000289 return new SkPdfType3Font(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000290}
291
edisonn@google.com571c70b2013-07-10 17:09:50 +0000292SkPdfTrueTypeFont* SkPdfFont::fontFromTrueTypeFontDictionary(SkNativeParsedPDF* doc, SkPdfTrueTypeFontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000293 if (dict == NULL) {
294 return NULL; // default one?
295 }
296
edisonn@google.com571c70b2013-07-10 17:09:50 +0000297 return new SkPdfTrueTypeFont(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000298}
299
edisonn@google.com571c70b2013-07-10 17:09:50 +0000300SkPdfMultiMasterFont* SkPdfFont::fontFromMultiMasterFontDictionary(SkNativeParsedPDF* doc, SkPdfMultiMasterFontDictionary* dict) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000301 if (dict == NULL) {
302 return NULL; // default one?
303 }
304
edisonn@google.com571c70b2013-07-10 17:09:50 +0000305 return new SkPdfMultiMasterFont(doc, dict);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000306}
307
edisonn@google.com571c70b2013-07-10 17:09:50 +0000308static int skstoi(const SkPdfObject* str) {
309 // TODO(edisonn): report err of it is not a (hex) string
edisonn@google.com1be794f2013-06-21 21:43:09 +0000310 int ret = 0;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000311 for (unsigned int i = 0 ; i < str->len(); i++) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000312 ret = (ret << 8) + ((unsigned char*)str->c_str())[i];
edisonn@google.com1be794f2013-06-21 21:43:09 +0000313 }
314 return ret;
315}
316
edisonn@google.com571c70b2013-07-10 17:09:50 +0000317#define tokenIsKeyword(token,keyword) (token.fType == kKeyword_TokenType && token.fKeywordLength==sizeof(keyword)-1 && strncmp(token.fKeyword, keyword, sizeof(keyword)-1) == 0)
318
319SkPdfToUnicode::SkPdfToUnicode(SkNativeParsedPDF* parsed, SkPdfStream* stream) : fParsed(parsed) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000320 fCMapEncoding = NULL;
321 fCMapEncodingFlag = NULL;
322
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000323 if (stream) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000324 SkPdfNativeTokenizer* tokenizer = fParsed->tokenizerOfStream(stream);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000325 PdfToken token;
326
327 fCMapEncoding = new unsigned short[256 * 256];
328 fCMapEncodingFlag = new unsigned char[256 * 256];
329 for (int i = 0 ; i < 256 * 256; i++) {
330 fCMapEncoding[i] = i;
331 fCMapEncodingFlag[i] = 0;
332 }
333
334 // TODO(edisonn): deal with multibyte character, or longer strings.
335 // Ritght now we deal with up 2 characters, e.g. <0020> but not longer like <00660066006C>
336 //2 beginbfrange
337 //<0000> <005E> <0020>
338 //<005F> <0061> [<00660066> <00660069> <00660066006C>]
339
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000340 while (tokenizer->readToken(&token)) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000341
edisonn@google.com571c70b2013-07-10 17:09:50 +0000342 // 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*
343 if (tokenIsKeyword(token, "begincodespacerange")) {
344 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endcodespacerange")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000345// tokenizer->PutBack(token);
346// tokenizer->readToken(&token);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000347 // TODO(edisonn): check token type! ignore/report errors.
edisonn@google.com571c70b2013-07-10 17:09:50 +0000348 int start = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000349 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000350 int end = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000351 for (int i = start; i <= end; i++) {
352 fCMapEncodingFlag[i] |= 1;
353 }
354 }
355 }
356
edisonn@google.com571c70b2013-07-10 17:09:50 +0000357 if (tokenIsKeyword(token, "beginbfchar")) {
358 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfchar")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000359// tokenizer->PutBack(token);
360// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000361 int from = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000362 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000363 int to = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000364
365 fCMapEncodingFlag[from] |= 2;
366 fCMapEncoding[from] = to;
367 }
368 }
369
edisonn@google.com571c70b2013-07-10 17:09:50 +0000370 if (tokenIsKeyword(token, "beginbfrange")) {
371 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfrange")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000372// tokenizer->PutBack(token);
373// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000374 int start = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000375 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000376 int end = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000377
378
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000379 tokenizer->readToken(&token); // [ or just an array directly?
380// tokenizer->PutBack(token);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000381
edisonn@google.com571c70b2013-07-10 17:09:50 +0000382 // TODO(edisonn): read spec: any string or only hex string?
383 if (token.fType == kObject_TokenType && token.fObject->isAnyString()) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000384// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000385 int value = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000386
387 for (int i = start; i <= end; i++) {
388 fCMapEncodingFlag[i] |= 2;
389 fCMapEncoding[i] = value;
390 value++;
391 // if i != end, verify last byte id not if, ignore/report error
392 }
393
394 // read one string
edisonn@google.com571c70b2013-07-10 17:09:50 +0000395 } else if (token.fType == kObject_TokenType && token.fObject->isArray()) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000396// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000397 for (unsigned int i = 0; i < token.fObject->size(); i++) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000398 fCMapEncodingFlag[start + i] |= 2;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000399 fCMapEncoding[start + i] = skstoi((*token.fObject)[i]);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000400 }
401 // read array
402 }
403
404 //fCMapEncodingFlag[from] = 1;
405 //fCMapEncoding[from] = to;
406 }
407 }
408 }
409 }
410}
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000411
412
edisonn@google.com571c70b2013-07-10 17:09:50 +0000413SkPdfType0Font::SkPdfType0Font(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict) {
414 fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str());
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000415 fEncoding = NULL;
416
417 if (dict->has_Encoding()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000418 if (dict->isEncodingAName(doc)) {
419 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(doc).c_str());
420 } else if (dict->isEncodingAStream(doc)) {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000421 //fEncoding = loadEncodingFromStream(dict->getEncodingAsStream());
422 } else {
423 // TODO(edisonn): error ... warning .. assert?
424 }
425 }
426
427 if (dict->has_ToUnicode()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000428 fToUnicode = new SkPdfToUnicode(doc, dict->ToUnicode(doc));
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000429 }
430}
431
432std::map<std::string, SkPdfEncoding*>& getStandardEncodings() {
433 static std::map<std::string, SkPdfEncoding*> encodings;
434 if (encodings.empty()) {
435 encodings["Identity-H"] = SkPdfIdentityHEncoding::instance();
436 }
437
438 return encodings;
439}
440
441
442SkPdfEncoding* SkPdfEncoding::fromName(const char* name) {
443 SkPdfEncoding* encoding = getStandardEncodings()[name];
444
445#ifdef PDF_TRACE
446 if (encoding == NULL) {
447 printf("Encoding not found: %s\n", name);
448 }
449#endif
450 return encoding;
451}