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" |
(...skipping 19 matching lines...) Expand all Loading... |
30 | 30 |
31 // TODO(edisonn): tool, show what objects were read at least, show the ones not
even read | 31 // TODO(edisonn): tool, show what objects were read at least, show the ones not
even read |
32 // keep for each object pos in file | 32 // 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 | 33 // plug in for VS? syntax coloring, show selected object ... from the text, or f
rom rendered x,y |
34 | 34 |
35 // TODO(edisonn): security - validate all the user input, all pdf! | 35 // TODO(edisonn): security - validate all the user input, all pdf! |
36 | 36 |
37 // TODO(edisonn): put drawtext in #ifdefs, so comparations will ignore minor cha
nges in text positioning and font | 37 // 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 | 38 // this way, we look more at other features and layout in diffs |
39 | 39 |
| 40 // TODO(edisonn): move trace dump in the get functions, and mapper ones too so i
t ghappens automatically |
| 41 /* |
| 42 #ifdef PDF_TRACE |
| 43 std::string str; |
| 44 pdfContext->fGraphicsState.fResources->podofo()->ToString(str); |
| 45 printf("Print Tf Resources: %s\n", str.c_str()); |
| 46 #endif |
| 47 */ |
| 48 |
40 #include "SkPdfHeaders_autogen.h" | 49 #include "SkPdfHeaders_autogen.h" |
41 #include "SkPdfPodofoMapper_autogen.h" | 50 #include "SkPdfMapper_autogen.h" |
42 #include "SkPdfParser.h" | 51 #include "SkPdfParser.h" |
43 | 52 |
44 #include "SkPdfBasics.h" | 53 #include "SkPdfBasics.h" |
45 #include "SkPdfUtils.h" | 54 #include "SkPdfUtils.h" |
46 | 55 |
47 #include "SkPdfFont.h" | 56 #include "SkPdfFont.h" |
48 | 57 |
49 bool skpdfmap(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdf
Object** out) { | |
50 return mapObject(podofoDoc, podofoObj, out); | |
51 } | |
52 | |
53 | |
54 /* | 58 /* |
55 * TODO(edisonn): | 59 * TODO(edisonn): |
56 * - all font types and all ppdf font features | 60 * - all font types and all ppdf font features |
57 * - word spacing | 61 * - word spacing |
58 * - load font for baidu.pdf | 62 * - load font for baidu.pdf |
59 * - load font for youtube.pdf | 63 * - load font for youtube.pdf |
60 * - parser for pdf from the definition already available in pdfspec_autoge
n.py | 64 * - parser for pdf from the definition already available in pdfspec_autoge
n.py |
61 * - all docs from ~/work | 65 * - all docs from ~/work |
62 * - encapsulate podofo in the pdf api so the skpdf does not know anything about
podofo ... in progress | 66 * - encapsulate podofo in the pdf api so the skpdf does not know anything about
podofo ... in progress |
63 * - load gs/ especially smask and already known prop (skp) ... in progress | 67 * - load gs/ especially smask and already known prop (skp) ... in progress |
(...skipping 26 matching lines...) Expand all Loading... |
90 return 1; | 94 return 1; |
91 } else if (colorSpace == "DeviceRGB" || | 95 } else if (colorSpace == "DeviceRGB" || |
92 colorSpace == "CalRGB" || | 96 colorSpace == "CalRGB" || |
93 colorSpace == "Lab") { | 97 colorSpace == "Lab") { |
94 return 3; | 98 return 3; |
95 } else { | 99 } else { |
96 return 0; | 100 return 0; |
97 } | 101 } |
98 } | 102 } |
99 | 103 |
100 const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, | 104 SkMatrix SkMatrixFromPdfMatrix(double array[6]) { |
101 const PdfObject* obj, | |
102 bool resolveOneElementArrays) { | |
103 while (obj && (obj->IsReference() || (resolveOneElementArrays && | |
104 obj->IsArray() && | |
105 obj->GetArray().GetSize() == 1))) { | |
106 if (obj->IsReference()) { | |
107 // We need to force the non const, the only update we will do is for
recurssion checks. | |
108 PdfReference& ref = (PdfReference&)obj->GetReference(); | |
109 obj = pdfDoc->GetObjects().GetObject(ref); | |
110 } else { | |
111 obj = &obj->GetArray()[0]; | |
112 } | |
113 } | |
114 | |
115 return obj; | |
116 } | |
117 | |
118 static SkMatrix SkMatrixFromPdfMatrix(double array[6]) { | |
119 SkMatrix matrix; | 105 SkMatrix matrix; |
120 matrix.setAll(SkDoubleToScalar(array[0]), | 106 matrix.setAll(SkDoubleToScalar(array[0]), |
121 SkDoubleToScalar(array[2]), | 107 SkDoubleToScalar(array[2]), |
122 SkDoubleToScalar(array[4]), | 108 SkDoubleToScalar(array[4]), |
123 SkDoubleToScalar(array[1]), | 109 SkDoubleToScalar(array[1]), |
124 SkDoubleToScalar(array[3]), | 110 SkDoubleToScalar(array[3]), |
125 SkDoubleToScalar(array[5]), | 111 SkDoubleToScalar(array[5]), |
126 SkDoubleToScalar(0), | 112 SkDoubleToScalar(0), |
127 SkDoubleToScalar(0), | 113 SkDoubleToScalar(0), |
128 SkDoubleToScalar(1)); | 114 SkDoubleToScalar(1)); |
129 | 115 |
130 return matrix; | 116 return matrix; |
131 } | 117 } |
132 | 118 |
133 SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { | 119 SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { |
134 double array[6]; | 120 double array[6]; |
135 | 121 |
136 // TODO(edisonn): security issue, ret if size() != 6 | 122 // TODO(edisonn): security issue, ret if size() != 6 |
137 for (int i = 0; i < 6; i++) { | 123 for (int i = 0; i < 6; i++) { |
138 const PdfObject* elem = resolveReferenceObject(pdfArray->doc(), (*pdfArr
ay)[i]->podofo()); | 124 const SkPdfObject* elem = pdfArray->operator [](i); |
139 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { | 125 if (elem == NULL || (!elem->asNumber() && !elem->asInteger())) { |
140 return SkMatrix::I(); // TODO(edisonn): report issue | 126 return SkMatrix::I(); // TODO(edisonn): report issue |
141 } | 127 } |
142 array[i] = elem->GetReal(); | 128 array[i] = elem->asNumber() ? elem->asNumber()->value() : elem->asIntege
r()->value(); |
143 } | 129 } |
144 | 130 |
145 return SkMatrixFromPdfMatrix(array); | 131 return SkMatrixFromPdfMatrix(array); |
146 } | 132 } |
147 | 133 |
148 PdfContext* gPdfContext = NULL; | |
149 SkBitmap* gDumpBitmap = NULL; | 134 SkBitmap* gDumpBitmap = NULL; |
150 SkCanvas* gDumpCanvas = NULL; | 135 SkCanvas* gDumpCanvas = NULL; |
151 char gLastKeyword[100] = ""; | 136 char gLastKeyword[100] = ""; |
152 int gLastOpKeyword = -1; | 137 int gLastOpKeyword = -1; |
153 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
,EI,Do,EX,"; | 138 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
,EI,Do,EX,"; |
154 int gReadOp = 0; | 139 int gReadOp = 0; |
155 | 140 |
156 | 141 |
157 | 142 |
158 bool hasVisualEffect(const char* pdfOp) { | 143 bool hasVisualEffect(const char* pdfOp) { |
159 return true; | 144 return true; |
160 if (*pdfOp == '\0') return false; | 145 if (*pdfOp == '\0') return false; |
161 | 146 |
162 char markedPdfOp[100] = ","; | 147 char markedPdfOp[100] = ","; |
163 strcat(markedPdfOp, pdfOp); | 148 strcat(markedPdfOp, pdfOp); |
164 strcat(markedPdfOp, ","); | 149 strcat(markedPdfOp, ","); |
165 | 150 |
166 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); | 151 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); |
167 } | 152 } |
168 | 153 |
169 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum
entation. | 154 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum
entation. |
170 static bool readToken(SkPdfTokenizer* fTokenizer, PdfToken* token) { | 155 static bool readToken(SkPdfPodofoTokenizer* fTokenizer, PdfToken* token) { |
171 bool ret = fTokenizer->readToken(token); | 156 bool ret = fTokenizer->readToken(token); |
172 | 157 |
173 gReadOp++; | 158 gReadOp++; |
174 | 159 |
175 #ifdef PDF_TRACE_DIFF_IN_PNG | 160 #ifdef PDF_TRACE_DIFF_IN_PNG |
176 // TODO(edisonn): compare with old bitmap, and save only new bits are availa
ble, and save | 161 // TODO(edisonn): compare with old bitmap, and save only new bits are availa
ble, and save |
177 // the numbar and name of last operation, so the file name will reflect op t
hat changed. | 162 // the numbar and name of last operation, so the file name will reflect op t
hat changed. |
178 if (hasVisualEffect(gLastKeyword)) { // TODO(edisonn): and has dirty bits. | 163 if (hasVisualEffect(gLastKeyword)) { // TODO(edisonn): and has dirty bits. |
179 gDumpCanvas->flush(); | 164 gDumpCanvas->flush(); |
180 | 165 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 #endif | 311 #endif |
327 | 312 |
328 // TODO(edisonn): Report Warning, NYI | 313 // TODO(edisonn): Report Warning, NYI |
329 return SkTypeface::CreateFromName( | 314 return SkTypeface::CreateFromName( |
330 "Times New Roman", | 315 "Times New Roman", |
331 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | | 316 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | |
332 (font->IsItalic() ? SkTypeface::kItalic : 0)))
; | 317 (font->IsItalic() ? SkTypeface::kItalic : 0)))
; |
333 } | 318 } |
334 | 319 |
335 PdfResult DrawText(PdfContext* pdfContext, | 320 PdfResult DrawText(PdfContext* pdfContext, |
336 const SkPdfObject* str, | 321 const SkPdfObject* _str, |
337 SkCanvas* canvas) | 322 SkCanvas* canvas) |
338 { | 323 { |
339 | 324 |
340 SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; | 325 SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; |
341 if (skfont == NULL) { | 326 if (skfont == NULL) { |
342 skfont = SkPdfFont::Default(); | 327 skfont = SkPdfFont::Default(); |
343 } | 328 } |
344 | 329 |
| 330 const SkPdfString* str = _str->asString(); |
| 331 |
| 332 if (str == NULL) { |
| 333 // TODO(edisonn): report warning |
| 334 return kIgnoreError_PdfResult; |
| 335 } |
| 336 |
345 SkUnencodedText binary(str); | 337 SkUnencodedText binary(str); |
346 | 338 |
347 SkDecodedText decoded; | 339 SkDecodedText decoded; |
348 | 340 |
349 if (skfont->encoding() == NULL) { | 341 if (skfont->encoding() == NULL) { |
350 // TODO(edisonn): report warning | 342 // TODO(edisonn): report warning |
351 return kNYI_PdfResult; | 343 return kNYI_PdfResult; |
352 } | 344 } |
353 | 345 |
354 skfont->encoding()->decodeText(binary, &decoded); | 346 skfont->encoding()->decodeText(binary, &decoded); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 | 385 |
394 return kPartial_PdfResult; | 386 return kPartial_PdfResult; |
395 } | 387 } |
396 | 388 |
397 // TODO(edisonn): create header files with declarations! | 389 // TODO(edisonn): create header files with declarations! |
398 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); | 390 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); |
399 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); | 391 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); |
400 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); | 392 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); |
401 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); | 393 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); |
402 | 394 |
403 // TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in Get
Key? | |
404 // Always pass long form in key, and have a map of long -> short key | |
405 bool LongFromDictionary(const PdfMemDocument* pdfDoc, | |
406 const PdfDictionary& dict, | |
407 const char* key, | |
408 long* data) { | |
409 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
410 dict.GetKey(PdfName(key))); | |
411 | |
412 if (value == NULL || !value->IsNumber()) { | |
413 return false; | |
414 } | |
415 if (data == NULL) { | |
416 return true; | |
417 } | |
418 | |
419 *data = value->GetNumber(); | |
420 return true; | |
421 } | |
422 | |
423 bool LongFromDictionary(const PdfMemDocument* pdfDoc, | |
424 const PdfDictionary& dict, | |
425 const char* key, | |
426 const char* abr, | |
427 long* data) { | |
428 if (LongFromDictionary(pdfDoc, dict, key, data)) return true; | |
429 if (abr == NULL || *abr == '\0') return false; | |
430 return LongFromDictionary(pdfDoc, dict, abr, data); | |
431 } | |
432 | |
433 bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, | |
434 const PdfDictionary& dict, | |
435 const char* key, | |
436 double* data) { | |
437 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
438 dict.GetKey(PdfName(key))); | |
439 | |
440 if (value == NULL || (!value->IsReal() && !value->IsNumber())) { | |
441 return false; | |
442 } | |
443 if (data == NULL) { | |
444 return true; | |
445 } | |
446 | |
447 *data = value->GetReal(); | |
448 return true; | |
449 } | |
450 | |
451 bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, | |
452 const PdfDictionary& dict, | |
453 const char* key, | |
454 const char* abr, | |
455 double* data) { | |
456 if (DoubleFromDictionary(pdfDoc, dict, key, data)) return true; | |
457 if (abr == NULL || *abr == '\0') return false; | |
458 return DoubleFromDictionary(pdfDoc, dict, abr, data); | |
459 } | |
460 | |
461 | |
462 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, | |
463 const PdfDictionary& dict, | |
464 const char* key, | |
465 bool* data) { | |
466 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
467 dict.GetKey(PdfName(key))); | |
468 | |
469 if (value == NULL || !value->IsBool()) { | |
470 return false; | |
471 } | |
472 if (data == NULL) { | |
473 return true; | |
474 } | |
475 | |
476 *data = value->GetBool(); | |
477 return true; | |
478 } | |
479 | |
480 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, | |
481 const PdfDictionary& dict, | |
482 const char* key, | |
483 const char* abr, | |
484 bool* data) { | |
485 if (BoolFromDictionary(pdfDoc, dict, key, data)) return true; | |
486 if (abr == NULL || *abr == '\0') return false; | |
487 return BoolFromDictionary(pdfDoc, dict, abr, data); | |
488 } | |
489 | |
490 bool NameFromDictionary(const PdfMemDocument* pdfDoc, | |
491 const PdfDictionary& dict, | |
492 const char* key, | |
493 std::string* data) { | |
494 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
495 dict.GetKey(PdfName(key)), | |
496 true); | |
497 if (value == NULL || !value->IsName()) { | |
498 return false; | |
499 } | |
500 if (data == NULL) { | |
501 return true; | |
502 } | |
503 | |
504 *data = value->GetName().GetName(); | |
505 return true; | |
506 } | |
507 | |
508 bool NameFromDictionary(const PdfMemDocument* pdfDoc, | |
509 const PdfDictionary& dict, | |
510 const char* key, | |
511 const char* abr, | |
512 std::string* data) { | |
513 if (NameFromDictionary(pdfDoc, dict, key, data)) return true; | |
514 if (abr == NULL || *abr == '\0') return false; | |
515 return NameFromDictionary(pdfDoc, dict, abr, data); | |
516 } | |
517 | |
518 bool StringFromDictionary(const PdfMemDocument* pdfDoc, | |
519 const PdfDictionary& dict, | |
520 const char* key, | |
521 std::string* data) { | |
522 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
523 dict.GetKey(PdfName(key)), | |
524 true); | |
525 if (value == NULL || (!value->IsString() && !value->IsHexString())) { | |
526 return false; | |
527 } | |
528 if (data == NULL) { | |
529 return true; | |
530 } | |
531 | |
532 *data = value->GetString().GetString(); | |
533 return true; | |
534 } | |
535 | |
536 bool StringFromDictionary(const PdfMemDocument* pdfDoc, | |
537 const PdfDictionary& dict, | |
538 const char* key, | |
539 const char* abr, | |
540 std::string* data) { | |
541 if (StringFromDictionary(pdfDoc, dict, key, data)) return true; | |
542 if (abr == NULL || *abr == '\0') return false; | |
543 return StringFromDictionary(pdfDoc, dict, abr, data); | |
544 } | |
545 | |
546 /* | |
547 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, | |
548 const PdfDictionary& dict, | |
549 const char* key, | |
550 SkPdfArray** data) { | |
551 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
552 dict.GetKey(PdfName(key)), | |
553 true); | |
554 if (value == NULL || !value->IsArray()) { | |
555 return false; | |
556 } | |
557 if (data == NULL) { | |
558 return true; | |
559 } | |
560 | |
561 return mapArray(*pdfDoc, *value, data); | |
562 } | |
563 | |
564 | |
565 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, | |
566 const PdfDictionary& dict, | |
567 const char* key, | |
568 const char* abr, | |
569 SkPdfArray** data) { | |
570 if (ArrayFromDictionary(pdfDoc, dict, key, data)) return true; | |
571 if (abr == NULL || *abr == '\0') return false; | |
572 return ArrayFromDictionary(pdfDoc, dict, abr, data); | |
573 } | |
574 | |
575 | |
576 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, | |
577 const PdfDictionary& dict, | |
578 const char* key, | |
579 SkPdfDictionary** data) { | |
580 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
581 dict.GetKey(PdfName(key)), | |
582 true); | |
583 if (value == NULL || !value->IsDictionary()) { | |
584 return false; | |
585 } | |
586 if (data == NULL) { | |
587 return true; | |
588 } | |
589 | |
590 return mapDictionary(*pdfDoc, *value, data); | |
591 } | |
592 | |
593 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, | |
594 const PdfDictionary& dict, | |
595 const char* key, | |
596 const char* abr, | |
597 SkPdfDictionary** data) { | |
598 if (DictionaryFromDictionary(pdfDoc, dict, key, data)) return true; | |
599 if (abr == NULL || *abr == '\0') return false; | |
600 return DictionaryFromDictionary(pdfDoc, dict, abr, data); | |
601 } | |
602 | |
603 | |
604 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, | |
605 const PdfDictionary& dict, | |
606 const char* key, | |
607 SkPdfObject** data) { | |
608 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
609 dict.GetKey(PdfName(key)), | |
610 true); | |
611 if (value == NULL) { | |
612 return false; | |
613 } | |
614 if (data == NULL) { | |
615 return true; | |
616 } | |
617 return mapObject(*pdfDoc, *value, data); | |
618 } | |
619 | |
620 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, | |
621 const PdfDictionary& dict, | |
622 const char* key, | |
623 const char* abr, | |
624 SkPdfObject** data) { | |
625 if (ObjectFromDictionary(pdfDoc, dict, key, data)) return true; | |
626 if (abr == NULL || *abr == '\0') return false; | |
627 return ObjectFromDictionary(pdfDoc, dict, abr, data); | |
628 } | |
629 | |
630 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, | |
631 const PdfDictionary& dict, | |
632 const char* key, | |
633 SkPdfStream** data) { | |
634 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
635 dict.GetKey(PdfName(key)), | |
636 true); | |
637 if (value == NULL) { | |
638 return false; | |
639 } | |
640 if (data == NULL) { | |
641 return true; | |
642 } | |
643 return mapStream(*pdfDoc, *value, data); | |
644 } | |
645 | |
646 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, | |
647 const PdfDictionary& dict, | |
648 const char* key, | |
649 const char* abr, | |
650 SkPdfStream** data) { | |
651 if (StreamFromDictionary(pdfDoc, dict, key, data)) return true; | |
652 if (abr == NULL || *abr == '\0') return false; | |
653 return StreamFromDictionary(pdfDoc, dict, abr, data); | |
654 } | |
655 */ | |
656 | |
657 // TODO(edisonn): perf!!! | 395 // TODO(edisonn): perf!!! |
658 | 396 |
659 static SkColorTable* getGrayColortable() { | 397 static SkColorTable* getGrayColortable() { |
660 static SkColorTable* grayColortable = NULL; | 398 static SkColorTable* grayColortable = NULL; |
661 if (grayColortable == NULL) { | 399 if (grayColortable == NULL) { |
662 SkPMColor* colors = new SkPMColor[256]; | 400 SkPMColor* colors = new SkPMColor[256]; |
663 for (int i = 0 ; i < 256; i++) { | 401 for (int i = 0 ; i < 256; i++) { |
664 colors[i] = SkPreMultiplyARGB(255, i, i, i); | 402 colors[i] = SkPreMultiplyARGB(255, i, i, i); |
665 } | 403 } |
666 grayColortable = new SkColorTable(colors, 256); | 404 grayColortable = new SkColorTable(colors, 256); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 // utils | 512 // utils |
775 | 513 |
776 // TODO(edisonn): add cache, or put the bitmap property directly on the PdfObjec
t | 514 // TODO(edisonn): add cache, or put the bitmap property directly on the PdfObjec
t |
777 // TODO(edisonn): deal with colorSpaces, we could add them to SkBitmap::Config | 515 // TODO(edisonn): deal with colorSpaces, we could add them to SkBitmap::Config |
778 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
22, 444 to closest | 516 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
22, 444 to closest |
779 // skia format, through a table | 517 // skia format, through a table |
780 | 518 |
781 // this functions returns the image, it does not look at the smask. | 519 // this functions returns the image, it does not look at the smask. |
782 | 520 |
783 SkBitmap getImageFromObject(PdfContext* pdfContext, const SkPdfImageDictionary*
image, bool transparencyMask) { | 521 SkBitmap getImageFromObject(PdfContext* pdfContext, const SkPdfImageDictionary*
image, bool transparencyMask) { |
784 if (image == NULL || !image->valid()) { | 522 if (image == NULL) { |
785 // TODO(edisonn): report warning to be used in testing. | 523 // TODO(edisonn): report warning to be used in testing. |
786 return SkBitmap(); | 524 return SkBitmap(); |
787 } | 525 } |
788 | 526 |
789 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... | 527 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... |
790 // PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 528 // PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, |
791 // obj.GetDictionary().GetKey(PdfNa
me("Filter"))); | 529 // obj.GetDictionary().GetKey(PdfNa
me("Filter"))); |
792 // if (value && value->IsArray() && value->GetArray().GetSize() == 1) { | 530 // if (value && value->IsArray() && value->GetArray().GetSize() == 1) { |
793 // value = resolveReferenceObject(pdfContext->fPdfDoc, | 531 // value = resolveReferenceObject(pdfContext->fPdfDoc, |
794 // &value->GetArray()[0]); | 532 // &value->GetArray()[0]); |
(...skipping 18 matching lines...) Expand all Loading... |
813 | 551 |
814 if (imageMask) { | 552 if (imageMask) { |
815 if (bpc != 0 && bpc != 1) { | 553 if (bpc != 0 && bpc != 1) { |
816 // TODO(edisonn): report warning to be used in testing. | 554 // TODO(edisonn): report warning to be used in testing. |
817 return SkBitmap(); | 555 return SkBitmap(); |
818 } | 556 } |
819 bpc = 1; | 557 bpc = 1; |
820 } | 558 } |
821 */ | 559 */ |
822 | 560 |
823 const PdfObject* obj = image->podofo(); | |
824 | |
825 char* uncompressedStream = NULL; | 561 char* uncompressedStream = NULL; |
826 pdf_long uncompressedStreamLength = 0; | 562 pdf_long uncompressedStreamLength = 0; |
827 | 563 |
828 PdfResult ret = kPartial_PdfResult; | 564 PdfResult ret = kPartial_PdfResult; |
829 // TODO(edisonn): get rid of try/catch exceptions! We should not throw on us
er data! | 565 SkPdfStream* stream = NULL; |
830 try { | 566 image->doc()->mapper()->mapStream(image, &stream); |
831 obj->GetStream()->GetFilteredCopy(&uncompressedStream, &uncompressedStre
amLength); | 567 |
832 } catch (PdfError& e) { | 568 if (!stream || !stream->GetFilteredCopy(&uncompressedStream, &uncompressedSt
reamLength) || |
| 569 uncompressedStream == NULL || uncompressedStreamLength == 0) { |
833 // TODO(edisonn): report warning to be used in testing. | 570 // TODO(edisonn): report warning to be used in testing. |
834 return SkBitmap(); | 571 return SkBitmap(); |
835 } | 572 } |
836 | 573 |
837 int bytesPerLine = uncompressedStreamLength / height; | 574 int bytesPerLine = uncompressedStreamLength / height; |
838 #ifdef PDF_TRACE | 575 #ifdef PDF_TRACE |
839 if (uncompressedStreamLength % height != 0) { | 576 if (uncompressedStreamLength % height != 0) { |
840 printf("Warning uncompressedStreamLength % height != 0 !!!\n"); | 577 printf("Warning uncompressedStreamLength % height != 0 !!!\n"); |
841 } | 578 } |
842 #endif | 579 #endif |
843 | 580 |
844 SkBitmap bitmap = transferImageStreamToBitmap( | 581 SkBitmap bitmap = transferImageStreamToBitmap( |
845 (unsigned char*)uncompressedStream, uncompressedStreamLength, | 582 (unsigned char*)uncompressedStream, uncompressedStreamLength, |
846 width, height, bytesPerLine, | 583 width, height, bytesPerLine, |
847 bpc, colorSpace, | 584 bpc, colorSpace, |
848 transparencyMask); | 585 transparencyMask); |
849 | 586 |
850 free(uncompressedStream); | 587 free(uncompressedStream); |
851 | 588 |
852 return bitmap; | 589 return bitmap; |
853 } | 590 } |
854 | 591 |
855 SkBitmap getSmaskFromObject(PdfContext* pdfContext, const SkPdfImageDictionary*
obj) { | 592 SkBitmap getSmaskFromObject(PdfContext* pdfContext, const SkPdfImageDictionary*
obj) { |
856 const PdfObject* sMask = resolveReferenceObject(&pdfContext->fPdfDoc->podofo
(), | 593 const SkPdfImageDictionary* sMask = obj->SMask(); |
857 obj->podofo()->GetDictionary().Get
Key(PdfName("SMask"))); | |
858 | |
859 #ifdef PDF_TRACE | |
860 std::string str; | |
861 if (sMask) { | |
862 sMask->ToString(str); | |
863 printf("/SMask of /Subtype /Image: %s\n", str.c_str()); | |
864 } | |
865 #endif | |
866 | 594 |
867 if (sMask) { | 595 if (sMask) { |
868 SkPdfImageDictionary skxobjmask(&pdfContext->fPdfDoc->podofo(), sMask); | 596 return getImageFromObject(pdfContext, sMask, true); |
869 return getImageFromObject(pdfContext, &skxobjmask, true); | |
870 } | 597 } |
871 | 598 |
872 // TODO(edisonn): implement GS SMask. Default to empty right now. | 599 // TODO(edisonn): implement GS SMask. Default to empty right now. |
873 return pdfContext->fGraphicsState.fSMask; | 600 return pdfContext->fGraphicsState.fSMask; |
874 } | 601 } |
875 | 602 |
876 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfI
mageDictionary* skpdfimage) { | 603 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfI
mageDictionary* skpdfimage) { |
877 if (skpdfimage == NULL || !skpdfimage->valid()) { | 604 if (skpdfimage == NULL) { |
878 return kIgnoreError_PdfResult; | 605 return kIgnoreError_PdfResult; |
879 } | 606 } |
880 | 607 |
881 SkBitmap image = getImageFromObject(pdfContext, skpdfimage, false); | 608 SkBitmap image = getImageFromObject(pdfContext, skpdfimage, false); |
882 SkBitmap sMask = getSmaskFromObject(pdfContext, skpdfimage); | 609 SkBitmap sMask = getSmaskFromObject(pdfContext, skpdfimage); |
883 | 610 |
884 canvas->save(); | 611 canvas->save(); |
885 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 612 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
886 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); | 613 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); |
887 | 614 |
888 if (sMask.empty()) { | 615 if (sMask.empty()) { |
889 canvas->drawBitmapRect(image, dst, NULL); | 616 canvas->drawBitmapRect(image, dst, NULL); |
890 } else { | 617 } else { |
891 canvas->saveLayer(&dst, NULL); | 618 canvas->saveLayer(&dst, NULL); |
892 canvas->drawBitmapRect(image, dst, NULL); | 619 canvas->drawBitmapRect(image, dst, NULL); |
893 SkPaint xfer; | 620 SkPaint xfer; |
894 pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); | 621 pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); |
895 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode | 622 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode |
896 canvas->drawBitmapRect(sMask, dst, &xfer); | 623 canvas->drawBitmapRect(sMask, dst, &xfer); |
897 canvas->restore(); | 624 canvas->restore(); |
898 } | 625 } |
899 | 626 |
900 canvas->restore(); | 627 canvas->restore(); |
901 | 628 |
902 return kPartial_PdfResult; | 629 return kPartial_PdfResult; |
903 } | 630 } |
904 | 631 |
905 bool SkMatrixFromDictionary(const PdfMemDocument* pdfDoc, | |
906 const PdfDictionary& dict, | |
907 const char* key, | |
908 SkMatrix** matrix) { | |
909 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
910 dict.GetKey(PdfName(key))); | |
911 | |
912 if (value == NULL || !value->IsArray()) { | |
913 return false; | |
914 } | |
915 | |
916 if (value->GetArray().GetSize() != 6) { | |
917 return false; | |
918 } | |
919 | |
920 double array[6]; | |
921 for (int i = 0; i < 6; i++) { | |
922 const PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray(
)[i]); | |
923 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { | |
924 return false; | |
925 } | |
926 array[i] = elem->GetReal(); | |
927 } | |
928 | |
929 *matrix = new SkMatrix(); | |
930 **matrix = SkMatrixFromPdfMatrix(array); | |
931 return true; | |
932 } | |
933 | |
934 bool SkMatrixFromDictionary(const PdfMemDocument* pdfDoc, | |
935 const PdfDictionary& dict, | |
936 const char* key, | |
937 const char* abr, | |
938 SkMatrix** data) { | |
939 if (SkMatrixFromDictionary(pdfDoc, dict, key, data)) return true; | |
940 if (abr == NULL || *abr == '\0') return false; | |
941 return SkMatrixFromDictionary(pdfDoc, dict, abr, data); | |
942 | |
943 } | |
944 | |
945 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, | |
946 const PdfDictionary& dict, | |
947 const char* key, | |
948 SkRect** rect) { | |
949 const PdfObject* value = resolveReferenceObject(pdfDoc, | |
950 dict.GetKey(PdfName(key))); | |
951 | |
952 if (value == NULL || !value->IsArray()) { | |
953 return false; | |
954 } | |
955 | |
956 if (value->GetArray().GetSize() != 4) { | |
957 return false; | |
958 } | |
959 | |
960 double array[4]; | |
961 for (int i = 0; i < 4; i++) { | |
962 const PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray(
)[i]); | |
963 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { | |
964 return false; | |
965 } | |
966 array[i] = elem->GetReal(); | |
967 } | |
968 | |
969 *rect = new SkRect(); | |
970 **rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]), | |
971 SkDoubleToScalar(array[1]), | |
972 SkDoubleToScalar(array[2]), | |
973 SkDoubleToScalar(array[3])); | |
974 return true; | |
975 } | |
976 | |
977 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, | |
978 const PdfDictionary& dict, | |
979 const char* key, | |
980 const char* abr, | |
981 SkRect** data) { | |
982 if (SkRectFromDictionary(pdfDoc, dict, key, data)) return true; | |
983 if (abr == NULL || *abr == '\0') return false; | |
984 return SkRectFromDictionary(pdfDoc, dict, abr, data); | |
985 | |
986 } | |
987 | 632 |
988 | 633 |
989 SkPdfObject* get(const SkPdfObject* obj, const char* key, const char* abr = "")
{ | |
990 SkPdfObject* ret = NULL; | |
991 if (obj == NULL) return NULL; | |
992 const SkPdfDictionary* dict = obj->asDictionary(); | |
993 if (dict == NULL) return NULL; | |
994 if (!dict->podofo()->IsDictionary()) return NULL; | |
995 ObjectFromDictionary(dict->doc(), dict->podofo()->GetDictionary(), key, abr,
&ret); | |
996 return ret; | |
997 } | |
998 | 634 |
999 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfType1For
mDictionary* skobj) { | 635 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfType1For
mDictionary* skobj) { |
1000 if (!skobj || !skobj->podofo() || !skobj->podofo()->HasStream() || skobj->po
dofo()->GetStream() == NULL || skobj->podofo()->GetStream()->GetLength() == 0) { | 636 if (!skobj) { |
1001 return kOK_PdfResult; | 637 return kIgnoreError_PdfResult; |
1002 } | 638 } |
1003 | 639 |
1004 PdfOp_q(pdfContext, canvas, NULL); | 640 PdfOp_q(pdfContext, canvas, NULL); |
1005 canvas->save(); | 641 canvas->save(); |
1006 | 642 |
1007 | 643 |
1008 if (skobj->Resources()) { | 644 if (skobj->Resources()) { |
1009 pdfContext->fGraphicsState.fResources = skobj->Resources(); | 645 pdfContext->fGraphicsState.fResources = skobj->Resources(); |
1010 } | 646 } |
1011 | 647 |
(...skipping 10 matching lines...) Expand all Loading... |
1022 | 658 |
1023 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 659 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
1024 | 660 |
1025 if (skobj->BBox()) { | 661 if (skobj->BBox()) { |
1026 canvas->clipRect(*skobj->BBox(), SkRegion::kIntersect_Op, true); // TOD
O(edisonn): AA from settings. | 662 canvas->clipRect(*skobj->BBox(), SkRegion::kIntersect_Op, true); // TOD
O(edisonn): AA from settings. |
1027 } | 663 } |
1028 | 664 |
1029 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. | 665 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. |
1030 // For this PdfContentsTokenizer needs to be extended. | 666 // For this PdfContentsTokenizer needs to be extended. |
1031 | 667 |
1032 PdfResult ret = kPartial_PdfResult; | 668 SkPdfStream* stream = NULL; |
1033 SkPdfTokenizer tokenizer(skobj); | 669 skobj->doc()->mapper()->mapStream(skobj, &stream); |
1034 PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas); | 670 |
1035 looper.loop(); | 671 SkPdfPodofoTokenizer* tokenizer = skobj->doc()->tokenizerOfStream(stream); |
| 672 if (tokenizer != NULL) { |
| 673 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); |
| 674 looper.loop(); |
| 675 delete tokenizer; |
| 676 } |
1036 | 677 |
1037 // TODO(edisonn): should we restore the variable stack at the same state? | 678 // TODO(edisonn): should we restore the variable stack at the same state? |
1038 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | 679 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. |
1039 canvas->restore(); | 680 canvas->restore(); |
1040 PdfOp_Q(pdfContext, canvas, NULL); | 681 PdfOp_Q(pdfContext, canvas, NULL); |
1041 return ret; | 682 return kPartial_PdfResult; |
1042 } | 683 } |
1043 | 684 |
1044 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
& obj) { | 685 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
& obj) { |
1045 return kNYI_PdfResult; | 686 return kNYI_PdfResult; |
1046 } | 687 } |
1047 | 688 |
1048 PdfResult doType3Char(PdfContext* pdfContext, SkCanvas* canvas, SkPdfObject* sko
bj, SkRect bBox, SkMatrix matrix, double textSize) { | 689 PdfResult doType3Char(PdfContext* pdfContext, SkCanvas* canvas, SkPdfObject* sko
bj, SkRect bBox, SkMatrix matrix, double textSize) { |
1049 if (!skobj || !skobj->podofo() || !skobj->podofo()->HasStream() || skobj->po
dofo()->GetStream() == NULL || skobj->podofo()->GetStream()->GetLength() == 0) { | 690 if (!skobj) { |
1050 return kOK_PdfResult; | 691 return kIgnoreError_PdfResult; |
1051 } | 692 } |
1052 | 693 |
1053 PdfOp_q(pdfContext, canvas, NULL); | 694 PdfOp_q(pdfContext, canvas, NULL); |
1054 canvas->save(); | 695 canvas->save(); |
1055 | 696 |
1056 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 697 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
1057 pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), Sk
DoubleToScalar(textSize)); | 698 pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), Sk
DoubleToScalar(textSize)); |
1058 | 699 |
1059 pdfContext->fGraphicsState.fMatrix = pdfContext->fGraphicsState.fMatrixTm; | 700 pdfContext->fGraphicsState.fMatrix = pdfContext->fGraphicsState.fMatrixTm; |
1060 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix; | 701 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix; |
1061 | 702 |
1062 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); | 703 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); |
1063 | 704 |
1064 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 705 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
1065 | 706 |
1066 SkRect rm = bBox; | 707 SkRect rm = bBox; |
1067 pdfContext->fGraphicsState.fMatrix.mapRect(&rm); | 708 pdfContext->fGraphicsState.fMatrix.mapRect(&rm); |
1068 | 709 |
1069 SkTraceRect(rm, "bbox mapped"); | 710 SkTraceRect(rm, "bbox mapped"); |
1070 | 711 |
1071 canvas->clipRect(bBox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA
from settings. | 712 canvas->clipRect(bBox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA
from settings. |
1072 | 713 |
1073 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. | 714 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. |
1074 // For this PdfContentsTokenizer needs to be extended. | 715 // For this PdfContentsTokenizer needs to be extended. |
1075 | 716 |
1076 PdfResult ret = kPartial_PdfResult; | 717 SkPdfStream* stream = NULL; |
1077 SkPdfTokenizer tokenizer(skobj); | 718 skobj->doc()->mapper()->mapStream(skobj, &stream); |
1078 PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas); | 719 |
1079 looper.loop(); | 720 SkPdfPodofoTokenizer* tokenizer = skobj->doc()->tokenizerOfStream(stream); |
| 721 if (tokenizer != NULL) { |
| 722 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); |
| 723 looper.loop(); |
| 724 delete tokenizer; |
| 725 } |
1080 | 726 |
1081 // TODO(edisonn): should we restore the variable stack at the same state? | 727 // TODO(edisonn): should we restore the variable stack at the same state? |
1082 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | 728 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. |
1083 canvas->restore(); | 729 canvas->restore(); |
1084 PdfOp_Q(pdfContext, canvas, NULL); | 730 PdfOp_Q(pdfContext, canvas, NULL); |
1085 return ret; | 731 |
| 732 return kPartial_PdfResult; |
1086 } | 733 } |
1087 | 734 |
1088 | 735 |
1089 // TODO(edisonn): faster, have the property on the SkPdfObject itself? | 736 // TODO(edisonn): faster, have the property on the SkPdfObject itself? |
1090 std::set<const PdfObject*> gInRendering; | 737 std::set<const void*> gInRendering; |
1091 | 738 |
1092 class CheckRecursiveRendering { | 739 class CheckRecursiveRendering { |
1093 const PdfObject& fObj; | 740 const void* fUniqueData; |
1094 public: | 741 public: |
1095 CheckRecursiveRendering(const PdfObject& obj) : fObj(obj) { | 742 CheckRecursiveRendering(const SkPdfObject* obj) : fUniqueData(obj->data()) { |
1096 gInRendering.insert(&obj); | 743 gInRendering.insert(obj); |
1097 } | 744 } |
1098 | 745 |
1099 ~CheckRecursiveRendering() { | 746 ~CheckRecursiveRendering() { |
1100 //SkASSERT(fObj.fInRendering); | 747 //SkASSERT(fObj.fInRendering); |
1101 gInRendering.erase(&fObj); | 748 gInRendering.erase(fUniqueData); |
1102 } | 749 } |
1103 | 750 |
1104 static bool IsInRendering(const PdfObject& obj) { | 751 static bool IsInRendering(const SkPdfObject* obj) { |
1105 return gInRendering.find(&obj) != gInRendering.end(); | 752 return gInRendering.find(obj->data()) != gInRendering.end(); |
1106 } | 753 } |
1107 }; | 754 }; |
1108 | 755 |
1109 PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfObject&
obj) { | 756 PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfObject&
obj) { |
1110 if (CheckRecursiveRendering::IsInRendering(*obj.podofo())) { | 757 if (CheckRecursiveRendering::IsInRendering(&obj)) { |
1111 // Oops, corrupt PDF! | 758 // Oops, corrupt PDF! |
1112 return kIgnoreError_PdfResult; | 759 return kIgnoreError_PdfResult; |
1113 } | 760 } |
1114 | 761 |
1115 CheckRecursiveRendering checkRecursion(*obj.podofo()); | 762 CheckRecursiveRendering checkRecursion(&obj); |
1116 | 763 |
1117 // TODO(edisonn): check type | 764 // TODO(edisonn): check type |
1118 SkPdfXObjectDictionary* skobj = NULL; | 765 SkPdfXObjectDictionary* skobj = NULL; |
1119 if (!mapXObjectDictionary(obj, &skobj)) return kIgnoreError_PdfResult; | 766 if (!obj.doc()->mapper()->mapXObjectDictionary(&obj, &skobj)) return kIgnore
Error_PdfResult; |
1120 | 767 |
1121 if (!skobj || !skobj->valid()) return kIgnoreError_PdfResult; | 768 if (!skobj) return kIgnoreError_PdfResult; |
1122 | 769 |
1123 PdfResult ret = kIgnoreError_PdfResult; | 770 PdfResult ret = kIgnoreError_PdfResult; |
1124 switch (skobj->getType()) | 771 switch (skobj->getType()) |
1125 { | 772 { |
1126 case kImageDictionary_SkPdfObjectType: | 773 case kImageDictionary_SkPdfObjectType: |
1127 ret = doXObject_Image(pdfContext, canvas, skobj->asImageDictionary()
); | 774 ret = doXObject_Image(pdfContext, canvas, skobj->asImageDictionary()
); |
1128 break; | 775 break; |
1129 case kType1FormDictionary_SkPdfObjectType: | 776 case kType1FormDictionary_SkPdfObjectType: |
1130 ret = doXObject_Form(pdfContext, canvas, skobj->asType1FormDictionar
y()); | 777 ret = doXObject_Form(pdfContext, canvas, skobj->asType1FormDictionar
y()); |
1131 break; | 778 break; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 SkMatrix matrix = SkMatrixFromPdfMatrix(array); | 818 SkMatrix matrix = SkMatrixFromPdfMatrix(array); |
1172 | 819 |
1173 pdfContext->fGraphicsState.fMatrix.preConcat(matrix); | 820 pdfContext->fGraphicsState.fMatrix.preConcat(matrix); |
1174 | 821 |
1175 #ifdef PDF_TRACE | 822 #ifdef PDF_TRACE |
1176 printf("cm "); | 823 printf("cm "); |
1177 for (int i = 0 ; i < 6 ; i++) { | 824 for (int i = 0 ; i < 6 ; i++) { |
1178 printf("%f ", array[i]); | 825 printf("%f ", array[i]); |
1179 } | 826 } |
1180 printf("\n"); | 827 printf("\n"); |
1181 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix); | 828 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "cm"); |
1182 #endif | 829 #endif |
1183 | 830 |
1184 return kOK_PdfResult; | 831 return kOK_PdfResult; |
1185 } | 832 } |
1186 | 833 |
1187 //leading TL Set the text leading, Tl | 834 //leading TL Set the text leading, Tl |
1188 //, to leading, which is a number expressed in unscaled text | 835 //, to leading, which is a number expressed in unscaled text |
1189 //space units. Text leading is used only by the T*, ', and " operators. Initial
value: 0. | 836 //space units. Text leading is used only by the T*, ', and " operators. Initial
value: 0. |
1190 PdfResult PdfOp_TL(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 837 PdfResult PdfOp_TL(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1191 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 838 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); |
(...skipping 14 matching lines...) Expand all Loading... |
1206 pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); | 853 pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); |
1207 | 854 |
1208 return kPartial_PdfResult; | 855 return kPartial_PdfResult; |
1209 } | 856 } |
1210 | 857 |
1211 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 858 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1212 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 859 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); |
1213 double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 860 double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); |
1214 | 861 |
1215 // TODO(edisonn): Create factory methods or constructors so podofo is hidden | 862 // TODO(edisonn): Create factory methods or constructors so podofo is hidden |
1216 PdfObject _ty(PdfVariant(-ty)); | 863 SkPdfNumber* _ty = pdfContext->fPdfDoc->createNumber(-ty); |
1217 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &_ty)); | 864 pdfContext->fObjectStack.push(_ty); |
1218 | 865 |
1219 PdfOp_TL(pdfContext, canvas, looper); | 866 PdfOp_TL(pdfContext, canvas, looper); |
1220 | 867 |
1221 PdfObject vtx(PdfVariant(-(-tx))); // TODO(edisonn): Hmm, the compiler thin
ks I have here a function pointer if we use (tx), but not -(-tx) | 868 SkPdfNumber* vtx = pdfContext->fPdfDoc->createNumber(tx); |
1222 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &vtx)); | 869 pdfContext->fObjectStack.push(vtx); |
1223 | 870 |
1224 PdfObject vty(PdfVariant(-(-ty))); | 871 SkPdfNumber* vty = pdfContext->fPdfDoc->createNumber(ty); |
1225 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &vty)); | 872 pdfContext->fObjectStack.push(vty); |
1226 | 873 |
1227 return PdfOp_Td(pdfContext, canvas, looper); | 874 PdfResult ret = PdfOp_Td(pdfContext, canvas, looper); |
| 875 |
| 876 // 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 |
| 878 delete _ty; |
| 879 delete vtx; |
| 880 delete vty; |
| 881 |
| 882 return ret; |
1228 } | 883 } |
1229 | 884 |
1230 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 885 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1231 double f = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 886 double f = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
1232 double e = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 887 double e = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
1233 double d = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 888 double d = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
1234 double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 889 double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
1235 double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 890 double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
1236 double a = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 891 double a = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
1237 | 892 |
(...skipping 12 matching lines...) Expand all Loading... |
1250 pdfContext->fGraphicsState.fMatrixTm = matrix; | 905 pdfContext->fGraphicsState.fMatrixTm = matrix; |
1251 pdfContext->fGraphicsState.fMatrixTlm = matrix;; | 906 pdfContext->fGraphicsState.fMatrixTlm = matrix;; |
1252 | 907 |
1253 return kPartial_PdfResult; | 908 return kPartial_PdfResult; |
1254 } | 909 } |
1255 | 910 |
1256 //— T* Move to the start of the next line. This operator has the same effect as
the code | 911 //— T* Move to the start of the next line. This operator has the same effect as
the code |
1257 //0 Tl Td | 912 //0 Tl Td |
1258 //where Tl is the current leading parameter in the text state | 913 //where Tl is the current leading parameter in the text state |
1259 PdfResult PdfOp_T_star(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper) { | 914 PdfResult PdfOp_T_star(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper) { |
1260 PdfObject zero(PdfVariant(0.0)); | 915 SkPdfNumber* zero = pdfContext->fPdfDoc->createNumber(0.0); |
1261 PdfObject tl(PdfVariant(-(-pdfContext->fGraphicsState.fTextLeading))); | 916 SkPdfNumber* tl = pdfContext->fPdfDoc->createNumber(pdfContext->fGraphicsSta
te.fTextLeading); |
1262 | 917 |
1263 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &zero)); | 918 pdfContext->fObjectStack.push(zero); |
1264 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &tl)); | 919 pdfContext->fObjectStack.push(tl); |
1265 return PdfOp_Td(pdfContext, canvas, looper); | 920 |
| 921 PdfResult ret = PdfOp_Td(pdfContext, canvas, looper); |
| 922 |
| 923 delete zero; // TODO(edisonn): do not alocate and delete constants! |
| 924 delete tl; |
| 925 |
| 926 return ret; |
1266 } | 927 } |
1267 | 928 |
1268 PdfResult PdfOp_m(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 929 PdfResult PdfOp_m(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
1269 if (pdfContext->fGraphicsState.fPathClosed) { | 930 if (pdfContext->fGraphicsState.fPathClosed) { |
1270 pdfContext->fGraphicsState.fPath.reset(); | 931 pdfContext->fGraphicsState.fPath.reset(); |
1271 pdfContext->fGraphicsState.fPathClosed = false; | 932 pdfContext->fGraphicsState.fPathClosed = false; |
1272 } | 933 } |
1273 | 934 |
1274 pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); | 935 pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); |
1275 pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); | 936 pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1518 //, to font and the text font size, Tfs, to size. font is the name of a | 1179 //, to font and the text font size, Tfs, to size. font is the name of a |
1519 //font resource in the Fontsubdictionary of the current resource dictionary; siz
e is | 1180 //font resource in the Fontsubdictionary of the current resource dictionary; siz
e is |
1520 //a number representing a scale factor. There is no initial value for either fon
t or | 1181 //a number representing a scale factor. There is no initial value for either fon
t or |
1521 //size; they must be specified explicitly using Tf before any text is shown. | 1182 //size; they must be specified explicitly using Tf before any text is shown. |
1522 PdfResult PdfOp_Tf(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1183 PdfResult PdfOp_Tf(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1523 pdfContext->fGraphicsState.fCurFontSize = pdfContext->fObjectStack.top()->as
Number()->value(); pdfContext->fObjectStack.pop(); | 1184 pdfContext->fGraphicsState.fCurFontSize = pdfContext->fObjectStack.top()->as
Number()->value(); pdfContext->fObjectStack.pop(); |
1524 std::string fontName = pdfContext->fObjectStack.top()->asName()->value();
pdfContext->fObjectStack.pop(); | 1185 std::string fontName = pdfContext->fObjectStack.top()->asName()->value();
pdfContext->fObjectStack.pop(); |
1525 | 1186 |
1526 #ifdef PDF_TRACE | 1187 #ifdef PDF_TRACE |
1527 printf("font name: %s\n", fontName.c_str()); | 1188 printf("font name: %s\n", fontName.c_str()); |
1528 std::string str; | |
1529 pdfContext->fGraphicsState.fResources->podofo()->ToString(str); | |
1530 printf("Print Tf Resources: %s\n", str.c_str()); | |
1531 pdfContext->fGraphicsState.fResources->Font()->podofo()->ToString(str); | |
1532 printf("Print Tf Resources/Font: %s\n", str.c_str()); | |
1533 #endif | 1189 #endif |
1534 | 1190 |
1535 SkPdfFontDictionary* fd = NULL; | 1191 SkPdfFontDictionary* fd = NULL; |
1536 if (pdfContext->fGraphicsState.fResources->Font()) { | 1192 if (pdfContext->fGraphicsState.fResources->Font()) { |
1537 SkPdfObject* objFont = pdfContext->fGraphicsState.fResources->Font()->ge
t(fontName.c_str()); | 1193 SkPdfObject* objFont = pdfContext->fGraphicsState.fResources->Font()->ge
t(fontName.c_str()); |
1538 mapFontDictionary(*objFont, &fd); | 1194 objFont->doc()->mapper()->mapFontDictionary(objFont, &fd); |
1539 | |
1540 #ifdef PDF_TRACE | |
1541 objFont->podofo()->ToString(str); | |
1542 printf("Print Font loaded: %s\n", str.c_str()); | |
1543 fd->podofo()->ToString(str); | |
1544 printf("Print Font loaded and resolved and upgraded: %s\n", str.c_str())
; | |
1545 #endif | |
1546 | |
1547 } | 1195 } |
1548 | 1196 |
1549 SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(fd); | 1197 SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(fd); |
1550 | 1198 |
1551 if (skfont) { | 1199 if (skfont) { |
1552 pdfContext->fGraphicsState.fSkFont = skfont; | 1200 pdfContext->fGraphicsState.fSkFont = skfont; |
1553 } | 1201 } |
1554 | 1202 |
1555 return kPartial_PdfResult; | 1203 return kPartial_PdfResult; |
1556 } | 1204 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1631 SkDoubleToScalar(0), | 1279 SkDoubleToScalar(0), |
1632 SkDoubleToScalar(0), | 1280 SkDoubleToScalar(0), |
1633 SkDoubleToScalar(1)); | 1281 SkDoubleToScalar(1)); |
1634 | 1282 |
1635 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 1283 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
1636 } | 1284 } |
1637 } | 1285 } |
1638 return kPartial_PdfResult; // TODO(edisonn): Implement fully DrawText befor
e returing OK. | 1286 return kPartial_PdfResult; // TODO(edisonn): Implement fully DrawText befor
e returing OK. |
1639 } | 1287 } |
1640 | 1288 |
1641 PdfResult PdfOp_CS_cs(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator
* colorOperator) { | 1289 PdfResult PdfOp_CS_cs(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
or* colorOperator) { |
1642 colorOperator->fColorSpace = pdfContext->fObjectStack.top()->asName()->value
(); pdfContext->fObjectStack.pop(); | 1290 colorOperator->fColorSpace = pdfContext->fObjectStack.top()->asName()->value
(); pdfContext->fObjectStack.pop(); |
1643 return kOK_PdfResult; | 1291 return kOK_PdfResult; |
1644 } | 1292 } |
1645 | 1293 |
1646 PdfResult PdfOp_CS(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1294 PdfResult PdfOp_CS(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1647 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); | 1295 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); |
1648 } | 1296 } |
1649 | 1297 |
1650 PdfResult PdfOp_cs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1298 PdfResult PdfOp_cs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1651 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); | 1299 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); |
1652 } | 1300 } |
1653 | 1301 |
1654 PdfResult PdfOp_SC_sc(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator
* colorOperator) { | 1302 PdfResult PdfOp_SC_sc(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
or* colorOperator) { |
1655 double c[4]; | 1303 double c[4]; |
1656 pdf_int64 v[4]; | 1304 pdf_int64 v[4]; |
1657 | 1305 |
1658 int n = GetColorSpaceComponents(colorOperator->fColorSpace); | 1306 int n = GetColorSpaceComponents(colorOperator->fColorSpace); |
1659 | 1307 |
1660 bool doubles = true; | 1308 bool doubles = true; |
1661 if (colorOperator->fColorSpace == "Indexed") { | 1309 if (colorOperator->fColorSpace == "Indexed") { |
1662 doubles = false; | 1310 doubles = false; |
1663 } | 1311 } |
1664 | 1312 |
1665 #ifdef PDF_TRACE | 1313 #ifdef PDF_TRACE |
1666 printf("color space = %s, N = %i\n", colorOperator->fColorSpace.c_str(), n); | 1314 printf("color space = %s, N = %i\n", colorOperator->fColorSpace.c_str(), n); |
1667 #endif | 1315 #endif |
1668 | 1316 |
1669 for (int i = n - 1; i >= 0 ; i--) { | 1317 for (int i = n - 1; i >= 0 ; i--) { |
1670 if (doubles) { | 1318 if (doubles) { |
1671 c[i] = pdfContext->fObjectStack.top()->asNumber()->value(); pdfC
ontext->fObjectStack.pop(); | 1319 c[i] = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); |
1672 } else { | 1320 } else { |
1673 v[i] = pdfContext->fObjectStack.top()->asInteger()->value(); pdfCo
ntext->fObjectStack.pop(); | 1321 v[i] = pdfContext->fObjectStack.top()->asInteger()->value();
pdfContext->fObjectStack.pop(); |
1674 } | 1322 } |
1675 } | 1323 } |
1676 | 1324 |
1677 // TODO(edisonn): Now, set that color. Only DeviceRGB supported. | 1325 // TODO(edisonn): Now, set that color. Only DeviceRGB supported. |
1678 if (colorOperator->fColorSpace == "DeviceRGB") { | 1326 if (colorOperator->fColorSpace == "DeviceRGB") { |
1679 colorOperator->setRGBColor(SkColorSetRGB(255*c[0], 255*c[1], 255*c[2])); | 1327 colorOperator->setRGBColor(SkColorSetRGB(255*c[0], 255*c[1], 255*c[2])); |
1680 } | 1328 } |
1681 return kPartial_PdfResult; | 1329 return kPartial_PdfResult; |
1682 } | 1330 } |
1683 | 1331 |
1684 PdfResult PdfOp_SC(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1332 PdfResult PdfOp_SC(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1685 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); | 1333 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); |
1686 } | 1334 } |
1687 | 1335 |
1688 PdfResult PdfOp_sc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1336 PdfResult PdfOp_sc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1689 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); | 1337 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); |
1690 } | 1338 } |
1691 | 1339 |
1692 PdfResult PdfOp_SCN_scn(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperat
or* colorOperator) { | 1340 PdfResult PdfOp_SCN_scn(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOper
ator* colorOperator) { |
1693 PdfString name; | 1341 PdfString name; |
1694 | 1342 |
1695 if (pdfContext->fObjectStack.top()->asName()) { | 1343 if (pdfContext->fObjectStack.top()->asName()) { |
1696 pdfContext->fObjectStack.pop(); | 1344 pdfContext->fObjectStack.pop(); |
1697 } | 1345 } |
1698 | 1346 |
1699 // TODO(edisonn): SCN supports more color spaces than SCN. Read and implemen
t spec. | 1347 // TODO(edisonn): SCN supports more color spaces than SCN. Read and implemen
t spec. |
1700 PdfOp_SC_sc(pdfContext, canvas, colorOperator); | 1348 PdfOp_SC_sc(pdfContext, canvas, colorOperator); |
1701 | 1349 |
1702 return kPartial_PdfResult; | 1350 return kPartial_PdfResult; |
1703 } | 1351 } |
1704 | 1352 |
1705 PdfResult PdfOp_SCN(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
ooper) { | 1353 PdfResult PdfOp_SCN(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
ooper) { |
1706 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroki
ng); | 1354 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroki
ng); |
1707 } | 1355 } |
1708 | 1356 |
1709 PdfResult PdfOp_scn(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
ooper) { | 1357 PdfResult PdfOp_scn(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
ooper) { |
1710 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStr
oking); | 1358 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStr
oking); |
1711 } | 1359 } |
1712 | 1360 |
1713 PdfResult PdfOp_G_g(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator*
colorOperator) { | 1361 PdfResult PdfOp_G_g(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator
* colorOperator) { |
1714 double gray = pdfContext->fObjectStack.top()->asNumber()->value(); pdfCo
ntext->fObjectStack.pop(); | 1362 double gray = pdfContext->fObjectStack.top()->asNumber()->value(); pdfCo
ntext->fObjectStack.pop(); |
1715 return kNYI_PdfResult; | 1363 return kNYI_PdfResult; |
1716 } | 1364 } |
1717 | 1365 |
1718 PdfResult PdfOp_G(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1366 PdfResult PdfOp_G(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
1719 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); | 1367 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); |
1720 } | 1368 } |
1721 | 1369 |
1722 PdfResult PdfOp_g(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1370 PdfResult PdfOp_g(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
1723 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
g); | 1371 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
g); |
1724 } | 1372 } |
1725 | 1373 |
1726 PdfResult PdfOp_RG_rg(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator
* colorOperator) { | 1374 PdfResult PdfOp_RG_rg(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
or* colorOperator) { |
1727 double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1375 double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); |
1728 double g = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1376 double g = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); |
1729 double r = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1377 double r = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); |
1730 | 1378 |
1731 colorOperator->fColorSpace = "DeviceRGB"; | 1379 colorOperator->fColorSpace = "DeviceRGB"; |
1732 colorOperator->setRGBColor(SkColorSetRGB(255*r, 255*g, 255*b)); | 1380 colorOperator->setRGBColor(SkColorSetRGB(255*r, 255*g, 255*b)); |
1733 return kOK_PdfResult; | 1381 return kOK_PdfResult; |
1734 } | 1382 } |
1735 | 1383 |
1736 PdfResult PdfOp_RG(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1384 PdfResult PdfOp_RG(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1737 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); | 1385 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); |
1738 } | 1386 } |
1739 | 1387 |
1740 PdfResult PdfOp_rg(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1388 PdfResult PdfOp_rg(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1741 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); | 1389 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); |
1742 } | 1390 } |
1743 | 1391 |
1744 PdfResult PdfOp_K_k(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator*
colorOperator) { | 1392 PdfResult PdfOp_K_k(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator
* colorOperator) { |
1745 // TODO(edisonn): spec has some rules about overprint, implement them. | 1393 // TODO(edisonn): spec has some rules about overprint, implement them. |
1746 double k = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1394 double k = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); |
1747 double y = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1395 double y = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); |
1748 double m = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1396 double m = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); |
1749 double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); | 1397 double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfConte
xt->fObjectStack.pop(); |
1750 | 1398 |
1751 colorOperator->fColorSpace = "DeviceCMYK"; | 1399 colorOperator->fColorSpace = "DeviceCMYK"; |
1752 // TODO(edisonn): Set color. | 1400 // TODO(edisonn): Set color. |
1753 return kNYI_PdfResult; | 1401 return kNYI_PdfResult; |
1754 } | 1402 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1889 | 1537 |
1890 if (extGStateDictionary == NULL) { | 1538 if (extGStateDictionary == NULL) { |
1891 #ifdef PDF_TRACE | 1539 #ifdef PDF_TRACE |
1892 printf("ExtGState is NULL!\n"); | 1540 printf("ExtGState is NULL!\n"); |
1893 #endif | 1541 #endif |
1894 return kIgnoreError_PdfResult; | 1542 return kIgnoreError_PdfResult; |
1895 } | 1543 } |
1896 | 1544 |
1897 SkPdfObject* value = extGStateDictionary->get(name.c_str()); | 1545 SkPdfObject* value = extGStateDictionary->get(name.c_str()); |
1898 | 1546 |
1899 #ifdef PDF_TRACE | |
1900 // value->ToString(str); | |
1901 // printf("gs object value: %s\n", str.c_str()); | |
1902 #endif | |
1903 | |
1904 SkPdfGraphicsStateDictionary* gs = NULL; | 1547 SkPdfGraphicsStateDictionary* gs = NULL; |
1905 mapGraphicsStateDictionary(*value, &gs); | 1548 value->doc()->mapper()->mapGraphicsStateDictionary(value, &gs); |
1906 | 1549 |
1907 // TODO(edisonn): now load all those properties in graphic state. | 1550 // TODO(edisonn): now load all those properties in graphic state. |
1908 if (gs == NULL) { | 1551 if (gs == NULL) { |
1909 return kIgnoreError_PdfResult; | 1552 return kIgnoreError_PdfResult; |
1910 } | 1553 } |
1911 | 1554 |
1912 if (gs->has_CA()) { | 1555 if (gs->has_CA()) { |
1913 pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(); | 1556 pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(); |
1914 } | 1557 } |
1915 | 1558 |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2293 // e.g. SkBitmap getPage(int page); | 1936 // e.g. SkBitmap getPage(int page); |
2294 // int formsCount(); | 1937 // int formsCount(); |
2295 // SkForm getForm(int formID); // SkForm(SkRect, .. other data) | 1938 // SkForm getForm(int formID); // SkForm(SkRect, .. other data) |
2296 // TODO (edisonn): Add intend when loading pdf, for example: for viewing, parsin
g all content, ... | 1939 // TODO (edisonn): Add intend when loading pdf, for example: for viewing, parsin
g all content, ... |
2297 // if we load the first page, and we zoom to fit to screen horizontally, then lo
ad only those | 1940 // if we load the first page, and we zoom to fit to screen horizontally, then lo
ad only those |
2298 // resources needed, so the preview is fast. | 1941 // resources needed, so the preview is fast. |
2299 // TODO (edisonn): hide parser/tokenizer behind and interface and a query langua
ge, and resolve | 1942 // TODO (edisonn): hide parser/tokenizer behind and interface and a query langua
ge, and resolve |
2300 // references automatically. | 1943 // references automatically. |
2301 | 1944 |
2302 bool SkPdfViewer::load(const SkString inputFileName, SkPicture* out) { | 1945 bool SkPdfViewer::load(const SkString inputFileName, SkPicture* out) { |
2303 try | 1946 std::cout << "Init: " << inputFileName.c_str() << std::endl; |
| 1947 |
| 1948 SkPodofoParsedPDF* doc = new SkPodofoParsedPDF(inputFileName.c_str()); |
| 1949 if (!doc->pages()) |
2304 { | 1950 { |
2305 std::cout << "Init: " << inputFileName.c_str() << std::endl; | 1951 std::cout << "ERROR: Empty Document" << inputFileName.c_str() << std::en
dl; |
| 1952 return false; |
| 1953 } else { |
2306 | 1954 |
2307 SkPdfDoc doc(inputFileName.c_str()); | 1955 for (int pn = 0; pn < doc->pages(); ++pn) { |
2308 if (!doc.pages()) | 1956 // TODO(edisonn): implement inheritance properties as per PDF spec |
2309 { | 1957 //SkRect rect = page->MediaBox(); |
2310 std::cout << "ERROR: Empty Document" << inputFileName.c_str() << std
::endl; | 1958 SkRect rect = doc->MediaBox(pn); |
2311 return false; | |
2312 } else { | |
2313 | 1959 |
2314 for (int pn = 0; pn < doc.pages(); ++pn) { | 1960 #ifdef PDF_TRACE |
2315 // TODO(edisonn): implement inheritance properties as per PDF sp
ec | 1961 printf("Page Width: %f, Page Height: %f\n", SkScalarToDouble(rect.wi
dth()), SkScalarToDouble(rect.height())); |
2316 //SkRect rect = page->MediaBox(); | 1962 #endif |
2317 SkRect rect = doc.MediaBox(pn); | |
2318 | 1963 |
2319 #ifdef PDF_TRACE | 1964 // TODO(edisonn): page->GetCropBox(), page->GetTrimBox() ... how to
use? |
2320 printf("Page Width: %f, Page Height: %f\n", SkScalarToDouble(rec
t.width()), SkScalarToDouble(rect.height())); | |
2321 #endif | |
2322 | 1965 |
2323 // TODO(edisonn): page->GetCropBox(), page->GetTrimBox() ... how
to use? | 1966 SkBitmap bitmap; |
| 1967 #ifdef PDF_DEBUG_3X |
| 1968 setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3 * (
int)SkScalarToDouble(rect.height())); |
| 1969 #else |
| 1970 setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)SkSc
alarToDouble(rect.height())); |
| 1971 #endif |
| 1972 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (bitmap))); |
| 1973 SkCanvas canvas(device); |
2324 | 1974 |
2325 SkBitmap bitmap; | 1975 gDumpBitmap = &bitmap; |
2326 #ifdef PDF_DEBUG_3X | |
2327 setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3
* (int)SkScalarToDouble(rect.height())); | |
2328 #else | |
2329 setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)
SkScalarToDouble(rect.height())); | |
2330 #endif | |
2331 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (bitmap))); | |
2332 SkCanvas canvas(device); | |
2333 | 1976 |
2334 gDumpBitmap = &bitmap; | 1977 gDumpCanvas = &canvas; |
| 1978 doc->drawPage(pn, &canvas); |
2335 | 1979 |
2336 doc.drawPage(pn, &canvas); | 1980 SkString out; |
2337 | 1981 if (doc->pages() > 1) { |
2338 SkString out; | 1982 out.appendf("%s-%i.png", inputFileName.c_str(), pn); |
2339 if (doc.pages() > 1) { | 1983 } else { |
2340 out.appendf("%s-%i.png", inputFileName.c_str(), pn); | 1984 out = inputFileName; |
2341 } else { | 1985 // .pdf -> .png |
2342 out = inputFileName; | 1986 out[out.size() - 2] = 'n'; |
2343 // .pdf -> .png | 1987 out[out.size() - 1] = 'g'; |
2344 out[out.size() - 2] = 'n'; | |
2345 out[out.size() - 1] = 'g'; | |
2346 } | |
2347 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::
kPNG_Type, 100); | |
2348 } | 1988 } |
2349 return true; | 1989 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG
_Type, 100); |
2350 } | 1990 } |
2351 } | 1991 return true; |
2352 catch( PdfError & e ) | |
2353 { | |
2354 e.PrintErrorMsg(); | |
2355 std::cout << "ERROR: PDF can't be parsed!" << inputFileName.c_str() << s
td::endl; | |
2356 return false; | |
2357 } | 1992 } |
2358 | 1993 |
2359 return true; | 1994 return true; |
2360 } | 1995 } |
OLD | NEW |