OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
9 #include "SkDevice.h" | 9 #include "SkDevice.h" |
| 10 #include "SkForceLinking.h" |
10 #include "SkGraphics.h" | 11 #include "SkGraphics.h" |
11 #include "SkImageDecoder.h" | 12 #include "SkImageDecoder.h" |
12 #include "SkImageEncoder.h" | 13 #include "SkImageEncoder.h" |
13 #include "SkOSFile.h" | 14 #include "SkOSFile.h" |
14 #include "SkPicture.h" | 15 #include "SkPicture.h" |
15 #include "SkStream.h" | 16 #include "SkStream.h" |
16 #include "SkTypeface.h" | 17 #include "SkTypeface.h" |
17 #include "SkTArray.h" | 18 #include "SkTArray.h" |
18 #include "picture_utils.h" | 19 #include "picture_utils.h" |
19 | 20 |
20 #include <iostream> | 21 #include <iostream> |
21 #include <cstdio> | 22 #include <cstdio> |
22 #include <stack> | 23 #include <stack> |
23 | 24 |
24 #include "podofo.h" | 25 #include "podofo.h" |
25 using namespace PoDoFo; | 26 using namespace PoDoFo; |
26 | 27 |
| 28 __SK_FORCE_IMAGE_DECODER_LINKING; |
| 29 |
27 const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, | 30 const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, |
28 const PdfObject* obj, | 31 const PdfObject* obj, |
29 bool resolveOneElementArrays = false); | 32 bool resolveOneElementArrays = false); |
30 | 33 |
31 bool LongFromDictionary(const PdfMemDocument* pdfDoc, | 34 bool LongFromDictionary(const PdfMemDocument* pdfDoc, |
32 const PdfDictionary& dict, | 35 const PdfDictionary& dict, |
33 const char* key, | 36 const char* key, |
34 const char* abr, | 37 const char* abr, |
35 long* data); | 38 long* data); |
36 | 39 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, | 172 bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, |
170 const PdfDictionary& dict, | 173 const PdfDictionary& dict, |
171 const char* key, | 174 const char* key, |
172 const char* abr, | 175 const char* abr, |
173 SkPdfFunction* data) {return false;} | 176 SkPdfFunction* data) {return false;} |
174 | 177 |
175 | 178 |
176 | 179 |
177 /* | 180 /* |
178 * TODO(edisonn): | 181 * TODO(edisonn): |
179 * - encapsulate podofo in the pdf api so the skpdf does not know anything about
podofo | 182 * - encapsulate podofo in the pdf api so the skpdf does not know anything about
podofo ... in progress |
180 * - ASAP so skp -> pdf -> png looks great | 183 * - ASAP so skp -> pdf -> png looks great |
181 * - load gs/ especially smask and already known prop (skp) | 184 * - load gs/ especially smask and already known prop (skp)... |
182 * - use transparency (I think ca and CA ops) (skp) | 185 * - all font types and all ppdf font features |
183 * - all font types | 186 * - word spacing |
184 * - word spacing | 187 * - load font for baidu.pdf |
185 * - load font for baidu.pdf | 188 * - load font for youtube.pdf |
186 * - load font for youtube.pdf | 189 * - parser for pdf from the definition already available in pdfspec_autoge
n.py |
| 190 * - wrapper on classes for customizations? e.g. |
| 191 * SkPdfPageObjectVanila - has only the basic loaders/getters |
| 192 * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add custom
izations here |
| 193 * need to find a nice object model for all this with constructors and factories |
| 194 * - deal with inheritable automatically ? |
| 195 * - deal with specific type in spec directly, add all dictionary types to known
types |
187 */ | 196 */ |
188 | 197 |
189 //#define PDF_TRACE | 198 //#define PDF_TRACE |
190 //#define PDF_TRACE_DIFF_IN_PNG | 199 //#define PDF_TRACE_DIFF_IN_PNG |
191 //#define PDF_DEBUG_NO_CLIPING | 200 //#define PDF_DEBUG_NO_CLIPING |
192 //#define PDF_DEBUG_NO_PAGE_CLIPING | 201 //#define PDF_DEBUG_NO_PAGE_CLIPING |
193 //#define PDF_DEBUG_3X | 202 //#define PDF_DEBUG_3X |
194 | 203 |
195 // TODO(edisonn): move in trace util. | 204 // TODO(edisonn): move in trace util. |
196 #ifdef PDF_TRACE | 205 #ifdef PDF_TRACE |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 SkDoubleToScalar(0), | 272 SkDoubleToScalar(0), |
264 SkDoubleToScalar(1)); | 273 SkDoubleToScalar(1)); |
265 | 274 |
266 return matrix; | 275 return matrix; |
267 } | 276 } |
268 | 277 |
269 // TODO(edisonn): better class design. | 278 // TODO(edisonn): better class design. |
270 struct PdfColorOperator { | 279 struct PdfColorOperator { |
271 std::string fColorSpace; // TODO(edisonn): use SkString | 280 std::string fColorSpace; // TODO(edisonn): use SkString |
272 SkColor fColor; | 281 SkColor fColor; |
| 282 double fOpacity; // ca or CA |
273 // TODO(edisonn): add here other color space options. | 283 // TODO(edisonn): add here other color space options. |
274 | 284 |
275 void setRGBColor(SkColor color) { | 285 void setRGBColor(SkColor color) { |
276 // TODO(edisonn): ASSERT DeviceRGB is the color space. | 286 // TODO(edisonn): ASSERT DeviceRGB is the color space. |
277 fColor = color; | 287 fColor = color; |
278 } | 288 } |
279 // TODO(edisonn): double check the default values for all fields. | 289 // TODO(edisonn): double check the default values for all fields. |
280 PdfColorOperator() : fColor(SK_ColorBLACK) {} | 290 PdfColorOperator() : fColor(SK_ColorBLACK), fOpacity(1) {} |
| 291 |
| 292 void applyGraphicsState(SkPaint* paint) { |
| 293 paint->setColor(SkColorSetA(fColor, fOpacity * 255)); |
| 294 } |
| 295 |
281 }; | 296 }; |
282 | 297 |
283 // TODO(edisonn): better class design. | 298 // TODO(edisonn): better class design. |
284 struct PdfGraphicsState { | 299 struct PdfGraphicsState { |
285 SkMatrix fMatrix; | 300 SkMatrix fMatrix; |
286 SkMatrix fMatrixTm; | 301 SkMatrix fMatrixTm; |
287 SkMatrix fMatrixTlm; | 302 SkMatrix fMatrixTlm; |
288 | 303 |
289 double fCurPosX; | 304 double fCurPosX; |
290 double fCurPosY; | 305 double fCurPosY; |
(...skipping 28 matching lines...) Expand all Loading... |
319 fCurFont = NULL; | 334 fCurFont = NULL; |
320 fMatrix = SkMatrix::I(); | 335 fMatrix = SkMatrix::I(); |
321 fMatrixTm = SkMatrix::I(); | 336 fMatrixTm = SkMatrix::I(); |
322 fMatrixTlm = SkMatrix::I(); | 337 fMatrixTlm = SkMatrix::I(); |
323 fPathClosed = true; | 338 fPathClosed = true; |
324 fLineWidth = 0; | 339 fLineWidth = 0; |
325 fTextLeading = 0; | 340 fTextLeading = 0; |
326 fWordSpace = 0; | 341 fWordSpace = 0; |
327 fCharSpace = 0; | 342 fCharSpace = 0; |
328 fHasClipPathToApply = false; | 343 fHasClipPathToApply = false; |
329 fResources = NULL; | 344 fResources = NULL; |
| 345 } |
| 346 |
| 347 void applyGraphicsState(SkPaint* paint, bool stroking) { |
| 348 if (stroking) { |
| 349 fStroking.applyGraphicsState(paint); |
| 350 } else { |
| 351 fNonStroking.applyGraphicsState(paint); |
| 352 } |
| 353 |
| 354 // TODO(edisonn): get this from pdfContext->options, |
| 355 // or pdfContext->addPaintOptions(&paint); |
| 356 paint->setAntiAlias(true); |
| 357 |
| 358 // TODO(edisonn): dashing, miter, ... |
| 359 paint->setStrokeWidth(SkDoubleToScalar(fLineWidth)); |
330 } | 360 } |
331 }; | 361 }; |
332 | 362 |
333 // TODO(edisonn): better class design. | 363 // TODO(edisonn): better class design. |
334 struct PdfInlineImage { | 364 struct PdfInlineImage { |
335 std::map<std::string, std::string> fKeyValuePairs; | 365 std::map<std::string, std::string> fKeyValuePairs; |
336 std::string fImageData; | 366 std::string fImageData; |
337 | 367 |
338 }; | 368 }; |
339 | 369 |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 | 786 |
757 SkPaint paint; | 787 SkPaint paint; |
758 // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCur
FontSize == 0? | 788 // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCur
FontSize == 0? |
759 // Or maybe just not call setTextSize at all? | 789 // Or maybe just not call setTextSize at all? |
760 if (pdfContext->fGraphicsState.fCurFontSize != 0) { | 790 if (pdfContext->fGraphicsState.fCurFontSize != 0) { |
761 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); | 791 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); |
762 } | 792 } |
763 if (fCurFont->GetFontScale() != 0) { | 793 if (fCurFont->GetFontScale() != 0) { |
764 paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0)); | 794 paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0)); |
765 } | 795 } |
766 paint.setColor(pdfContext->fGraphicsState.fNonStroking.fColor); | 796 |
| 797 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
767 | 798 |
768 paint.setTypeface(SkTypefaceFromPdfFont(fCurFont)); | 799 paint.setTypeface(SkTypefaceFromPdfFont(fCurFont)); |
769 | 800 |
770 paint.setAntiAlias(true); | 801 paint.setAntiAlias(true); |
771 // TODO(edisonn): paint.setStyle(...); | 802 // TODO(edisonn): paint.setStyle(...); |
772 | 803 |
773 canvas->save(); | 804 canvas->save(); |
774 SkMatrix matrix = pdfContext->fGraphicsState.fMatrixTm; | 805 SkMatrix matrix = pdfContext->fGraphicsState.fMatrixTm; |
775 | 806 |
776 #if 0 | 807 #if 0 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 bool LongFromDictionary(const PdfMemDocument* pdfDoc, | 907 bool LongFromDictionary(const PdfMemDocument* pdfDoc, |
877 const PdfDictionary& dict, | 908 const PdfDictionary& dict, |
878 const char* key, | 909 const char* key, |
879 long* data) { | 910 long* data) { |
880 const PdfObject* value = resolveReferenceObject(pdfDoc, | 911 const PdfObject* value = resolveReferenceObject(pdfDoc, |
881 dict.GetKey(PdfName(key))); | 912 dict.GetKey(PdfName(key))); |
882 | 913 |
883 if (value == NULL || !value->IsNumber()) { | 914 if (value == NULL || !value->IsNumber()) { |
884 return false; | 915 return false; |
885 } | 916 } |
| 917 if (data == NULL) { |
| 918 return true; |
| 919 } |
886 | 920 |
887 *data = value->GetNumber(); | 921 *data = value->GetNumber(); |
888 return true; | 922 return true; |
889 } | 923 } |
890 | 924 |
891 bool LongFromDictionary(const PdfMemDocument* pdfDoc, | 925 bool LongFromDictionary(const PdfMemDocument* pdfDoc, |
892 const PdfDictionary& dict, | 926 const PdfDictionary& dict, |
893 const char* key, | 927 const char* key, |
894 const char* abr, | 928 const char* abr, |
895 long* data) { | 929 long* data) { |
896 if (LongFromDictionary(pdfDoc, dict, key, data)) return true; | 930 if (LongFromDictionary(pdfDoc, dict, key, data)) return true; |
897 if (abr == NULL || *abr == '\0') return false; | 931 if (abr == NULL || *abr == '\0') return false; |
898 return LongFromDictionary(pdfDoc, dict, abr, data); | 932 return LongFromDictionary(pdfDoc, dict, abr, data); |
899 } | 933 } |
900 | 934 |
901 bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, | 935 bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, |
902 const PdfDictionary& dict, | 936 const PdfDictionary& dict, |
903 const char* key, | 937 const char* key, |
904 double* data) { | 938 double* data) { |
905 const PdfObject* value = resolveReferenceObject(pdfDoc, | 939 const PdfObject* value = resolveReferenceObject(pdfDoc, |
906 dict.GetKey(PdfName(key))); | 940 dict.GetKey(PdfName(key))); |
907 | 941 |
908 if (value == NULL || !value->IsReal()) { | 942 if (value == NULL || (!value->IsReal() && !value->IsNumber())) { |
909 return false; | 943 return false; |
910 } | 944 } |
| 945 if (data == NULL) { |
| 946 return true; |
| 947 } |
911 | 948 |
912 *data = value->GetReal(); | 949 *data = value->GetReal(); |
913 return true; | 950 return true; |
914 } | 951 } |
915 | 952 |
916 bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, | 953 bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, |
917 const PdfDictionary& dict, | 954 const PdfDictionary& dict, |
918 const char* key, | 955 const char* key, |
919 const char* abr, | 956 const char* abr, |
920 double* data) { | 957 double* data) { |
921 if (DoubleFromDictionary(pdfDoc, dict, key, data)) return true; | 958 if (DoubleFromDictionary(pdfDoc, dict, key, data)) return true; |
922 if (abr == NULL || *abr == '\0') return false; | 959 if (abr == NULL || *abr == '\0') return false; |
923 return DoubleFromDictionary(pdfDoc, dict, abr, data); | 960 return DoubleFromDictionary(pdfDoc, dict, abr, data); |
924 } | 961 } |
925 | 962 |
926 | 963 |
927 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, | 964 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, |
928 const PdfDictionary& dict, | 965 const PdfDictionary& dict, |
929 const char* key, | 966 const char* key, |
930 bool* data) { | 967 bool* data) { |
931 const PdfObject* value = resolveReferenceObject(pdfDoc, | 968 const PdfObject* value = resolveReferenceObject(pdfDoc, |
932 dict.GetKey(PdfName(key))); | 969 dict.GetKey(PdfName(key))); |
933 | 970 |
934 if (value == NULL || !value->IsBool()) { | 971 if (value == NULL || !value->IsBool()) { |
935 return false; | 972 return false; |
936 } | 973 } |
| 974 if (data == NULL) { |
| 975 return true; |
| 976 } |
937 | 977 |
938 *data = value->GetBool(); | 978 *data = value->GetBool(); |
939 return true; | 979 return true; |
940 } | 980 } |
941 | 981 |
942 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, | 982 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, |
943 const PdfDictionary& dict, | 983 const PdfDictionary& dict, |
944 const char* key, | 984 const char* key, |
945 const char* abr, | 985 const char* abr, |
946 bool* data) { | 986 bool* data) { |
947 if (BoolFromDictionary(pdfDoc, dict, key, data)) return true; | 987 if (BoolFromDictionary(pdfDoc, dict, key, data)) return true; |
948 if (abr == NULL || *abr == '\0') return false; | 988 if (abr == NULL || *abr == '\0') return false; |
949 return BoolFromDictionary(pdfDoc, dict, abr, data); | 989 return BoolFromDictionary(pdfDoc, dict, abr, data); |
950 } | 990 } |
951 | 991 |
952 bool NameFromDictionary(const PdfMemDocument* pdfDoc, | 992 bool NameFromDictionary(const PdfMemDocument* pdfDoc, |
953 const PdfDictionary& dict, | 993 const PdfDictionary& dict, |
954 const char* key, | 994 const char* key, |
955 std::string* data) { | 995 std::string* data) { |
956 const PdfObject* value = resolveReferenceObject(pdfDoc, | 996 const PdfObject* value = resolveReferenceObject(pdfDoc, |
957 dict.GetKey(PdfName(key)), | 997 dict.GetKey(PdfName(key)), |
958 true); | 998 true); |
959 if (value == NULL || !value->IsName()) { | 999 if (value == NULL || !value->IsName()) { |
960 return false; | 1000 return false; |
961 } | 1001 } |
| 1002 if (data == NULL) { |
| 1003 return true; |
| 1004 } |
962 | 1005 |
963 *data = value->GetName().GetName(); | 1006 *data = value->GetName().GetName(); |
964 return true; | 1007 return true; |
965 } | 1008 } |
966 | 1009 |
967 bool NameFromDictionary(const PdfMemDocument* pdfDoc, | 1010 bool NameFromDictionary(const PdfMemDocument* pdfDoc, |
968 const PdfDictionary& dict, | 1011 const PdfDictionary& dict, |
969 const char* key, | 1012 const char* key, |
970 const char* abr, | 1013 const char* abr, |
971 std::string* data) { | 1014 std::string* data) { |
972 if (NameFromDictionary(pdfDoc, dict, key, data)) return true; | 1015 if (NameFromDictionary(pdfDoc, dict, key, data)) return true; |
973 if (abr == NULL || *abr == '\0') return false; | 1016 if (abr == NULL || *abr == '\0') return false; |
974 return NameFromDictionary(pdfDoc, dict, abr, data); | 1017 return NameFromDictionary(pdfDoc, dict, abr, data); |
975 } | 1018 } |
976 | 1019 |
977 bool StringFromDictionary(const PdfMemDocument* pdfDoc, | 1020 bool StringFromDictionary(const PdfMemDocument* pdfDoc, |
978 const PdfDictionary& dict, | 1021 const PdfDictionary& dict, |
979 const char* key, | 1022 const char* key, |
980 std::string* data) { | 1023 std::string* data) { |
981 const PdfObject* value = resolveReferenceObject(pdfDoc, | 1024 const PdfObject* value = resolveReferenceObject(pdfDoc, |
982 dict.GetKey(PdfName(key)), | 1025 dict.GetKey(PdfName(key)), |
983 true); | 1026 true); |
984 if (value == NULL || (!value->IsString() && !value->IsHexString())) { | 1027 if (value == NULL || (!value->IsString() && !value->IsHexString())) { |
985 return false; | 1028 return false; |
986 } | 1029 } |
| 1030 if (data == NULL) { |
| 1031 return true; |
| 1032 } |
987 | 1033 |
988 *data = value->GetString().GetString(); | 1034 *data = value->GetString().GetString(); |
989 return true; | 1035 return true; |
990 } | 1036 } |
991 | 1037 |
992 bool StringFromDictionary(const PdfMemDocument* pdfDoc, | 1038 bool StringFromDictionary(const PdfMemDocument* pdfDoc, |
993 const PdfDictionary& dict, | 1039 const PdfDictionary& dict, |
994 const char* key, | 1040 const char* key, |
995 const char* abr, | 1041 const char* abr, |
996 std::string* data) { | 1042 std::string* data) { |
997 if (StringFromDictionary(pdfDoc, dict, key, data)) return true; | 1043 if (StringFromDictionary(pdfDoc, dict, key, data)) return true; |
998 if (abr == NULL || *abr == '\0') return false; | 1044 if (abr == NULL || *abr == '\0') return false; |
999 return StringFromDictionary(pdfDoc, dict, abr, data); | 1045 return StringFromDictionary(pdfDoc, dict, abr, data); |
1000 } | 1046 } |
1001 | 1047 |
1002 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, | 1048 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, |
1003 const PdfDictionary& dict, | 1049 const PdfDictionary& dict, |
1004 const char* key, | 1050 const char* key, |
1005 SkPdfDictionary** data) { | 1051 SkPdfDictionary** data) { |
1006 const PdfObject* value = resolveReferenceObject(pdfDoc, | 1052 const PdfObject* value = resolveReferenceObject(pdfDoc, |
1007 dict.GetKey(PdfName(key)), | 1053 dict.GetKey(PdfName(key)), |
1008 true); | 1054 true); |
1009 if (value == NULL || !value->IsDictionary()) { | 1055 if (value == NULL || !value->IsDictionary()) { |
1010 return false; | 1056 return false; |
1011 } | 1057 } |
| 1058 if (data == NULL) { |
| 1059 return true; |
| 1060 } |
1012 | 1061 |
1013 return PodofoMapper::map(*pdfDoc, *value, (SkPdfObject**)data); | 1062 return PodofoMapper::map(*pdfDoc, *value, (SkPdfObject**)data); |
1014 } | 1063 } |
1015 | 1064 |
1016 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, | 1065 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, |
1017 const PdfDictionary& dict, | 1066 const PdfDictionary& dict, |
1018 const char* key, | 1067 const char* key, |
1019 const char* abr, | 1068 const char* abr, |
1020 SkPdfDictionary** data) { | 1069 SkPdfDictionary** data) { |
1021 if (DictionaryFromDictionary(pdfDoc, dict, key, data)) return true; | 1070 if (DictionaryFromDictionary(pdfDoc, dict, key, data)) return true; |
1022 if (abr == NULL || *abr == '\0') return false; | 1071 if (abr == NULL || *abr == '\0') return false; |
1023 return DictionaryFromDictionary(pdfDoc, dict, abr, data); | 1072 return DictionaryFromDictionary(pdfDoc, dict, abr, data); |
1024 } | 1073 } |
1025 | 1074 |
1026 template <typename T> | 1075 template <typename T> |
1027 bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc, | 1076 bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc, |
1028 const PdfDictionary& dict, | 1077 const PdfDictionary& dict, |
1029 const char* key, | 1078 const char* key, |
1030 SkPdfDictionary** data) { | 1079 SkPdfDictionary** data) { |
1031 const PdfObject* value = resolveReferenceObject(pdfDoc, | 1080 const PdfObject* value = resolveReferenceObject(pdfDoc, |
1032 dict.GetKey(PdfName(key)), | 1081 dict.GetKey(PdfName(key)), |
1033 true); | 1082 true); |
1034 if (value == NULL || !value->IsDictionary()) { | 1083 if (value == NULL || !value->IsDictionary()) { |
1035 return false; | 1084 return false; |
1036 } | 1085 } |
1037 | 1086 |
| 1087 if (data == NULL) { |
| 1088 return true; |
| 1089 } |
| 1090 |
1038 return PodofoMapper::map(*pdfDoc, *value, (T**)data); | 1091 return PodofoMapper::map(*pdfDoc, *value, (T**)data); |
1039 } | 1092 } |
1040 | 1093 |
1041 template <typename T> | 1094 template <typename T> |
1042 bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc, | 1095 bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc, |
1043 const PdfDictionary& dict, | 1096 const PdfDictionary& dict, |
1044 const char* key, | 1097 const char* key, |
1045 const char* abr, | 1098 const char* abr, |
1046 T** data) { | 1099 T** data) { |
1047 if (DictionaryFromDictionary2<T>(pdfDoc, dict, key, data)) return true; | 1100 if (DictionaryFromDictionary2<T>(pdfDoc, dict, key, data)) return true; |
1048 if (abr == NULL || *abr == '\0') return false; | 1101 if (abr == NULL || *abr == '\0') return false; |
1049 return DictionaryFromDictionary2<T>(pdfDoc, dict, abr, data); | 1102 return DictionaryFromDictionary2<T>(pdfDoc, dict, abr, data); |
1050 } | 1103 } |
1051 | 1104 |
1052 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, | 1105 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, |
1053 const PdfDictionary& dict, | 1106 const PdfDictionary& dict, |
1054 const char* key, | 1107 const char* key, |
1055 SkPdfObject** data) { | 1108 SkPdfObject** data) { |
1056 const PdfObject* value = resolveReferenceObject(pdfDoc, | 1109 const PdfObject* value = resolveReferenceObject(pdfDoc, |
1057 dict.GetKey(PdfName(key)), | 1110 dict.GetKey(PdfName(key)), |
1058 true); | 1111 true); |
1059 if (value == NULL) { | 1112 if (value == NULL) { |
1060 return false; | 1113 return false; |
1061 } | 1114 } |
| 1115 if (data == NULL) { |
| 1116 return true; |
| 1117 } |
1062 return PodofoMapper::map(*pdfDoc, *value, data); | 1118 return PodofoMapper::map(*pdfDoc, *value, data); |
1063 } | 1119 } |
1064 | 1120 |
1065 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, | 1121 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, |
1066 const PdfDictionary& dict, | 1122 const PdfDictionary& dict, |
1067 const char* key, | 1123 const char* key, |
1068 const char* abr, | 1124 const char* abr, |
1069 SkPdfObject** data) { | 1125 SkPdfObject** data) { |
1070 if (ObjectFromDictionary(pdfDoc, dict, key, data)) return true; | 1126 if (ObjectFromDictionary(pdfDoc, dict, key, data)) return true; |
1071 if (abr == NULL || *abr == '\0') return false; | 1127 if (abr == NULL || *abr == '\0') return false; |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1304 canvas->save(); | 1360 canvas->save(); |
1305 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 1361 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
1306 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); | 1362 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); |
1307 | 1363 |
1308 if (sMask.empty()) { | 1364 if (sMask.empty()) { |
1309 canvas->drawBitmapRect(image, dst, NULL); | 1365 canvas->drawBitmapRect(image, dst, NULL); |
1310 } else { | 1366 } else { |
1311 canvas->saveLayer(&dst, NULL); | 1367 canvas->saveLayer(&dst, NULL); |
1312 canvas->drawBitmapRect(image, dst, NULL); | 1368 canvas->drawBitmapRect(image, dst, NULL); |
1313 SkPaint xfer; | 1369 SkPaint xfer; |
| 1370 pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); |
1314 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode | 1371 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode |
1315 canvas->drawBitmapRect(sMask, dst, &xfer); | 1372 canvas->drawBitmapRect(sMask, dst, &xfer); |
1316 canvas->restore(); | 1373 canvas->restore(); |
1317 } | 1374 } |
1318 | 1375 |
1319 canvas->restore(); | 1376 canvas->restore(); |
1320 | 1377 |
1321 return kPartial_PdfResult; | 1378 return kPartial_PdfResult; |
1322 } | 1379 } |
1323 | 1380 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1590 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 1647 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
1591 pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); | 1648 pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); |
1592 | 1649 |
1593 return kPartial_PdfResult; | 1650 return kPartial_PdfResult; |
1594 } | 1651 } |
1595 | 1652 |
1596 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1653 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1597 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 1654 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); |
1598 double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 1655 double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); |
1599 | 1656 |
| 1657 // TODO(edisonn): Create factory methods or constructors so podofo is hidden |
1600 PdfObject _ty(PdfVariant(-ty)); | 1658 PdfObject _ty(PdfVariant(-ty)); |
1601 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&_ty)); | 1659 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&_ty)); |
1602 | 1660 |
1603 PdfOp_TL(pdfContext, canvas, looper); | 1661 PdfOp_TL(pdfContext, canvas, looper); |
1604 | 1662 |
1605 PdfObject vtx(PdfVariant(-(-tx))); // TODO(edisonn) Hmm, the compiler think
s I have here a function pointer if we use (tx), but not -(-tx) | 1663 PdfObject vtx(PdfVariant(-(-tx))); // TODO(edisonn): Hmm, the compiler thin
ks I have here a function pointer if we use (tx), but not -(-tx) |
1606 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&vtx)); | 1664 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&vtx)); |
1607 | 1665 |
1608 PdfObject vty(PdfVariant(-(-ty))); | 1666 PdfObject vty(PdfVariant(-(-ty))); |
1609 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&vty)); | 1667 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&vty)); |
1610 | 1668 |
1611 return PdfOp_Td(pdfContext, canvas, looper); | 1669 return PdfOp_Td(pdfContext, canvas, looper); |
1612 } | 1670 } |
1613 | 1671 |
1614 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1672 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1615 double f = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 1673 double f = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1778 SkPath path = pdfContext->fGraphicsState.fPath; | 1836 SkPath path = pdfContext->fGraphicsState.fPath; |
1779 | 1837 |
1780 if (close) { | 1838 if (close) { |
1781 path.close(); | 1839 path.close(); |
1782 } | 1840 } |
1783 | 1841 |
1784 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 1842 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
1785 | 1843 |
1786 SkPaint paint; | 1844 SkPaint paint; |
1787 | 1845 |
1788 // TODO(edisonn): get this from pdfContext->options, | |
1789 // or pdfContext->addPaintOptions(&paint); | |
1790 paint.setAntiAlias(true); | |
1791 | |
1792 // TODO(edisonn): dashing, miter, ... | |
1793 | |
1794 // path.transform(pdfContext->fGraphicsState.fMatrix); | |
1795 // path.transform(pdfContext->fOriginalMatrix); | |
1796 | |
1797 SkPoint line[2]; | 1846 SkPoint line[2]; |
1798 if (fill && !stroke && path.isLine(line)) { | 1847 if (fill && !stroke && path.isLine(line)) { |
1799 paint.setStyle(SkPaint::kStroke_Style); | 1848 paint.setStyle(SkPaint::kStroke_Style); |
1800 paint.setColor(pdfContext->fGraphicsState.fNonStroking.fColor); | 1849 |
| 1850 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
1801 paint.setStrokeWidth(SkDoubleToScalar(0)); | 1851 paint.setStrokeWidth(SkDoubleToScalar(0)); |
| 1852 |
1802 canvas->drawPath(path, paint); | 1853 canvas->drawPath(path, paint); |
1803 } else { | 1854 } else { |
1804 if (fill) { | 1855 if (fill) { |
1805 paint.setStyle(SkPaint::kFill_Style); | 1856 paint.setStyle(SkPaint::kFill_Style); |
1806 if (evenOdd) { | 1857 if (evenOdd) { |
1807 path.setFillType(SkPath::kEvenOdd_FillType); | 1858 path.setFillType(SkPath::kEvenOdd_FillType); |
1808 } | 1859 } |
1809 paint.setColor(pdfContext->fGraphicsState.fNonStroking.fColor); | 1860 |
| 1861 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
| 1862 |
1810 canvas->drawPath(path, paint); | 1863 canvas->drawPath(path, paint); |
1811 } | 1864 } |
1812 | 1865 |
1813 if (stroke) { | 1866 if (stroke) { |
1814 paint.setStyle(SkPaint::kStroke_Style); | 1867 paint.setStyle(SkPaint::kStroke_Style); |
1815 paint.setColor(pdfContext->fGraphicsState.fStroking.fColor); | 1868 |
1816 paint.setStrokeWidth(SkDoubleToScalar(pdfContext->fGraphicsState.fLi
neWidth)); | 1869 pdfContext->fGraphicsState.applyGraphicsState(&paint, true); |
| 1870 |
1817 path.setFillType(SkPath::kWinding_FillType); // reset it, just in c
ase it messes up the stroke | 1871 path.setFillType(SkPath::kWinding_FillType); // reset it, just in c
ase it messes up the stroke |
1818 canvas->drawPath(path, paint); | 1872 canvas->drawPath(path, paint); |
1819 } | 1873 } |
1820 } | 1874 } |
1821 | 1875 |
1822 pdfContext->fGraphicsState.fPath.reset(); | 1876 pdfContext->fGraphicsState.fPath.reset(); |
1823 // todo zoom ... other stuff ? | 1877 // todo zoom ... other stuff ? |
1824 | 1878 |
1825 if (pdfContext->fGraphicsState.fHasClipPathToApply) { | 1879 if (pdfContext->fGraphicsState.fHasClipPathToApply) { |
1826 #ifndef PDF_DEBUG_NO_CLIPING | 1880 #ifndef PDF_DEBUG_NO_CLIPING |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2283 | 2337 |
2284 #ifdef PDF_TRACE | 2338 #ifdef PDF_TRACE |
2285 // value->ToString(str); | 2339 // value->ToString(str); |
2286 // printf("gs object value: %s\n", str.c_str()); | 2340 // printf("gs object value: %s\n", str.c_str()); |
2287 #endif | 2341 #endif |
2288 | 2342 |
2289 SkPdfGraphicsStateDictionary* gs = NULL; | 2343 SkPdfGraphicsStateDictionary* gs = NULL; |
2290 PodofoMapper::map(value, &gs); | 2344 PodofoMapper::map(value, &gs); |
2291 | 2345 |
2292 // TODO(edisonn): now load all those properties in graphic state. | 2346 // TODO(edisonn): now load all those properties in graphic state. |
| 2347 if (gs == NULL) { |
| 2348 return kIgnoreError_PdfResult; |
| 2349 } |
| 2350 |
| 2351 if (gs->has_CA()) { |
| 2352 pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(); |
| 2353 } |
| 2354 |
| 2355 if (gs->has_ca()) { |
| 2356 pdfContext->fGraphicsState.fNonStroking.fOpacity = gs->ca(); |
| 2357 } |
| 2358 |
| 2359 if (gs->has_LW()) { |
| 2360 pdfContext->fGraphicsState.fLineWidth = gs->LW(); |
| 2361 } |
| 2362 |
| 2363 |
2293 | 2364 |
2294 return kNYI_PdfResult; | 2365 return kNYI_PdfResult; |
2295 } | 2366 } |
2296 | 2367 |
2297 //charSpace Tc Set the character spacing, Tc | 2368 //charSpace Tc Set the character spacing, Tc |
2298 //, to charSpace, which is a number expressed in unscaled text space units. Char
acter spacing is used by the Tj, TJ, and ' operators. | 2369 //, to charSpace, which is a number expressed in unscaled text space units. Char
acter spacing is used by the Tj, TJ, and ' operators. |
2299 //Initial value: 0. | 2370 //Initial value: 0. |
2300 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 2371 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
2301 double charSpace = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); | 2372 double charSpace = pdfContext->fObjectStack.top()->asNumber()->value();
pdfContext->fObjectStack.pop(); |
2302 pdfContext->fGraphicsState.fCharSpace = charSpace; | 2373 pdfContext->fGraphicsState.fCharSpace = charSpace; |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2989 } | 3060 } |
2990 | 3061 |
2991 return 0; | 3062 return 0; |
2992 } | 3063 } |
2993 | 3064 |
2994 #if !defined SK_BUILD_FOR_IOS | 3065 #if !defined SK_BUILD_FOR_IOS |
2995 int main(int argc, char * const argv[]) { | 3066 int main(int argc, char * const argv[]) { |
2996 return tool_main(argc, (char**) argv); | 3067 return tool_main(argc, (char**) argv); |
2997 } | 3068 } |
2998 #endif | 3069 #endif |
OLD | NEW |