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