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 "SkGraphics.h" | 10 #include "SkGraphics.h" |
11 #include "SkImageDecoder.h" | 11 #include "SkImageDecoder.h" |
12 #include "SkImageEncoder.h" | 12 #include "SkImageEncoder.h" |
13 #include "SkOSFile.h" | 13 #include "SkOSFile.h" |
14 #include "SkPicture.h" | 14 #include "SkPicture.h" |
15 #include "SkStream.h" | 15 #include "SkStream.h" |
16 #include "SkTypeface.h" | 16 #include "SkTypeface.h" |
17 #include "SkTArray.h" | 17 #include "SkTArray.h" |
18 #include "picture_utils.h" | 18 #include "picture_utils.h" |
19 | 19 |
20 #include <iostream> | 20 #include <iostream> |
21 #include <cstdio> | 21 #include <cstdio> |
22 #include <stack> | 22 #include <stack> |
23 | 23 |
24 #include "podofo.h" | 24 #include "podofo.h" |
| 25 using namespace PoDoFo; |
| 26 |
| 27 bool LongFromDictionary(const PdfMemDocument* pdfDoc, |
| 28 const PdfDictionary& dict, |
| 29 const char* key, |
| 30 const char* abr, |
| 31 long* data); |
| 32 |
| 33 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, |
| 34 const PdfDictionary& dict, |
| 35 const char* key, |
| 36 const char* abr, |
| 37 bool* data); |
| 38 |
| 39 bool NameFromDictionary(const PdfMemDocument* pdfDoc, |
| 40 const PdfDictionary& dict, |
| 41 const char* key, |
| 42 const char* abr, |
| 43 std::string* data); |
| 44 |
| 45 |
| 46 |
| 47 #include "pdf_auto_gen.h" |
25 | 48 |
26 /* | 49 /* |
27 * TODO(edisonn): ASAP so skp -> pdf -> png looks greap | 50 * TODO(edisonn): ASAP so skp -> pdf -> png looks greap |
28 * - load gs/ especially smask and already known prop | 51 * - load gs/ especially smask and already known prop |
29 * - use transparency (I think ca and CA ops) | 52 * - use transparency (I think ca and CA ops) |
30 * - load font for baidu.pdf | 53 * - load font for baidu.pdf |
31 * - load font for youtube.pdf | 54 * - load font for youtube.pdf |
32 */ | 55 */ |
33 | 56 |
34 //#define PDF_TRACE | 57 #define PDF_TRACE |
35 //#define PDF_TRACE_DIFF_IN_PNG | 58 //#define PDF_TRACE_DIFF_IN_PNG |
36 //#define PDF_DEBUG_NO_CLIPING | 59 //#define PDF_DEBUG_NO_CLIPING |
37 //#define PDF_DEBUG_NO_PAGE_CLIPING | 60 //#define PDF_DEBUG_NO_PAGE_CLIPING |
38 //#define PDF_DEBUG_3X | 61 //#define PDF_DEBUG_3X |
39 | 62 |
40 // TODO(edisonn): move in trace util. | 63 // TODO(edisonn): move in trace util. |
41 #ifdef PDF_TRACE | 64 #ifdef PDF_TRACE |
42 static void SkTraceMatrix(const SkMatrix& matrix, const char* sz = "") { | 65 static void SkTraceMatrix(const SkMatrix& matrix, const char* sz = "") { |
43 printf("SkMatrix %s ", sz); | 66 printf("SkMatrix %s ", sz); |
44 for (int i = 0 ; i < 9 ; i++) { | 67 for (int i = 0 ; i < 9 ; i++) { |
(...skipping 26 matching lines...) Expand all Loading... |
71 return 1; | 94 return 1; |
72 } else if (colorSpace == "DeviceRGB" || | 95 } else if (colorSpace == "DeviceRGB" || |
73 colorSpace == "CalRGB" || | 96 colorSpace == "CalRGB" || |
74 colorSpace == "Lab") { | 97 colorSpace == "Lab") { |
75 return 3; | 98 return 3; |
76 } else { | 99 } else { |
77 return 0; | 100 return 0; |
78 } | 101 } |
79 } | 102 } |
80 | 103 |
81 PdfObject* resolveReferenceObject(PdfMemDocument* pdfDoc, | 104 const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, |
82 PdfObject* obj, | 105 const PdfObject* obj, |
83 bool resolveOneElementArrays = false) { | 106 bool resolveOneElementArrays = false) { |
84 while (obj && (obj->IsReference() || (resolveOneElementArrays && | 107 while (obj && (obj->IsReference() || (resolveOneElementArrays && |
85 obj->IsArray() && | 108 obj->IsArray() && |
86 obj->GetArray().GetSize() == 1))) { | 109 obj->GetArray().GetSize() == 1))) { |
87 if (obj->IsReference()) { | 110 if (obj->IsReference()) { |
88 // We need to force the non const, the only update we will do is for
recurssion checks. | 111 // We need to force the non const, the only update we will do is for
recurssion checks. |
89 PdfReference& ref = (PdfReference&)obj->GetReference(); | 112 PdfReference& ref = (PdfReference&)obj->GetReference(); |
90 obj = pdfDoc->GetObjects().GetObject(ref); | 113 obj = pdfDoc->GetObjects().GetObject(ref); |
91 } else { | 114 } else { |
92 obj = &obj->GetArray()[0]; | 115 obj = &obj->GetArray()[0]; |
93 } | 116 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 SkPath fClipPath; | 168 SkPath fClipPath; |
146 | 169 |
147 PdfColorOperator fStroking; | 170 PdfColorOperator fStroking; |
148 PdfColorOperator fNonStroking; | 171 PdfColorOperator fNonStroking; |
149 | 172 |
150 double fLineWidth; | 173 double fLineWidth; |
151 double fTextLeading; | 174 double fTextLeading; |
152 double fWordSpace; | 175 double fWordSpace; |
153 double fCharSpace; | 176 double fCharSpace; |
154 | 177 |
155 PdfObject* fObjectWithResources; | 178 const PdfObject* fObjectWithResources; |
156 | 179 |
157 SkBitmap fSMask; | 180 SkBitmap fSMask; |
158 | 181 |
159 PdfGraphicsState() { | 182 PdfGraphicsState() { |
160 fCurPosX = 0.0; | 183 fCurPosX = 0.0; |
161 fCurPosY = 0.0; | 184 fCurPosY = 0.0; |
162 fCurFontSize = 0.0; | 185 fCurFontSize = 0.0; |
163 fTextBlock = false; | 186 fTextBlock = false; |
164 fCurFont = NULL; | 187 fCurFont = NULL; |
165 fMatrix = SkMatrix::I(); | 188 fMatrix = SkMatrix::I(); |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 | 578 |
556 // TODO(edisonn): move this code in podofo, so we don't have to fix the font. | 579 // TODO(edisonn): move this code in podofo, so we don't have to fix the font. |
557 // This logic needs to be moved in PdfEncodingObjectFactory::CreateEncoding | 580 // This logic needs to be moved in PdfEncodingObjectFactory::CreateEncoding |
558 std::map<PdfFont*, PdfCMapEncoding*> gFontsFixed; | 581 std::map<PdfFont*, PdfCMapEncoding*> gFontsFixed; |
559 PdfEncoding* FixPdfFont(PdfContext* pdfContext, PdfFont* fCurFont) { | 582 PdfEncoding* FixPdfFont(PdfContext* pdfContext, PdfFont* fCurFont) { |
560 // TODO(edisonn): and is Identity-H | 583 // TODO(edisonn): and is Identity-H |
561 if (gFontsFixed.find(fCurFont) == gFontsFixed.end()) { | 584 if (gFontsFixed.find(fCurFont) == gFontsFixed.end()) { |
562 if (fCurFont->GetObject()->IsDictionary() && fCurFont->GetObject()->GetD
ictionary().HasKey(PdfName("ToUnicode"))) { | 585 if (fCurFont->GetObject()->IsDictionary() && fCurFont->GetObject()->GetD
ictionary().HasKey(PdfName("ToUnicode"))) { |
563 PdfCMapEncoding* enc = new PdfCMapEncoding( | 586 PdfCMapEncoding* enc = new PdfCMapEncoding( |
564 fCurFont->GetObject(), | 587 fCurFont->GetObject(), |
565 resolveReferenceObject(pdfContext->fPdfDoc, | 588 (PdfObject*)resolveReferenceObject(pdfContext->fPdfDoc, |
566 fCurFont->GetObject()->GetDictionary(
).GetKey(PdfName("ToUnicode"))), | 589 fCurFont->GetObject()->GetDictionary(
).GetKey(PdfName("ToUnicode"))), |
567 PdfCMapEncoding::eBaseEncoding_Identity); // todo, read the
base encoding | 590 PdfCMapEncoding::eBaseEncoding_Identity); // todo, read the
base encoding |
568 gFontsFixed[fCurFont] = enc; | 591 gFontsFixed[fCurFont] = enc; |
569 return enc; | 592 return enc; |
570 } | 593 } |
571 | 594 |
572 return NULL; | 595 return NULL; |
573 } | 596 } |
574 | 597 |
575 return gFontsFixed[fCurFont]; | 598 return gFontsFixed[fCurFont]; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 } | 744 } |
722 | 745 |
723 // TODO(edisonn): create header files with declarations! | 746 // TODO(edisonn): create header files with declarations! |
724 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); | 747 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); |
725 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); | 748 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); |
726 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); | 749 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); |
727 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); | 750 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); |
728 | 751 |
729 // TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in Get
Key? | 752 // TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in Get
Key? |
730 // Always pass long form in key, and have a map of long -> short key | 753 // Always pass long form in key, and have a map of long -> short key |
731 bool LongFromDictionary(PdfContext* pdfContext, | 754 bool LongFromDictionary(const PdfMemDocument* pdfDoc, |
732 PdfDictionary& dict, | 755 const PdfDictionary& dict, |
733 const char* key, | 756 const char* key, |
734 long* data) { | 757 long* data) { |
735 PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 758 const PdfObject* value = resolveReferenceObject(pdfDoc, |
736 dict.GetKey(PdfName(key))); | 759 dict.GetKey(PdfName(key))); |
737 | 760 |
738 if (value == NULL || !value->IsNumber()) { | 761 if (value == NULL || !value->IsNumber()) { |
739 return false; | 762 return false; |
740 } | 763 } |
741 | 764 |
742 *data = value->GetNumber(); | 765 *data = value->GetNumber(); |
743 return true; | 766 return true; |
744 } | 767 } |
745 | 768 |
746 bool BoolFromDictionary(PdfContext* pdfContext, | 769 bool LongFromDictionary(const PdfMemDocument* pdfDoc, |
747 PdfDictionary& dict, | 770 const PdfDictionary& dict, |
| 771 const char* key, |
| 772 const char* abr, |
| 773 long* data) { |
| 774 if (LongFromDictionary(pdfDoc, dict, key, data)) return true; |
| 775 if (abr == NULL || *abr == '\0') return false; |
| 776 return LongFromDictionary(pdfDoc, dict, abr, data); |
| 777 } |
| 778 |
| 779 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, |
| 780 const PdfDictionary& dict, |
748 const char* key, | 781 const char* key, |
749 bool* data) { | 782 bool* data) { |
750 PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 783 const PdfObject* value = resolveReferenceObject(pdfDoc, |
751 dict.GetKey(PdfName(key))); | 784 dict.GetKey(PdfName(key))); |
752 | 785 |
753 if (value == NULL || !value->IsBool()) { | 786 if (value == NULL || !value->IsBool()) { |
754 return false; | 787 return false; |
755 } | 788 } |
756 | 789 |
757 *data = value->GetBool(); | 790 *data = value->GetBool(); |
758 return true; | 791 return true; |
759 } | 792 } |
760 | 793 |
761 bool NameFromDictionary(PdfContext* pdfContext, | 794 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, |
762 PdfDictionary& dict, | 795 const PdfDictionary& dict, |
| 796 const char* key, |
| 797 const char* abr, |
| 798 bool* data) { |
| 799 if (BoolFromDictionary(pdfDoc, dict, key, data)) return true; |
| 800 if (abr == NULL || *abr == '\0') return false; |
| 801 return BoolFromDictionary(pdfDoc, dict, abr, data); |
| 802 } |
| 803 |
| 804 bool NameFromDictionary(const PdfMemDocument* pdfDoc, |
| 805 const PdfDictionary& dict, |
763 const char* key, | 806 const char* key, |
764 std::string* data) { | 807 std::string* data) { |
765 PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 808 const PdfObject* value = resolveReferenceObject(pdfDoc, |
766 dict.GetKey(PdfName(key)), | 809 dict.GetKey(PdfName(key)), |
767 true); | 810 true); |
768 if (value == NULL || !value->IsName()) { | 811 if (value == NULL || !value->IsName()) { |
769 return false; | 812 return false; |
770 } | 813 } |
771 | 814 |
772 *data = value->GetName().GetName(); | 815 *data = value->GetName().GetName(); |
773 return true; | 816 return true; |
774 } | 817 } |
775 | 818 |
| 819 bool NameFromDictionary(const PdfMemDocument* pdfDoc, |
| 820 const PdfDictionary& dict, |
| 821 const char* key, |
| 822 const char* abr, |
| 823 std::string* data) { |
| 824 if (NameFromDictionary(pdfDoc, dict, key, data)) return true; |
| 825 if (abr == NULL || *abr == '\0') return false; |
| 826 return NameFromDictionary(pdfDoc, dict, abr, data); |
| 827 } |
| 828 |
776 // TODO(edisonn): perf!!! | 829 // TODO(edisonn): perf!!! |
777 | 830 |
778 static SkColorTable* getGrayColortable() { | 831 static SkColorTable* getGrayColortable() { |
779 static SkColorTable* grayColortable = NULL; | 832 static SkColorTable* grayColortable = NULL; |
780 if (grayColortable == NULL) { | 833 if (grayColortable == NULL) { |
781 SkPMColor* colors = new SkPMColor[256]; | 834 SkPMColor* colors = new SkPMColor[256]; |
782 for (int i = 0 ; i < 256; i++) { | 835 for (int i = 0 ; i < 256; i++) { |
783 colors[i] = SkPreMultiplyARGB(255, i, i, i); | 836 colors[i] = SkPreMultiplyARGB(255, i, i, i); |
784 } | 837 } |
785 grayColortable = new SkColorTable(colors, 256); | 838 grayColortable = new SkColorTable(colors, 256); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 | 945 |
893 // utils | 946 // utils |
894 | 947 |
895 // TODO(edisonn): add cache, or put the bitmap property directly on the PdfObjec
t | 948 // TODO(edisonn): add cache, or put the bitmap property directly on the PdfObjec
t |
896 // TODO(edisonn): deal with colorSpaces, we could add them to SkBitmap::Config | 949 // TODO(edisonn): deal with colorSpaces, we could add them to SkBitmap::Config |
897 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
22, 444 to closest | 950 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
22, 444 to closest |
898 // skia format, through a table | 951 // skia format, through a table |
899 | 952 |
900 // this functions returns the image, it does not look at the smask. | 953 // this functions returns the image, it does not look at the smask. |
901 | 954 |
902 SkBitmap getImageFromObject(PdfContext* pdfContext, PdfObject& obj, bool transpa
rencyMask) { | 955 SkBitmap getImageFromObject(PdfContext* pdfContext, const SkPdfImage* image, boo
l transparencyMask) { |
| 956 if (image == NULL || !image->valid()) { |
| 957 // TODO(edisonn): report warning to be used in testing. |
| 958 return SkBitmap(); |
| 959 } |
| 960 |
| 961 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... |
| 962 // PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, |
| 963 // obj.GetDictionary().GetKey(PdfNa
me("Filter"))); |
| 964 // if (value && value->IsArray() && value->GetArray().GetSize() == 1) { |
| 965 // value = resolveReferenceObject(pdfContext->fPdfDoc, |
| 966 // &value->GetArray()[0]); |
| 967 // } |
| 968 // if (value && value->IsName() && value->GetName().GetName() == "DCTDecode")
{ |
| 969 // SkStream stream = SkStream:: |
| 970 // SkImageDecoder::Factory() |
| 971 // } |
| 972 |
| 973 long bpc = image->bpc(); |
| 974 long width = image->w(); |
| 975 long height = image->h(); |
| 976 std::string colorSpace = image->cs(); |
| 977 |
| 978 /* |
| 979 bool imageMask = image->imageMask(); |
| 980 |
| 981 if (imageMask) { |
| 982 if (bpc != 0 && bpc != 1) { |
| 983 // TODO(edisonn): report warning to be used in testing. |
| 984 return SkBitmap(); |
| 985 } |
| 986 bpc = 1; |
| 987 } |
| 988 */ |
| 989 |
| 990 const PdfObject* obj = image->podofo(); |
| 991 |
| 992 char* uncompressedStream = NULL; |
| 993 pdf_long uncompressedStreamLength = 0; |
| 994 |
| 995 PdfResult ret = kPartial_PdfResult; |
| 996 // TODO(edisonn): get rid of try/catch exceptions! We should not throw on us
er data! |
| 997 try { |
| 998 obj->GetStream()->GetFilteredCopy(&uncompressedStream, &uncompressedStre
amLength); |
| 999 } catch (PdfError& e) { |
| 1000 // TODO(edisonn): report warning to be used in testing. |
| 1001 return SkBitmap(); |
| 1002 } |
| 1003 |
| 1004 int bytesPerLine = uncompressedStreamLength / height; |
| 1005 #ifdef PDF_TRACE |
| 1006 if (uncompressedStreamLength % height != 0) { |
| 1007 printf("Warning uncompressedStreamLength % height != 0 !!!\n"); |
| 1008 } |
| 1009 #endif |
| 1010 |
| 1011 SkBitmap bitmap = transferImageStreamToBitmap( |
| 1012 (unsigned char*)uncompressedStream, uncompressedStreamLength, |
| 1013 width, height, bytesPerLine, |
| 1014 bpc, colorSpace, |
| 1015 transparencyMask); |
| 1016 |
| 1017 free(uncompressedStream); |
| 1018 |
| 1019 return bitmap; |
| 1020 } |
| 1021 |
| 1022 SkBitmap getImageFromObjectOld(PdfContext* pdfContext, const PdfObject& obj, boo
l transparencyMask) { |
903 if (!obj.HasStream() || obj.GetStream() == NULL || obj.GetStream()->GetLengt
h() == 0 || | 1023 if (!obj.HasStream() || obj.GetStream() == NULL || obj.GetStream()->GetLengt
h() == 0 || |
904 !obj.IsDictionary()) { | 1024 !obj.IsDictionary()) { |
905 // TODO(edisonn): report warning to be used in testing. | 1025 // TODO(edisonn): report warning to be used in testing. |
906 return SkBitmap(); | 1026 return SkBitmap(); |
907 } | 1027 } |
908 | 1028 |
909 PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 1029 const PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, |
910 obj.GetDictionary().GetKey(PdfName
("Filter"))); | 1030 obj.GetDictionary().GetKey(PdfName
("Filter"))); |
911 | 1031 |
912 if (value && value->IsArray() && value->GetArray().GetSize() == 1) { | 1032 if (value && value->IsArray() && value->GetArray().GetSize() == 1) { |
913 value = resolveReferenceObject(pdfContext->fPdfDoc, | 1033 value = resolveReferenceObject(pdfContext->fPdfDoc, |
914 &value->GetArray()[0]); | 1034 &value->GetArray()[0]); |
915 } | 1035 } |
916 | 1036 |
917 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... | 1037 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... |
918 // if (value && value->IsName() && value->GetName().GetName() == "DCTDecode")
{ | 1038 // if (value && value->IsName() && value->GetName().GetName() == "DCTDecode")
{ |
919 // SkStream stream = SkStream:: | 1039 // SkStream stream = SkStream:: |
920 // SkImageDecoder::Factory() | 1040 // SkImageDecoder::Factory() |
921 // } | 1041 // } |
922 | 1042 |
923 // Get color space | 1043 // Get color space |
924 // translate | 1044 // translate |
925 | 1045 |
926 long bpc = 0; | 1046 long bpc = 0; |
927 LongFromDictionary(pdfContext, obj.GetDictionary(), "BitsPerComponent", &bpc
); | 1047 LongFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "BitsPerCompone
nt", "BPC", &bpc); |
928 | 1048 |
929 bool imageMask = false; | 1049 bool imageMask = false; |
930 BoolFromDictionary(pdfContext, obj.GetDictionary(), "ImageMask", &imageMask)
; | 1050 BoolFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "ImageMask", ""
, &imageMask); |
931 | 1051 |
932 if (imageMask) { | 1052 if (imageMask) { |
933 if (bpc != 0 && bpc != 1) { | 1053 if (bpc != 0 && bpc != 1) { |
934 // TODO(edisonn): report warning to be used in testing. | 1054 // TODO(edisonn): report warning to be used in testing. |
935 return SkBitmap(); | 1055 return SkBitmap(); |
936 } | 1056 } |
937 bpc = 1; | 1057 bpc = 1; |
938 } | 1058 } |
939 | 1059 |
940 long width; | 1060 long width; |
941 if (!LongFromDictionary(pdfContext, obj.GetDictionary(), "Width", &width)) { | 1061 if (!LongFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "Width", &
width)) { |
942 // TODO(edisonn): report warning to be used in testing. | 1062 // TODO(edisonn): report warning to be used in testing. |
943 return SkBitmap(); | 1063 return SkBitmap(); |
944 } | 1064 } |
945 | 1065 |
946 long height; | 1066 long height; |
947 if (!LongFromDictionary(pdfContext, obj.GetDictionary(), "Height", &height))
{ | 1067 if (!LongFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "Height",
&height)) { |
948 // TODO(edisonn): report warning to be used in testing. | 1068 // TODO(edisonn): report warning to be used in testing. |
949 return SkBitmap(); | 1069 return SkBitmap(); |
950 } | 1070 } |
951 | 1071 |
952 std::string colorSpace; // TODO(edisonn): load others than names, for more
complicated | 1072 std::string colorSpace; // TODO(edisonn): load others than names, for more
complicated |
953 if (!NameFromDictionary(pdfContext, obj.GetDictionary(), "ColorSpace", &colo
rSpace)) { | 1073 if (!NameFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "ColorSpac
e", &colorSpace)) { |
954 // TODO(edisonn): report warning to be used in testing. | 1074 // TODO(edisonn): report warning to be used in testing. |
955 return SkBitmap(); | 1075 return SkBitmap(); |
956 } | 1076 } |
957 | 1077 |
958 char* uncompressedStream = NULL; | 1078 char* uncompressedStream = NULL; |
959 pdf_long uncompressedStreamLength = 0; | 1079 pdf_long uncompressedStreamLength = 0; |
960 | 1080 |
961 PdfResult ret = kPartial_PdfResult; | 1081 PdfResult ret = kPartial_PdfResult; |
962 // TODO(edisonn): get rid of try/catch exceptions! We should not throw on us
er data! | 1082 // TODO(edisonn): get rid of try/catch exceptions! We should not throw on us
er data! |
963 try { | 1083 try { |
(...skipping 14 matching lines...) Expand all Loading... |
978 (unsigned char*)uncompressedStream, uncompressedStreamLength, | 1098 (unsigned char*)uncompressedStream, uncompressedStreamLength, |
979 width, height, bytesPerLine, | 1099 width, height, bytesPerLine, |
980 bpc, colorSpace, | 1100 bpc, colorSpace, |
981 transparencyMask); | 1101 transparencyMask); |
982 | 1102 |
983 free(uncompressedStream); | 1103 free(uncompressedStream); |
984 | 1104 |
985 return bitmap; | 1105 return bitmap; |
986 } | 1106 } |
987 | 1107 |
988 SkBitmap getSmaskFromObject(PdfContext* pdfContext, PdfObject& obj) { | 1108 SkBitmap getSmaskFromObject(PdfContext* pdfContext, const SkPdfImage* obj) { |
989 PdfObject* sMask = resolveReferenceObject(pdfContext->fPdfDoc, | 1109 const PdfObject* sMask = resolveReferenceObject(pdfContext->fPdfDoc, |
| 1110 obj->podofo()->GetDictionary().Get
Key(PdfName("SMask"))); |
| 1111 |
| 1112 #ifdef PDF_TRACE |
| 1113 std::string str; |
| 1114 if (sMask) { |
| 1115 sMask->ToString(str); |
| 1116 printf("/SMask of /Subtype /Image: %s\n", str.c_str()); |
| 1117 } |
| 1118 #endif |
| 1119 |
| 1120 if (sMask) { |
| 1121 SkPdfImage skxobjmask(pdfContext->fPdfDoc, sMask); |
| 1122 return getImageFromObject(pdfContext, &skxobjmask, true); |
| 1123 } |
| 1124 |
| 1125 // TODO(edisonn): implement GS SMask. Default to empty right now. |
| 1126 return pdfContext->fGraphicsState.fSMask; |
| 1127 } |
| 1128 |
| 1129 SkBitmap getSmaskFromObjectOld(PdfContext* pdfContext, const PdfObject& obj) { |
| 1130 const PdfObject* sMask = resolveReferenceObject(pdfContext->fPdfDoc, |
990 obj.GetDictionary().GetKey(PdfName
("SMask"))); | 1131 obj.GetDictionary().GetKey(PdfName
("SMask"))); |
991 | 1132 |
992 #ifdef PDF_TRACE | 1133 #ifdef PDF_TRACE |
993 std::string str; | 1134 std::string str; |
994 if (sMask) { | 1135 if (sMask) { |
995 sMask->ToString(str); | 1136 sMask->ToString(str); |
996 printf("/SMask of /Subtype /Image: %s\n", str.c_str()); | 1137 printf("/SMask of /Subtype /Image: %s\n", str.c_str()); |
997 } | 1138 } |
998 #endif | 1139 #endif |
999 | 1140 |
1000 if (sMask) { | 1141 if (sMask) { |
1001 return getImageFromObject(pdfContext, *sMask, true); | 1142 return getImageFromObjectOld(pdfContext, *sMask, true); |
1002 } | 1143 } |
1003 | 1144 |
1004 // TODO(edisonn): implement GS SMask. Default to empty right now. | 1145 // TODO(edisonn): implement GS SMask. Default to empty right now. |
1005 return pdfContext->fGraphicsState.fSMask; | 1146 return pdfContext->fGraphicsState.fSMask; |
1006 } | 1147 } |
1007 | 1148 |
1008 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, PdfObject& o
bj) { | 1149 |
| 1150 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfI
mage* skpdfimage) { |
| 1151 if (skpdfimage == NULL || !skpdfimage->valid()) { |
| 1152 return kIgnoreError_PdfResult; |
| 1153 } |
| 1154 |
| 1155 SkBitmap image = getImageFromObject(pdfContext, skpdfimage, false); |
| 1156 SkBitmap sMask = getSmaskFromObject(pdfContext, skpdfimage); |
| 1157 |
| 1158 canvas->save(); |
| 1159 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
| 1160 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); |
| 1161 |
| 1162 if (sMask.empty()) { |
| 1163 canvas->drawBitmapRect(image, dst, NULL); |
| 1164 } else { |
| 1165 canvas->saveLayer(&dst, NULL); |
| 1166 canvas->drawBitmapRect(image, dst, NULL); |
| 1167 SkPaint xfer; |
| 1168 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode |
| 1169 canvas->drawBitmapRect(sMask, dst, &xfer); |
| 1170 canvas->restore(); |
| 1171 } |
| 1172 |
| 1173 canvas->restore(); |
| 1174 |
| 1175 return kPartial_PdfResult; |
| 1176 } |
| 1177 |
| 1178 PdfResult doXObject_ImageOld(PdfContext* pdfContext, SkCanvas* canvas, const Pdf
Object& obj) { |
1009 if (!obj.HasStream() || obj.GetStream() == NULL || obj.GetStream()->GetLengt
h() == 0 || | 1179 if (!obj.HasStream() || obj.GetStream() == NULL || obj.GetStream()->GetLengt
h() == 0 || |
1010 !obj.IsDictionary()) { | 1180 !obj.IsDictionary()) { |
1011 return kIgnoreError_PdfResult; | 1181 return kIgnoreError_PdfResult; |
1012 } | 1182 } |
1013 | 1183 |
1014 SkBitmap image = getImageFromObject(pdfContext, obj, false); | 1184 SkBitmap image = getImageFromObjectOld(pdfContext, obj, false); |
1015 SkBitmap sMask = getSmaskFromObject(pdfContext, obj); | 1185 SkBitmap sMask = getSmaskFromObjectOld(pdfContext, obj); |
1016 | 1186 |
1017 canvas->save(); | 1187 canvas->save(); |
1018 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 1188 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
1019 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); | 1189 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); |
1020 | 1190 |
1021 if (sMask.empty()) { | 1191 if (sMask.empty()) { |
1022 canvas->drawBitmapRect(image, dst, NULL); | 1192 canvas->drawBitmapRect(image, dst, NULL); |
1023 } else { | 1193 } else { |
1024 canvas->saveLayer(&dst, NULL); | 1194 canvas->saveLayer(&dst, NULL); |
1025 canvas->drawBitmapRect(image, dst, NULL); | 1195 canvas->drawBitmapRect(image, dst, NULL); |
1026 SkPaint xfer; | 1196 SkPaint xfer; |
1027 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode | 1197 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode |
1028 canvas->drawBitmapRect(sMask, dst, &xfer); | 1198 canvas->drawBitmapRect(sMask, dst, &xfer); |
1029 canvas->restore(); | 1199 canvas->restore(); |
1030 } | 1200 } |
1031 | 1201 |
1032 canvas->restore(); | 1202 canvas->restore(); |
1033 | 1203 |
1034 return kPartial_PdfResult; | 1204 return kPartial_PdfResult; |
1035 } | 1205 } |
1036 | 1206 |
1037 PdfResult doXObject_ImageOld(PdfContext* pdfContext, SkCanvas* canvas, PdfObject
& obj) { | 1207 |
| 1208 PdfResult doXObject_ImageOld2(PdfContext* pdfContext, SkCanvas* canvas, const Pd
fObject& obj) { |
1038 if (!obj.HasStream() || obj.GetStream() == NULL || obj.GetStream()->GetLengt
h() == 0 || | 1209 if (!obj.HasStream() || obj.GetStream() == NULL || obj.GetStream()->GetLengt
h() == 0 || |
1039 !obj.IsDictionary()) { | 1210 !obj.IsDictionary()) { |
1040 return kIgnoreError_PdfResult; | 1211 return kIgnoreError_PdfResult; |
1041 } | 1212 } |
1042 | 1213 |
1043 PdfObject* sMask = resolveReferenceObject(pdfContext->fPdfDoc, | 1214 const PdfObject* sMask = resolveReferenceObject(pdfContext->fPdfDoc, |
1044 obj.GetDictionary().GetKey(PdfName
("SMask"))); | 1215 obj.GetDictionary().GetKey(PdfName
("SMask"))); |
1045 // TODO(edisonn): else get smask from graphi state | 1216 // TODO(edisonn): else get smask from graphi state |
1046 // TODO(edisonn): add utility, SkBitmap loadBitmap(PdfObject& obj, bool no_s
mask); | 1217 // TODO(edisonn): add utility, SkBitmap loadBitmap(PdfObject& obj, bool no_s
mask); |
1047 // TODO(edisonn): add utility, SkBitmap loadSmask(state, PdfObject& obj); | 1218 // TODO(edisonn): add utility, SkBitmap loadSmask(state, PdfObject& obj); |
1048 | 1219 |
1049 #ifdef PDF_TRACE | 1220 #ifdef PDF_TRACE |
1050 std::string str; | 1221 std::string str; |
1051 if (sMask) { | 1222 if (sMask) { |
1052 sMask->ToString(str); | 1223 sMask->ToString(str); |
1053 printf("/SMask of /Subtype /Image: %s\n", str.c_str()); | 1224 printf("/SMask of /Subtype /Image: %s\n", str.c_str()); |
1054 } | 1225 } |
1055 #endif | 1226 #endif |
1056 | 1227 |
| 1228 /* |
| 1229 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... |
1057 PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 1230 PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, |
1058 obj.GetDictionary().GetKey(PdfName
("Filter"))); | 1231 obj.GetDictionary().GetKey(PdfName
("Filter"))); |
1059 | 1232 |
1060 if (value && value->IsArray() && value->GetArray().GetSize() == 1) { | 1233 if (value && value->IsArray() && value->GetArray().GetSize() == 1) { |
1061 value = resolveReferenceObject(pdfContext->fPdfDoc, | 1234 value = resolveReferenceObject(pdfContext->fPdfDoc, |
1062 &value->GetArray()[0]); | 1235 &value->GetArray()[0]); |
1063 } | 1236 } |
1064 | 1237 |
1065 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... | 1238 if (value && value->IsName() && value->GetName().GetName() == "DCTDecode") { |
1066 // if (value && value->IsName() && value->GetName().GetName() == "DCTDecode")
{ | 1239 SkStream stream = SkStream:: |
1067 // SkStream stream = SkStream:: | 1240 SkImageDecoder::Factory() |
1068 // SkImageDecoder::Factory() | 1241 } |
1069 // } | 1242 */ |
1070 | |
1071 // Get color space | 1243 // Get color space |
1072 // trasnlate | 1244 // trasnlate |
1073 | 1245 |
1074 long bpc = 0; | 1246 long bpc = 0; |
1075 LongFromDictionary(pdfContext, obj.GetDictionary(), "BitsPerComponent", &bpc
); | 1247 LongFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "BitsPerCompone
nt", "BPC", &bpc); |
1076 | 1248 |
1077 bool imageMask = false; | 1249 bool imageMask = false; |
1078 BoolFromDictionary(pdfContext, obj.GetDictionary(), "ImageMask", &imageMask)
; | 1250 BoolFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "ImageMask", ""
, &imageMask); |
1079 | 1251 |
1080 if (imageMask) { | 1252 if (imageMask) { |
1081 if (bpc != 0 && bpc != 1) { | 1253 if (bpc != 0 && bpc != 1) { |
1082 return kIgnoreError_PdfResult; | 1254 return kIgnoreError_PdfResult; |
1083 } | 1255 } |
1084 bpc = 1; | 1256 bpc = 1; |
1085 } | 1257 } |
1086 | 1258 |
1087 long width; | 1259 long width; |
1088 if (!LongFromDictionary(pdfContext, obj.GetDictionary(), "Width", &width)) { | 1260 if (!LongFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "Width", "
W", &width)) { |
1089 return kIgnoreError_PdfResult; | 1261 return kIgnoreError_PdfResult; |
1090 } | 1262 } |
1091 | 1263 |
1092 long height; | 1264 long height; |
1093 if (!LongFromDictionary(pdfContext, obj.GetDictionary(), "Height", &height))
{ | 1265 if (!LongFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "Height",
"H", &height)) { |
1094 return kIgnoreError_PdfResult; | 1266 return kIgnoreError_PdfResult; |
1095 } | 1267 } |
1096 | 1268 |
1097 std::string colorSpace; // TODO(edisonn): load others than names, for more
complicated | 1269 std::string colorSpace; // TODO(edisonn): load others than names, for more
complicated |
1098 if (!NameFromDictionary(pdfContext, obj.GetDictionary(), "ColorSpace", &colo
rSpace)) { | 1270 if (!NameFromDictionary(pdfContext->fPdfDoc, obj.GetDictionary(), "ColorSpac
e", "", &colorSpace)) { |
1099 return kIgnoreError_PdfResult; | 1271 return kIgnoreError_PdfResult; |
1100 } | 1272 } |
1101 | 1273 |
1102 char* uncompressedStream = NULL; | 1274 char* uncompressedStream = NULL; |
1103 pdf_long uncompressedStreamLength = 0; | 1275 pdf_long uncompressedStreamLength = 0; |
1104 | 1276 |
1105 PdfResult ret = kPartial_PdfResult; | 1277 PdfResult ret = kPartial_PdfResult; |
1106 // TODO(edisonn): get rid of try/catch exceptions! We should not throw on us
er data! | 1278 // TODO(edisonn): get rid of try/catch exceptions! We should not throw on us
er data! |
1107 try { | 1279 try { |
1108 obj.GetStream()->GetFilteredCopy(&uncompressedStream, &uncompressedStrea
mLength); | 1280 obj.GetStream()->GetFilteredCopy(&uncompressedStream, &uncompressedStrea
mLength); |
(...skipping 30 matching lines...) Expand all Loading... |
1139 canvas->save(); | 1311 canvas->save(); |
1140 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 1312 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
1141 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); | 1313 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); |
1142 canvas->drawBitmapRect(bitmap, dst, NULL); | 1314 canvas->drawBitmapRect(bitmap, dst, NULL); |
1143 canvas->restore(); | 1315 canvas->restore(); |
1144 | 1316 |
1145 return kPartial_PdfResult; | 1317 return kPartial_PdfResult; |
1146 } | 1318 } |
1147 | 1319 |
1148 bool SkMatrixFromDictionary(PdfContext* pdfContext, | 1320 bool SkMatrixFromDictionary(PdfContext* pdfContext, |
1149 PdfDictionary& dict, | 1321 const PdfDictionary& dict, |
1150 const char* key, | 1322 const char* key, |
1151 SkMatrix* matrix) { | 1323 SkMatrix* matrix) { |
1152 PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 1324 const PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, |
1153 dict.GetKey(PdfName(key))); | 1325 dict.GetKey(PdfName(key))); |
1154 | 1326 |
1155 if (value == NULL || !value->IsArray()) { | 1327 if (value == NULL || !value->IsArray()) { |
1156 return false; | 1328 return false; |
1157 } | 1329 } |
1158 | 1330 |
1159 if (value->GetArray().GetSize() != 6) { | 1331 if (value->GetArray().GetSize() != 6) { |
1160 return false; | 1332 return false; |
1161 } | 1333 } |
1162 | 1334 |
1163 double array[6]; | 1335 double array[6]; |
1164 for (int i = 0; i < 6; i++) { | 1336 for (int i = 0; i < 6; i++) { |
1165 PdfObject* elem = resolveReferenceObject(pdfContext->fPdfDoc, &value->Ge
tArray()[i]); | 1337 const PdfObject* elem = resolveReferenceObject(pdfContext->fPdfDoc, &val
ue->GetArray()[i]); |
1166 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { | 1338 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { |
1167 return false; | 1339 return false; |
1168 } | 1340 } |
1169 array[i] = elem->GetReal(); | 1341 array[i] = elem->GetReal(); |
1170 } | 1342 } |
1171 | 1343 |
1172 *matrix = SkMatrixFromPdfMatrix(array); | 1344 *matrix = SkMatrixFromPdfMatrix(array); |
1173 return true; | 1345 return true; |
1174 } | 1346 } |
1175 | 1347 |
1176 bool SkRectFromDictionary(PdfContext* pdfContext, | 1348 bool SkRectFromDictionary(PdfContext* pdfContext, |
1177 PdfDictionary& dict, | 1349 const PdfDictionary& dict, |
1178 const char* key, | 1350 const char* key, |
1179 SkRect* rect) { | 1351 SkRect* rect) { |
1180 PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 1352 const PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, |
1181 dict.GetKey(PdfName(key))); | 1353 dict.GetKey(PdfName(key))); |
1182 | 1354 |
1183 if (value == NULL || !value->IsArray()) { | 1355 if (value == NULL || !value->IsArray()) { |
1184 return false; | 1356 return false; |
1185 } | 1357 } |
1186 | 1358 |
1187 if (value->GetArray().GetSize() != 4) { | 1359 if (value->GetArray().GetSize() != 4) { |
1188 return false; | 1360 return false; |
1189 } | 1361 } |
1190 | 1362 |
1191 double array[4]; | 1363 double array[4]; |
1192 for (int i = 0; i < 4; i++) { | 1364 for (int i = 0; i < 4; i++) { |
1193 PdfObject* elem = resolveReferenceObject(pdfContext->fPdfDoc, &value->Ge
tArray()[i]); | 1365 const PdfObject* elem = resolveReferenceObject(pdfContext->fPdfDoc, &val
ue->GetArray()[i]); |
1194 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { | 1366 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { |
1195 return false; | 1367 return false; |
1196 } | 1368 } |
1197 array[i] = elem->GetReal(); | 1369 array[i] = elem->GetReal(); |
1198 } | 1370 } |
1199 | 1371 |
1200 *rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]), | 1372 *rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]), |
1201 SkDoubleToScalar(array[1]), | 1373 SkDoubleToScalar(array[1]), |
1202 SkDoubleToScalar(array[2]), | 1374 SkDoubleToScalar(array[2]), |
1203 SkDoubleToScalar(array[3])); | 1375 SkDoubleToScalar(array[3])); |
1204 return true; | 1376 return true; |
1205 } | 1377 } |
1206 | 1378 |
1207 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, PdfObject& ob
j) { | 1379 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, const PdfObje
ct& obj) { |
1208 if (!obj.HasStream() || obj.GetStream() == NULL || obj.GetStream()->GetLengt
h() == 0) { | 1380 if (!obj.HasStream() || obj.GetStream() == NULL || obj.GetStream()->GetLengt
h() == 0) { |
1209 return kOK_PdfResult; | 1381 return kOK_PdfResult; |
1210 } | 1382 } |
1211 | 1383 |
1212 PdfOp_q(pdfContext, canvas, NULL); | 1384 PdfOp_q(pdfContext, canvas, NULL); |
1213 canvas->save(); | 1385 canvas->save(); |
1214 | 1386 |
1215 pdfContext->fGraphicsState.fObjectWithResources = &obj; | 1387 pdfContext->fGraphicsState.fObjectWithResources = &obj; |
1216 | 1388 |
1217 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Current matrix"); | 1389 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Current matrix"); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1254 ret = kIgnoreError_PdfResult; | 1426 ret = kIgnoreError_PdfResult; |
1255 } | 1427 } |
1256 | 1428 |
1257 // TODO(edisonn): should we restore the variable stack at the same state? | 1429 // TODO(edisonn): should we restore the variable stack at the same state? |
1258 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | 1430 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. |
1259 canvas->restore(); | 1431 canvas->restore(); |
1260 PdfOp_Q(pdfContext, canvas, NULL); | 1432 PdfOp_Q(pdfContext, canvas, NULL); |
1261 return ret; | 1433 return ret; |
1262 } | 1434 } |
1263 | 1435 |
1264 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, PdfObject& obj)
{ | 1436 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
& obj) { |
1265 return kNYI_PdfResult; | 1437 return kNYI_PdfResult; |
1266 } | 1438 } |
1267 | 1439 |
1268 // TODO(edisonn): faster, have the property on the PdfObject itself. | 1440 // TODO(edisonn): faster, have the property on the PdfObject itself. |
1269 std::set<PdfObject*> gInRendering; | 1441 std::set<const PdfObject*> gInRendering; |
1270 | 1442 |
1271 class CheckRecursiveRendering { | 1443 class CheckRecursiveRendering { |
1272 PdfObject& fObj; | 1444 const PdfObject& fObj; |
1273 public: | 1445 public: |
1274 CheckRecursiveRendering(PdfObject& obj) : fObj(obj) { | 1446 CheckRecursiveRendering(const PdfObject& obj) : fObj(obj) { |
1275 gInRendering.insert(&obj); | 1447 gInRendering.insert(&obj); |
1276 } | 1448 } |
1277 | 1449 |
1278 ~CheckRecursiveRendering() { | 1450 ~CheckRecursiveRendering() { |
1279 //SkASSERT(fObj.fInRendering); | 1451 //SkASSERT(fObj.fInRendering); |
1280 gInRendering.erase(&fObj); | 1452 gInRendering.erase(&fObj); |
1281 } | 1453 } |
1282 | 1454 |
1283 static bool IsInRendering(PdfObject& obj) { | 1455 static bool IsInRendering(const PdfObject& obj) { |
1284 return gInRendering.find(&obj) != gInRendering.end(); | 1456 return gInRendering.find(&obj) != gInRendering.end(); |
1285 } | 1457 } |
1286 }; | 1458 }; |
1287 | 1459 |
1288 PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, PdfObject& obj) { | 1460 PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject& o
bj) { |
1289 if (CheckRecursiveRendering::IsInRendering(obj)) { | 1461 if (CheckRecursiveRendering::IsInRendering(obj)) { |
1290 // Oops, corrupt PDF! | 1462 // Oops, corrupt PDF! |
1291 return kIgnoreError_PdfResult; | 1463 return kIgnoreError_PdfResult; |
1292 } | 1464 } |
1293 | 1465 |
1294 CheckRecursiveRendering checkRecursion(obj); | 1466 CheckRecursiveRendering checkRecursion(obj); |
1295 | 1467 |
| 1468 // TODO(edisonn): check type |
| 1469 SkPdfObject* skobj = NULL; |
| 1470 if (!PodofoMapper::mapObject(*pdfContext->fPdfDoc, obj, &skobj)) return kIgn
oreError_PdfResult; |
| 1471 |
| 1472 if (!skobj || !skobj->valid()) return kIgnoreError_PdfResult; |
| 1473 |
| 1474 PdfResult ret = kIgnoreError_PdfResult; |
| 1475 switch (skobj->getType()) |
| 1476 { |
| 1477 case kObjectDictionaryXObjectImage_SkPdfObjectType: |
| 1478 ret = doXObject_Image(pdfContext, canvas, skobj->asImage()); |
| 1479 //case kObjectDictionaryXObjectForm_SkPdfObjectType: |
| 1480 //return doXObject_Form(skxobj.asForm()); |
| 1481 //case kObjectDictionaryXObjectPS_SkPdfObjectType: |
| 1482 //return doXObject_PS(skxobj.asPS()); |
| 1483 } |
| 1484 |
| 1485 delete skobj; |
| 1486 return ret; |
| 1487 } |
| 1488 |
| 1489 PdfResult doXObjectOld(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
& obj) { |
| 1490 if (CheckRecursiveRendering::IsInRendering(obj)) { |
| 1491 // Oops, corrupt PDF! |
| 1492 return kIgnoreError_PdfResult; |
| 1493 } |
| 1494 |
| 1495 CheckRecursiveRendering checkRecursion(obj); |
| 1496 |
1296 if (!obj.IsDictionary()) { | 1497 if (!obj.IsDictionary()) { |
1297 return kIgnoreError_PdfResult; | 1498 return kIgnoreError_PdfResult; |
1298 } | 1499 } |
1299 | 1500 |
1300 PdfObject* type = resolveReferenceObject(pdfContext->fPdfDoc, | 1501 const PdfObject* type = resolveReferenceObject(pdfContext->fPdfDoc, |
1301 obj.GetDictionary().GetKey(Pd
fName("Type"))); | 1502 obj.GetDictionary().GetKey(Pd
fName("Type"))); |
1302 | 1503 |
1303 if (type == NULL || !type->IsName()) { | 1504 if (type == NULL || !type->IsName()) { |
1304 return kIgnoreError_PdfResult; | 1505 return kIgnoreError_PdfResult; |
1305 } | 1506 } |
1306 | 1507 |
1307 if (type->GetName().GetName() != "XObject") { | 1508 if (type->GetName().GetName() != "XObject") { |
1308 return kIgnoreError_PdfResult; | 1509 return kIgnoreError_PdfResult; |
1309 } | 1510 } |
1310 | 1511 |
1311 PdfObject* subtype = | 1512 const PdfObject* subtype = |
1312 resolveReferenceObject(pdfContext->fPdfDoc, | 1513 resolveReferenceObject(pdfContext->fPdfDoc, |
1313 obj.GetDictionary().GetKey(PdfName("Subtype")
)); | 1514 obj.GetDictionary().GetKey(PdfName("Subtype")
)); |
1314 | 1515 |
1315 if (subtype == NULL || !subtype->IsName()) { | 1516 if (subtype == NULL || !subtype->IsName()) { |
1316 return kIgnoreError_PdfResult; | 1517 return kIgnoreError_PdfResult; |
1317 } | 1518 } |
1318 | 1519 |
1319 if (subtype->GetName().GetName() == "Image") { | 1520 if (subtype->GetName().GetName() == "Image") { |
1320 return doXObject_Image(pdfContext, canvas, obj); | 1521 return doXObject_ImageOld(pdfContext, canvas, obj); |
1321 } else if (subtype->GetName().GetName() == "Form") { | 1522 } else if (subtype->GetName().GetName() == "Form") { |
1322 return doXObject_Form(pdfContext, canvas, obj); | 1523 return doXObject_Form(pdfContext, canvas, obj); |
1323 } else if (subtype->GetName().GetName() == "PS") { | 1524 } else if (subtype->GetName().GetName() == "PS") { |
1324 return doXObject_PS(pdfContext, canvas, obj); | 1525 return doXObject_PS(pdfContext, canvas, obj); |
1325 } | 1526 } |
1326 return kIgnoreError_PdfResult; | 1527 return kIgnoreError_PdfResult; |
1327 } | 1528 } |
1328 | 1529 |
1329 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1530 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
1330 pdfContext->fStateStack.push(pdfContext->fGraphicsState); | 1531 pdfContext->fStateStack.push(pdfContext->fGraphicsState); |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2051 pdfContext->fVarStack.pop(); | 2252 pdfContext->fVarStack.pop(); |
2052 | 2253 |
2053 return kNYI_PdfResult; | 2254 return kNYI_PdfResult; |
2054 } | 2255 } |
2055 | 2256 |
2056 //dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictN
ame is | 2257 //dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictN
ame is |
2057 //the name of a graphics state parameter dictionary in the ExtGState subdictiona
ry of the current resource dictionary (see the next section). | 2258 //the name of a graphics state parameter dictionary in the ExtGState subdictiona
ry of the current resource dictionary (see the next section). |
2058 PdfResult PdfOp_gs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 2259 PdfResult PdfOp_gs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
2059 PdfName name = pdfContext->fVarStack.top().GetName(); pdfContext->fVarSta
ck.pop(); | 2260 PdfName name = pdfContext->fVarStack.top().GetName(); pdfContext->fVarSta
ck.pop(); |
2060 | 2261 |
2061 PdfDictionary& pageDict = pdfContext->fGraphicsState.fObjectWithResources->G
etDictionary(); | 2262 const PdfDictionary& pageDict = pdfContext->fGraphicsState.fObjectWithResour
ces->GetDictionary(); |
2062 PdfObject* resources = resolveReferenceObject(pdfContext->fPdfDoc, | 2263 const PdfObject* resources = resolveReferenceObject(pdfContext->fPdfDoc, |
2063 pageDict.GetKey("Resourc
es")); | 2264 pageDict.GetKey("Resourc
es")); |
2064 | 2265 |
2065 if (resources == NULL) { | 2266 if (resources == NULL) { |
2066 #ifdef PDF_TRACE | 2267 #ifdef PDF_TRACE |
2067 printf("WARNING: No Resources for a page with 'gs' operator!\n"); | 2268 printf("WARNING: No Resources for a page with 'gs' operator!\n"); |
2068 #endif | 2269 #endif |
2069 return kIgnoreError_PdfResult; | 2270 return kIgnoreError_PdfResult; |
2070 } | 2271 } |
2071 | 2272 |
2072 #ifdef PDF_TRACE | 2273 #ifdef PDF_TRACE |
2073 std::string str; | 2274 std::string str; |
2074 resources->ToString(str); | 2275 resources->ToString(str); |
2075 printf("Print gs Page Resources: %s\n", str.c_str()); | 2276 printf("Print gs Page Resources: %s\n", str.c_str()); |
2076 #endif | 2277 #endif |
2077 | 2278 |
2078 if (!resources->IsDictionary()) { | 2279 if (!resources->IsDictionary()) { |
2079 #ifdef PDF_TRACE | 2280 #ifdef PDF_TRACE |
2080 printf("Resources is not a dictionary!\n"); | 2281 printf("Resources is not a dictionary!\n"); |
2081 #endif | 2282 #endif |
2082 return kIgnoreError_PdfResult; | 2283 return kIgnoreError_PdfResult; |
2083 } | 2284 } |
2084 | 2285 |
2085 PdfDictionary& resourceDict = resources->GetDictionary(); | 2286 const PdfDictionary& resourceDict = resources->GetDictionary(); |
2086 //Next, get the ExtGState Dictionary from the Resource Dictionary: | 2287 //Next, get the ExtGState Dictionary from the Resource Dictionary: |
2087 PdfObject* extGStateDictionary = resolveReferenceObject(pdfContext->fPdfDoc, | 2288 const PdfObject* extGStateDictionary = resolveReferenceObject(pdfContext->fP
dfDoc, |
2088 resourceDict.Get
Key("ExtGState")); | 2289 resourceDict.Get
Key("ExtGState")); |
2089 | 2290 |
2090 if (extGStateDictionary == NULL) { | 2291 if (extGStateDictionary == NULL) { |
2091 #ifdef PDF_TRACE | 2292 #ifdef PDF_TRACE |
2092 printf("ExtGState is NULL!\n"); | 2293 printf("ExtGState is NULL!\n"); |
2093 #endif | 2294 #endif |
2094 return kIgnoreError_PdfResult; | 2295 return kIgnoreError_PdfResult; |
2095 } | 2296 } |
2096 | 2297 |
2097 if (!extGStateDictionary->IsDictionary()) { | 2298 if (!extGStateDictionary->IsDictionary()) { |
2098 #ifdef PDF_TRACE | 2299 #ifdef PDF_TRACE |
2099 printf("extGStateDictionary is not a dictionary!\n"); | 2300 printf("extGStateDictionary is not a dictionary!\n"); |
2100 #endif | 2301 #endif |
2101 return kIgnoreError_PdfResult; | 2302 return kIgnoreError_PdfResult; |
2102 } | 2303 } |
2103 | 2304 |
2104 PdfObject* value = | 2305 const PdfObject* value = |
2105 resolveReferenceObject(pdfContext->fPdfDoc, | 2306 resolveReferenceObject(pdfContext->fPdfDoc, |
2106 extGStateDictionary->GetDictionary().GetKey(n
ame)); | 2307 extGStateDictionary->GetDictionary().GetKey(n
ame)); |
2107 | 2308 |
2108 if (value == NULL) { | 2309 if (value == NULL) { |
2109 #ifdef PDF_TRACE | 2310 #ifdef PDF_TRACE |
2110 printf("Named object not found!\n"); | 2311 printf("Named object not found!\n"); |
2111 #endif | 2312 #endif |
2112 return kIgnoreError_PdfResult; | 2313 return kIgnoreError_PdfResult; |
2113 } | 2314 } |
2114 | 2315 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2193 PdfResult PdfOp_sh(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 2394 PdfResult PdfOp_sh(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
2194 pdfContext->fVarStack.pop(); | 2395 pdfContext->fVarStack.pop(); |
2195 | 2396 |
2196 return kNYI_PdfResult; | 2397 return kNYI_PdfResult; |
2197 } | 2398 } |
2198 | 2399 |
2199 //name Do | 2400 //name Do |
2200 PdfResult PdfOp_Do(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 2401 PdfResult PdfOp_Do(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
2201 PdfName name = pdfContext->fVarStack.top().GetName(); pdfContext->fVarSta
ck.pop(); | 2402 PdfName name = pdfContext->fVarStack.top().GetName(); pdfContext->fVarSta
ck.pop(); |
2202 | 2403 |
2203 PdfDictionary& pageDict = pdfContext->fGraphicsState.fObjectWithResources->G
etDictionary(); | 2404 const PdfDictionary& pageDict = pdfContext->fGraphicsState.fObjectWithResour
ces->GetDictionary(); |
2204 PdfObject* resources = resolveReferenceObject(pdfContext->fPdfDoc, | 2405 const PdfObject* resources = resolveReferenceObject(pdfContext->fPdfDoc, |
2205 pageDict.GetKey("Resourc
es")); | 2406 pageDict.GetKey("Resourc
es")); |
2206 | 2407 |
2207 if (resources == NULL) { | 2408 if (resources == NULL) { |
2208 #ifdef PDF_TRACE | 2409 #ifdef PDF_TRACE |
2209 printf("WARNING: No Resources for a page with 'Do' operator!s\n"); | 2410 printf("WARNING: No Resources for a page with 'Do' operator!s\n"); |
2210 #endif | 2411 #endif |
2211 return kIgnoreError_PdfResult; | 2412 return kIgnoreError_PdfResult; |
2212 } | 2413 } |
2213 | 2414 |
2214 #ifdef PDF_TRACE | 2415 #ifdef PDF_TRACE |
2215 std::string str; | 2416 std::string str; |
2216 resources->ToString(str); | 2417 resources->ToString(str); |
2217 printf("Print Do Page Resources: %s\n", str.c_str()); | 2418 printf("Print Do Page Resources: %s\n", str.c_str()); |
2218 #endif | 2419 #endif |
2219 | 2420 |
2220 if (!resources->IsDictionary()) { | 2421 if (!resources->IsDictionary()) { |
2221 #ifdef PDF_TRACE | 2422 #ifdef PDF_TRACE |
2222 printf("Resources is not a dictionary!\n"); | 2423 printf("Resources is not a dictionary!\n"); |
2223 #endif | 2424 #endif |
2224 return kIgnoreError_PdfResult; | 2425 return kIgnoreError_PdfResult; |
2225 } | 2426 } |
2226 | 2427 |
2227 PdfDictionary& resourceDict = resources->GetDictionary(); | 2428 const PdfDictionary& resourceDict = resources->GetDictionary(); |
2228 //Next, get the XObject Dictionary from the Resource Dictionary: | 2429 //Next, get the XObject Dictionary from the Resource Dictionary: |
2229 PdfObject* xObjectDictionary = resolveReferenceObject(pdfContext->fPdfDoc, | 2430 const PdfObject* xObjectDictionary = resolveReferenceObject(pdfContext->fPdf
Doc, |
2230 resourceDict.Get
Key("XObject")); | 2431 resourceDict.Get
Key("XObject")); |
2231 | 2432 |
2232 if (xObjectDictionary == NULL) { | 2433 if (xObjectDictionary == NULL) { |
2233 #ifdef PDF_TRACE | 2434 #ifdef PDF_TRACE |
2234 printf("XObject is NULL!\n"); | 2435 printf("XObject is NULL!\n"); |
2235 #endif | 2436 #endif |
2236 return kIgnoreError_PdfResult; | 2437 return kIgnoreError_PdfResult; |
2237 } | 2438 } |
2238 | 2439 |
2239 if (!xObjectDictionary->IsDictionary()) { | 2440 if (!xObjectDictionary->IsDictionary()) { |
2240 #ifdef PDF_TRACE | 2441 #ifdef PDF_TRACE |
2241 printf("xObjectDictionary is not a dictionary!\n"); | 2442 printf("xObjectDictionary is not a dictionary!\n"); |
2242 #endif | 2443 #endif |
2243 return kIgnoreError_PdfResult; | 2444 return kIgnoreError_PdfResult; |
2244 } | 2445 } |
2245 | 2446 |
2246 PdfObject* value = | 2447 const PdfObject* value = |
2247 resolveReferenceObject(pdfContext->fPdfDoc, | 2448 resolveReferenceObject(pdfContext->fPdfDoc, |
2248 xObjectDictionary->GetDictionary().GetKey(nam
e)); | 2449 xObjectDictionary->GetDictionary().GetKey(nam
e)); |
2249 | 2450 |
2250 if (value == NULL) { | 2451 if (value == NULL) { |
2251 #ifdef PDF_TRACE | 2452 #ifdef PDF_TRACE |
2252 printf("Named object not found!\n"); | 2453 printf("Named object not found!\n"); |
2253 #endif | 2454 #endif |
2254 return kIgnoreError_PdfResult; | 2455 return kIgnoreError_PdfResult; |
2255 } | 2456 } |
2256 | 2457 |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2863 } | 3064 } |
2864 | 3065 |
2865 return 0; | 3066 return 0; |
2866 } | 3067 } |
2867 | 3068 |
2868 #if !defined SK_BUILD_FOR_IOS | 3069 #if !defined SK_BUILD_FOR_IOS |
2869 int main(int argc, char * const argv[]) { | 3070 int main(int argc, char * const argv[]) { |
2870 return tool_main(argc, (char**) argv); | 3071 return tool_main(argc, (char**) argv); |
2871 } | 3072 } |
2872 #endif | 3073 #endif |
OLD | NEW |