blob: e5c880d585ad0888fa1b7140c29e3ab9fd846f9f [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.com2ccc3af2013-07-23 17:43:18 +0000167 const unsigned char* uncompressedStream = NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000168 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.com2ccc3af2013-07-23 17:43:18 +0000172 !pdfStream->GetFilteredStreamRef(&uncompressedStream, &uncompressedStreamLength) ||
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);
edisonn@google.comb44334c2013-07-23 20:47:05 +0000200 if (!obj || !obj->isDictionary()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000201 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.com2ccc3af2013-07-23 17:43:18 +0000324 // Since font will be cached, the font has to sit in the per doc allocator, not to be
325 // freed after the page is done drawing.
326 SkPdfNativeTokenizer* tokenizer = fParsed->tokenizerOfStream(stream, parsed->allocator());
edisonn@google.com1be794f2013-06-21 21:43:09 +0000327 PdfToken token;
328
329 fCMapEncoding = new unsigned short[256 * 256];
330 fCMapEncodingFlag = new unsigned char[256 * 256];
331 for (int i = 0 ; i < 256 * 256; i++) {
332 fCMapEncoding[i] = i;
333 fCMapEncodingFlag[i] = 0;
334 }
335
336 // TODO(edisonn): deal with multibyte character, or longer strings.
337 // Ritght now we deal with up 2 characters, e.g. <0020> but not longer like <00660066006C>
338 //2 beginbfrange
339 //<0000> <005E> <0020>
340 //<005F> <0061> [<00660066> <00660069> <00660066006C>]
341
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000342 while (tokenizer->readToken(&token)) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000343
edisonn@google.com571c70b2013-07-10 17:09:50 +0000344 // 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*
345 if (tokenIsKeyword(token, "begincodespacerange")) {
346 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endcodespacerange")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000347// tokenizer->PutBack(token);
348// tokenizer->readToken(&token);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000349 // TODO(edisonn): check token type! ignore/report errors.
edisonn@google.com571c70b2013-07-10 17:09:50 +0000350 int start = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000351 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000352 int end = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000353 for (int i = start; i <= end; i++) {
354 fCMapEncodingFlag[i] |= 1;
355 }
356 }
357 }
358
edisonn@google.com571c70b2013-07-10 17:09:50 +0000359 if (tokenIsKeyword(token, "beginbfchar")) {
360 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfchar")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000361// tokenizer->PutBack(token);
362// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000363 int from = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000364 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000365 int to = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000366
367 fCMapEncodingFlag[from] |= 2;
368 fCMapEncoding[from] = to;
369 }
370 }
371
edisonn@google.com571c70b2013-07-10 17:09:50 +0000372 if (tokenIsKeyword(token, "beginbfrange")) {
373 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfrange")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000374// tokenizer->PutBack(token);
375// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000376 int start = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000377 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000378 int end = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000379
380
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000381 tokenizer->readToken(&token); // [ or just an array directly?
382// tokenizer->PutBack(token);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000383
edisonn@google.com571c70b2013-07-10 17:09:50 +0000384 // TODO(edisonn): read spec: any string or only hex string?
385 if (token.fType == kObject_TokenType && token.fObject->isAnyString()) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000386// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000387 int value = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000388
389 for (int i = start; i <= end; i++) {
390 fCMapEncodingFlag[i] |= 2;
391 fCMapEncoding[i] = value;
392 value++;
393 // if i != end, verify last byte id not if, ignore/report error
394 }
395
396 // read one string
edisonn@google.com571c70b2013-07-10 17:09:50 +0000397 } else if (token.fType == kObject_TokenType && token.fObject->isArray()) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000398// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000399 for (unsigned int i = 0; i < token.fObject->size(); i++) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000400 fCMapEncodingFlag[start + i] |= 2;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000401 fCMapEncoding[start + i] = skstoi((*token.fObject)[i]);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000402 }
403 // read array
404 }
405
406 //fCMapEncodingFlag[from] = 1;
407 //fCMapEncoding[from] = to;
408 }
409 }
410 }
411 }
412}
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000413
414
edisonn@google.com571c70b2013-07-10 17:09:50 +0000415SkPdfType0Font::SkPdfType0Font(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict) {
416 fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str());
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000417 fEncoding = NULL;
418
419 if (dict->has_Encoding()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000420 if (dict->isEncodingAName(doc)) {
421 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(doc).c_str());
422 } else if (dict->isEncodingAStream(doc)) {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000423 //fEncoding = loadEncodingFromStream(dict->getEncodingAsStream());
424 } else {
425 // TODO(edisonn): error ... warning .. assert?
426 }
427 }
428
429 if (dict->has_ToUnicode()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000430 fToUnicode = new SkPdfToUnicode(doc, dict->ToUnicode(doc));
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000431 }
432}
433
434std::map<std::string, SkPdfEncoding*>& getStandardEncodings() {
435 static std::map<std::string, SkPdfEncoding*> encodings;
436 if (encodings.empty()) {
437 encodings["Identity-H"] = SkPdfIdentityHEncoding::instance();
438 }
439
440 return encodings;
441}
442
443
444SkPdfEncoding* SkPdfEncoding::fromName(const char* name) {
445 SkPdfEncoding* encoding = getStandardEncodings()[name];
446
447#ifdef PDF_TRACE
448 if (encoding == NULL) {
449 printf("Encoding not found: %s\n", name);
450 }
451#endif
452 return encoding;
453}