| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
| 9 #include "SkDevice.h" | 9 #include "SkDevice.h" |
| 10 #include "SkForceLinking.h" | 10 #include "SkForceLinking.h" |
| 11 #include "SkGraphics.h" | 11 #include "SkGraphics.h" |
| 12 #include "SkImageDecoder.h" | 12 #include "SkImageDecoder.h" |
| 13 #include "SkImageEncoder.h" | 13 #include "SkImageEncoder.h" |
| 14 #include "SkOSFile.h" | 14 #include "SkOSFile.h" |
| 15 #include "SkPicture.h" | 15 #include "SkPicture.h" |
| 16 #include "SkStream.h" | 16 #include "SkStream.h" |
| 17 #include "SkTypeface.h" | 17 #include "SkTypeface.h" |
| 18 #include "SkTArray.h" | 18 #include "SkTArray.h" |
| 19 #include "picture_utils.h" | 19 #include "picture_utils.h" |
| 20 | 20 |
| 21 #include <iostream> | 21 #include <iostream> |
| 22 #include <cstdio> | 22 #include <cstdio> |
| 23 #include <stack> | 23 #include <stack> |
| 24 | 24 #include <set> |
| 25 #include "podofo.h" | |
| 26 using namespace PoDoFo; | |
| 27 | |
| 28 | 25 |
| 29 __SK_FORCE_IMAGE_DECODER_LINKING; | 26 __SK_FORCE_IMAGE_DECODER_LINKING; |
| 30 | 27 |
| 31 // TODO(edisonn): tool, show what objects were read at least, show the ones not
even read | 28 // TODO(edisonn): tool, show what objects were read at least, show the ones not
even read |
| 32 // keep for each object pos in file | 29 // keep for each object pos in file |
| 33 // plug in for VS? syntax coloring, show selected object ... from the text, or f
rom rendered x,y | 30 // plug in for VS? syntax coloring, show selected object ... from the text, or f
rom rendered x,y |
| 34 | 31 |
| 35 // TODO(edisonn): security - validate all the user input, all pdf! | 32 // TODO(edisonn): security - validate all the user input, all pdf! |
| 36 | 33 |
| 37 // TODO(edisonn): put drawtext in #ifdefs, so comparations will ignore minor cha
nges in text positioning and font | 34 // TODO(edisonn): put drawtext in #ifdefs, so comparations will ignore minor cha
nges in text positioning and font |
| 38 // this way, we look more at other features and layout in diffs | 35 // this way, we look more at other features and layout in diffs |
| 39 | 36 |
| 40 // TODO(edisonn): move trace dump in the get functions, and mapper ones too so i
t ghappens automatically | 37 // TODO(edisonn): move trace dump in the get functions, and mapper ones too so i
t ghappens automatically |
| 41 /* | 38 /* |
| 42 #ifdef PDF_TRACE | 39 #ifdef PDF_TRACE |
| 43 std::string str; | 40 std::string str; |
| 44 pdfContext->fGraphicsState.fResources->podofo()->ToString(str); | 41 pdfContext->fGraphicsState.fResources->native()->ToString(str); |
| 45 printf("Print Tf Resources: %s\n", str.c_str()); | 42 printf("Print Tf Resources: %s\n", str.c_str()); |
| 46 #endif | 43 #endif |
| 47 */ | 44 */ |
| 48 | 45 |
| 49 #include "SkPdfHeaders_autogen.h" | 46 #include "SkPdfHeaders_autogen.h" |
| 50 #include "SkPdfMapper_autogen.h" | 47 #include "SkPdfMapper_autogen.h" |
| 51 #include "SkPdfParser.h" | 48 #include "SkPdfParser.h" |
| 52 | 49 |
| 53 #include "SkPdfBasics.h" | 50 #include "SkPdfBasics.h" |
| 54 #include "SkPdfUtils.h" | 51 #include "SkPdfUtils.h" |
| 55 | 52 |
| 56 #include "SkPdfFont.h" | 53 #include "SkPdfFont.h" |
| 57 | 54 |
| 58 /* | 55 /* |
| 59 * TODO(edisonn): | 56 * TODO(edisonn): |
| 60 * - all font types and all ppdf font features | 57 * - all font types and all ppdf font features |
| 61 * - word spacing | 58 * - word spacing |
| 62 * - load font for baidu.pdf | 59 * - load font for baidu.pdf |
| 63 * - load font for youtube.pdf | 60 * - load font for youtube.pdf |
| 64 * - parser for pdf from the definition already available in pdfspec_autoge
n.py | 61 * - parser for pdf from the definition already available in pdfspec_autoge
n.py |
| 65 * - all docs from ~/work | 62 * - all docs from ~/work |
| 66 * - encapsulate podofo in the pdf api so the skpdf does not know anything about
podofo ... in progress | 63 * - encapsulate native in the pdf api so the skpdf does not know anything about
native ... in progress |
| 67 * - load gs/ especially smask and already known prop (skp) ... in progress | 64 * - load gs/ especially smask and already known prop (skp) ... in progress |
| 68 * - wrapper on classes for customizations? e.g. | 65 * - wrapper on classes for customizations? e.g. |
| 69 * SkPdfPageObjectVanila - has only the basic loaders/getters | 66 * SkPdfPageObjectVanila - has only the basic loaders/getters |
| 70 * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add custom
izations here | 67 * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add custom
izations here |
| 71 * need to find a nice object model for all this with constructors and factories | 68 * need to find a nice object model for all this with constructors and factories |
| 72 * - deal with inheritable automatically ? | 69 * - deal with inheritable automatically ? |
| 73 * - deal with specific type in spec directly, add all dictionary types to known
types | 70 * - deal with specific type in spec directly, add all dictionary types to known
types |
| 74 */ | 71 */ |
| 75 | 72 |
| 76 using namespace std; | 73 using namespace std; |
| 77 using namespace PoDoFo; | |
| 78 | 74 |
| 79 // Utilities | 75 // Utilities |
| 80 static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color
= SK_ColorWHITE) { | 76 static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color
= SK_ColorWHITE) { |
| 81 bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); | 77 bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); |
| 82 | 78 |
| 83 bitmap->allocPixels(); | 79 bitmap->allocPixels(); |
| 84 bitmap->eraseColor(color); | 80 bitmap->eraseColor(color); |
| 85 } | 81 } |
| 86 | 82 |
| 87 // TODO(edisonn): synonyms? DeviceRGB and RGB ... | 83 // TODO(edisonn): synonyms? DeviceRGB and RGB ... |
| (...skipping 27 matching lines...) Expand all Loading... |
| 115 | 111 |
| 116 return matrix; | 112 return matrix; |
| 117 } | 113 } |
| 118 | 114 |
| 119 SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { | 115 SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { |
| 120 double array[6]; | 116 double array[6]; |
| 121 | 117 |
| 122 // TODO(edisonn): security issue, ret if size() != 6 | 118 // TODO(edisonn): security issue, ret if size() != 6 |
| 123 for (int i = 0; i < 6; i++) { | 119 for (int i = 0; i < 6; i++) { |
| 124 const SkPdfObject* elem = pdfArray->operator [](i); | 120 const SkPdfObject* elem = pdfArray->operator [](i); |
| 125 if (elem == NULL || (!elem->asNumber() && !elem->asInteger())) { | 121 if (elem == NULL || !elem->isNumber()) { |
| 126 return SkMatrix::I(); // TODO(edisonn): report issue | 122 return SkMatrix::I(); // TODO(edisonn): report issue |
| 127 } | 123 } |
| 128 array[i] = elem->asNumber() ? elem->asNumber()->value() : elem->asIntege
r()->value(); | 124 array[i] = elem->numberValue(); |
| 129 } | 125 } |
| 130 | 126 |
| 131 return SkMatrixFromPdfMatrix(array); | 127 return SkMatrixFromPdfMatrix(array); |
| 132 } | 128 } |
| 133 | 129 |
| 134 SkBitmap* gDumpBitmap = NULL; | 130 SkBitmap* gDumpBitmap = NULL; |
| 135 SkCanvas* gDumpCanvas = NULL; | 131 SkCanvas* gDumpCanvas = NULL; |
| 136 char gLastKeyword[100] = ""; | 132 char gLastKeyword[100] = ""; |
| 137 int gLastOpKeyword = -1; | 133 int gLastOpKeyword = -1; |
| 138 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
,EI,Do,EX,"; | 134 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
,EI,Do,EX,"; |
| 139 int gReadOp = 0; | 135 int gReadOp = 0; |
| 140 | 136 |
| 141 | 137 |
| 142 | 138 |
| 143 bool hasVisualEffect(const char* pdfOp) { | 139 bool hasVisualEffect(const char* pdfOp) { |
| 144 return true; | 140 return true; |
| 145 if (*pdfOp == '\0') return false; | 141 if (*pdfOp == '\0') return false; |
| 146 | 142 |
| 147 char markedPdfOp[100] = ","; | 143 char markedPdfOp[100] = ","; |
| 148 strcat(markedPdfOp, pdfOp); | 144 strcat(markedPdfOp, pdfOp); |
| 149 strcat(markedPdfOp, ","); | 145 strcat(markedPdfOp, ","); |
| 150 | 146 |
| 151 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); | 147 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); |
| 152 } | 148 } |
| 153 | 149 |
| 154 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum
entation. | 150 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum
entation. |
| 155 static bool readToken(SkPdfPodofoTokenizer* fTokenizer, PdfToken* token) { | 151 static bool readToken(SkPdfNativeTokenizer* fTokenizer, PdfToken* token) { |
| 156 bool ret = fTokenizer->readToken(token); | 152 bool ret = fTokenizer->readToken(token); |
| 157 | 153 |
| 158 gReadOp++; | 154 gReadOp++; |
| 159 | 155 |
| 160 #ifdef PDF_TRACE_DIFF_IN_PNG | 156 #ifdef PDF_TRACE_DIFF_IN_PNG |
| 161 // TODO(edisonn): compare with old bitmap, and save only new bits are availa
ble, and save | 157 // TODO(edisonn): compare with old bitmap, and save only new bits are availa
ble, and save |
| 162 // the numbar and name of last operation, so the file name will reflect op t
hat changed. | 158 // the numbar and name of last operation, so the file name will reflect op t
hat changed. |
| 163 if (hasVisualEffect(gLastKeyword)) { // TODO(edisonn): and has dirty bits. | 159 if (hasVisualEffect(gLastKeyword)) { // TODO(edisonn): and has dirty bits. |
| 164 gDumpCanvas->flush(); | 160 gDumpCanvas->flush(); |
| 165 | 161 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 } | 240 } |
| 245 | 241 |
| 246 | 242 |
| 247 | 243 |
| 248 typedef PdfResult (*PdfOperatorRenderer)(PdfContext*, SkCanvas*, PdfTokenLooper*
*); | 244 typedef PdfResult (*PdfOperatorRenderer)(PdfContext*, SkCanvas*, PdfTokenLooper*
*); |
| 249 | 245 |
| 250 map<std::string, PdfOperatorRenderer> gPdfOps; | 246 map<std::string, PdfOperatorRenderer> gPdfOps; |
| 251 | 247 |
| 252 map<std::string, int> gRenderStats[kCount_PdfResult]; | 248 map<std::string, int> gRenderStats[kCount_PdfResult]; |
| 253 | 249 |
| 254 char* gRenderStatsNames[kCount_PdfResult] = { | 250 const char* gRenderStatsNames[kCount_PdfResult] = { |
| 255 "Success", | 251 "Success", |
| 256 "Partially implemented", | 252 "Partially implemented", |
| 257 "Not yet implemented", | 253 "Not yet implemented", |
| 258 "Ignore Error", | 254 "Ignore Error", |
| 259 "Error", | 255 "Error", |
| 260 "Unsupported/Unknown" | 256 "Unsupported/Unknown" |
| 261 }; | 257 }; |
| 262 | 258 |
| 263 static SkTypeface* SkTypefaceFromPdfFont(PdfFont* font) { | |
| 264 if (font == NULL) { | |
| 265 return SkTypeface::CreateFromName("Times New Roman", SkTypeface::kNormal
); | |
| 266 } | |
| 267 | |
| 268 PdfObject* fontObject = font->GetObject(); | |
| 269 | |
| 270 PdfObject* pBaseFont = NULL; | |
| 271 // TODO(edisonn): warning, PoDoFo has a bug in PdfFont constructor, does not
call InitVars() | |
| 272 // for now fixed locally. | |
| 273 pBaseFont = fontObject->GetIndirectKey( "BaseFont" ); | |
| 274 const char* pszBaseFontName = pBaseFont->GetName().GetName().c_str(); | |
| 275 | |
| 276 #ifdef PDF_TRACE | |
| 277 std::string str; | |
| 278 fontObject->ToString(str); | |
| 279 printf("Base Font Name: %s\n", pszBaseFontName); | |
| 280 printf("Font Object Data: %s\n", str.c_str()); | |
| 281 #endif | |
| 282 | |
| 283 SkTypeface* typeface = SkTypefaceFromPdfStandardFont(pszBaseFontName, font->
IsBold(), font->IsItalic()); | |
| 284 | |
| 285 if (typeface != NULL) { | |
| 286 return typeface; | |
| 287 } | |
| 288 | |
| 289 char name[1000]; | |
| 290 // HACK | |
| 291 strncpy(name, pszBaseFontName, 1000); | |
| 292 char* comma = strstr(name, ","); | |
| 293 char* dash = strstr(name, "-"); | |
| 294 if (comma) *comma = '\0'; | |
| 295 if (dash) *dash = '\0'; | |
| 296 | |
| 297 typeface = SkTypeface::CreateFromName( | |
| 298 name, | |
| 299 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | | |
| 300 (font->IsItalic() ? SkTypeface::kItalic : 0)))
; | |
| 301 | |
| 302 if (typeface != NULL) { | |
| 303 #ifdef PDF_TRACE | |
| 304 printf("HACKED FONT found %s\n", name); | |
| 305 #endif | |
| 306 return typeface; | |
| 307 } | |
| 308 | |
| 309 #ifdef PDF_TRACE | |
| 310 printf("FONT_NOT_FOUND %s\n", pszBaseFontName); | |
| 311 #endif | |
| 312 | |
| 313 // TODO(edisonn): Report Warning, NYI | |
| 314 return SkTypeface::CreateFromName( | |
| 315 "Times New Roman", | |
| 316 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | | |
| 317 (font->IsItalic() ? SkTypeface::kItalic : 0)))
; | |
| 318 } | |
| 319 | |
| 320 PdfResult DrawText(PdfContext* pdfContext, | 259 PdfResult DrawText(PdfContext* pdfContext, |
| 321 const SkPdfObject* _str, | 260 const SkPdfObject* _str, |
| 322 SkCanvas* canvas) | 261 SkCanvas* canvas) |
| 323 { | 262 { |
| 324 | 263 |
| 325 SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; | 264 SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; |
| 326 if (skfont == NULL) { | 265 if (skfont == NULL) { |
| 327 skfont = SkPdfFont::Default(); | 266 skfont = SkPdfFont::Default(); |
| 328 } | 267 } |
| 329 | 268 |
| 330 const SkPdfString* str = _str->asString(); | |
| 331 | 269 |
| 332 if (str == NULL) { | 270 if (_str == NULL || !_str->isAnyString()) { |
| 333 // TODO(edisonn): report warning | 271 // TODO(edisonn): report warning |
| 334 return kIgnoreError_PdfResult; | 272 return kIgnoreError_PdfResult; |
| 335 } | 273 } |
| 274 const SkPdfString* str = (const SkPdfString*)_str; |
| 336 | 275 |
| 337 SkUnencodedText binary(str); | 276 SkUnencodedText binary(str); |
| 338 | 277 |
| 339 SkDecodedText decoded; | 278 SkDecodedText decoded; |
| 340 | 279 |
| 341 if (skfont->encoding() == NULL) { | 280 if (skfont->encoding() == NULL) { |
| 342 // TODO(edisonn): report warning | 281 // TODO(edisonn): report warning |
| 343 return kNYI_PdfResult; | 282 return kNYI_PdfResult; |
| 344 } | 283 } |
| 345 | 284 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 if (grayColortable == NULL) { | 338 if (grayColortable == NULL) { |
| 400 SkPMColor* colors = new SkPMColor[256]; | 339 SkPMColor* colors = new SkPMColor[256]; |
| 401 for (int i = 0 ; i < 256; i++) { | 340 for (int i = 0 ; i < 256; i++) { |
| 402 colors[i] = SkPreMultiplyARGB(255, i, i, i); | 341 colors[i] = SkPreMultiplyARGB(255, i, i, i); |
| 403 } | 342 } |
| 404 grayColortable = new SkColorTable(colors, 256); | 343 grayColortable = new SkColorTable(colors, 256); |
| 405 } | 344 } |
| 406 return grayColortable; | 345 return grayColortable; |
| 407 } | 346 } |
| 408 | 347 |
| 409 SkBitmap transferImageStreamToBitmap(unsigned char* uncompressedStream, pdf_long
uncompressedStreamLength, | 348 SkBitmap transferImageStreamToBitmap(unsigned char* uncompressedStream, size_t u
ncompressedStreamLength, |
| 410 int width, int height, int bytesPerLine, | 349 int width, int height, int bytesPerLine, |
| 411 int bpc, const std::string& colorSpace, | 350 int bpc, const std::string& colorSpace, |
| 412 bool transparencyMask) { | 351 bool transparencyMask) { |
| 413 SkBitmap bitmap; | 352 SkBitmap bitmap; |
| 414 | 353 |
| 415 int components = GetColorSpaceComponents(colorSpace); | 354 //int components = GetColorSpaceComponents(colorSpace); |
| 416 //#define MAX_COMPONENTS 10 | 355 //#define MAX_COMPONENTS 10 |
| 417 | 356 |
| 418 int bitsPerLine = width * components * bpc; | |
| 419 // TODO(edisonn): assume start of lines are aligned at 32 bits? | 357 // TODO(edisonn): assume start of lines are aligned at 32 bits? |
| 420 // Is there a faster way to load the uncompressed stream into a bitmap? | 358 // Is there a faster way to load the uncompressed stream into a bitmap? |
| 421 | 359 |
| 422 // minimal support for now | 360 // minimal support for now |
| 423 if ((colorSpace == "DeviceRGB" || colorSpace == "RGB") && bpc == 8) { | 361 if ((colorSpace == "DeviceRGB" || colorSpace == "RGB") && bpc == 8) { |
| 424 SkColor* uncompressedStreamArgb = (SkColor*)malloc(width * height * size
of(SkColor)); | 362 SkColor* uncompressedStreamArgb = (SkColor*)malloc(width * height * size
of(SkColor)); |
| 425 | 363 |
| 426 for (int h = 0 ; h < height; h++) { | 364 for (int h = 0 ; h < height; h++) { |
| 427 long i = width * (height - 1 - h); | 365 long i = width * (h); |
| 428 for (int w = 0 ; w < width; w++) { | 366 for (int w = 0 ; w < width; w++) { |
| 429 uncompressedStreamArgb[i] = SkColorSetRGB(uncompressedStream[3 *
w], | 367 uncompressedStreamArgb[i] = SkColorSetRGB(uncompressedStream[3 *
w], |
| 430 uncompressedStream[3 *
w + 1], | 368 uncompressedStream[3 *
w + 1], |
| 431 uncompressedStream[3 *
w + 2]); | 369 uncompressedStream[3 *
w + 2]); |
| 432 i++; | 370 i++; |
| 433 } | 371 } |
| 434 uncompressedStream += bytesPerLine; | 372 uncompressedStream += bytesPerLine; |
| 435 } | 373 } |
| 436 | 374 |
| 437 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); | 375 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); |
| 438 bitmap.setPixels(uncompressedStreamArgb); | 376 bitmap.setPixels(uncompressedStreamArgb); |
| 439 } | 377 } |
| 440 else if ((colorSpace == "DeviceGray" || colorSpace == "Gray") && bpc == 8) { | 378 else if ((colorSpace == "DeviceGray" || colorSpace == "Gray") && bpc == 8) { |
| 441 unsigned char* uncompressedStreamA8 = (unsigned char*)malloc(width * hei
ght); | 379 unsigned char* uncompressedStreamA8 = (unsigned char*)malloc(width * hei
ght); |
| 442 | 380 |
| 443 for (int h = 0 ; h < height; h++) { | 381 for (int h = 0 ; h < height; h++) { |
| 444 long i = width * (height - 1 - h); | 382 long i = width * (h); |
| 445 for (int w = 0 ; w < width; w++) { | 383 for (int w = 0 ; w < width; w++) { |
| 446 uncompressedStreamA8[i] = transparencyMask ? 255 - uncompressedS
tream[w] : | 384 uncompressedStreamA8[i] = transparencyMask ? 255 - uncompressedS
tream[w] : |
| 447 uncompressedStream[
w]; | 385 uncompressedStream[
w]; |
| 448 i++; | 386 i++; |
| 449 } | 387 } |
| 450 uncompressedStream += bytesPerLine; | 388 uncompressedStream += bytesPerLine; |
| 451 } | 389 } |
| 452 | 390 |
| 453 bitmap.setConfig(transparencyMask ? SkBitmap::kA8_Config : SkBitmap::kIn
dex8_Config, | 391 bitmap.setConfig(transparencyMask ? SkBitmap::kA8_Config : SkBitmap::kIn
dex8_Config, |
| 454 width, height); | 392 width, height); |
| 455 bitmap.setPixels(uncompressedStreamA8, transparencyMask ? NULL : getGray
Colortable()); | 393 bitmap.setPixels(uncompressedStreamA8, transparencyMask ? NULL : getGray
Colortable()); |
| 456 } | 394 } |
| 457 | 395 |
| 458 // TODO(edisonn): Report Warning, NYI, or error | 396 // TODO(edisonn): Report Warning, NYI, or error |
| 459 return bitmap; | 397 return bitmap; |
| 460 } | 398 } |
| 461 | 399 |
| 462 bool transferImageStreamToARGB(unsigned char* uncompressedStream, pdf_long uncom
pressedStreamLength, | 400 bool transferImageStreamToARGB(unsigned char* uncompressedStream, size_t uncompr
essedStreamLength, |
| 463 int width, int bytesPerLine, | 401 int width, int bytesPerLine, |
| 464 int bpc, const std::string& colorSpace, | 402 int bpc, const std::string& colorSpace, |
| 465 SkColor** uncompressedStreamArgb, | 403 SkColor** uncompressedStreamArgb, |
| 466 pdf_long* uncompressedStreamLengthInBytesArgb) { | 404 size_t* uncompressedStreamLengthInBytesArgb) { |
| 467 int components = GetColorSpaceComponents(colorSpace); | 405 //int components = GetColorSpaceComponents(colorSpace); |
| 468 //#define MAX_COMPONENTS 10 | 406 //#define MAX_COMPONENTS 10 |
| 469 | 407 |
| 470 int bitsPerLine = width * components * bpc; | |
| 471 // TODO(edisonn): assume start of lines are aligned at 32 bits? | 408 // TODO(edisonn): assume start of lines are aligned at 32 bits? |
| 472 int height = uncompressedStreamLength / bytesPerLine; | 409 int height = uncompressedStreamLength / bytesPerLine; |
| 473 | 410 |
| 474 // minimal support for now | 411 // minimal support for now |
| 475 if ((colorSpace == "DeviceRGB" || colorSpace == "RGB") && bpc == 8) { | 412 if ((colorSpace == "DeviceRGB" || colorSpace == "RGB") && bpc == 8) { |
| 476 *uncompressedStreamLengthInBytesArgb = width * height * 4; | 413 *uncompressedStreamLengthInBytesArgb = width * height * 4; |
| 477 *uncompressedStreamArgb = (SkColor*)malloc(*uncompressedStreamLengthInBy
tesArgb); | 414 *uncompressedStreamArgb = (SkColor*)malloc(*uncompressedStreamLengthInBy
tesArgb); |
| 478 | 415 |
| 479 for (int h = 0 ; h < height; h++) { | 416 for (int h = 0 ; h < height; h++) { |
| 480 long i = width * (height - 1 - h); | 417 long i = width * (h); |
| 481 for (int w = 0 ; w < width; w++) { | 418 for (int w = 0 ; w < width; w++) { |
| 482 (*uncompressedStreamArgb)[i] = SkColorSetRGB(uncompressedStream[
3 * w], | 419 (*uncompressedStreamArgb)[i] = SkColorSetRGB(uncompressedStream[
3 * w], |
| 483 uncompressedStream[
3 * w + 1], | 420 uncompressedStream[
3 * w + 1], |
| 484 uncompressedStream[
3 * w + 2]); | 421 uncompressedStream[
3 * w + 2]); |
| 485 i++; | 422 i++; |
| 486 } | 423 } |
| 487 uncompressedStream += bytesPerLine; | 424 uncompressedStream += bytesPerLine; |
| 488 } | 425 } |
| 489 return true; | 426 return true; |
| 490 } | 427 } |
| 491 | 428 |
| 492 if ((colorSpace == "DeviceGray" || colorSpace == "Gray") && bpc == 8) { | 429 if ((colorSpace == "DeviceGray" || colorSpace == "Gray") && bpc == 8) { |
| 493 *uncompressedStreamLengthInBytesArgb = width * height * 4; | 430 *uncompressedStreamLengthInBytesArgb = width * height * 4; |
| 494 *uncompressedStreamArgb = (SkColor*)malloc(*uncompressedStreamLengthInBy
tesArgb); | 431 *uncompressedStreamArgb = (SkColor*)malloc(*uncompressedStreamLengthInBy
tesArgb); |
| 495 | 432 |
| 496 for (int h = 0 ; h < height; h++) { | 433 for (int h = 0 ; h < height; h++) { |
| 497 long i = width * (height - 1 - h); | 434 long i = width * (h); |
| 498 for (int w = 0 ; w < width; w++) { | 435 for (int w = 0 ; w < width; w++) { |
| 499 (*uncompressedStreamArgb)[i] = SkColorSetRGB(uncompressedStream[
w], | 436 (*uncompressedStreamArgb)[i] = SkColorSetRGB(uncompressedStream[
w], |
| 500 uncompressedStream[
w], | 437 uncompressedStream[
w], |
| 501 uncompressedStream[
w]); | 438 uncompressedStream[
w]); |
| 502 i++; | 439 i++; |
| 503 } | 440 } |
| 504 uncompressedStream += bytesPerLine; | 441 uncompressedStream += bytesPerLine; |
| 505 } | 442 } |
| 506 return true; | 443 return true; |
| 507 } | 444 } |
| 508 | 445 |
| 509 return false; | 446 return false; |
| 510 } | 447 } |
| 511 | 448 |
| 512 // utils | 449 // utils |
| 513 | 450 |
| 514 // TODO(edisonn): add cache, or put the bitmap property directly on the PdfObjec
t | 451 // TODO(edisonn): add cache, or put the bitmap property directly on the PdfObjec
t |
| 515 // TODO(edisonn): deal with colorSpaces, we could add them to SkBitmap::Config | 452 // TODO(edisonn): deal with colorSpaces, we could add them to SkBitmap::Config |
| 516 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
22, 444 to closest | 453 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
22, 444 to closest |
| 517 // skia format, through a table | 454 // skia format, through a table |
| 518 | 455 |
| 519 // this functions returns the image, it does not look at the smask. | 456 // this functions returns the image, it does not look at the smask. |
| 520 | 457 |
| 521 SkBitmap getImageFromObject(PdfContext* pdfContext, const SkPdfImageDictionary*
image, bool transparencyMask) { | 458 SkBitmap getImageFromObject(PdfContext* pdfContext, SkPdfImageDictionary* image,
bool transparencyMask) { |
| 522 if (image == NULL) { | 459 if (image == NULL || !image->hasStream()) { |
| 523 // TODO(edisonn): report warning to be used in testing. | 460 // TODO(edisonn): report warning to be used in testing. |
| 524 return SkBitmap(); | 461 return SkBitmap(); |
| 525 } | 462 } |
| 526 | 463 |
| 527 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... | 464 long bpc = image->BitsPerComponent(pdfContext->fPdfDoc); |
| 528 // PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 465 long width = image->Width(pdfContext->fPdfDoc); |
| 529 // obj.GetDictionary().GetKey(PdfNa
me("Filter"))); | 466 long height = image->Height(pdfContext->fPdfDoc); |
| 530 // if (value && value->IsArray() && value->GetArray().GetSize() == 1) { | |
| 531 // value = resolveReferenceObject(pdfContext->fPdfDoc, | |
| 532 // &value->GetArray()[0]); | |
| 533 // } | |
| 534 // if (value && value->IsName() && value->GetName().GetName() == "DCTDecode")
{ | |
| 535 // SkStream stream = SkStream:: | |
| 536 // SkImageDecoder::Factory() | |
| 537 // } | |
| 538 | |
| 539 long bpc = image->BitsPerComponent(); | |
| 540 long width = image->Width(); | |
| 541 long height = image->Height(); | |
| 542 std::string colorSpace = "DeviceRGB"; | 467 std::string colorSpace = "DeviceRGB"; |
| 543 | 468 |
| 544 // TODO(edisonn): color space can be an array too! | 469 // TODO(edisonn): color space can be an array too! |
| 545 if (image->isColorSpaceAName()) { | 470 if (image->isColorSpaceAName(pdfContext->fPdfDoc)) { |
| 546 colorSpace = image->getColorSpaceAsName(); | 471 colorSpace = image->getColorSpaceAsName(pdfContext->fPdfDoc); |
| 547 } | 472 } |
| 548 | 473 |
| 549 /* | 474 /* |
| 550 bool imageMask = image->imageMask(); | 475 bool imageMask = image->imageMask(); |
| 551 | 476 |
| 552 if (imageMask) { | 477 if (imageMask) { |
| 553 if (bpc != 0 && bpc != 1) { | 478 if (bpc != 0 && bpc != 1) { |
| 554 // TODO(edisonn): report warning to be used in testing. | 479 // TODO(edisonn): report warning to be used in testing. |
| 555 return SkBitmap(); | 480 return SkBitmap(); |
| 556 } | 481 } |
| 557 bpc = 1; | 482 bpc = 1; |
| 558 } | 483 } |
| 559 */ | 484 */ |
| 560 | 485 |
| 561 char* uncompressedStream = NULL; | 486 unsigned char* uncompressedStream = NULL; |
| 562 pdf_long uncompressedStreamLength = 0; | 487 size_t uncompressedStreamLength = 0; |
| 563 | 488 |
| 564 PdfResult ret = kPartial_PdfResult; | 489 SkPdfStream* stream = (SkPdfStream*)image; |
| 565 SkPdfStream* stream = NULL; | |
| 566 image->doc()->mapper()->mapStream(image, &stream); | |
| 567 | 490 |
| 568 if (!stream || !stream->GetFilteredCopy(&uncompressedStream, &uncompressedSt
reamLength) || | 491 if (!stream || !stream->GetFilteredStreamRef(&uncompressedStream, &uncompres
sedStreamLength, pdfContext->fPdfDoc->allocator()) || |
| 569 uncompressedStream == NULL || uncompressedStreamLength == 0) { | 492 uncompressedStream == NULL || uncompressedStreamLength == 0) { |
| 570 // TODO(edisonn): report warning to be used in testing. | 493 // TODO(edisonn): report warning to be used in testing. |
| 571 return SkBitmap(); | 494 return SkBitmap(); |
| 572 } | 495 } |
| 573 | 496 |
| 497 SkPdfStreamCommonDictionary* streamDict = (SkPdfStreamCommonDictionary*)stre
am; |
| 498 |
| 499 if (streamDict->has_Filter() && ((streamDict->isFilterAName(NULL) && |
| 500 streamDict->getFilterAsName(NULL) == "
DCTDecode") || |
| 501 (streamDict->isFilterAArray(NULL) && |
| 502 streamDict->getFilterAsArray(NULL)->si
ze() > 0 && |
| 503 streamDict->getFilterAsArray(NULL)->ob
jAtAIndex(0)->isName() && |
| 504 streamDict->getFilterAsArray(NULL)->ob
jAtAIndex(0)->nameValue2() == "DCTDecode"))) { |
| 505 SkBitmap bitmap; |
| 506 SkImageDecoder::DecodeMemory(uncompressedStream, uncompressedStreamLengt
h, &bitmap); |
| 507 return bitmap; |
| 508 } |
| 509 |
| 510 |
| 511 |
| 512 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... |
| 513 // PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, |
| 514 // obj.GetDictionary().GetKey(PdfNa
me("Filter"))); |
| 515 // if (value && value->IsArray() && value->GetArray().GetSize() == 1) { |
| 516 // value = resolveReferenceObject(pdfContext->fPdfDoc, |
| 517 // &value->GetArray()[0]); |
| 518 // } |
| 519 // if (value && value->IsName() && value->GetName().GetName() == "DCTDecode")
{ |
| 520 // SkStream stream = SkStream:: |
| 521 // SkImageDecoder::Factory() |
| 522 // } |
| 523 |
| 574 int bytesPerLine = uncompressedStreamLength / height; | 524 int bytesPerLine = uncompressedStreamLength / height; |
| 575 #ifdef PDF_TRACE | 525 #ifdef PDF_TRACE |
| 576 if (uncompressedStreamLength % height != 0) { | 526 if (uncompressedStreamLength % height != 0) { |
| 577 printf("Warning uncompressedStreamLength % height != 0 !!!\n"); | 527 printf("Warning uncompressedStreamLength modulo height != 0 !!!\n"); |
| 578 } | 528 } |
| 579 #endif | 529 #endif |
| 580 | 530 |
| 581 SkBitmap bitmap = transferImageStreamToBitmap( | 531 SkBitmap bitmap = transferImageStreamToBitmap( |
| 582 (unsigned char*)uncompressedStream, uncompressedStreamLength, | 532 (unsigned char*)uncompressedStream, uncompressedStreamLength, |
| 583 width, height, bytesPerLine, | 533 width, height, bytesPerLine, |
| 584 bpc, colorSpace, | 534 bpc, colorSpace, |
| 585 transparencyMask); | 535 transparencyMask); |
| 586 | 536 |
| 587 free(uncompressedStream); | |
| 588 | |
| 589 return bitmap; | 537 return bitmap; |
| 590 } | 538 } |
| 591 | 539 |
| 592 SkBitmap getSmaskFromObject(PdfContext* pdfContext, const SkPdfImageDictionary*
obj) { | 540 SkBitmap getSmaskFromObject(PdfContext* pdfContext, SkPdfImageDictionary* obj) { |
| 593 const SkPdfImageDictionary* sMask = obj->SMask(); | 541 SkPdfImageDictionary* sMask = obj->SMask(pdfContext->fPdfDoc); |
| 594 | 542 |
| 595 if (sMask) { | 543 if (sMask) { |
| 596 return getImageFromObject(pdfContext, sMask, true); | 544 return getImageFromObject(pdfContext, sMask, true); |
| 597 } | 545 } |
| 598 | 546 |
| 599 // TODO(edisonn): implement GS SMask. Default to empty right now. | 547 // TODO(edisonn): implement GS SMask. Default to empty right now. |
| 600 return pdfContext->fGraphicsState.fSMask; | 548 return pdfContext->fGraphicsState.fSMask; |
| 601 } | 549 } |
| 602 | 550 |
| 603 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfI
mageDictionary* skpdfimage) { | 551 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, SkPdfImageDi
ctionary* skpdfimage) { |
| 604 if (skpdfimage == NULL) { | 552 if (skpdfimage == NULL) { |
| 605 return kIgnoreError_PdfResult; | 553 return kIgnoreError_PdfResult; |
| 606 } | 554 } |
| 607 | 555 |
| 608 SkBitmap image = getImageFromObject(pdfContext, skpdfimage, false); | 556 SkBitmap image = getImageFromObject(pdfContext, skpdfimage, false); |
| 609 SkBitmap sMask = getSmaskFromObject(pdfContext, skpdfimage); | 557 SkBitmap sMask = getSmaskFromObject(pdfContext, skpdfimage); |
| 610 | 558 |
| 611 canvas->save(); | 559 canvas->save(); |
| 612 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 560 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
| 561 |
| 562 #if 1 |
| 563 SkScalar z = SkIntToScalar(0); |
| 564 SkScalar one = SkIntToScalar(1); |
| 565 |
| 566 SkPoint from[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), SkPoint::Make
(one, one), SkPoint::Make(z, one)}; |
| 567 SkPoint to[4] = {SkPoint::Make(z, one), SkPoint::Make(one, one), SkPoint::Ma
ke(one, z), SkPoint::Make(z, z)}; |
| 568 SkMatrix flip; |
| 569 SkAssertResult(flip.setPolyToPoly(from, to, 4)); |
| 570 SkMatrix solveImageFlip = pdfContext->fGraphicsState.fMatrix; |
| 571 solveImageFlip.preConcat(flip); |
| 572 canvas->setMatrix(solveImageFlip); |
| 573 #endif |
| 574 |
| 613 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); | 575 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); |
| 614 | 576 |
| 615 if (sMask.empty()) { | 577 if (sMask.empty()) { |
| 616 canvas->drawBitmapRect(image, dst, NULL); | 578 canvas->drawBitmapRect(image, dst, NULL); |
| 617 } else { | 579 } else { |
| 618 canvas->saveLayer(&dst, NULL); | 580 canvas->saveLayer(&dst, NULL); |
| 619 canvas->drawBitmapRect(image, dst, NULL); | 581 canvas->drawBitmapRect(image, dst, NULL); |
| 620 SkPaint xfer; | 582 SkPaint xfer; |
| 621 pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); | 583 pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); |
| 622 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode | 584 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode |
| 623 canvas->drawBitmapRect(sMask, dst, &xfer); | 585 canvas->drawBitmapRect(sMask, dst, &xfer); |
| 624 canvas->restore(); | 586 canvas->restore(); |
| 625 } | 587 } |
| 626 | 588 |
| 627 canvas->restore(); | 589 canvas->restore(); |
| 628 | 590 |
| 629 return kPartial_PdfResult; | 591 return kPartial_PdfResult; |
| 630 } | 592 } |
| 631 | 593 |
| 632 | 594 |
| 633 | 595 |
| 634 | 596 |
| 635 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfType1For
mDictionary* skobj) { | 597 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfType1For
mDictionary* skobj) { |
| 636 if (!skobj) { | 598 if (!skobj || !skobj->hasStream()) { |
| 637 return kIgnoreError_PdfResult; | 599 return kIgnoreError_PdfResult; |
| 638 } | 600 } |
| 639 | 601 |
| 640 PdfOp_q(pdfContext, canvas, NULL); | 602 PdfOp_q(pdfContext, canvas, NULL); |
| 641 canvas->save(); | 603 canvas->save(); |
| 642 | 604 |
| 643 | 605 |
| 644 if (skobj->Resources()) { | 606 if (skobj->Resources(pdfContext->fPdfDoc)) { |
| 645 pdfContext->fGraphicsState.fResources = skobj->Resources(); | 607 pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPd
fDoc); |
| 646 } | 608 } |
| 647 | 609 |
| 648 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Current matrix"); | 610 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Current matrix"); |
| 649 | 611 |
| 650 if (skobj->Matrix()) { | 612 if (skobj->has_Matrix()) { |
| 651 pdfContext->fGraphicsState.fMatrix.preConcat(*skobj->Matrix()); | 613 pdfContext->fGraphicsState.fMatrix.preConcat(skobj->Matrix(pdfContext->f
PdfDoc)); |
| 652 pdfContext->fGraphicsState.fMatrixTm = pdfContext->fGraphicsState.fMatri
x; | 614 pdfContext->fGraphicsState.fMatrixTm = pdfContext->fGraphicsState.fMatri
x; |
| 653 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatr
ix; | 615 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatr
ix; |
| 654 // TODO(edisonn) reset matrixTm and matricTlm also? | 616 // TODO(edisonn) reset matrixTm and matricTlm also? |
| 655 } | 617 } |
| 656 | 618 |
| 657 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); | 619 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); |
| 658 | 620 |
| 659 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 621 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
| 660 | 622 |
| 661 if (skobj->BBox()) { | 623 if (skobj->has_BBox()) { |
| 662 canvas->clipRect(*skobj->BBox(), SkRegion::kIntersect_Op, true); // TOD
O(edisonn): AA from settings. | 624 canvas->clipRect(skobj->BBox(pdfContext->fPdfDoc), SkRegion::kIntersect_
Op, true); // TODO(edisonn): AA from settings. |
| 663 } | 625 } |
| 664 | 626 |
| 665 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. | 627 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. |
| 666 // For this PdfContentsTokenizer needs to be extended. | 628 // For this PdfContentsTokenizer needs to be extended. |
| 667 | 629 |
| 668 SkPdfStream* stream = NULL; | 630 SkPdfStream* stream = (SkPdfStream*)skobj; |
| 669 skobj->doc()->mapper()->mapStream(skobj, &stream); | |
| 670 | 631 |
| 671 SkPdfPodofoTokenizer* tokenizer = skobj->doc()->tokenizerOfStream(stream); | 632 SkPdfNativeTokenizer* tokenizer = pdfContext->fPdfDoc->tokenizerOfStream(str
eam); |
| 672 if (tokenizer != NULL) { | 633 if (tokenizer != NULL) { |
| 673 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); | 634 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); |
| 674 looper.loop(); | 635 looper.loop(); |
| 675 delete tokenizer; | 636 delete tokenizer; |
| 676 } | 637 } |
| 677 | 638 |
| 678 // TODO(edisonn): should we restore the variable stack at the same state? | 639 // TODO(edisonn): should we restore the variable stack at the same state? |
| 679 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | 640 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. |
| 680 canvas->restore(); | 641 canvas->restore(); |
| 681 PdfOp_Q(pdfContext, canvas, NULL); | 642 PdfOp_Q(pdfContext, canvas, NULL); |
| 682 return kPartial_PdfResult; | 643 return kPartial_PdfResult; |
| 683 } | 644 } |
| 684 | 645 |
| 685 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
& obj) { | 646 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfObje
ct* obj) { |
| 686 return kNYI_PdfResult; | 647 return kNYI_PdfResult; |
| 687 } | 648 } |
| 688 | 649 |
| 689 PdfResult doType3Char(PdfContext* pdfContext, SkCanvas* canvas, SkPdfObject* sko
bj, SkRect bBox, SkMatrix matrix, double textSize) { | 650 PdfResult doType3Char(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfObjec
t* skobj, SkRect bBox, SkMatrix matrix, double textSize) { |
| 690 if (!skobj) { | 651 if (!skobj || !skobj->hasStream()) { |
| 691 return kIgnoreError_PdfResult; | 652 return kIgnoreError_PdfResult; |
| 692 } | 653 } |
| 693 | 654 |
| 694 PdfOp_q(pdfContext, canvas, NULL); | 655 PdfOp_q(pdfContext, canvas, NULL); |
| 695 canvas->save(); | 656 canvas->save(); |
| 696 | 657 |
| 697 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 658 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
| 698 pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), Sk
DoubleToScalar(textSize)); | 659 pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), Sk
DoubleToScalar(textSize)); |
| 699 | 660 |
| 700 pdfContext->fGraphicsState.fMatrix = pdfContext->fGraphicsState.fMatrixTm; | 661 pdfContext->fGraphicsState.fMatrix = pdfContext->fGraphicsState.fMatrixTm; |
| 701 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix; | 662 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix; |
| 702 | 663 |
| 703 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); | 664 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); |
| 704 | 665 |
| 705 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 666 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
| 706 | 667 |
| 707 SkRect rm = bBox; | 668 SkRect rm = bBox; |
| 708 pdfContext->fGraphicsState.fMatrix.mapRect(&rm); | 669 pdfContext->fGraphicsState.fMatrix.mapRect(&rm); |
| 709 | 670 |
| 710 SkTraceRect(rm, "bbox mapped"); | 671 SkTraceRect(rm, "bbox mapped"); |
| 711 | 672 |
| 712 canvas->clipRect(bBox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA
from settings. | 673 canvas->clipRect(bBox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA
from settings. |
| 713 | 674 |
| 714 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. | 675 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. |
| 715 // For this PdfContentsTokenizer needs to be extended. | 676 // For this PdfContentsTokenizer needs to be extended. |
| 716 | 677 |
| 717 SkPdfStream* stream = NULL; | 678 SkPdfStream* stream = (SkPdfStream*)skobj; |
| 718 skobj->doc()->mapper()->mapStream(skobj, &stream); | |
| 719 | 679 |
| 720 SkPdfPodofoTokenizer* tokenizer = skobj->doc()->tokenizerOfStream(stream); | 680 SkPdfNativeTokenizer* tokenizer = pdfContext->fPdfDoc->tokenizerOfStream(str
eam); |
| 721 if (tokenizer != NULL) { | 681 if (tokenizer != NULL) { |
| 722 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); | 682 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); |
| 723 looper.loop(); | 683 looper.loop(); |
| 724 delete tokenizer; | 684 delete tokenizer; |
| 725 } | 685 } |
| 726 | 686 |
| 727 // TODO(edisonn): should we restore the variable stack at the same state? | 687 // TODO(edisonn): should we restore the variable stack at the same state? |
| 728 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | 688 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. |
| 729 canvas->restore(); | 689 canvas->restore(); |
| 730 PdfOp_Q(pdfContext, canvas, NULL); | 690 PdfOp_Q(pdfContext, canvas, NULL); |
| 731 | 691 |
| 732 return kPartial_PdfResult; | 692 return kPartial_PdfResult; |
| 733 } | 693 } |
| 734 | 694 |
| 735 | 695 |
| 736 // TODO(edisonn): faster, have the property on the SkPdfObject itself? | 696 // TODO(edisonn): make sure the pointer is unique |
| 737 std::set<const void*> gInRendering; | 697 std::set<const SkPdfObject*> gInRendering; |
| 738 | 698 |
| 739 class CheckRecursiveRendering { | 699 class CheckRecursiveRendering { |
| 740 const void* fUniqueData; | 700 const SkPdfObject* fUniqueData; |
| 741 public: | 701 public: |
| 742 CheckRecursiveRendering(const SkPdfObject* obj) : fUniqueData(obj->data()) { | 702 CheckRecursiveRendering(const SkPdfObject* obj) : fUniqueData(obj) { |
| 743 gInRendering.insert(obj); | 703 gInRendering.insert(obj); |
| 744 } | 704 } |
| 745 | 705 |
| 746 ~CheckRecursiveRendering() { | 706 ~CheckRecursiveRendering() { |
| 747 //SkASSERT(fObj.fInRendering); | 707 //SkASSERT(fObj.fInRendering); |
| 748 gInRendering.erase(fUniqueData); | 708 gInRendering.erase(fUniqueData); |
| 749 } | 709 } |
| 750 | 710 |
| 751 static bool IsInRendering(const SkPdfObject* obj) { | 711 static bool IsInRendering(const SkPdfObject* obj) { |
| 752 return gInRendering.find(obj->data()) != gInRendering.end(); | 712 return gInRendering.find(obj) != gInRendering.end(); |
| 753 } | 713 } |
| 754 }; | 714 }; |
| 755 | 715 |
| 756 PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfObject&
obj) { | 716 PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfObject*
obj) { |
| 757 if (CheckRecursiveRendering::IsInRendering(&obj)) { | 717 if (CheckRecursiveRendering::IsInRendering(obj)) { |
| 758 // Oops, corrupt PDF! | 718 // Oops, corrupt PDF! |
| 759 return kIgnoreError_PdfResult; | 719 return kIgnoreError_PdfResult; |
| 760 } | 720 } |
| 761 | 721 |
| 762 CheckRecursiveRendering checkRecursion(&obj); | 722 CheckRecursiveRendering checkRecursion(obj); |
| 763 | 723 |
| 764 // TODO(edisonn): check type | 724 switch (pdfContext->fPdfDoc->mapper()->mapXObjectDictionary(obj)) |
| 765 SkPdfXObjectDictionary* skobj = NULL; | |
| 766 if (!obj.doc()->mapper()->mapXObjectDictionary(&obj, &skobj)) return kIgnore
Error_PdfResult; | |
| 767 | |
| 768 if (!skobj) return kIgnoreError_PdfResult; | |
| 769 | |
| 770 PdfResult ret = kIgnoreError_PdfResult; | |
| 771 switch (skobj->getType()) | |
| 772 { | 725 { |
| 773 case kImageDictionary_SkPdfObjectType: | 726 case kImageDictionary_SkPdfObjectType: |
| 774 ret = doXObject_Image(pdfContext, canvas, skobj->asImageDictionary()
); | 727 return doXObject_Image(pdfContext, canvas, (SkPdfImageDictionary*)ob
j); |
| 775 break; | |
| 776 case kType1FormDictionary_SkPdfObjectType: | 728 case kType1FormDictionary_SkPdfObjectType: |
| 777 ret = doXObject_Form(pdfContext, canvas, skobj->asType1FormDictionar
y()); | 729 return doXObject_Form(pdfContext, canvas, (SkPdfType1FormDictionary*
)obj); |
| 778 break; | |
| 779 //case kObjectDictionaryXObjectPS_SkPdfObjectType: | 730 //case kObjectDictionaryXObjectPS_SkPdfObjectType: |
| 780 //return doXObject_PS(skxobj.asPS()); | 731 //return doXObject_PS(skxobj.asPS()); |
| 732 default: |
| 733 return kIgnoreError_PdfResult; |
| 781 } | 734 } |
| 782 | |
| 783 delete skobj; | |
| 784 return ret; | |
| 785 } | 735 } |
| 786 | 736 |
| 787 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 737 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 788 pdfContext->fStateStack.push(pdfContext->fGraphicsState); | 738 pdfContext->fStateStack.push(pdfContext->fGraphicsState); |
| 789 canvas->save(); | 739 canvas->save(); |
| 790 return kOK_PdfResult; | 740 return kOK_PdfResult; |
| 791 } | 741 } |
| 792 | 742 |
| 793 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 743 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 794 pdfContext->fGraphicsState = pdfContext->fStateStack.top(); | 744 pdfContext->fGraphicsState = pdfContext->fStateStack.top(); |
| 795 pdfContext->fStateStack.pop(); | 745 pdfContext->fStateStack.pop(); |
| 796 canvas->restore(); | 746 canvas->restore(); |
| 797 return kOK_PdfResult; | 747 return kOK_PdfResult; |
| 798 } | 748 } |
| 799 | 749 |
| 800 PdfResult PdfOp_cm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 750 PdfResult PdfOp_cm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 801 double array[6]; | 751 double array[6]; |
| 802 for (int i = 0 ; i < 6 ; i++) { | 752 for (int i = 0 ; i < 6 ; i++) { |
| 803 array[5 - i] = pdfContext->fObjectStack.top()->asNumber()->value(); | 753 array[5 - i] = pdfContext->fObjectStack.top()->numberValue(); |
| 804 pdfContext->fObjectStack.pop(); | 754 pdfContext->fObjectStack.pop(); |
| 805 } | 755 } |
| 806 | 756 |
| 807 // a b | 757 // a b |
| 808 // c d | 758 // c d |
| 809 // e f | 759 // e f |
| 810 | 760 |
| 811 // 0 1 | 761 // 0 1 |
| 812 // 2 3 | 762 // 2 3 |
| 813 // 4 5 | 763 // 4 5 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 828 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "cm"); | 778 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "cm"); |
| 829 #endif | 779 #endif |
| 830 | 780 |
| 831 return kOK_PdfResult; | 781 return kOK_PdfResult; |
| 832 } | 782 } |
| 833 | 783 |
| 834 //leading TL Set the text leading, Tl | 784 //leading TL Set the text leading, Tl |
| 835 //, to leading, which is a number expressed in unscaled text | 785 //, to leading, which is a number expressed in unscaled text |
| 836 //space units. Text leading is used only by the T*, ', and " operators. Initial
value: 0. | 786 //space units. Text leading is used only by the T*, ', and " operators. Initial
value: 0. |
| 837 PdfResult PdfOp_TL(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 787 PdfResult PdfOp_TL(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 838 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 788 double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fOb
jectStack.pop(); |
| 839 | 789 |
| 840 pdfContext->fGraphicsState.fTextLeading = ty; | 790 pdfContext->fGraphicsState.fTextLeading = ty; |
| 841 | 791 |
| 842 return kOK_PdfResult; | 792 return kOK_PdfResult; |
| 843 } | 793 } |
| 844 | 794 |
| 845 PdfResult PdfOp_Td(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 795 PdfResult PdfOp_Td(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 846 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 796 double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObje
ctStack.pop(); |
| 847 double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 797 double tx = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObje
ctStack.pop(); |
| 848 | 798 |
| 849 double array[6] = {1, 0, 0, 1, tx, ty}; | 799 double array[6] = {1, 0, 0, 1, tx, ty}; |
| 850 SkMatrix matrix = SkMatrixFromPdfMatrix(array); | 800 SkMatrix matrix = SkMatrixFromPdfMatrix(array); |
| 851 | 801 |
| 852 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 802 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
| 853 pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); | 803 pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); |
| 854 | 804 |
| 855 return kPartial_PdfResult; | 805 return kPartial_PdfResult; |
| 856 } | 806 } |
| 857 | 807 |
| 858 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 808 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 859 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 809 double ty = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObje
ctStack.pop(); |
| 860 double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 810 double tx = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObje
ctStack.pop(); |
| 861 | 811 |
| 862 // TODO(edisonn): Create factory methods or constructors so podofo is hidden | 812 // TODO(edisonn): Create factory methods or constructors so native is hidden |
| 863 SkPdfNumber* _ty = pdfContext->fPdfDoc->createNumber(-ty); | 813 SkPdfReal* _ty = pdfContext->fPdfDoc->createReal(-ty); |
| 864 pdfContext->fObjectStack.push(_ty); | 814 pdfContext->fObjectStack.push(_ty); |
| 865 | 815 |
| 866 PdfOp_TL(pdfContext, canvas, looper); | 816 PdfOp_TL(pdfContext, canvas, looper); |
| 867 | 817 |
| 868 SkPdfNumber* vtx = pdfContext->fPdfDoc->createNumber(tx); | 818 SkPdfReal* vtx = pdfContext->fPdfDoc->createReal(tx); |
| 869 pdfContext->fObjectStack.push(vtx); | 819 pdfContext->fObjectStack.push(vtx); |
| 870 | 820 |
| 871 SkPdfNumber* vty = pdfContext->fPdfDoc->createNumber(ty); | 821 SkPdfReal* vty = pdfContext->fPdfDoc->createReal(ty); |
| 872 pdfContext->fObjectStack.push(vty); | 822 pdfContext->fObjectStack.push(vty); |
| 873 | 823 |
| 874 PdfResult ret = PdfOp_Td(pdfContext, canvas, looper); | 824 PdfResult ret = PdfOp_Td(pdfContext, canvas, looper); |
| 875 | 825 |
| 876 // TODO(edisonn): delete all the objects after rendering was complete, in th
is way pdf is rendered faster | 826 // TODO(edisonn): delete all the objects after rendering was complete, in th
is way pdf is rendered faster |
| 877 // and the cleanup can happen while the user looks at the image | 827 // and the cleanup can happen while the user looks at the image |
| 878 delete _ty; | 828 delete _ty; |
| 879 delete vtx; | 829 delete vtx; |
| 880 delete vty; | 830 delete vty; |
| 881 | 831 |
| 882 return ret; | 832 return ret; |
| 883 } | 833 } |
| 884 | 834 |
| 885 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 835 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 886 double f = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 836 double f = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjec
tStack.pop(); |
| 887 double e = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 837 double e = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjec
tStack.pop(); |
| 888 double d = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 838 double d = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjec
tStack.pop(); |
| 889 double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 839 double c = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjec
tStack.pop(); |
| 890 double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 840 double b = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjec
tStack.pop(); |
| 891 double a = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 841 double a = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fObjec
tStack.pop(); |
| 892 | 842 |
| 893 double array[6]; | 843 double array[6]; |
| 894 array[0] = a; | 844 array[0] = a; |
| 895 array[1] = b; | 845 array[1] = b; |
| 896 array[2] = c; | 846 array[2] = c; |
| 897 array[3] = d; | 847 array[3] = d; |
| 898 array[4] = e; | 848 array[4] = e; |
| 899 array[5] = f; | 849 array[5] = f; |
| 900 | 850 |
| 901 SkMatrix matrix = SkMatrixFromPdfMatrix(array); | 851 SkMatrix matrix = SkMatrixFromPdfMatrix(array); |
| 902 matrix.postConcat(pdfContext->fGraphicsState.fMatrix); | 852 matrix.postConcat(pdfContext->fGraphicsState.fMatrix); |
| 903 | 853 |
| 904 // TODO(edisonn): Text positioning. | 854 // TODO(edisonn): Text positioning. |
| 905 pdfContext->fGraphicsState.fMatrixTm = matrix; | 855 pdfContext->fGraphicsState.fMatrixTm = matrix; |
| 906 pdfContext->fGraphicsState.fMatrixTlm = matrix;; | 856 pdfContext->fGraphicsState.fMatrixTlm = matrix;; |
| 907 | 857 |
| 908 return kPartial_PdfResult; | 858 return kPartial_PdfResult; |
| 909 } | 859 } |
| 910 | 860 |
| 911 //— T* Move to the start of the next line. This operator has the same effect as
the code | 861 //— T* Move to the start of the next line. This operator has the same effect as
the code |
| 912 //0 Tl Td | 862 //0 Tl Td |
| 913 //where Tl is the current leading parameter in the text state | 863 //where Tl is the current leading parameter in the text state |
| 914 PdfResult PdfOp_T_star(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper) { | 864 PdfResult PdfOp_T_star(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper) { |
| 915 SkPdfNumber* zero = pdfContext->fPdfDoc->createNumber(0.0); | 865 SkPdfReal* zero = pdfContext->fPdfDoc->createReal(0.0); |
| 916 SkPdfNumber* tl = pdfContext->fPdfDoc->createNumber(pdfContext->fGraphicsSta
te.fTextLeading); | 866 SkPdfReal* tl = pdfContext->fPdfDoc->createReal(pdfContext->fGraphicsState.f
TextLeading); |
| 917 | 867 |
| 918 pdfContext->fObjectStack.push(zero); | 868 pdfContext->fObjectStack.push(zero); |
| 919 pdfContext->fObjectStack.push(tl); | 869 pdfContext->fObjectStack.push(tl); |
| 920 | 870 |
| 921 PdfResult ret = PdfOp_Td(pdfContext, canvas, looper); | 871 PdfResult ret = PdfOp_Td(pdfContext, canvas, looper); |
| 922 | 872 |
| 923 delete zero; // TODO(edisonn): do not alocate and delete constants! | 873 delete zero; // TODO(edisonn): do not alocate and delete constants! |
| 924 delete tl; | 874 delete tl; |
| 925 | 875 |
| 926 return ret; | 876 return ret; |
| 927 } | 877 } |
| 928 | 878 |
| 929 PdfResult PdfOp_m(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 879 PdfResult PdfOp_m(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 930 if (pdfContext->fGraphicsState.fPathClosed) { | 880 if (pdfContext->fGraphicsState.fPathClosed) { |
| 931 pdfContext->fGraphicsState.fPath.reset(); | 881 pdfContext->fGraphicsState.fPath.reset(); |
| 932 pdfContext->fGraphicsState.fPathClosed = false; | 882 pdfContext->fGraphicsState.fPathClosed = false; |
| 933 } | 883 } |
| 934 | 884 |
| 935 pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); | 885 pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->number
Value(); pdfContext->fObjectStack.pop(); |
| 936 pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); | 886 pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->number
Value(); pdfContext->fObjectStack.pop(); |
| 937 | 887 |
| 938 pdfContext->fGraphicsState.fPath.moveTo(SkDoubleToScalar(pdfContext->fGraphi
csState.fCurPosX), | 888 pdfContext->fGraphicsState.fPath.moveTo(SkDoubleToScalar(pdfContext->fGraphi
csState.fCurPosX), |
| 939 SkDoubleToScalar(pdfContext->fGraphics
State.fCurPosY)); | 889 SkDoubleToScalar(pdfContext->fGraphics
State.fCurPosY)); |
| 940 | 890 |
| 941 return kOK_PdfResult; | 891 return kOK_PdfResult; |
| 942 } | 892 } |
| 943 | 893 |
| 944 PdfResult PdfOp_l(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 894 PdfResult PdfOp_l(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 945 if (pdfContext->fGraphicsState.fPathClosed) { | 895 if (pdfContext->fGraphicsState.fPathClosed) { |
| 946 pdfContext->fGraphicsState.fPath.reset(); | 896 pdfContext->fGraphicsState.fPath.reset(); |
| 947 pdfContext->fGraphicsState.fPathClosed = false; | 897 pdfContext->fGraphicsState.fPathClosed = false; |
| 948 } | 898 } |
| 949 | 899 |
| 950 pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); | 900 pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->number
Value(); pdfContext->fObjectStack.pop(); |
| 951 pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); | 901 pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->number
Value(); pdfContext->fObjectStack.pop(); |
| 952 | 902 |
| 953 pdfContext->fGraphicsState.fPath.lineTo(SkDoubleToScalar(pdfContext->fGraphi
csState.fCurPosX), | 903 pdfContext->fGraphicsState.fPath.lineTo(SkDoubleToScalar(pdfContext->fGraphi
csState.fCurPosX), |
| 954 SkDoubleToScalar(pdfContext->fGraphics
State.fCurPosY)); | 904 SkDoubleToScalar(pdfContext->fGraphics
State.fCurPosY)); |
| 955 | 905 |
| 956 return kOK_PdfResult; | 906 return kOK_PdfResult; |
| 957 } | 907 } |
| 958 | 908 |
| 959 PdfResult PdfOp_c(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 909 PdfResult PdfOp_c(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 960 if (pdfContext->fGraphicsState.fPathClosed) { | 910 if (pdfContext->fGraphicsState.fPathClosed) { |
| 961 pdfContext->fGraphicsState.fPath.reset(); | 911 pdfContext->fGraphicsState.fPath.reset(); |
| 962 pdfContext->fGraphicsState.fPathClosed = false; | 912 pdfContext->fGraphicsState.fPathClosed = false; |
| 963 } | 913 } |
| 964 | 914 |
| 965 double y3 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 915 double y3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 966 double x3 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 916 double x3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 967 double y2 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 917 double y2 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 968 double x2 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 918 double x2 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 969 double y1 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 919 double y1 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 970 double x1 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 920 double x1 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 971 | 921 |
| 972 pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToSca
lar(y1), | 922 pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToSca
lar(y1), |
| 973 SkDoubleToScalar(x2), SkDoubleToScal
ar(y2), | 923 SkDoubleToScalar(x2), SkDoubleToScal
ar(y2), |
| 974 SkDoubleToScalar(x3), SkDoubleToScal
ar(y3)); | 924 SkDoubleToScalar(x3), SkDoubleToScal
ar(y3)); |
| 975 | 925 |
| 976 pdfContext->fGraphicsState.fCurPosX = x3; | 926 pdfContext->fGraphicsState.fCurPosX = x3; |
| 977 pdfContext->fGraphicsState.fCurPosY = y3; | 927 pdfContext->fGraphicsState.fCurPosY = y3; |
| 978 | 928 |
| 979 return kOK_PdfResult; | 929 return kOK_PdfResult; |
| 980 } | 930 } |
| 981 | 931 |
| 982 PdfResult PdfOp_v(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 932 PdfResult PdfOp_v(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 983 if (pdfContext->fGraphicsState.fPathClosed) { | 933 if (pdfContext->fGraphicsState.fPathClosed) { |
| 984 pdfContext->fGraphicsState.fPath.reset(); | 934 pdfContext->fGraphicsState.fPath.reset(); |
| 985 pdfContext->fGraphicsState.fPathClosed = false; | 935 pdfContext->fGraphicsState.fPathClosed = false; |
| 986 } | 936 } |
| 987 | 937 |
| 988 double y3 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 938 double y3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 989 double x3 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 939 double x3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 990 double y2 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 940 double y2 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 991 double x2 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 941 double x2 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 992 double y1 = pdfContext->fGraphicsState.fCurPosY; | 942 double y1 = pdfContext->fGraphicsState.fCurPosY; |
| 993 double x1 = pdfContext->fGraphicsState.fCurPosX; | 943 double x1 = pdfContext->fGraphicsState.fCurPosX; |
| 994 | 944 |
| 995 pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToSca
lar(y1), | 945 pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToSca
lar(y1), |
| 996 SkDoubleToScalar(x2), SkDoubleToScal
ar(y2), | 946 SkDoubleToScalar(x2), SkDoubleToScal
ar(y2), |
| 997 SkDoubleToScalar(x3), SkDoubleToScal
ar(y3)); | 947 SkDoubleToScalar(x3), SkDoubleToScal
ar(y3)); |
| 998 | 948 |
| 999 pdfContext->fGraphicsState.fCurPosX = x3; | 949 pdfContext->fGraphicsState.fCurPosX = x3; |
| 1000 pdfContext->fGraphicsState.fCurPosY = y3; | 950 pdfContext->fGraphicsState.fCurPosY = y3; |
| 1001 | 951 |
| 1002 return kOK_PdfResult; | 952 return kOK_PdfResult; |
| 1003 } | 953 } |
| 1004 | 954 |
| 1005 PdfResult PdfOp_y(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 955 PdfResult PdfOp_y(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1006 if (pdfContext->fGraphicsState.fPathClosed) { | 956 if (pdfContext->fGraphicsState.fPathClosed) { |
| 1007 pdfContext->fGraphicsState.fPath.reset(); | 957 pdfContext->fGraphicsState.fPath.reset(); |
| 1008 pdfContext->fGraphicsState.fPathClosed = false; | 958 pdfContext->fGraphicsState.fPathClosed = false; |
| 1009 } | 959 } |
| 1010 | 960 |
| 1011 double y3 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 961 double y3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 1012 double x3 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 962 double x3 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 1013 double y2 = pdfContext->fGraphicsState.fCurPosY; | 963 double y2 = pdfContext->fGraphicsState.fCurPosY; |
| 1014 double x2 = pdfContext->fGraphicsState.fCurPosX; | 964 double x2 = pdfContext->fGraphicsState.fCurPosX; |
| 1015 double y1 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 965 double y1 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 1016 double x1 = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 966 double x1 = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 1017 | 967 |
| 1018 pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToSca
lar(y1), | 968 pdfContext->fGraphicsState.fPath.cubicTo(SkDoubleToScalar(x1), SkDoubleToSca
lar(y1), |
| 1019 SkDoubleToScalar(x2), SkDoubleToScal
ar(y2), | 969 SkDoubleToScalar(x2), SkDoubleToScal
ar(y2), |
| 1020 SkDoubleToScalar(x3), SkDoubleToScal
ar(y3)); | 970 SkDoubleToScalar(x3), SkDoubleToScal
ar(y3)); |
| 1021 | 971 |
| 1022 pdfContext->fGraphicsState.fCurPosX = x3; | 972 pdfContext->fGraphicsState.fCurPosX = x3; |
| 1023 pdfContext->fGraphicsState.fCurPosY = y3; | 973 pdfContext->fGraphicsState.fCurPosY = y3; |
| 1024 | 974 |
| 1025 return kOK_PdfResult; | 975 return kOK_PdfResult; |
| 1026 } | 976 } |
| 1027 | 977 |
| 1028 PdfResult PdfOp_re(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 978 PdfResult PdfOp_re(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1029 if (pdfContext->fGraphicsState.fPathClosed) { | 979 if (pdfContext->fGraphicsState.fPathClosed) { |
| 1030 pdfContext->fGraphicsState.fPath.reset(); | 980 pdfContext->fGraphicsState.fPath.reset(); |
| 1031 pdfContext->fGraphicsState.fPathClosed = false; | 981 pdfContext->fGraphicsState.fPathClosed = false; |
| 1032 } | 982 } |
| 1033 | 983 |
| 1034 double height = pdfContext->fObjectStack.top()->asNumber()->value(); pd
fContext->fObjectStack.pop(); | 984 double height = pdfContext->fObjectStack.top()->numberValue(); pdfConte
xt->fObjectStack.pop(); |
| 1035 double width = pdfContext->fObjectStack.top()->asNumber()->value(); pd
fContext->fObjectStack.pop(); | 985 double width = pdfContext->fObjectStack.top()->numberValue(); pdfConte
xt->fObjectStack.pop(); |
| 1036 double y = pdfContext->fObjectStack.top()->asNumber()->value(); pd
fContext->fObjectStack.pop(); | 986 double y = pdfContext->fObjectStack.top()->numberValue(); pdfConte
xt->fObjectStack.pop(); |
| 1037 double x = pdfContext->fObjectStack.top()->asNumber()->value(); pd
fContext->fObjectStack.pop(); | 987 double x = pdfContext->fObjectStack.top()->numberValue(); pdfConte
xt->fObjectStack.pop(); |
| 1038 | 988 |
| 1039 pdfContext->fGraphicsState.fPath.addRect(SkDoubleToScalar(x), SkDoubleToScal
ar(y), | 989 pdfContext->fGraphicsState.fPath.addRect(SkDoubleToScalar(x), SkDoubleToScal
ar(y), |
| 1040 SkDoubleToScalar(x + width), SkDouble
ToScalar(y + height)); | 990 SkDoubleToScalar(x + width), SkDouble
ToScalar(y + height)); |
| 1041 | 991 |
| 1042 pdfContext->fGraphicsState.fCurPosX = x; | 992 pdfContext->fGraphicsState.fCurPosX = x; |
| 1043 pdfContext->fGraphicsState.fCurPosY = y + height; | 993 pdfContext->fGraphicsState.fCurPosY = y + height; |
| 1044 | 994 |
| 1045 return kOK_PdfResult; | 995 return kOK_PdfResult; |
| 1046 } | 996 } |
| 1047 | 997 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1174 // TODO(edisonn): anything else to be done once we are done with draw text?
Like restore stack? | 1124 // TODO(edisonn): anything else to be done once we are done with draw text?
Like restore stack? |
| 1175 return kPartial_PdfResult; | 1125 return kPartial_PdfResult; |
| 1176 } | 1126 } |
| 1177 | 1127 |
| 1178 //font size Tf Set the text font, Tf | 1128 //font size Tf Set the text font, Tf |
| 1179 //, to font and the text font size, Tfs, to size. font is the name of a | 1129 //, to font and the text font size, Tfs, to size. font is the name of a |
| 1180 //font resource in the Fontsubdictionary of the current resource dictionary; siz
e is | 1130 //font resource in the Fontsubdictionary of the current resource dictionary; siz
e is |
| 1181 //a number representing a scale factor. There is no initial value for either fon
t or | 1131 //a number representing a scale factor. There is no initial value for either fon
t or |
| 1182 //size; they must be specified explicitly using Tf before any text is shown. | 1132 //size; they must be specified explicitly using Tf before any text is shown. |
| 1183 PdfResult PdfOp_Tf(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1133 PdfResult PdfOp_Tf(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1184 pdfContext->fGraphicsState.fCurFontSize = pdfContext->fObjectStack.top()->as
Number()->value(); pdfContext->fObjectStack.pop(); | 1134 pdfContext->fGraphicsState.fCurFontSize = pdfContext->fObjectStack.top()->nu
mberValue(); pdfContext->fObjectStack.pop(); |
| 1185 std::string fontName = pdfContext->fObjectStack.top()->asName()->value();
pdfContext->fObjectStack.pop(); | 1135 const char* fontName = pdfContext->fObjectStack.top()->nameValue();
pdfContext->fObjectStack.pop(); |
| 1186 | 1136 |
| 1187 #ifdef PDF_TRACE | 1137 #ifdef PDF_TRACE |
| 1188 printf("font name: %s\n", fontName.c_str()); | 1138 printf("font name: %s\n", fontName); |
| 1189 #endif | 1139 #endif |
| 1190 | 1140 |
| 1191 SkPdfFontDictionary* fd = NULL; | 1141 if (pdfContext->fGraphicsState.fResources->Font(pdfContext->fPdfDoc)) { |
| 1192 if (pdfContext->fGraphicsState.fResources->Font()) { | 1142 SkPdfObject* objFont = pdfContext->fGraphicsState.fResources->Font(pdfCo
ntext->fPdfDoc)->get(fontName); |
| 1193 SkPdfObject* objFont = pdfContext->fGraphicsState.fResources->Font()->ge
t(fontName.c_str()); | 1143 objFont = pdfContext->fPdfDoc->resolveReference(objFont); |
| 1194 objFont->doc()->mapper()->mapFontDictionary(objFont, &fd); | 1144 if (kNone_SkPdfObjectType == pdfContext->fPdfDoc->mapper()->mapFontDicti
onary(objFont)) { |
| 1145 // TODO(edisonn): try to recover and draw it any way? |
| 1146 return kIgnoreError_PdfResult; |
| 1147 } |
| 1148 SkPdfFontDictionary* fd = (SkPdfFontDictionary*)objFont; |
| 1149 |
| 1150 SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(pdfContext->fPdfDoc
, fd); |
| 1151 |
| 1152 if (skfont) { |
| 1153 pdfContext->fGraphicsState.fSkFont = skfont; |
| 1154 } |
| 1195 } | 1155 } |
| 1196 | 1156 return kIgnoreError_PdfResult; |
| 1197 SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(fd); | |
| 1198 | |
| 1199 if (skfont) { | |
| 1200 pdfContext->fGraphicsState.fSkFont = skfont; | |
| 1201 } | |
| 1202 | |
| 1203 return kPartial_PdfResult; | |
| 1204 } | 1157 } |
| 1205 | 1158 |
| 1206 PdfResult PdfOp_Tj(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1159 PdfResult PdfOp_Tj(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1207 if (!pdfContext->fGraphicsState.fTextBlock) { | 1160 if (!pdfContext->fGraphicsState.fTextBlock) { |
| 1208 // TODO(edisonn): try to recover and draw it any way? | 1161 // TODO(edisonn): try to recover and draw it any way? |
| 1209 return kIgnoreError_PdfResult; | 1162 return kIgnoreError_PdfResult; |
| 1210 } | 1163 } |
| 1211 | 1164 |
| 1212 PdfResult ret = DrawText(pdfContext, | 1165 PdfResult ret = DrawText(pdfContext, |
| 1213 pdfContext->fObjectStack.top(), | 1166 pdfContext->fObjectStack.top(), |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 | 1202 |
| 1250 return kPartial_PdfResult; | 1203 return kPartial_PdfResult; |
| 1251 } | 1204 } |
| 1252 | 1205 |
| 1253 PdfResult PdfOp_TJ(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1206 PdfResult PdfOp_TJ(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1254 if (!pdfContext->fGraphicsState.fTextBlock) { | 1207 if (!pdfContext->fGraphicsState.fTextBlock) { |
| 1255 // TODO(edisonn): try to recover and draw it any way? | 1208 // TODO(edisonn): try to recover and draw it any way? |
| 1256 return kIgnoreError_PdfResult; | 1209 return kIgnoreError_PdfResult; |
| 1257 } | 1210 } |
| 1258 | 1211 |
| 1259 SkPdfArray* array = pdfContext->fObjectStack.top()->asArray(); | 1212 SkPdfArray* array = (SkPdfArray*)pdfContext->fObjectStack.top(); |
| 1260 pdfContext->fObjectStack.pop(); | 1213 pdfContext->fObjectStack.pop(); |
| 1261 | 1214 |
| 1215 if (!array->isArray()) { |
| 1216 return kIgnoreError_PdfResult; |
| 1217 } |
| 1218 |
| 1262 for( int i=0; i<static_cast<int>(array->size()); i++ ) | 1219 for( int i=0; i<static_cast<int>(array->size()); i++ ) |
| 1263 { | 1220 { |
| 1264 if( (*array)[i]->asString()) { | 1221 if( (*array)[i]->isAnyString()) { |
| 1265 SkPdfObject* obj = (*array)[i]; | 1222 SkPdfObject* obj = (*array)[i]; |
| 1266 DrawText(pdfContext, | 1223 DrawText(pdfContext, |
| 1267 obj, | 1224 obj, |
| 1268 canvas); | 1225 canvas); |
| 1269 } else if ((*array)[i]->asInteger() || (*array)[i]->asNumber()) { | 1226 } else if ((*array)[i]->isNumber()) { |
| 1270 double dx = (*array)[i]->asNumber()->value(); | 1227 double dx = (*array)[i]->numberValue(); |
| 1271 SkMatrix matrix; | 1228 SkMatrix matrix; |
| 1272 matrix.setAll(SkDoubleToScalar(1), | 1229 matrix.setAll(SkDoubleToScalar(1), |
| 1273 SkDoubleToScalar(0), | 1230 SkDoubleToScalar(0), |
| 1274 // TODO(edisonn): use writing mode, vertical/horizonta
l. | 1231 // TODO(edisonn): use writing mode, vertical/horizonta
l. |
| 1275 SkDoubleToScalar(-dx), // amount is substracted!!! | 1232 SkDoubleToScalar(-dx), // amount is substracted!!! |
| 1276 SkDoubleToScalar(0), | 1233 SkDoubleToScalar(0), |
| 1277 SkDoubleToScalar(1), | 1234 SkDoubleToScalar(1), |
| 1278 SkDoubleToScalar(0), | 1235 SkDoubleToScalar(0), |
| 1279 SkDoubleToScalar(0), | 1236 SkDoubleToScalar(0), |
| 1280 SkDoubleToScalar(0), | 1237 SkDoubleToScalar(0), |
| 1281 SkDoubleToScalar(1)); | 1238 SkDoubleToScalar(1)); |
| 1282 | 1239 |
| 1283 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 1240 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
| 1284 } | 1241 } |
| 1285 } | 1242 } |
| 1286 return kPartial_PdfResult; // TODO(edisonn): Implement fully DrawText befor
e returing OK. | 1243 return kPartial_PdfResult; // TODO(edisonn): Implement fully DrawText befor
e returing OK. |
| 1287 } | 1244 } |
| 1288 | 1245 |
| 1289 PdfResult PdfOp_CS_cs(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
or* colorOperator) { | 1246 PdfResult PdfOp_CS_cs(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
or* colorOperator) { |
| 1290 colorOperator->fColorSpace = pdfContext->fObjectStack.top()->asName()->value
(); pdfContext->fObjectStack.pop(); | 1247 colorOperator->fColorSpace = pdfContext->fObjectStack.top()->nameValue();
pdfContext->fObjectStack.pop(); |
| 1291 return kOK_PdfResult; | 1248 return kOK_PdfResult; |
| 1292 } | 1249 } |
| 1293 | 1250 |
| 1294 PdfResult PdfOp_CS(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1251 PdfResult PdfOp_CS(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1295 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); | 1252 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); |
| 1296 } | 1253 } |
| 1297 | 1254 |
| 1298 PdfResult PdfOp_cs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1255 PdfResult PdfOp_cs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1299 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); | 1256 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); |
| 1300 } | 1257 } |
| 1301 | 1258 |
| 1302 PdfResult PdfOp_SC_sc(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
or* colorOperator) { | 1259 PdfResult PdfOp_SC_sc(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
or* colorOperator) { |
| 1303 double c[4]; | 1260 double c[4]; |
| 1304 pdf_int64 v[4]; | 1261 // int64_t v[4]; |
| 1305 | 1262 |
| 1306 int n = GetColorSpaceComponents(colorOperator->fColorSpace); | 1263 int n = GetColorSpaceComponents(colorOperator->fColorSpace); |
| 1307 | 1264 |
| 1308 bool doubles = true; | 1265 bool doubles = true; |
| 1309 if (colorOperator->fColorSpace == "Indexed") { | 1266 if (strcmp(colorOperator->fColorSpace, "Indexed") == 0) { |
| 1310 doubles = false; | 1267 doubles = false; |
| 1311 } | 1268 } |
| 1312 | 1269 |
| 1313 #ifdef PDF_TRACE | 1270 #ifdef PDF_TRACE |
| 1314 printf("color space = %s, N = %i\n", colorOperator->fColorSpace.c_str(), n); | 1271 printf("color space = %s, N = %i\n", colorOperator->fColorSpace, n); |
| 1315 #endif | 1272 #endif |
| 1316 | 1273 |
| 1317 for (int i = n - 1; i >= 0 ; i--) { | 1274 for (int i = n - 1; i >= 0 ; i--) { |
| 1318 if (doubles) { | 1275 if (doubles) { |
| 1319 c[i] = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); | 1276 c[i] = pdfContext->fObjectStack.top()->numberValue(); pdfCon
text->fObjectStack.pop(); |
| 1320 } else { | 1277 // } else { |
| 1321 v[i] = pdfContext->fObjectStack.top()->asInteger()->value();
pdfContext->fObjectStack.pop(); | 1278 // v[i] = pdfContext->fObjectStack.top()->intValue(); pdfConte
xt->fObjectStack.pop(); |
| 1322 } | 1279 } |
| 1323 } | 1280 } |
| 1324 | 1281 |
| 1325 // TODO(edisonn): Now, set that color. Only DeviceRGB supported. | 1282 // TODO(edisonn): Now, set that color. Only DeviceRGB supported. |
| 1326 if (colorOperator->fColorSpace == "DeviceRGB") { | 1283 // TODO(edisonn): do possible field values to enum at parsing time! |
| 1284 // TODO(edisonn): support also abreviations /DeviceRGB == /RGB |
| 1285 if (strcmp(colorOperator->fColorSpace, "DeviceRGB") == 0 || strcmp(colorOper
ator->fColorSpace, "RGB") == 0) { |
| 1327 colorOperator->setRGBColor(SkColorSetRGB(255*c[0], 255*c[1], 255*c[2])); | 1286 colorOperator->setRGBColor(SkColorSetRGB(255*c[0], 255*c[1], 255*c[2])); |
| 1328 } | 1287 } |
| 1329 return kPartial_PdfResult; | 1288 return kPartial_PdfResult; |
| 1330 } | 1289 } |
| 1331 | 1290 |
| 1332 PdfResult PdfOp_SC(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1291 PdfResult PdfOp_SC(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1333 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); | 1292 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); |
| 1334 } | 1293 } |
| 1335 | 1294 |
| 1336 PdfResult PdfOp_sc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1295 PdfResult PdfOp_sc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1337 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); | 1296 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); |
| 1338 } | 1297 } |
| 1339 | 1298 |
| 1340 PdfResult PdfOp_SCN_scn(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOper
ator* colorOperator) { | 1299 PdfResult PdfOp_SCN_scn(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOper
ator* colorOperator) { |
| 1341 PdfString name; | 1300 //SkPdfString* name; |
| 1342 | 1301 if (pdfContext->fObjectStack.top()->isName()) { |
| 1343 if (pdfContext->fObjectStack.top()->asName()) { | 1302 // TODO(edisonn): get name, pass it |
| 1344 pdfContext->fObjectStack.pop(); | 1303 pdfContext->fObjectStack.pop(); |
| 1345 } | 1304 } |
| 1346 | 1305 |
| 1347 // TODO(edisonn): SCN supports more color spaces than SCN. Read and implemen
t spec. | 1306 // TODO(edisonn): SCN supports more color spaces than SCN. Read and implemen
t spec. |
| 1348 PdfOp_SC_sc(pdfContext, canvas, colorOperator); | 1307 PdfOp_SC_sc(pdfContext, canvas, colorOperator); |
| 1349 | 1308 |
| 1350 return kPartial_PdfResult; | 1309 return kPartial_PdfResult; |
| 1351 } | 1310 } |
| 1352 | 1311 |
| 1353 PdfResult PdfOp_SCN(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
ooper) { | 1312 PdfResult PdfOp_SCN(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
ooper) { |
| 1354 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroki
ng); | 1313 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroki
ng); |
| 1355 } | 1314 } |
| 1356 | 1315 |
| 1357 PdfResult PdfOp_scn(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
ooper) { | 1316 PdfResult PdfOp_scn(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
ooper) { |
| 1358 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStr
oking); | 1317 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStr
oking); |
| 1359 } | 1318 } |
| 1360 | 1319 |
| 1361 PdfResult PdfOp_G_g(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator
* colorOperator) { | 1320 PdfResult PdfOp_G_g(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator
* colorOperator) { |
| 1362 double gray = pdfContext->fObjectStack.top()->asNumber()->value(); pdfCo
ntext->fObjectStack.pop(); | 1321 /*double gray = */pdfContext->fObjectStack.top()->numberValue(); pdfCont
ext->fObjectStack.pop(); |
| 1363 return kNYI_PdfResult; | 1322 return kNYI_PdfResult; |
| 1364 } | 1323 } |
| 1365 | 1324 |
| 1366 PdfResult PdfOp_G(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1325 PdfResult PdfOp_G(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1367 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); | 1326 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); |
| 1368 } | 1327 } |
| 1369 | 1328 |
| 1370 PdfResult PdfOp_g(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1329 PdfResult PdfOp_g(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1371 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
g); | 1330 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
g); |
| 1372 } | 1331 } |
| 1373 | 1332 |
| 1374 PdfResult PdfOp_RG_rg(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
or* colorOperator) { | 1333 PdfResult PdfOp_RG_rg(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
or* colorOperator) { |
| 1375 double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1334 double b = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 1376 double g = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1335 double g = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 1377 double r = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1336 double r = pdfContext->fObjectStack.top()->numberValue(); pdfContext->fO
bjectStack.pop(); |
| 1378 | 1337 |
| 1379 colorOperator->fColorSpace = "DeviceRGB"; | 1338 colorOperator->fColorSpace = "DeviceRGB"; |
| 1380 colorOperator->setRGBColor(SkColorSetRGB(255*r, 255*g, 255*b)); | 1339 colorOperator->setRGBColor(SkColorSetRGB(255*r, 255*g, 255*b)); |
| 1381 return kOK_PdfResult; | 1340 return kOK_PdfResult; |
| 1382 } | 1341 } |
| 1383 | 1342 |
| 1384 PdfResult PdfOp_RG(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1343 PdfResult PdfOp_RG(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1385 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); | 1344 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); |
| 1386 } | 1345 } |
| 1387 | 1346 |
| 1388 PdfResult PdfOp_rg(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1347 PdfResult PdfOp_rg(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1389 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); | 1348 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); |
| 1390 } | 1349 } |
| 1391 | 1350 |
| 1392 PdfResult PdfOp_K_k(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator
* colorOperator) { | 1351 PdfResult PdfOp_K_k(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator
* colorOperator) { |
| 1393 // TODO(edisonn): spec has some rules about overprint, implement them. | 1352 // TODO(edisonn): spec has some rules about overprint, implement them. |
| 1394 double k = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1353 /*double k = */pdfContext->fObjectStack.top()->numberValue(); pdfContext
->fObjectStack.pop(); |
| 1395 double y = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1354 /*double y = */pdfContext->fObjectStack.top()->numberValue(); pdfContext
->fObjectStack.pop(); |
| 1396 double m = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1355 /*double m = */pdfContext->fObjectStack.top()->numberValue(); pdfContext
->fObjectStack.pop(); |
| 1397 double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1356 /*double c = */pdfContext->fObjectStack.top()->numberValue(); pdfContext
->fObjectStack.pop(); |
| 1398 | 1357 |
| 1399 colorOperator->fColorSpace = "DeviceCMYK"; | 1358 colorOperator->fColorSpace = "DeviceCMYK"; |
| 1400 // TODO(edisonn): Set color. | 1359 // TODO(edisonn): Set color. |
| 1401 return kNYI_PdfResult; | 1360 return kNYI_PdfResult; |
| 1402 } | 1361 } |
| 1403 | 1362 |
| 1404 PdfResult PdfOp_K(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1363 PdfResult PdfOp_K(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1405 return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); | 1364 return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); |
| 1406 } | 1365 } |
| 1407 | 1366 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 PdfResult PdfOp_EI(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1420 PdfResult PdfOp_EI(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1462 #ifdef ASSERT_BAD_PDF_OPS | 1421 #ifdef ASSERT_BAD_PDF_OPS |
| 1463 SkASSERT(false); // must be processed in inline image looper, but let's | 1422 SkASSERT(false); // must be processed in inline image looper, but let's |
| 1464 // have the assert when testing good pdfs. | 1423 // have the assert when testing good pdfs. |
| 1465 #endif | 1424 #endif |
| 1466 return kIgnoreError_PdfResult; | 1425 return kIgnoreError_PdfResult; |
| 1467 } | 1426 } |
| 1468 | 1427 |
| 1469 //lineWidth w Set the line width in the graphics state (see “Line Width” on page
152). | 1428 //lineWidth w Set the line width in the graphics state (see “Line Width” on page
152). |
| 1470 PdfResult PdfOp_w(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1429 PdfResult PdfOp_w(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1471 double lineWidth = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); | 1430 double lineWidth = pdfContext->fObjectStack.top()->numberValue(); pdfCon
text->fObjectStack.pop(); |
| 1472 pdfContext->fGraphicsState.fLineWidth = lineWidth; | 1431 pdfContext->fGraphicsState.fLineWidth = lineWidth; |
| 1473 | 1432 |
| 1474 return kOK_PdfResult; | 1433 return kOK_PdfResult; |
| 1475 } | 1434 } |
| 1476 | 1435 |
| 1477 //lineCap J Set the line cap style in the graphics state (see “Line Cap Style” o
n page 153). | 1436 //lineCap J Set the line cap style in the graphics state (see “Line Cap Style” o
n page 153). |
| 1478 PdfResult PdfOp_J(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1437 PdfResult PdfOp_J(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1479 pdfContext->fObjectStack.pop(); | 1438 pdfContext->fObjectStack.pop(); |
| 1480 //double lineCap = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); | 1439 //double lineCap = pdfContext->fObjectStack.top()->numberValue(); pdfCon
text->fObjectStack.pop(); |
| 1481 | 1440 |
| 1482 return kNYI_PdfResult; | 1441 return kNYI_PdfResult; |
| 1483 } | 1442 } |
| 1484 | 1443 |
| 1485 //lineJoin j Set the line join style in the graphics state (see “Line Join Style
” on page 153). | 1444 //lineJoin j Set the line join style in the graphics state (see “Line Join Style
” on page 153). |
| 1486 PdfResult PdfOp_j(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1445 PdfResult PdfOp_j(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1487 pdfContext->fObjectStack.pop(); | 1446 pdfContext->fObjectStack.pop(); |
| 1488 //double lineJoin = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); | 1447 //double lineJoin = pdfContext->fObjectStack.top()->numberValue(); pdfCo
ntext->fObjectStack.pop(); |
| 1489 | 1448 |
| 1490 return kNYI_PdfResult; | 1449 return kNYI_PdfResult; |
| 1491 } | 1450 } |
| 1492 | 1451 |
| 1493 //miterLimit M Set the miter limit in the graphics state (see “Miter Limit” on p
age 153). | 1452 //miterLimit M Set the miter limit in the graphics state (see “Miter Limit” on p
age 153). |
| 1494 PdfResult PdfOp_M(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1453 PdfResult PdfOp_M(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1495 pdfContext->fObjectStack.pop(); | 1454 pdfContext->fObjectStack.pop(); |
| 1496 //double miterLimit = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); | 1455 //double miterLimit = pdfContext->fObjectStack.top()->numberValue(); pdf
Context->fObjectStack.pop(); |
| 1497 | 1456 |
| 1498 return kNYI_PdfResult; | 1457 return kNYI_PdfResult; |
| 1499 } | 1458 } |
| 1500 | 1459 |
| 1501 //dashArray dashPhase d Set the line dash pattern in the graphics state (see “Li
ne Dash Pattern” on | 1460 //dashArray dashPhase d Set the line dash pattern in the graphics state (see “Li
ne Dash Pattern” on |
| 1502 //page 155). | 1461 //page 155). |
| 1503 PdfResult PdfOp_d(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1462 PdfResult PdfOp_d(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1504 pdfContext->fObjectStack.pop(); | 1463 pdfContext->fObjectStack.pop(); |
| 1505 pdfContext->fObjectStack.pop(); | 1464 pdfContext->fObjectStack.pop(); |
| 1506 | 1465 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1519 //fies the output device’s default flatness tolerance. | 1478 //fies the output device’s default flatness tolerance. |
| 1520 PdfResult PdfOp_i(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1479 PdfResult PdfOp_i(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1521 pdfContext->fObjectStack.pop(); | 1480 pdfContext->fObjectStack.pop(); |
| 1522 | 1481 |
| 1523 return kNYI_PdfResult; | 1482 return kNYI_PdfResult; |
| 1524 } | 1483 } |
| 1525 | 1484 |
| 1526 //dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictN
ame is | 1485 //dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictN
ame is |
| 1527 //the name of a graphics state parameter dictionary in the ExtGState subdictiona
ry of the current resource dictionary (see the next section). | 1486 //the name of a graphics state parameter dictionary in the ExtGState subdictiona
ry of the current resource dictionary (see the next section). |
| 1528 PdfResult PdfOp_gs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1487 PdfResult PdfOp_gs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1529 std::string name = pdfContext->fObjectStack.top()->asName()->value(); pdf
Context->fObjectStack.pop(); | 1488 const char* name = pdfContext->fObjectStack.top()->nameValue(); pdfContex
t->fObjectStack.pop(); |
| 1530 | 1489 |
| 1531 #ifdef PDF_TRACE | 1490 #ifdef PDF_TRACE |
| 1532 std::string str; | 1491 std::string str; |
| 1533 #endif | 1492 #endif |
| 1534 | 1493 |
| 1535 //Next, get the ExtGState Dictionary from the Resource Dictionary: | 1494 //Next, get the ExtGState Dictionary from the Resource Dictionary: |
| 1536 const SkPdfDictionary* extGStateDictionary = pdfContext->fGraphicsState.fRes
ources->ExtGState(); | 1495 SkPdfDictionary* extGStateDictionary = pdfContext->fGraphicsState.fResources
->ExtGState(pdfContext->fPdfDoc); |
| 1537 | 1496 |
| 1538 if (extGStateDictionary == NULL) { | 1497 if (extGStateDictionary == NULL) { |
| 1539 #ifdef PDF_TRACE | 1498 #ifdef PDF_TRACE |
| 1540 printf("ExtGState is NULL!\n"); | 1499 printf("ExtGState is NULL!\n"); |
| 1541 #endif | 1500 #endif |
| 1542 return kIgnoreError_PdfResult; | 1501 return kIgnoreError_PdfResult; |
| 1543 } | 1502 } |
| 1544 | 1503 |
| 1545 SkPdfObject* value = extGStateDictionary->get(name.c_str()); | 1504 SkPdfObject* value = pdfContext->fPdfDoc->resolveReference(extGStateDictiona
ry->get(name)); |
| 1546 | 1505 |
| 1547 SkPdfGraphicsStateDictionary* gs = NULL; | 1506 if (kNone_SkPdfObjectType == pdfContext->fPdfDoc->mapper()->mapGraphicsState
Dictionary(value)) { |
| 1548 value->doc()->mapper()->mapGraphicsStateDictionary(value, &gs); | 1507 return kIgnoreError_PdfResult; |
| 1508 } |
| 1509 SkPdfGraphicsStateDictionary* gs = (SkPdfGraphicsStateDictionary*)value; |
| 1549 | 1510 |
| 1550 // TODO(edisonn): now load all those properties in graphic state. | 1511 // TODO(edisonn): now load all those properties in graphic state. |
| 1551 if (gs == NULL) { | 1512 if (gs == NULL) { |
| 1552 return kIgnoreError_PdfResult; | 1513 return kIgnoreError_PdfResult; |
| 1553 } | 1514 } |
| 1554 | 1515 |
| 1555 if (gs->has_CA()) { | 1516 if (gs->has_CA()) { |
| 1556 pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(); | 1517 pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(pdfContext->fPdfD
oc); |
| 1557 } | 1518 } |
| 1558 | 1519 |
| 1559 if (gs->has_ca()) { | 1520 if (gs->has_ca()) { |
| 1560 pdfContext->fGraphicsState.fNonStroking.fOpacity = gs->ca(); | 1521 pdfContext->fGraphicsState.fNonStroking.fOpacity = gs->ca(pdfContext->fP
dfDoc); |
| 1561 } | 1522 } |
| 1562 | 1523 |
| 1563 if (gs->has_LW()) { | 1524 if (gs->has_LW()) { |
| 1564 pdfContext->fGraphicsState.fLineWidth = gs->LW(); | 1525 pdfContext->fGraphicsState.fLineWidth = gs->LW(pdfContext->fPdfDoc); |
| 1565 } | 1526 } |
| 1566 | 1527 |
| 1567 | |
| 1568 | |
| 1569 return kNYI_PdfResult; | 1528 return kNYI_PdfResult; |
| 1570 } | 1529 } |
| 1571 | 1530 |
| 1572 //charSpace Tc Set the character spacing, Tc | 1531 //charSpace Tc Set the character spacing, Tc |
| 1573 //, to charSpace, which is a number expressed in unscaled text space units. Char
acter spacing is used by the Tj, TJ, and ' operators. | 1532 //, to charSpace, which is a number expressed in unscaled text space units. Char
acter spacing is used by the Tj, TJ, and ' operators. |
| 1574 //Initial value: 0. | 1533 //Initial value: 0. |
| 1575 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1534 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1576 double charSpace = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); | 1535 double charSpace = pdfContext->fObjectStack.top()->numberValue(); pdfCon
text->fObjectStack.pop(); |
| 1577 pdfContext->fGraphicsState.fCharSpace = charSpace; | 1536 pdfContext->fGraphicsState.fCharSpace = charSpace; |
| 1578 | 1537 |
| 1579 return kOK_PdfResult; | 1538 return kOK_PdfResult; |
| 1580 } | 1539 } |
| 1581 | 1540 |
| 1582 //wordSpace Tw Set the word spacing, T | 1541 //wordSpace Tw Set the word spacing, T |
| 1583 //w | 1542 //w |
| 1584 //, to wordSpace, which is a number expressed in unscaled | 1543 //, to wordSpace, which is a number expressed in unscaled |
| 1585 //text space units. Word spacing is used by the Tj, TJ, and ' operators. Initial | 1544 //text space units. Word spacing is used by the Tj, TJ, and ' operators. Initial |
| 1586 //value: 0. | 1545 //value: 0. |
| 1587 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1546 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1588 double wordSpace = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); | 1547 double wordSpace = pdfContext->fObjectStack.top()->numberValue(); pdfCon
text->fObjectStack.pop(); |
| 1589 pdfContext->fGraphicsState.fWordSpace = wordSpace; | 1548 pdfContext->fGraphicsState.fWordSpace = wordSpace; |
| 1590 | 1549 |
| 1591 return kOK_PdfResult; | 1550 return kOK_PdfResult; |
| 1592 } | 1551 } |
| 1593 | 1552 |
| 1594 //scale Tz Set the horizontal scaling, Th | 1553 //scale Tz Set the horizontal scaling, Th |
| 1595 //, to (scale ˜ 100). scale is a number specifying the | 1554 //, to (scale ˜ 100). scale is a number specifying the |
| 1596 //percentage of the normal width. Initial value: 100 (normal width). | 1555 //percentage of the normal width. Initial value: 100 (normal width). |
| 1597 PdfResult PdfOp_Tz(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1556 PdfResult PdfOp_Tz(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1598 double scale = pdfContext->fObjectStack.top()->asNumber()->value(); pdfC
ontext->fObjectStack.pop(); | 1557 /*double scale = */pdfContext->fObjectStack.top()->numberValue(); pdfCon
text->fObjectStack.pop(); |
| 1599 | 1558 |
| 1600 return kNYI_PdfResult; | 1559 return kNYI_PdfResult; |
| 1601 } | 1560 } |
| 1602 | 1561 |
| 1603 //render Tr Set the text rendering mode, T | 1562 //render Tr Set the text rendering mode, T |
| 1604 //mode, to render, which is an integer. Initial value: 0. | 1563 //mode, to render, which is an integer. Initial value: 0. |
| 1605 PdfResult PdfOp_Tr(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1564 PdfResult PdfOp_Tr(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1606 double render = pdfContext->fObjectStack.top()->asNumber()->value(); pdf
Context->fObjectStack.pop(); | 1565 /*double render = */pdfContext->fObjectStack.top()->numberValue(); pdfCo
ntext->fObjectStack.pop(); |
| 1607 | 1566 |
| 1608 return kNYI_PdfResult; | 1567 return kNYI_PdfResult; |
| 1609 } | 1568 } |
| 1610 //rise Ts Set the text rise, Trise, to rise, which is a number expressed in unsc
aled text space | 1569 //rise Ts Set the text rise, Trise, to rise, which is a number expressed in unsc
aled text space |
| 1611 //units. Initial value: 0. | 1570 //units. Initial value: 0. |
| 1612 PdfResult PdfOp_Ts(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1571 PdfResult PdfOp_Ts(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1613 double rise = pdfContext->fObjectStack.top()->asNumber()->value(); pdfCo
ntext->fObjectStack.pop(); | 1572 /*double rise = */pdfContext->fObjectStack.top()->numberValue(); pdfCont
ext->fObjectStack.pop(); |
| 1614 | 1573 |
| 1615 return kNYI_PdfResult; | 1574 return kNYI_PdfResult; |
| 1616 } | 1575 } |
| 1617 | 1576 |
| 1618 //wx wy d0 | 1577 //wx wy d0 |
| 1619 PdfResult PdfOp_d0(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1578 PdfResult PdfOp_d0(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1620 pdfContext->fObjectStack.pop(); | 1579 pdfContext->fObjectStack.pop(); |
| 1621 pdfContext->fObjectStack.pop(); | 1580 pdfContext->fObjectStack.pop(); |
| 1622 | 1581 |
| 1623 return kNYI_PdfResult; | 1582 return kNYI_PdfResult; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1637 | 1596 |
| 1638 //name sh | 1597 //name sh |
| 1639 PdfResult PdfOp_sh(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1598 PdfResult PdfOp_sh(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1640 pdfContext->fObjectStack.pop(); | 1599 pdfContext->fObjectStack.pop(); |
| 1641 | 1600 |
| 1642 return kNYI_PdfResult; | 1601 return kNYI_PdfResult; |
| 1643 } | 1602 } |
| 1644 | 1603 |
| 1645 //name Do | 1604 //name Do |
| 1646 PdfResult PdfOp_Do(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1605 PdfResult PdfOp_Do(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1647 std::string name = pdfContext->fObjectStack.top()->asName()->value(); pdf
Context->fObjectStack.pop(); | 1606 const char* name = pdfContext->fObjectStack.top()->nameValue(); pdfContex
t->fObjectStack.pop(); |
| 1648 | 1607 |
| 1649 SkPdfDictionary* xObject = pdfContext->fGraphicsState.fResources->XObject()
; | 1608 SkPdfDictionary* xObject = pdfContext->fGraphicsState.fResources->XObject(p
dfContext->fPdfDoc); |
| 1650 | 1609 |
| 1651 if (xObject == NULL) { | 1610 if (xObject == NULL) { |
| 1652 #ifdef PDF_TRACE | 1611 #ifdef PDF_TRACE |
| 1653 printf("XObject is NULL!\n"); | 1612 printf("XObject is NULL!\n"); |
| 1654 #endif | 1613 #endif |
| 1655 return kIgnoreError_PdfResult; | 1614 return kIgnoreError_PdfResult; |
| 1656 } | 1615 } |
| 1657 | 1616 |
| 1658 SkPdfObject* value = xObject->get(name.c_str()); | 1617 SkPdfObject* value = xObject->get(name); |
| 1618 value = pdfContext->fPdfDoc->resolveReference(value); |
| 1659 | 1619 |
| 1660 #ifdef PDF_TRACE | 1620 #ifdef PDF_TRACE |
| 1661 // value->ToString(str); | 1621 // value->ToString(str); |
| 1662 // printf("Do object value: %s\n", str.c_str()); | 1622 // printf("Do object value: %s\n", str); |
| 1663 #endif | 1623 #endif |
| 1664 | 1624 |
| 1665 return doXObject(pdfContext, canvas, *value); | 1625 return doXObject(pdfContext, canvas, value); |
| 1666 } | 1626 } |
| 1667 | 1627 |
| 1668 //tag MP Designate a marked-content point. tag is a name object indicating the r
ole or | 1628 //tag MP Designate a marked-content point. tag is a name object indicating the r
ole or |
| 1669 //significance of the point. | 1629 //significance of the point. |
| 1670 PdfResult PdfOp_MP(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1630 PdfResult PdfOp_MP(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1671 pdfContext->fObjectStack.pop(); | 1631 pdfContext->fObjectStack.pop(); |
| 1672 | 1632 |
| 1673 return kNYI_PdfResult; | 1633 return kNYI_PdfResult; |
| 1674 } | 1634 } |
| 1675 | 1635 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1819 std::map<std::string, int>::iterator iter; | 1779 std::map<std::string, int>::iterator iter; |
| 1820 | 1780 |
| 1821 for (int i = 0 ; i < kCount_PdfResult; i++) { | 1781 for (int i = 0 ; i < kCount_PdfResult; i++) { |
| 1822 for (iter = gRenderStats[i].begin(); iter != gRenderStats[i].end(); ++it
er) { | 1782 for (iter = gRenderStats[i].begin(); iter != gRenderStats[i].end(); ++it
er) { |
| 1823 printf("%s: %s -> count %i\n", gRenderStatsNames[i], iter->first.c_s
tr(), iter->second); | 1783 printf("%s: %s -> count %i\n", gRenderStatsNames[i], iter->first.c_s
tr(), iter->second); |
| 1824 } | 1784 } |
| 1825 } | 1785 } |
| 1826 } | 1786 } |
| 1827 | 1787 |
| 1828 PdfResult PdfMainLooper::consumeToken(PdfToken& token) { | 1788 PdfResult PdfMainLooper::consumeToken(PdfToken& token) { |
| 1829 if (token.fType == kKeyword_TokenType) | 1789 char keyword[256]; |
| 1790 |
| 1791 if (token.fType == kKeyword_TokenType && token.fKeywordLength < 256) |
| 1830 { | 1792 { |
| 1793 strncpy(keyword, token.fKeyword, token.fKeywordLength); |
| 1794 keyword[token.fKeywordLength] = '\0'; |
| 1831 // TODO(edisonn): log trace flag (verbose, error, info, warning, ...) | 1795 // TODO(edisonn): log trace flag (verbose, error, info, warning, ...) |
| 1832 PdfOperatorRenderer pdfOperatorRenderer = gPdfOps[token.fKeyword]; | 1796 PdfOperatorRenderer pdfOperatorRenderer = gPdfOps[keyword]; |
| 1833 if (pdfOperatorRenderer) { | 1797 if (pdfOperatorRenderer) { |
| 1834 // caller, main work is done by pdfOperatorRenderer(...) | 1798 // caller, main work is done by pdfOperatorRenderer(...) |
| 1835 PdfTokenLooper* childLooper = NULL; | 1799 PdfTokenLooper* childLooper = NULL; |
| 1836 gRenderStats[pdfOperatorRenderer(fPdfContext, fCanvas, &childLooper)
][token.fKeyword]++; | 1800 gRenderStats[pdfOperatorRenderer(fPdfContext, fCanvas, &childLooper)
][keyword]++; |
| 1837 | 1801 |
| 1838 if (childLooper) { | 1802 if (childLooper) { |
| 1839 childLooper->setUp(this); | 1803 childLooper->setUp(this); |
| 1840 childLooper->loop(); | 1804 childLooper->loop(); |
| 1841 delete childLooper; | 1805 delete childLooper; |
| 1842 } | 1806 } |
| 1843 } else { | 1807 } else { |
| 1844 gRenderStats[kUnsupported_PdfResult][token.fKeyword]++; | 1808 gRenderStats[kUnsupported_PdfResult][keyword]++; |
| 1845 } | 1809 } |
| 1846 } | 1810 } |
| 1847 else if (token.fType == kObject_TokenType) | 1811 else if (token.fType == kObject_TokenType) |
| 1848 { | 1812 { |
| 1849 fPdfContext->fObjectStack.push( token.fObject ); | 1813 fPdfContext->fObjectStack.push( token.fObject ); |
| 1850 } | 1814 } |
| 1851 else if ( token.fType == kImageData_TokenType) { | |
| 1852 // TODO(edisonn): implement inline image. | |
| 1853 } | |
| 1854 else { | 1815 else { |
| 1816 // TODO(edisonn): deine or use assert not reached |
| 1855 return kIgnoreError_PdfResult; | 1817 return kIgnoreError_PdfResult; |
| 1856 } | 1818 } |
| 1857 return kOK_PdfResult; | 1819 return kOK_PdfResult; |
| 1858 } | 1820 } |
| 1859 | 1821 |
| 1860 void PdfMainLooper::loop() { | 1822 void PdfMainLooper::loop() { |
| 1861 PdfToken token; | 1823 PdfToken token; |
| 1862 while (readToken(fTokenizer, &token)) { | 1824 while (readToken(fTokenizer, &token)) { |
| 1863 consumeToken(token); | 1825 consumeToken(token); |
| 1864 } | 1826 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1938 // SkForm getForm(int formID); // SkForm(SkRect, .. other data) | 1900 // SkForm getForm(int formID); // SkForm(SkRect, .. other data) |
| 1939 // TODO (edisonn): Add intend when loading pdf, for example: for viewing, parsin
g all content, ... | 1901 // TODO (edisonn): Add intend when loading pdf, for example: for viewing, parsin
g all content, ... |
| 1940 // if we load the first page, and we zoom to fit to screen horizontally, then lo
ad only those | 1902 // if we load the first page, and we zoom to fit to screen horizontally, then lo
ad only those |
| 1941 // resources needed, so the preview is fast. | 1903 // resources needed, so the preview is fast. |
| 1942 // TODO (edisonn): hide parser/tokenizer behind and interface and a query langua
ge, and resolve | 1904 // TODO (edisonn): hide parser/tokenizer behind and interface and a query langua
ge, and resolve |
| 1943 // references automatically. | 1905 // references automatically. |
| 1944 | 1906 |
| 1945 bool SkPdfViewer::load(const SkString inputFileName, SkPicture* out) { | 1907 bool SkPdfViewer::load(const SkString inputFileName, SkPicture* out) { |
| 1946 std::cout << "Init: " << inputFileName.c_str() << std::endl; | 1908 std::cout << "Init: " << inputFileName.c_str() << std::endl; |
| 1947 | 1909 |
| 1948 SkPodofoParsedPDF* doc = new SkPodofoParsedPDF(inputFileName.c_str()); | 1910 SkNativeParsedPDF* doc = new SkNativeParsedPDF(inputFileName.c_str()); |
| 1949 if (!doc->pages()) | 1911 if (!doc->pages()) |
| 1950 { | 1912 { |
| 1951 std::cout << "ERROR: Empty Document" << inputFileName.c_str() << std::en
dl; | 1913 std::cout << "ERROR: Empty Document" << inputFileName.c_str() << std::en
dl; |
| 1952 return false; | 1914 return false; |
| 1953 } else { | 1915 } else { |
| 1954 | 1916 |
| 1955 for (int pn = 0; pn < doc->pages(); ++pn) { | 1917 for (int pn = 0; pn < doc->pages(); ++pn) { |
| 1956 // TODO(edisonn): implement inheritance properties as per PDF spec | 1918 // TODO(edisonn): implement inheritance properties as per PDF spec |
| 1957 //SkRect rect = page->MediaBox(); | 1919 //SkRect rect = page->MediaBox(); |
| 1958 SkRect rect = doc->MediaBox(pn); | 1920 SkRect rect = doc->MediaBox(pn); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1986 out[out.size() - 2] = 'n'; | 1948 out[out.size() - 2] = 'n'; |
| 1987 out[out.size() - 1] = 'g'; | 1949 out[out.size() - 1] = 'g'; |
| 1988 } | 1950 } |
| 1989 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG
_Type, 100); | 1951 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG
_Type, 100); |
| 1990 } | 1952 } |
| 1991 return true; | 1953 return true; |
| 1992 } | 1954 } |
| 1993 | 1955 |
| 1994 return true; | 1956 return true; |
| 1995 } | 1957 } |
| OLD | NEW |