blob: 5d8cfe6d9ab7e711b75c766a7c9081e5666d5056 [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.comb0145ce2013-08-05 16:23:23 +0000258 if (!dict->hasData(SkPdfObject::kFont_Data)) {
259 dict->setData(fontFromPdfDictionaryOnce(doc, dict), SkPdfObject::kFont_Data);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000260 }
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000261 return (SkPdfFont*)dict->data(SkPdfObject::kFont_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.come878e722013-07-29 19:10:58 +0000311 for (unsigned int i = 0 ; i < str->lenstr(); 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 }
edisonn@google.com1acab362013-07-25 22:03:22 +0000314 // TODO(edisonn): character larger than 0x0000ffff not supported right now.
315 return ret & 0x0000ffff;
edisonn@google.com1be794f2013-06-21 21:43:09 +0000316}
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.com2ccc3af2013-07-23 17:43:18 +0000325 // Since font will be cached, the font has to sit in the per doc allocator, not to be
326 // freed after the page is done drawing.
327 SkPdfNativeTokenizer* tokenizer = fParsed->tokenizerOfStream(stream, parsed->allocator());
edisonn@google.com1be794f2013-06-21 21:43:09 +0000328 PdfToken token;
329
330 fCMapEncoding = new unsigned short[256 * 256];
331 fCMapEncodingFlag = new unsigned char[256 * 256];
332 for (int i = 0 ; i < 256 * 256; i++) {
333 fCMapEncoding[i] = i;
334 fCMapEncodingFlag[i] = 0;
335 }
336
337 // TODO(edisonn): deal with multibyte character, or longer strings.
338 // Ritght now we deal with up 2 characters, e.g. <0020> but not longer like <00660066006C>
339 //2 beginbfrange
340 //<0000> <005E> <0020>
341 //<005F> <0061> [<00660066> <00660069> <00660066006C>]
342
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000343 while (tokenizer->readToken(&token)) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000344
edisonn@google.com571c70b2013-07-10 17:09:50 +0000345 // 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*
346 if (tokenIsKeyword(token, "begincodespacerange")) {
347 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endcodespacerange")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000348// tokenizer->PutBack(token);
349// tokenizer->readToken(&token);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000350 // TODO(edisonn): check token type! ignore/report errors.
edisonn@google.com571c70b2013-07-10 17:09:50 +0000351 int start = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000352 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000353 int end = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000354 for (int i = start; i <= end; i++) {
355 fCMapEncodingFlag[i] |= 1;
356 }
357 }
358 }
359
edisonn@google.com571c70b2013-07-10 17:09:50 +0000360 if (tokenIsKeyword(token, "beginbfchar")) {
361 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfchar")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000362// tokenizer->PutBack(token);
363// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000364 int from = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000365 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000366 int to = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000367
368 fCMapEncodingFlag[from] |= 2;
369 fCMapEncoding[from] = to;
370 }
371 }
372
edisonn@google.com571c70b2013-07-10 17:09:50 +0000373 if (tokenIsKeyword(token, "beginbfrange")) {
374 while (tokenizer->readToken(&token) && !tokenIsKeyword(token, "endbfrange")) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000375// tokenizer->PutBack(token);
376// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000377 int start = skstoi(token.fObject);
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000378 tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000379 int end = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000380
381
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000382 tokenizer->readToken(&token); // [ or just an array directly?
383// tokenizer->PutBack(token);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000384
edisonn@google.com571c70b2013-07-10 17:09:50 +0000385 // TODO(edisonn): read spec: any string or only hex string?
386 if (token.fType == kObject_TokenType && token.fObject->isAnyString()) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000387// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000388 int value = skstoi(token.fObject);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000389
390 for (int i = start; i <= end; i++) {
391 fCMapEncodingFlag[i] |= 2;
392 fCMapEncoding[i] = value;
393 value++;
394 // if i != end, verify last byte id not if, ignore/report error
395 }
396
397 // read one string
edisonn@google.com571c70b2013-07-10 17:09:50 +0000398 } else if (token.fType == kObject_TokenType && token.fObject->isArray()) {
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000399// tokenizer->readToken(&token);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000400 for (unsigned int i = 0; i < token.fObject->size(); i++) {
edisonn@google.com1be794f2013-06-21 21:43:09 +0000401 fCMapEncodingFlag[start + i] |= 2;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000402 fCMapEncoding[start + i] = skstoi((*token.fObject)[i]);
edisonn@google.com1be794f2013-06-21 21:43:09 +0000403 }
404 // read array
405 }
406
407 //fCMapEncodingFlag[from] = 1;
408 //fCMapEncoding[from] = to;
409 }
410 }
411 }
412 }
413}
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000414
415
edisonn@google.com571c70b2013-07-10 17:09:50 +0000416SkPdfType0Font::SkPdfType0Font(SkNativeParsedPDF* doc, SkPdfType0FontDictionary* dict) {
417 fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str());
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000418 fEncoding = NULL;
419
420 if (dict->has_Encoding()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000421 if (dict->isEncodingAName(doc)) {
422 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(doc).c_str());
423 } else if (dict->isEncodingAStream(doc)) {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000424 //fEncoding = loadEncodingFromStream(dict->getEncodingAsStream());
425 } else {
426 // TODO(edisonn): error ... warning .. assert?
427 }
428 }
429
430 if (dict->has_ToUnicode()) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000431 fToUnicode = new SkPdfToUnicode(doc, dict->ToUnicode(doc));
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000432 }
433}
434
435std::map<std::string, SkPdfEncoding*>& getStandardEncodings() {
436 static std::map<std::string, SkPdfEncoding*> encodings;
437 if (encodings.empty()) {
438 encodings["Identity-H"] = SkPdfIdentityHEncoding::instance();
439 }
440
441 return encodings;
442}
443
444
445SkPdfEncoding* SkPdfEncoding::fromName(const char* name) {
446 SkPdfEncoding* encoding = getStandardEncodings()[name];
447
448#ifdef PDF_TRACE
449 if (encoding == NULL) {
450 printf("Encoding not found: %s\n", name);
451 }
452#endif
453 return encoding;
454}