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