OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2013 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "SkPdfFont.h" | |
9 | |
10 #include "SkPdfNativeTokenizer.h" | |
11 #include "SkStream.h" | |
12 #include "SkTypeface.h" | |
13 | |
14 SkTDict<SkPdfStandardFontEntry>& getStandardFonts() { | |
15 static SkTDict<SkPdfStandardFontEntry> gPdfStandardFonts(100); | |
16 | |
17 // TODO (edisonn): , vs - ? what does it mean? | |
18 // TODO (edisonn): MT, PS, Oblique=italic?, ... what does it mean? | |
19 if (gPdfStandardFonts.count() == 0) { | |
20 gPdfStandardFonts.set("Arial", SkPdfStandardFontEntry("Arial", false, fa
lse)); | |
21 gPdfStandardFonts.set("Arial,Bold", SkPdfStandardFontEntry("Arial", true
, false)); | |
22 gPdfStandardFonts.set("Arial,BoldItalic", SkPdfStandardFontEntry("Arial"
, true, true)); | |
23 gPdfStandardFonts.set("Arial,Italic", SkPdfStandardFontEntry("Arial", fa
lse, true)); | |
24 gPdfStandardFonts.set("Arial-Bold", SkPdfStandardFontEntry("Arial", true
, false)); | |
25 gPdfStandardFonts.set("Arial-BoldItalic", SkPdfStandardFontEntry("Arial"
, true, true)); | |
26 gPdfStandardFonts.set("Arial-BoldItalicMT", SkPdfStandardFontEntry("Aria
l", true, true)); | |
27 gPdfStandardFonts.set("Arial-BoldMT", SkPdfStandardFontEntry("Arial", tr
ue, false)); | |
28 gPdfStandardFonts.set("Arial-Italic", SkPdfStandardFontEntry("Arial", fa
lse, true)); | |
29 gPdfStandardFonts.set("Arial-ItalicMT", SkPdfStandardFontEntry("Arial",
false, true)); | |
30 gPdfStandardFonts.set("ArialMT", SkPdfStandardFontEntry("Arial", false,
false)); | |
31 gPdfStandardFonts.set("Courier", SkPdfStandardFontEntry("Courier New", f
alse, false)); | |
32 gPdfStandardFonts.set("Courier,Bold", SkPdfStandardFontEntry("Courier Ne
w", true, false)); | |
33 gPdfStandardFonts.set("Courier,BoldItalic", SkPdfStandardFontEntry("Cour
ier New", true, true)); | |
34 gPdfStandardFonts.set("Courier,Italic", SkPdfStandardFontEntry("Courier
New", false, true)); | |
35 gPdfStandardFonts.set("Courier-Bold", SkPdfStandardFontEntry("Courier Ne
w", true, false)); | |
36 gPdfStandardFonts.set("Courier-BoldOblique", SkPdfStandardFontEntry("Cou
rier New", true, true)); | |
37 gPdfStandardFonts.set("Courier-Oblique", SkPdfStandardFontEntry("Courier
New", false, true)); | |
38 gPdfStandardFonts.set("CourierNew", SkPdfStandardFontEntry("Courier New"
, false, false)); | |
39 gPdfStandardFonts.set("CourierNew,Bold", SkPdfStandardFontEntry("Courier
New", true, false)); | |
40 gPdfStandardFonts.set("CourierNew,BoldItalic", SkPdfStandardFontEntry("C
ourier New", true, true)); | |
41 gPdfStandardFonts.set("CourierNew,Italic", SkPdfStandardFontEntry("Couri
er New", false, true)); | |
42 gPdfStandardFonts.set("CourierNew-Bold", SkPdfStandardFontEntry("Courier
New", true, false)); | |
43 gPdfStandardFonts.set("CourierNew-BoldItalic", SkPdfStandardFontEntry("C
ourier New", true, true)); | |
44 gPdfStandardFonts.set("CourierNew-Italic", SkPdfStandardFontEntry("Couri
er New", false, true)); | |
45 gPdfStandardFonts.set("CourierNewPS-BoldItalicMT", SkPdfStandardFontEntr
y("Courier New", true, true)); | |
46 gPdfStandardFonts.set("CourierNewPS-BoldMT", SkPdfStandardFontEntry("Cou
rier New", true, false)); | |
47 gPdfStandardFonts.set("CourierNewPS-ItalicMT", SkPdfStandardFontEntry("C
ourier New", false, true)); | |
48 gPdfStandardFonts.set("CourierNewPSMT", SkPdfStandardFontEntry("Courier
New", false, false)); | |
49 gPdfStandardFonts.set("Helvetica", SkPdfStandardFontEntry("Helvetica", f
alse, false)); | |
50 gPdfStandardFonts.set("Helvetica,Bold", SkPdfStandardFontEntry("Helvetic
a", true, false)); | |
51 gPdfStandardFonts.set("Helvetica,BoldItalic", SkPdfStandardFontEntry("He
lvetica", true, true)); | |
52 gPdfStandardFonts.set("Helvetica,Italic", SkPdfStandardFontEntry("Helvet
ica", false, true)); | |
53 gPdfStandardFonts.set("Helvetica-Bold", SkPdfStandardFontEntry("Helvetic
a", true, false)); | |
54 gPdfStandardFonts.set("Helvetica-BoldItalic", SkPdfStandardFontEntry("He
lvetica", true, true)); | |
55 gPdfStandardFonts.set("Helvetica-BoldOblique", SkPdfStandardFontEntry("H
elvetica", true, true)); | |
56 gPdfStandardFonts.set("Helvetica-Italic", SkPdfStandardFontEntry("Helvet
ica", false, true)); | |
57 gPdfStandardFonts.set("Helvetica-Oblique", SkPdfStandardFontEntry("Helve
tica", false, true)); | |
58 gPdfStandardFonts.set("Times-Bold", SkPdfStandardFontEntry("Times New Ro
man", true, false)); | |
59 gPdfStandardFonts.set("Times-BoldItalic", SkPdfStandardFontEntry("Times
New Roman", true, true)); | |
60 gPdfStandardFonts.set("Times-Italic", SkPdfStandardFontEntry("Times New
Roman", false, true)); | |
61 gPdfStandardFonts.set("Times-Roman", SkPdfStandardFontEntry("Times New R
oman", false, false)); | |
62 gPdfStandardFonts.set("TimesNewRoman", SkPdfStandardFontEntry("Times New
Roman", false, false)); | |
63 gPdfStandardFonts.set("TimesNewRoman,Bold", SkPdfStandardFontEntry("Time
s New Roman", true, false)); | |
64 gPdfStandardFonts.set("TimesNewRoman,BoldItalic", SkPdfStandardFontEntry
("Times New Roman", true, true)); | |
65 gPdfStandardFonts.set("TimesNewRoman,Italic", SkPdfStandardFontEntry("Ti
mes New Roman", false, true)); | |
66 gPdfStandardFonts.set("TimesNewRoman-Bold", SkPdfStandardFontEntry("Time
s New Roman", true, false)); | |
67 gPdfStandardFonts.set("TimesNewRoman-BoldItalic", SkPdfStandardFontEntry
("Times New Roman", true, true)); | |
68 gPdfStandardFonts.set("TimesNewRoman-Italic", SkPdfStandardFontEntry("Ti
mes New Roman", false, true)); | |
69 gPdfStandardFonts.set("TimesNewRomanPS", SkPdfStandardFontEntry("Times N
ew Roman", false, false)); | |
70 gPdfStandardFonts.set("TimesNewRomanPS-Bold", SkPdfStandardFontEntry("Ti
mes New Roman", true, false)); | |
71 gPdfStandardFonts.set("TimesNewRomanPS-BoldItalic", SkPdfStandardFontEnt
ry("Times New Roman", true, true)); | |
72 gPdfStandardFonts.set("TimesNewRomanPS-BoldItalicMT", SkPdfStandardFontE
ntry("Times New Roman", true, true)); | |
73 gPdfStandardFonts.set("TimesNewRomanPS-BoldMT", SkPdfStandardFontEntry("
Times New Roman", true, false)); | |
74 gPdfStandardFonts.set("TimesNewRomanPS-Italic", SkPdfStandardFontEntry("
Times New Roman", false, true)); | |
75 gPdfStandardFonts.set("TimesNewRomanPS-ItalicMT", SkPdfStandardFontEntry
("Times New Roman", false, true)); | |
76 gPdfStandardFonts.set("TimesNewRomanPSMT", SkPdfStandardFontEntry("Times
New Roman", false, false)); | |
77 gPdfStandardFonts.set("Symbol", SkPdfStandardFontEntry("Symbol", false,
false)); | |
78 gPdfStandardFonts.set("ZapfDingbats", SkPdfStandardFontEntry("ZapfDingba
ts", false, false)); | |
79 | |
80 // TODO(edisonn): these are hacks. Load Post Script font name. | |
81 // see FT_Get_Postscript_Name | |
82 // Font config is not using it, yet. | |
83 //https://bugs.freedesktop.org/show_bug.cgi?id=18095 | |
84 | |
85 gPdfStandardFonts.set("Arial-Black", SkPdfStandardFontEntry("Arial", tru
e, false)); | |
86 gPdfStandardFonts.set("DejaVuSans", SkPdfStandardFontEntry("DejaVu Sans"
, false, false)); | |
87 gPdfStandardFonts.set("DejaVuSansMono", SkPdfStandardFontEntry("DejaVuSa
ns Mono", false, false)); | |
88 gPdfStandardFonts.set("DejaVuSansMono-Bold", SkPdfStandardFontEntry("Dej
aVuSans Mono", true, false)); | |
89 gPdfStandardFonts.set("DejaVuSansMono-Oblique", SkPdfStandardFontEntry("
DejaVuSans Mono", false, true)); | |
90 gPdfStandardFonts.set("Georgia-Bold", SkPdfStandardFontEntry("Georgia",
true, false)); | |
91 gPdfStandardFonts.set("Georgia-BoldItalic", SkPdfStandardFontEntry("Geor
gia", true, true)); | |
92 gPdfStandardFonts.set("Georgia-Italic", SkPdfStandardFontEntry("Georgia"
, false, true)); | |
93 gPdfStandardFonts.set("TrebuchetMS", SkPdfStandardFontEntry("Trebuchet M
S", false, false)); | |
94 gPdfStandardFonts.set("TrebuchetMS-Bold", SkPdfStandardFontEntry("Trebuc
het MS", true, false)); | |
95 gPdfStandardFonts.set("Verdana-Bold", SkPdfStandardFontEntry("Verdana",
true, false)); | |
96 gPdfStandardFonts.set("WenQuanYiMicroHei", SkPdfStandardFontEntry("WenQu
anYi Micro Hei", false, false)); | |
97 | |
98 // TODO(edisonn): list all fonts available, buil post script name as in
pdf spec | |
99 // TODO(edisonn): Does it work in all OSs ? | |
100 /* | |
101 * The PostScript name for the value of BaseFontis determined in one of
two ways: | |
102 • Use the PostScript name that is an optional entry in the “name” table of the | |
103 TrueType font itself. | |
104 • In the absence of such an entry in the “name” table, derive a PostScript name | |
105 from the name by which the font is known in the host operating system: on a | |
106 Windows system, it is based on the lfFaceName field in a LOGFONT structure; in | |
107 the Mac OS, it is based on the name of the FONDresource. If the name contains | |
108 any spaces, the spaces are removed. | |
109 If the font in a source document uses a bold or italic style, but there is no fo
nt | |
110 data for that style, the host operating system will synthesize the style. In thi
s case, | |
111 a comma and the style name (one of Bold, Italic, or BoldItalic) are appended to
the | |
112 font name. For example, for a TrueType font that is a bold variant of the New | |
113 */ | |
114 | |
115 /* | |
116 * If the value of Subtype is MMType1. | |
117 • If the PostScript name of the instance contains spaces, the spaces are replace
d | |
118 by underscores in the value of BaseFont. For instance, as illustrated in Example | |
119 5.7, the name “MinionMM 366 465 11 ” (which ends with a space character) | |
120 becomes /MinionMM_366_465_11_. | |
121 */ | |
122 } | |
123 | |
124 return gPdfStandardFonts; | |
125 } | |
126 | |
127 SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold, bool
italic) { | |
128 SkTDict<SkPdfStandardFontEntry>& standardFontMap = getStandardFonts(); | |
129 | |
130 SkTypeface* typeface = NULL; | |
131 SkPdfStandardFontEntry fontData; | |
132 | |
133 if (standardFontMap.find(fontName, &fontData)) { | |
134 // TODO(edisonn): How does the bold/italic specified in standard definit
ion combines with | |
135 // the one in /font key? use OR for now. | |
136 bold = bold || fontData.fIsBold; | |
137 italic = italic || fontData.fIsItalic; | |
138 | |
139 typeface = SkTypeface::CreateFromName( | |
140 fontData.fName, | |
141 SkTypeface::Style((bold ? SkTypeface::kBold : 0) | | |
142 (italic ? SkTypeface::kItalic : 0))); | |
143 } else { | |
144 typeface = SkTypeface::CreateFromName( | |
145 fontName, | |
146 SkTypeface::kNormal); | |
147 } | |
148 | |
149 if (typeface) { | |
150 typeface->ref(); | |
151 } | |
152 return typeface; | |
153 } | |
154 | |
155 SkPdfFont* SkPdfFont::fontFromFontDescriptor(SkPdfNativeDoc* doc, SkPdfFontDescr
iptorDictionary* fd, | |
156 bool loadFromName) { | |
157 // TODO(edisonn): partial implementation. | |
158 // Only one, at most be available | |
159 SkPdfStream* pdfStream = NULL; | |
160 if (fd->has_FontFile()) { | |
161 pdfStream = fd->FontFile(doc); | |
162 } else if (fd->has_FontFile2()) { | |
163 pdfStream = fd->FontFile2(doc); | |
164 } if (fd->has_FontFile3()) { | |
165 pdfStream = fd->FontFile3(doc); | |
166 } else { | |
167 if (loadFromName) { | |
168 return fontFromName(doc, fd, fd->FontName(doc).c_str()); | |
169 } | |
170 } | |
171 | |
172 const unsigned char* uncompressedStream = NULL; | |
173 size_t uncompressedStreamLength = 0; | |
174 | |
175 // TODO(edisonn): report warning to be used in testing. | |
176 if (!pdfStream || | |
177 !pdfStream->GetFilteredStreamRef(&uncompressedStream, &uncompressedS
treamLength) || | |
178 !uncompressedStream || | |
179 !uncompressedStreamLength) { | |
180 return NULL; | |
181 } | |
182 | |
183 SkMemoryStream* skStream = new SkMemoryStream(uncompressedStream, uncompress
edStreamLength); | |
184 SkTypeface* face = SkTypeface::CreateFromStream(skStream); | |
185 | |
186 if (face == NULL) { | |
187 // TODO(edisonn): report warning to be used in testing. | |
188 return NULL; | |
189 } | |
190 | |
191 face->ref(); | |
192 | |
193 return new SkPdfStandardFont(face); | |
194 } | |
195 | |
196 SkPdfFont* fontFromName(SkPdfNativeDoc* doc, SkPdfNativeObject* obj, const char*
fontName) { | |
197 SkTypeface* typeface = SkTypefaceFromPdfStandardFont(fontName, false, false)
; | |
198 if (typeface != NULL) { | |
199 return new SkPdfStandardFont(typeface); | |
200 } | |
201 | |
202 // TODO(edisonn): perf - make a map | |
203 for (unsigned int i = 0 ; i < doc->objects(); i++) { | |
204 SkPdfNativeObject* obj = doc->object(i); | |
205 if (!obj || !obj->isDictionary()) { | |
206 continue; | |
207 } | |
208 | |
209 SkPdfFontDescriptorDictionary* fd = obj->asDictionary()->asFontDescripto
rDictionary(); | |
210 | |
211 if (!fd->valid()) { | |
212 continue; | |
213 } | |
214 | |
215 if (fd->has_FontName() && fd->FontName(doc).equals(fontName)) { | |
216 SkPdfFont* font = SkPdfFont::fontFromFontDescriptor(doc, fd, false); | |
217 if (font) { | |
218 return font; | |
219 } else { | |
220 // failed to load font descriptor | |
221 break; | |
222 } | |
223 } | |
224 } | |
225 | |
226 // TODO(edisonn): warning/report issue | |
227 return SkPdfFont::Default(); | |
228 } | |
229 | |
230 SkPdfFont* SkPdfFont::fontFromPdfDictionaryOnce(SkPdfNativeDoc* doc, SkPdfFontDi
ctionary* dict) { | |
231 // TODO(edisonn): keep the type in a smart way in the SkPdfNativeObject | |
232 // 1) flag, isResolved (1bit): reset at reset, add/remove/update (array) and
set(dict) | |
233 // in a tree like structure, 3-4 bits for all the datatypes inheriting from
obj (int, real, ...) | |
234 // if is a dict, reserve a few bytes to encode type of dict, and so on like
in a tree | |
235 // issue: type can be determined from context! atribute night be missing/wro
ng | |
236 switch (doc->mapper()->mapFontDictionary(dict)) { | |
237 case kType0FontDictionary_SkPdfNativeObjectType: | |
238 return fontFromType0FontDictionary(doc, dict->asType0FontDictionary(
)); | |
239 | |
240 case kTrueTypeFontDictionary_SkPdfNativeObjectType: | |
241 return fontFromTrueTypeFontDictionary(doc, dict->asTrueTypeFontDicti
onary()); | |
242 | |
243 case kType1FontDictionary_SkPdfNativeObjectType: | |
244 return fontFromType1FontDictionary(doc, dict->asType1FontDictionary(
)); | |
245 | |
246 case kMultiMasterFontDictionary_SkPdfNativeObjectType: | |
247 return fontFromMultiMasterFontDictionary(doc, dict->asMultiMasterFon
tDictionary()); | |
248 | |
249 case kType3FontDictionary_SkPdfNativeObjectType: | |
250 return fontFromType3FontDictionary(doc, dict->asType3FontDictionary(
)); | |
251 | |
252 default: | |
253 // TODO(edisonn): report error? | |
254 return NULL; | |
255 } | |
256 } | |
257 | |
258 SkPdfFont* SkPdfFont::fontFromPdfDictionary(SkPdfNativeDoc* doc, SkPdfFontDictio
nary* dict) { | |
259 if (dict == NULL) { | |
260 return NULL; // TODO(edisonn): report default one? | |
261 } | |
262 | |
263 if (!dict->hasData(SkPdfNativeObject::kFont_Data)) { | |
264 dict->setData(fontFromPdfDictionaryOnce(doc, dict), SkPdfNativeObject::k
Font_Data); | |
265 } | |
266 return (SkPdfFont*)dict->data(SkPdfNativeObject::kFont_Data); | |
267 } | |
268 | |
269 | |
270 | |
271 SkPdfType0Font* SkPdfFont::fontFromType0FontDictionary(SkPdfNativeDoc* doc, | |
272 SkPdfType0FontDictionary*
dict) { | |
273 if (dict == NULL) { | |
274 return NULL; // default one? | |
275 } | |
276 | |
277 return new SkPdfType0Font(doc, dict); | |
278 } | |
279 | |
280 SkPdfType1Font* SkPdfFont:: fontFromType1FontDictionary(SkPdfNativeDoc* doc, | |
281 SkPdfType1FontDictionary
* dict) { | |
282 if (dict == NULL) { | |
283 return NULL; // default one? | |
284 } | |
285 | |
286 return new SkPdfType1Font(doc, dict); | |
287 } | |
288 | |
289 SkPdfType3Font* SkPdfFont::fontFromType3FontDictionary(SkPdfNativeDoc* doc, | |
290 SkPdfType3FontDictionary*
dict) { | |
291 if (dict == NULL) { | |
292 return NULL; // default one? | |
293 } | |
294 | |
295 | |
296 | |
297 return new SkPdfType3Font(doc, dict); | |
298 } | |
299 | |
300 SkPdfTrueTypeFont* SkPdfFont::fontFromTrueTypeFontDictionary(SkPdfNativeDoc* doc
, | |
301 SkPdfTrueTypeFontDi
ctionary* dict) { | |
302 if (dict == NULL) { | |
303 return NULL; // default one? | |
304 } | |
305 | |
306 return new SkPdfTrueTypeFont(doc, dict); | |
307 } | |
308 | |
309 SkPdfMultiMasterFont* SkPdfFont::fontFromMultiMasterFontDictionary( | |
310 SkPdfNativeDoc* doc, SkPdfMultiMasterFontDictionary* dict) { | |
311 if (dict == NULL) { | |
312 return NULL; // default one? | |
313 } | |
314 | |
315 return new SkPdfMultiMasterFont(doc, dict); | |
316 } | |
317 | |
318 static int skstoi(const SkPdfNativeObject* str) { | |
319 // TODO(edisonn): report err of it is not a (hex) string | |
320 int ret = 0; | |
321 for (unsigned int i = 0 ; i < str->lenstr(); i++) { | |
322 ret = (ret << 8) + ((unsigned char*)str->c_str())[i]; | |
323 } | |
324 // TODO(edisonn): character larger than 0x0000ffff not supported right now. | |
325 return ret & 0x0000ffff; | |
326 } | |
327 | |
328 #define tokenIsKeyword(token,keyword) (token.fType == kKeyword_TokenType && \ | |
329 token.fKeywordLength==sizeof(keyword)-1 &&
\ | |
330 strncmp(token.fKeyword, keyword, sizeof(ke
yword)-1) == 0) | |
331 | |
332 SkPdfToUnicode::SkPdfToUnicode(SkPdfNativeDoc* parsed, SkPdfStream* stream) { | |
333 fCMapEncoding = NULL; | |
334 fCMapEncodingFlag = NULL; | |
335 | |
336 if (stream) { | |
337 // Since font will be cached, the font has to sit in the per doc allocat
or, not to be | |
338 // freed after the page is done drawing. | |
339 SkPdfNativeTokenizer tokenizer(stream, parsed->allocator(), parsed); | |
340 PdfToken token; | |
341 | |
342 fCMapEncoding = new unsigned short[256 * 256]; | |
343 fCMapEncodingFlag = new unsigned char[256 * 256]; | |
344 for (int i = 0 ; i < 256 * 256; i++) { | |
345 fCMapEncoding[i] = i; | |
346 fCMapEncodingFlag[i] = 0; | |
347 } | |
348 | |
349 // TODO(edisonn): deal with multibyte character, or longer strings. | |
350 // Right now we deal with up 2 characters, e.g. <0020> but not longer li
ke <00660066006C> | |
351 //2 beginbfrange | |
352 //<0000> <005E> <0020> | |
353 //<005F> <0061> [<00660066> <00660069> <00660066006C>] | |
354 | |
355 while (tokenizer.readToken(&token)) { | |
356 | |
357 if (tokenIsKeyword(token, "begincodespacerange")) { | |
358 while (tokenizer.readToken(&token) && | |
359 !tokenIsKeyword(token, "endcodespacerange")) { | |
360 // tokenizer.PutBack(token); | |
361 // tokenizer.readToken(&token); | |
362 // TODO(edisonn): check token type! ignore/report errors. | |
363 int start = skstoi(token.fObject); | |
364 tokenizer.readToken(&token); | |
365 int end = skstoi(token.fObject); | |
366 for (int i = start; i <= end; i++) { | |
367 fCMapEncodingFlag[i] |= 1; | |
368 } | |
369 } | |
370 } | |
371 | |
372 if (tokenIsKeyword(token, "beginbfchar")) { | |
373 while (tokenizer.readToken(&token) && !tokenIsKeyword(token, "en
dbfchar")) { | |
374 // tokenizer.PutBack(token); | |
375 // tokenizer.readToken(&token); | |
376 int from = skstoi(token.fObject); | |
377 tokenizer.readToken(&token); | |
378 int to = skstoi(token.fObject); | |
379 | |
380 fCMapEncodingFlag[from] |= 2; | |
381 fCMapEncoding[from] = to; | |
382 } | |
383 } | |
384 | |
385 if (tokenIsKeyword(token, "beginbfrange")) { | |
386 while (tokenizer.readToken(&token) && !tokenIsKeyword(token, "en
dbfrange")) { | |
387 // tokenizer.PutBack(token); | |
388 // tokenizer.readToken(&token); | |
389 int start = skstoi(token.fObject); | |
390 tokenizer.readToken(&token); | |
391 int end = skstoi(token.fObject); | |
392 | |
393 | |
394 tokenizer.readToken(&token); // [ or just an array directly? | |
395 // do not putback, we will reuse the read. See next commente
d read. | |
396 // tokenizer.PutBack(token); | |
397 | |
398 // TODO(edisonn): read spec: any string or only hex string? | |
399 if (token.fType == kObject_TokenType && token.fObject->isAny
String()) { | |
400 // tokenizer.readToken(&token); | |
401 int value = skstoi(token.fObject); | |
402 | |
403 for (int i = start; i <= end; i++) { | |
404 fCMapEncodingFlag[i] |= 2; | |
405 fCMapEncoding[i] = value; | |
406 value++; | |
407 // if i != end, verify last byte id not if, ignore/r
eport error | |
408 } | |
409 | |
410 // read one string | |
411 } else if (token.fType == kObject_TokenType && token.fObject
->isArray()) { | |
412 // tokenizer.readToken(&token); | |
413 // read array | |
414 for (unsigned int i = 0; i < token.fObject->size(); i++)
{ | |
415 fCMapEncodingFlag[start + i] |= 2; | |
416 fCMapEncoding[start + i] = skstoi((*token.fObject)[i
]); | |
417 } | |
418 } else { | |
419 tokenizer.PutBack(token); | |
420 } | |
421 } | |
422 } | |
423 } | |
424 } | |
425 } | |
426 | |
427 SkPdfType0Font::SkPdfType0Font(SkPdfNativeDoc* doc, SkPdfType0FontDictionary* di
ct) { | |
428 fBaseFont = fontFromName(doc, dict, dict->BaseFont(doc).c_str()); | |
429 fEncoding = NULL; | |
430 | |
431 if (dict->has_Encoding()) { | |
432 if (dict->isEncodingAName(doc)) { | |
433 fEncoding = SkPdfEncoding::fromName(dict->getEncodingAsName(doc).c_s
tr()); | |
434 } else if (dict->isEncodingAStream(doc)) { | |
435 // TODO(edisonn): NYI | |
436 //fEncoding = loadEncodingFromStream(dict->getEncodingAsStream()); | |
437 } else { | |
438 // TODO(edisonn): error ... warning .. assert? | |
439 } | |
440 } | |
441 | |
442 if (dict->has_ToUnicode()) { | |
443 fToUnicode = new SkPdfToUnicode(doc, dict->ToUnicode(doc)); | |
444 } | |
445 } | |
446 | |
447 SkTDict<SkPdfEncoding*>& getStandardEncodings() { | |
448 static SkTDict<SkPdfEncoding*> encodings(10); | |
449 if (encodings.count() == 0) { | |
450 encodings.set("Identity-H", SkPdfIdentityHEncoding::instance()); | |
451 } | |
452 | |
453 return encodings; | |
454 } | |
455 | |
456 SkPdfEncoding* SkPdfEncoding::fromName(const char* name) { | |
457 SkPdfEncoding* encoding = NULL; | |
458 if (!getStandardEncodings().find(name, &encoding)) { | |
459 encoding = NULL; | |
460 } | |
461 | |
462 #ifdef PDF_TRACE | |
463 if (encoding == NULL) { | |
464 printf("Encoding not found: %s\n", name); | |
465 } | |
466 #endif | |
467 return encoding; | |
468 } | |
OLD | NEW |