| 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 |