| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkCanvas.h" | 8 #include "SkCanvas.h" |
| 9 #include "SkDevice.h" | 9 #include "SkDevice.h" |
| 10 #include "SkForceLinking.h" | 10 #include "SkForceLinking.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include <iostream> | 21 #include <iostream> |
| 22 #include <cstdio> | 22 #include <cstdio> |
| 23 #include <stack> | 23 #include <stack> |
| 24 | 24 |
| 25 #include "podofo.h" | 25 #include "podofo.h" |
| 26 using namespace PoDoFo; | 26 using namespace PoDoFo; |
| 27 | 27 |
| 28 | 28 |
| 29 __SK_FORCE_IMAGE_DECODER_LINKING; | 29 __SK_FORCE_IMAGE_DECODER_LINKING; |
| 30 | 30 |
| 31 // TODO(edisonn): tool, show what objects were read at least, show the ones not
even read |
| 32 // keep for each object pos in file |
| 33 // plug in for VS? syntax coloring, show selected object ... from the text, or f
rom rendered x,y |
| 31 | 34 |
| 32 //#define PDF_TRACE | 35 // TODO(edisonn): security - validate all the user input, all pdf! |
| 33 //#define PDF_TRACE_DIFF_IN_PNG | |
| 34 //#define PDF_DEBUG_NO_CLIPING | |
| 35 //#define PDF_DEBUG_NO_PAGE_CLIPING | |
| 36 //#define PDF_DEBUG_3X | |
| 37 | 36 |
| 38 | 37 |
| 39 const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, | |
| 40 const PdfObject* obj, | |
| 41 bool resolveOneElementArrays = false); | |
| 42 | |
| 43 bool LongFromDictionary(const PdfMemDocument* pdfDoc, | |
| 44 const PdfDictionary& dict, | |
| 45 const char* key, | |
| 46 const char* abr, | |
| 47 long* data); | |
| 48 | |
| 49 bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, | |
| 50 const PdfDictionary& dict, | |
| 51 const char* key, | |
| 52 const char* abr, | |
| 53 double* data); | |
| 54 | |
| 55 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, | |
| 56 const PdfDictionary& dict, | |
| 57 const char* key, | |
| 58 const char* abr, | |
| 59 bool* data); | |
| 60 | |
| 61 bool NameFromDictionary(const PdfMemDocument* pdfDoc, | |
| 62 const PdfDictionary& dict, | |
| 63 const char* key, | |
| 64 const char* abr, | |
| 65 std::string* data); | |
| 66 | |
| 67 bool StringFromDictionary(const PdfMemDocument* pdfDoc, | |
| 68 const PdfDictionary& dict, | |
| 69 const char* key, | |
| 70 const char* abr, | |
| 71 std::string* data); | |
| 72 | |
| 73 class SkPdfDictionary; | |
| 74 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, | |
| 75 const PdfDictionary& dict, | |
| 76 const char* key, | |
| 77 const char* abr, | |
| 78 SkPdfDictionary** data); | |
| 79 | |
| 80 template <typename T> | |
| 81 bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc, | |
| 82 const PdfDictionary& dict, | |
| 83 const char* key, | |
| 84 const char* abr, | |
| 85 T** data); | |
| 86 | |
| 87 class SkPdfObject; | |
| 88 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, | |
| 89 const PdfDictionary& dict, | |
| 90 const char* key, | |
| 91 const char* abr, | |
| 92 SkPdfObject** data); | |
| 93 | |
| 94 | |
| 95 struct SkPdfFileSpec {}; | |
| 96 class SkPdfArray; | |
| 97 class SkPdfStream; | |
| 98 struct SkPdfDate {}; | |
| 99 struct SkPdfTree {}; | |
| 100 struct SkPdfFunction {}; | |
| 101 | |
| 102 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, | |
| 103 const PdfDictionary& dict, | |
| 104 const char* key, | |
| 105 const char* abr, | |
| 106 SkPdfArray* data); | |
| 107 | |
| 108 | |
| 109 bool FileSpecFromDictionary(const PdfMemDocument* pdfDoc, | |
| 110 const PdfDictionary& dict, | |
| 111 const char* key, | |
| 112 const char* abr, | |
| 113 SkPdfFileSpec* data); | |
| 114 | |
| 115 | |
| 116 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, | |
| 117 const PdfDictionary& dict, | |
| 118 const char* key, | |
| 119 const char* abr, | |
| 120 SkPdfStream** data); | |
| 121 | |
| 122 bool TreeFromDictionary(const PdfMemDocument* pdfDoc, | |
| 123 const PdfDictionary& dict, | |
| 124 const char* key, | |
| 125 const char* abr, | |
| 126 SkPdfTree** data); | |
| 127 | |
| 128 bool DateFromDictionary(const PdfMemDocument* pdfDoc, | |
| 129 const PdfDictionary& dict, | |
| 130 const char* key, | |
| 131 const char* abr, | |
| 132 SkPdfDate* data); | |
| 133 | |
| 134 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, | |
| 135 const PdfDictionary& dict, | |
| 136 const char* key, | |
| 137 const char* abr, | |
| 138 SkRect* data); | |
| 139 | |
| 140 bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, | |
| 141 const PdfDictionary& dict, | |
| 142 const char* key, | |
| 143 const char* abr, | |
| 144 SkPdfFunction* data); | |
| 145 | |
| 146 bool skpdfmap(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdf
Object** out); | |
| 147 | |
| 148 #include "SkPdfHeaders_autogen.h" | 38 #include "SkPdfHeaders_autogen.h" |
| 149 #include "SkPdfPodofoMapper_autogen.h" | 39 #include "SkPdfPodofoMapper_autogen.h" |
| 150 #include "SkPdfParser.h" | 40 #include "SkPdfParser.h" |
| 41 |
| 42 #include "SkPdfBasics.h" |
| 43 #include "SkPdfUtils.h" |
| 44 |
| 151 #include "SkPdfFont.h" | 45 #include "SkPdfFont.h" |
| 152 | 46 |
| 153 // TODO(edisonn): fix the mess with the files. | 47 // TODO(edisonn): fix the mess with the files. |
| 154 #include "SkPdfFont.cpp" | 48 #include "SkPdfFont.cpp" |
| 49 #include "SkPdfBasics.cpp" |
| 50 #include "SkPdfUtils.cpp" |
| 155 | 51 |
| 156 bool skpdfmap(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdf
Object** out) { | 52 bool skpdfmap(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdf
Object** out) { |
| 157 return PodofoMapper::map(podofoDoc, podofoObj, out); | 53 return PodofoMapper::map(podofoDoc, podofoObj, out); |
| 158 } | 54 } |
| 159 | 55 |
| 160 | 56 |
| 161 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, | |
| 162 const PdfDictionary& dict, | |
| 163 const char* key, | |
| 164 const char* abr, | |
| 165 SkPdfArray* data) {return false;} | |
| 166 | |
| 167 bool FileSpecFromDictionary(const PdfMemDocument* pdfDoc, | |
| 168 const PdfDictionary& dict, | |
| 169 const char* key, | |
| 170 const char* abr, | |
| 171 SkPdfFileSpec* data) {return false;} | |
| 172 | |
| 173 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, | |
| 174 const PdfDictionary& dict, | |
| 175 const char* key, | |
| 176 const char* abr, | |
| 177 SkPdfStream** data); | |
| 178 | |
| 179 bool TreeFromDictionary(const PdfMemDocument* pdfDoc, | |
| 180 const PdfDictionary& dict, | |
| 181 const char* key, | |
| 182 const char* abr, | |
| 183 SkPdfTree** data) {return false;} | |
| 184 | |
| 185 bool DateFromDictionary(const PdfMemDocument* pdfDoc, | |
| 186 const PdfDictionary& dict, | |
| 187 const char* key, | |
| 188 const char* abr, | |
| 189 SkPdfDate* data) {return false;} | |
| 190 | |
| 191 bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, | |
| 192 const PdfDictionary& dict, | |
| 193 const char* key, | |
| 194 const char* abr, | |
| 195 SkPdfFunction* data) {return false;} | |
| 196 | |
| 197 | |
| 198 | |
| 199 /* | 57 /* |
| 200 * TODO(edisonn): | 58 * TODO(edisonn): |
| 201 * - all font types and all ppdf font features | 59 * - all font types and all ppdf font features |
| 202 * - word spacing | 60 * - word spacing |
| 203 * - load font for baidu.pdf | 61 * - load font for baidu.pdf |
| 204 * - load font for youtube.pdf | 62 * - load font for youtube.pdf |
| 205 * - parser for pdf from the definition already available in pdfspec_autoge
n.py | 63 * - parser for pdf from the definition already available in pdfspec_autoge
n.py |
| 206 * - all docs from ~/work | 64 * - all docs from ~/work |
| 207 * - encapsulate podofo in the pdf api so the skpdf does not know anything about
podofo ... in progress | 65 * - encapsulate podofo in the pdf api so the skpdf does not know anything about
podofo ... in progress |
| 208 * - load gs/ especially smask and already known prop (skp) ... in progress | 66 * - load gs/ especially smask and already known prop (skp) ... in progress |
| 209 * - wrapper on classes for customizations? e.g. | 67 * - wrapper on classes for customizations? e.g. |
| 210 * SkPdfPageObjectVanila - has only the basic loaders/getters | 68 * SkPdfPageObjectVanila - has only the basic loaders/getters |
| 211 * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add custom
izations here | 69 * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add custom
izations here |
| 212 * need to find a nice object model for all this with constructors and factories | 70 * need to find a nice object model for all this with constructors and factories |
| 213 * - deal with inheritable automatically ? | 71 * - deal with inheritable automatically ? |
| 214 * - deal with specific type in spec directly, add all dictionary types to known
types | 72 * - deal with specific type in spec directly, add all dictionary types to known
types |
| 215 */ | 73 */ |
| 216 | 74 |
| 217 | 75 |
| 218 // TODO(edisonn): move in trace util. | 76 // TODO(edisonn): move in trace util. |
| 219 #ifdef PDF_TRACE | 77 #ifdef PDF_TRACE |
| 220 static void SkTraceMatrix(const SkMatrix& matrix, const char* sz = "") { | 78 static void SkTraceMatrix(const SkMatrix& matrix, const char* sz = "") { |
| 221 printf("SkMatrix %s ", sz); | 79 printf("SkMatrix %s ", sz); |
| 222 for (int i = 0 ; i < 9 ; i++) { | 80 for (int i = 0 ; i < 9 ; i++) { |
| 223 printf("%f ", SkScalarToDouble(matrix.get(i))); | 81 printf("%f ", SkScalarToDouble(matrix.get(i))); |
| 224 } | 82 } |
| 225 printf("\n"); | 83 printf("\n"); |
| 226 } | 84 } |
| 85 |
| 86 static void SkTraceRect(const SkRect& rect, const char* sz = "") { |
| 87 printf("SkRect %s ", sz); |
| 88 printf("x = %f ", SkScalarToDouble(rect.x())); |
| 89 printf("y = %f ", SkScalarToDouble(rect.y())); |
| 90 printf("w = %f ", SkScalarToDouble(rect.width())); |
| 91 printf("h = %f ", SkScalarToDouble(rect.height())); |
| 92 printf("\n"); |
| 93 } |
| 94 |
| 227 #else | 95 #else |
| 228 #define SkTraceMatrix(a,b) | 96 #define SkTraceMatrix(a,b) |
| 97 #define SkTraceRect(a,b) |
| 229 #endif | 98 #endif |
| 230 | 99 |
| 231 using namespace std; | 100 using namespace std; |
| 232 using namespace PoDoFo; | 101 using namespace PoDoFo; |
| 233 | 102 |
| 234 // Utilities | 103 // Utilities |
| 235 static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color
= SK_ColorWHITE) { | 104 static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color
= SK_ColorWHITE) { |
| 236 bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); | 105 bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); |
| 237 | 106 |
| 238 bitmap->allocPixels(); | 107 bitmap->allocPixels(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 SkDoubleToScalar(array[1]), | 151 SkDoubleToScalar(array[1]), |
| 283 SkDoubleToScalar(array[3]), | 152 SkDoubleToScalar(array[3]), |
| 284 SkDoubleToScalar(array[5]), | 153 SkDoubleToScalar(array[5]), |
| 285 SkDoubleToScalar(0), | 154 SkDoubleToScalar(0), |
| 286 SkDoubleToScalar(0), | 155 SkDoubleToScalar(0), |
| 287 SkDoubleToScalar(1)); | 156 SkDoubleToScalar(1)); |
| 288 | 157 |
| 289 return matrix; | 158 return matrix; |
| 290 } | 159 } |
| 291 | 160 |
| 292 // TODO(edisonn): better class design. | 161 SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { |
| 293 struct PdfColorOperator { | 162 double array[6]; |
| 294 std::string fColorSpace; // TODO(edisonn): use SkString | |
| 295 SkColor fColor; | |
| 296 double fOpacity; // ca or CA | |
| 297 // TODO(edisonn): add here other color space options. | |
| 298 | 163 |
| 299 void setRGBColor(SkColor color) { | 164 // TODO(edisonn): security issue, ret if size() != 6 |
| 300 // TODO(edisonn): ASSERT DeviceRGB is the color space. | 165 for (int i = 0; i < 6; i++) { |
| 301 fColor = color; | 166 const PdfObject* elem = resolveReferenceObject(pdfArray->doc(), (*pdfArr
ay)[i]->podofo()); |
| 302 } | 167 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { |
| 303 // TODO(edisonn): double check the default values for all fields. | 168 return SkMatrix::I(); // TODO(edisonn): report issue |
| 304 PdfColorOperator() : fColor(SK_ColorBLACK), fOpacity(1) {} | 169 } |
| 305 | 170 array[i] = elem->GetReal(); |
| 306 void applyGraphicsState(SkPaint* paint) { | |
| 307 paint->setColor(SkColorSetA(fColor, fOpacity * 255)); | |
| 308 } | 171 } |
| 309 | 172 |
| 310 }; | 173 return SkMatrixFromPdfMatrix(array); |
| 311 | 174 } |
| 312 // TODO(edisonn): better class design. | |
| 313 struct PdfGraphicsState { | |
| 314 SkMatrix fMatrix; | |
| 315 SkMatrix fMatrixTm; | |
| 316 SkMatrix fMatrixTlm; | |
| 317 | |
| 318 double fCurPosX; | |
| 319 double fCurPosY; | |
| 320 | |
| 321 double fCurFontSize; | |
| 322 bool fTextBlock; | |
| 323 PdfFont* fCurFont; | |
| 324 SkPdfFont* fSkFont; | |
| 325 SkPath fPath; | |
| 326 bool fPathClosed; | |
| 327 | |
| 328 // Clip that is applied after the drawing is done!!! | |
| 329 bool fHasClipPathToApply; | |
| 330 SkPath fClipPath; | |
| 331 | |
| 332 PdfColorOperator fStroking; | |
| 333 PdfColorOperator fNonStroking; | |
| 334 | |
| 335 double fLineWidth; | |
| 336 double fTextLeading; | |
| 337 double fWordSpace; | |
| 338 double fCharSpace; | |
| 339 | |
| 340 SkPdfResourceDictionary* fResources; | |
| 341 | |
| 342 SkBitmap fSMask; | |
| 343 | |
| 344 PdfGraphicsState() { | |
| 345 fCurPosX = 0.0; | |
| 346 fCurPosY = 0.0; | |
| 347 fCurFontSize = 0.0; | |
| 348 fTextBlock = false; | |
| 349 fCurFont = NULL; | |
| 350 fMatrix = SkMatrix::I(); | |
| 351 fMatrixTm = SkMatrix::I(); | |
| 352 fMatrixTlm = SkMatrix::I(); | |
| 353 fPathClosed = true; | |
| 354 fLineWidth = 0; | |
| 355 fTextLeading = 0; | |
| 356 fWordSpace = 0; | |
| 357 fCharSpace = 0; | |
| 358 fHasClipPathToApply = false; | |
| 359 fResources = NULL; | |
| 360 fSkFont = NULL; | |
| 361 } | |
| 362 | |
| 363 void applyGraphicsState(SkPaint* paint, bool stroking) { | |
| 364 if (stroking) { | |
| 365 fStroking.applyGraphicsState(paint); | |
| 366 } else { | |
| 367 fNonStroking.applyGraphicsState(paint); | |
| 368 } | |
| 369 | |
| 370 // TODO(edisonn): get this from pdfContext->options, | |
| 371 // or pdfContext->addPaintOptions(&paint); | |
| 372 paint->setAntiAlias(true); | |
| 373 | |
| 374 // TODO(edisonn): dashing, miter, ... | |
| 375 paint->setStrokeWidth(SkDoubleToScalar(fLineWidth)); | |
| 376 } | |
| 377 }; | |
| 378 | |
| 379 // TODO(edisonn): better class design. | |
| 380 struct PdfInlineImage { | |
| 381 std::map<std::string, std::string> fKeyValuePairs; | |
| 382 std::string fImageData; | |
| 383 | |
| 384 }; | |
| 385 | |
| 386 // TODO(edisonn): better class design. | |
| 387 struct PdfContext { | |
| 388 std::stack<SkPdfObject*> fObjectStack; | |
| 389 std::stack<PdfGraphicsState> fStateStack; | |
| 390 PdfGraphicsState fGraphicsState; | |
| 391 SkPdfDoc& fPdfDoc; | |
| 392 SkMatrix fOriginalMatrix; | |
| 393 | |
| 394 PdfInlineImage fInlineImage; | |
| 395 | |
| 396 PdfContext(SkPdfDoc& doc) : fPdfDoc(doc) {} | |
| 397 | |
| 398 }; | |
| 399 | |
| 400 // TODO(edisonn): temporary code, to report how much of the PDF we actually thi
nk we rendered. | |
| 401 enum PdfResult { | |
| 402 kOK_PdfResult, | |
| 403 kPartial_PdfResult, | |
| 404 kNYI_PdfResult, | |
| 405 kIgnoreError_PdfResult, | |
| 406 kError_PdfResult, | |
| 407 kUnsupported_PdfResult, | |
| 408 | |
| 409 kCount_PdfResult | |
| 410 }; | |
| 411 | 175 |
| 412 PdfContext* gPdfContext = NULL; | 176 PdfContext* gPdfContext = NULL; |
| 413 SkBitmap* gDumpBitmap = NULL; | 177 SkBitmap* gDumpBitmap = NULL; |
| 414 SkCanvas* gDumpCanvas = NULL; | 178 SkCanvas* gDumpCanvas = NULL; |
| 415 char gLastKeyword[100] = ""; | 179 char gLastKeyword[100] = ""; |
| 416 int gLastOpKeyword = -1; | 180 int gLastOpKeyword = -1; |
| 417 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
,EI,Do,EX,"; | 181 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
,EI,Do,EX,"; |
| 418 int gReadOp = 0; | 182 int gReadOp = 0; |
| 419 | 183 |
| 420 | 184 |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 printf("FONT_NOT_FOUND %s\n", pszBaseFontName); | 408 printf("FONT_NOT_FOUND %s\n", pszBaseFontName); |
| 645 #endif | 409 #endif |
| 646 | 410 |
| 647 // TODO(edisonn): Report Warning, NYI | 411 // TODO(edisonn): Report Warning, NYI |
| 648 return SkTypeface::CreateFromName( | 412 return SkTypeface::CreateFromName( |
| 649 "Times New Roman", | 413 "Times New Roman", |
| 650 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | | 414 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | |
| 651 (font->IsItalic() ? SkTypeface::kItalic : 0)))
; | 415 (font->IsItalic() ? SkTypeface::kItalic : 0)))
; |
| 652 } | 416 } |
| 653 | 417 |
| 654 | |
| 655 // TODO(edisonn): move this code in podofo, so we don't have to fix the font. | |
| 656 // This logic needs to be moved in PdfEncodingObjectFactory::CreateEncoding | |
| 657 std::map<PdfFont*, PdfCMapEncoding*> gFontsFixed; | |
| 658 PdfEncoding* FixPdfFont(PdfContext* pdfContext, PdfFont* fCurFont) { | |
| 659 // TODO(edisonn): and is Identity-H | |
| 660 if (gFontsFixed.find(fCurFont) == gFontsFixed.end()) { | |
| 661 if (fCurFont->GetObject()->IsDictionary() && fCurFont->GetObject()->GetD
ictionary().HasKey(PdfName("ToUnicode"))) { | |
| 662 PdfCMapEncoding* enc = new PdfCMapEncoding( | |
| 663 fCurFont->GetObject(), | |
| 664 (PdfObject*)resolveReferenceObject(&pdfContext->fPdfDoc.podo
fo(), | |
| 665 fCurFont->GetObject()->GetDictionary(
).GetKey(PdfName("ToUnicode"))), | |
| 666 PdfCMapEncoding::eBaseEncoding_Identity); // todo, read the
base encoding | |
| 667 gFontsFixed[fCurFont] = enc; | |
| 668 return enc; | |
| 669 } | |
| 670 | |
| 671 return NULL; | |
| 672 } | |
| 673 | |
| 674 return gFontsFixed[fCurFont]; | |
| 675 } | |
| 676 | |
| 677 PdfResult DrawText(PdfContext* pdfContext, | 418 PdfResult DrawText(PdfContext* pdfContext, |
| 678 const SkPdfObject* str, | 419 const SkPdfObject* str, |
| 679 SkCanvas* canvas) | 420 SkCanvas* canvas) |
| 680 { | 421 { |
| 681 | 422 |
| 682 SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; | 423 SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; |
| 683 if (skfont == NULL) { | 424 if (skfont == NULL) { |
| 684 skfont = SkPdfFont::Default(); | 425 skfont = SkPdfFont::Default(); |
| 685 } | 426 } |
| 686 | 427 |
| 687 SkUnencodedText binary(str); | 428 SkUnencodedText binary(str); |
| 688 | 429 |
| 689 SkDecodedText decoded; | 430 SkDecodedText decoded; |
| 431 |
| 432 if (skfont->encoding() == NULL) { |
| 433 // TODO(edisonn): report warning |
| 434 return kNYI_PdfResult; |
| 435 } |
| 436 |
| 690 skfont->encoding()->decodeText(binary, &decoded); | 437 skfont->encoding()->decodeText(binary, &decoded); |
| 691 | 438 |
| 692 SkUnicodeText unicode; | |
| 693 skfont->ToUnicode(decoded, &unicode); | |
| 694 | |
| 695 SkPaint paint; | 439 SkPaint paint; |
| 696 // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCur
FontSize == 0? | 440 // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCur
FontSize == 0? |
| 697 // Or maybe just not call setTextSize at all? | 441 // Or maybe just not call setTextSize at all? |
| 698 if (pdfContext->fGraphicsState.fCurFontSize != 0) { | 442 if (pdfContext->fGraphicsState.fCurFontSize != 0) { |
| 699 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); | 443 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); |
| 700 } | 444 } |
| 701 | 445 |
| 702 // if (fCurFont && fCurFont->GetFontScale() != 0) { | 446 // if (fCurFont && fCurFont->GetFontScale() != 0) { |
| 703 // paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0))
; | 447 // paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0))
; |
| 704 // } | 448 // } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 720 // TODO(edisonn): post rotate, skew | 464 // TODO(edisonn): post rotate, skew |
| 721 mirror.postTranslate(0, point1.y()); | 465 mirror.postTranslate(0, point1.y()); |
| 722 | 466 |
| 723 matrix.postConcat(mirror); | 467 matrix.postConcat(mirror); |
| 724 | 468 |
| 725 canvas->setMatrix(matrix); | 469 canvas->setMatrix(matrix); |
| 726 | 470 |
| 727 SkTraceMatrix(matrix, "mirrored"); | 471 SkTraceMatrix(matrix, "mirrored"); |
| 728 #endif | 472 #endif |
| 729 | 473 |
| 730 skfont->drawText(unicode, &paint, canvas, &pdfContext->fGraphicsState.fMatri
xTm); | 474 skfont->drawText(decoded, &paint, pdfContext, canvas, &pdfContext->fGraphics
State.fMatrixTm); |
| 731 canvas->restore(); | 475 canvas->restore(); |
| 732 | 476 |
| 733 /* | |
| 734 PdfString& rString = str->podofo()->GetString(); | |
| 735 | |
| 736 //pdfContext->fGraphicsState.fSkFont->GetDecoding()->ToUnicode(rString); | |
| 737 //void* text; | |
| 738 //int len; | |
| 739 //SkPaint paint; | |
| 740 //pdfContext->fGraphicsState.fSkFont->drawText(text, len, paint, canvas, &pd
fContext->fGraphicsState.fMatrixTm); | |
| 741 | |
| 742 PdfFont* fCurFont = pdfContext->fGraphicsState.fCurFont; | |
| 743 | |
| 744 if (!fCurFont) | |
| 745 { | |
| 746 // TODO(edisonn): ignore the error, use the default font? | |
| 747 // return kError_PdfResult; | |
| 748 } | |
| 749 | |
| 750 const PdfEncoding* enc = fCurFont ? FixPdfFont(pdfContext, fCurFont) : NULL; | |
| 751 bool cMapUnicodeFont = enc != NULL; | |
| 752 if (!enc) enc = fCurFont ? fCurFont->GetEncoding() : NULL; | |
| 753 if (!enc) | |
| 754 { | |
| 755 // TODO(edisonn): Can we recover from this error? | |
| 756 //return kError_PdfResult; | |
| 757 } | |
| 758 | |
| 759 PdfString r2 = rString; | |
| 760 PdfString unicode; | |
| 761 | |
| 762 if (cMapUnicodeFont) { | |
| 763 r2 = PdfString((pdf_utf16be*)rString.GetString(), rString.GetLength() /
2); | |
| 764 } | |
| 765 | |
| 766 unicode = enc ? enc->ConvertToUnicode( r2, fCurFont ) : r2.ToUnicode(); | |
| 767 | |
| 768 #ifdef PDF_TRACE | |
| 769 printf("%i %i ? %c rString.len = %i\n", (int)rString.GetString()[0], (int)rS
tring.GetString()[1], (int)rString.GetString()[1], rString.GetLength()); | |
| 770 printf("%i %i %i %i %c unicode.len = %i\n", (int)unicode.GetString()[0], (in
t)unicode.GetString()[1], (int)unicode.GetString()[2], (int)unicode.GetString()[
3], (int)unicode.GetString()[0], unicode.GetLength()); | |
| 771 #endif | |
| 772 | |
| 773 SkPaint paint; | |
| 774 // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCur
FontSize == 0? | |
| 775 // Or maybe just not call setTextSize at all? | |
| 776 if (pdfContext->fGraphicsState.fCurFontSize != 0) { | |
| 777 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); | |
| 778 } | |
| 779 if (fCurFont && fCurFont->GetFontScale() != 0) { | |
| 780 paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0)); | |
| 781 } | |
| 782 | |
| 783 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); | |
| 784 | |
| 785 paint.setTypeface(SkTypefaceFromPdfFont(fCurFont)); | |
| 786 | |
| 787 canvas->save(); | |
| 788 SkMatrix matrix = pdfContext->fGraphicsState.fMatrixTm; | |
| 789 | |
| 790 #if 0 | |
| 791 // Reverse now the space, otherwise the text is upside down. | |
| 792 SkScalar z = SkIntToScalar(0); | |
| 793 SkScalar one = SkIntToScalar(1); | |
| 794 | |
| 795 SkPoint normalSpace1[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), SkPoi
nt::Make(one, one), SkPoint::Make(z, one)}; | |
| 796 SkPoint mirrorSpace1[4]; | |
| 797 pdfContext->fGraphicsState.fMatrixTm.mapPoints(mirrorSpace1, normalSpace1, 4
); | |
| 798 | |
| 799 SkPoint normalSpace2[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), SkPoi
nt::Make(one, -one), SkPoint::Make(z, -one)}; | |
| 800 SkPoint mirrorSpace2[4]; | |
| 801 pdfContext->fGraphicsState.fMatrixTm.mapPoints(mirrorSpace2, normalSpace2, 4
); | |
| 802 | |
| 803 #ifdef PDF_TRACE | |
| 804 printf("mirror1[0], x = %f y = %f\n", SkScalarToDouble(mirrorSpace1[0].x()),
SkScalarToDouble(mirrorSpace1[0].y())); | |
| 805 printf("mirror1[1], x = %f y = %f\n", SkScalarToDouble(mirrorSpace1[1].x()),
SkScalarToDouble(mirrorSpace1[1].y())); | |
| 806 printf("mirror1[2], x = %f y = %f\n", SkScalarToDouble(mirrorSpace1[2].x()),
SkScalarToDouble(mirrorSpace1[2].y())); | |
| 807 printf("mirror1[3], x = %f y = %f\n", SkScalarToDouble(mirrorSpace1[3].x()),
SkScalarToDouble(mirrorSpace1[3].y())); | |
| 808 printf("mirror2[0], x = %f y = %f\n", SkScalarToDouble(mirrorSpace2[0].x()),
SkScalarToDouble(mirrorSpace2[0].y())); | |
| 809 printf("mirror2[1], x = %f y = %f\n", SkScalarToDouble(mirrorSpace2[1].x()),
SkScalarToDouble(mirrorSpace2[1].y())); | |
| 810 printf("mirror2[2], x = %f y = %f\n", SkScalarToDouble(mirrorSpace2[2].x()),
SkScalarToDouble(mirrorSpace2[2].y())); | |
| 811 printf("mirror2[3], x = %f y = %f\n", SkScalarToDouble(mirrorSpace2[3].x()),
SkScalarToDouble(mirrorSpace2[3].y())); | |
| 812 #endif | |
| 813 | |
| 814 SkMatrix mirror; | |
| 815 SkASSERT(mirror.setPolyToPoly(mirrorSpace1, mirrorSpace2, 4)); | |
| 816 | |
| 817 // TODO(edisonn): text positioning wrong right now. Need to get matrix opera
tions right. | |
| 818 matrix.preConcat(mirror); | |
| 819 canvas->setMatrix(matrix); | |
| 820 #endif | |
| 821 | |
| 822 SkPoint point1; | |
| 823 pdfContext->fGraphicsState.fMatrixTm.mapXY(SkIntToScalar(0), SkIntToScalar(0
), &point1); | |
| 824 | |
| 825 SkMatrix mirror; | |
| 826 mirror.setTranslate(0, -point1.y()); | |
| 827 // TODO(edisonn): fix rotated text, and skewed too | |
| 828 mirror.postScale(SK_Scalar1, -SK_Scalar1); | |
| 829 // TODO(edisonn): post rotate, skew | |
| 830 mirror.postTranslate(0, point1.y()); | |
| 831 | |
| 832 matrix.postConcat(mirror); | |
| 833 | |
| 834 canvas->setMatrix(matrix); | |
| 835 | |
| 836 SkTraceMatrix(matrix, "mirrored"); | |
| 837 | |
| 838 #ifdef PDF_TRACE | |
| 839 SkPoint point; | |
| 840 pdfContext->fGraphicsState.fMatrixTm.mapXY(SkDoubleToScalar(0), SkDoubleToSc
alar(0), &point); | |
| 841 printf("Original SkCanvas resolved coordinates, x = %f y = %f\n", SkScalarTo
Double(point.x()), SkScalarToDouble(point.y())); | |
| 842 matrix.mapXY(SkDoubleToScalar(0), SkDoubleToScalar(0), &point); | |
| 843 printf("Mirored SkCanvas resolved coordinates, x = %f y = %f\n", SkScalarToD
ouble(point.x()), SkScalarToDouble(point.y())); | |
| 844 #endif | |
| 845 | |
| 846 // TODO(edisonn): remove this call once we load the font properly | |
| 847 // The extra * will show that we got at least the text positioning right | |
| 848 // even if font failed to be loaded | |
| 849 // canvas->drawText(".", 1, SkDoubleToScalar(-5.0), SkDoubleToScalar(0.0), pa
int); | |
| 850 | |
| 851 | |
| 852 | |
| 853 // TODO(edisonn): use character and word spacing .. add utility function | |
| 854 if (cMapUnicodeFont) { | |
| 855 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); | |
| 856 SkScalar textWidth = paint.measureText(unicode.GetString(), unicode.GetL
ength()); | |
| 857 pdfContext->fGraphicsState.fMatrixTm.preTranslate(textWidth, SkDoubleToS
calar(0.0)); | |
| 858 canvas->drawText(unicode.GetString(), unicode.GetLength(), SkDoubleToSca
lar(0.0), SkDoubleToScalar(0.0), paint); | |
| 859 } | |
| 860 else { | |
| 861 paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); | |
| 862 SkScalar textWidth = paint.measureText(unicode.GetStringUtf8().c_str(),
strlen(unicode.GetStringUtf8().c_str())); | |
| 863 pdfContext->fGraphicsState.fMatrixTm.preTranslate(textWidth, SkDoubleToS
calar(0.0)); | |
| 864 canvas->drawText(unicode.GetStringUtf8().c_str(), strlen(unicode.GetStri
ngUtf8().c_str()), SkDoubleToScalar(0.0), SkDoubleToScalar(0.0), paint); | |
| 865 } | |
| 866 | |
| 867 // paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); | |
| 868 // unsigned char ch = *(unicode.GetString() + 3); | |
| 869 // if ((ch & 0xC0) != 0x80 && ch < 0x80) { | |
| 870 // printf("x%i", ch); | |
| 871 // SkScalar textWidth = paint.measureText(&ch, 1); | |
| 872 // pdfContext->fGraphicsState.fMatrixTm.preTranslate(textWidth, SkDoubleT
oScalar(0.0)); | |
| 873 // canvas->drawText(&ch, 1, SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
paint); | |
| 874 // } | |
| 875 | |
| 876 canvas->restore(); | |
| 877 | |
| 878 */ | |
| 879 return kPartial_PdfResult; | 477 return kPartial_PdfResult; |
| 880 } | 478 } |
| 881 | 479 |
| 882 // TODO(edisonn): create header files with declarations! | 480 // TODO(edisonn): create header files with declarations! |
| 883 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); | 481 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); |
| 884 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); | 482 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); |
| 885 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); | 483 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); |
| 886 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); | 484 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); |
| 887 | 485 |
| 888 // TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in Get
Key? | 486 // TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in Get
Key? |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 bool StringFromDictionary(const PdfMemDocument* pdfDoc, | 619 bool StringFromDictionary(const PdfMemDocument* pdfDoc, |
| 1022 const PdfDictionary& dict, | 620 const PdfDictionary& dict, |
| 1023 const char* key, | 621 const char* key, |
| 1024 const char* abr, | 622 const char* abr, |
| 1025 std::string* data) { | 623 std::string* data) { |
| 1026 if (StringFromDictionary(pdfDoc, dict, key, data)) return true; | 624 if (StringFromDictionary(pdfDoc, dict, key, data)) return true; |
| 1027 if (abr == NULL || *abr == '\0') return false; | 625 if (abr == NULL || *abr == '\0') return false; |
| 1028 return StringFromDictionary(pdfDoc, dict, abr, data); | 626 return StringFromDictionary(pdfDoc, dict, abr, data); |
| 1029 } | 627 } |
| 1030 | 628 |
| 629 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |
| 630 const PdfDictionary& dict, |
| 631 const char* key, |
| 632 SkPdfArray** data) { |
| 633 const PdfObject* value = resolveReferenceObject(pdfDoc, |
| 634 dict.GetKey(PdfName(key)), |
| 635 true); |
| 636 if (value == NULL || !value->IsArray()) { |
| 637 return false; |
| 638 } |
| 639 if (data == NULL) { |
| 640 return true; |
| 641 } |
| 642 |
| 643 return PodofoMapper::map(*pdfDoc, *value, (SkPdfObject**)data); |
| 644 } |
| 645 |
| 646 |
| 647 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |
| 648 const PdfDictionary& dict, |
| 649 const char* key, |
| 650 const char* abr, |
| 651 SkPdfArray** data) { |
| 652 if (ArrayFromDictionary(pdfDoc, dict, key, data)) return true; |
| 653 if (abr == NULL || *abr == '\0') return false; |
| 654 return ArrayFromDictionary(pdfDoc, dict, abr, data); |
| 655 } |
| 656 |
| 657 |
| 1031 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, | 658 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, |
| 1032 const PdfDictionary& dict, | 659 const PdfDictionary& dict, |
| 1033 const char* key, | 660 const char* key, |
| 1034 SkPdfDictionary** data) { | 661 SkPdfDictionary** data) { |
| 1035 const PdfObject* value = resolveReferenceObject(pdfDoc, | 662 const PdfObject* value = resolveReferenceObject(pdfDoc, |
| 1036 dict.GetKey(PdfName(key)), | 663 dict.GetKey(PdfName(key)), |
| 1037 true); | 664 true); |
| 1038 if (value == NULL || !value->IsDictionary()) { | 665 if (value == NULL || !value->IsDictionary()) { |
| 1039 return false; | 666 return false; |
| 1040 } | 667 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1052 SkPdfDictionary** data) { | 679 SkPdfDictionary** data) { |
| 1053 if (DictionaryFromDictionary(pdfDoc, dict, key, data)) return true; | 680 if (DictionaryFromDictionary(pdfDoc, dict, key, data)) return true; |
| 1054 if (abr == NULL || *abr == '\0') return false; | 681 if (abr == NULL || *abr == '\0') return false; |
| 1055 return DictionaryFromDictionary(pdfDoc, dict, abr, data); | 682 return DictionaryFromDictionary(pdfDoc, dict, abr, data); |
| 1056 } | 683 } |
| 1057 | 684 |
| 1058 template <typename T> | 685 template <typename T> |
| 1059 bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc, | 686 bool DictionaryFromDictionary2(const PdfMemDocument* pdfDoc, |
| 1060 const PdfDictionary& dict, | 687 const PdfDictionary& dict, |
| 1061 const char* key, | 688 const char* key, |
| 1062 SkPdfDictionary** data) { | 689 T** data) { |
| 1063 const PdfObject* value = resolveReferenceObject(pdfDoc, | 690 const PdfObject* value = resolveReferenceObject(pdfDoc, |
| 1064 dict.GetKey(PdfName(key)), | 691 dict.GetKey(PdfName(key)), |
| 1065 true); | 692 true); |
| 1066 if (value == NULL || !value->IsDictionary()) { | 693 if (value == NULL || !value->IsDictionary()) { |
| 1067 return false; | 694 return false; |
| 1068 } | 695 } |
| 1069 | 696 |
| 1070 if (data == NULL) { | 697 if (data == NULL) { |
| 1071 return true; | 698 return true; |
| 1072 } | 699 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1330 width, height, bytesPerLine, | 957 width, height, bytesPerLine, |
| 1331 bpc, colorSpace, | 958 bpc, colorSpace, |
| 1332 transparencyMask); | 959 transparencyMask); |
| 1333 | 960 |
| 1334 free(uncompressedStream); | 961 free(uncompressedStream); |
| 1335 | 962 |
| 1336 return bitmap; | 963 return bitmap; |
| 1337 } | 964 } |
| 1338 | 965 |
| 1339 SkBitmap getSmaskFromObject(PdfContext* pdfContext, const SkPdfImageDictionary*
obj) { | 966 SkBitmap getSmaskFromObject(PdfContext* pdfContext, const SkPdfImageDictionary*
obj) { |
| 1340 const PdfObject* sMask = resolveReferenceObject(&pdfContext->fPdfDoc.podofo(
), | 967 const PdfObject* sMask = resolveReferenceObject(&pdfContext->fPdfDoc->podofo
(), |
| 1341 obj->podofo()->GetDictionary().Get
Key(PdfName("SMask"))); | 968 obj->podofo()->GetDictionary().Get
Key(PdfName("SMask"))); |
| 1342 | 969 |
| 1343 #ifdef PDF_TRACE | 970 #ifdef PDF_TRACE |
| 1344 std::string str; | 971 std::string str; |
| 1345 if (sMask) { | 972 if (sMask) { |
| 1346 sMask->ToString(str); | 973 sMask->ToString(str); |
| 1347 printf("/SMask of /Subtype /Image: %s\n", str.c_str()); | 974 printf("/SMask of /Subtype /Image: %s\n", str.c_str()); |
| 1348 } | 975 } |
| 1349 #endif | 976 #endif |
| 1350 | 977 |
| 1351 if (sMask) { | 978 if (sMask) { |
| 1352 SkPdfImageDictionary skxobjmask(&pdfContext->fPdfDoc.podofo(), sMask); | 979 SkPdfImageDictionary skxobjmask(&pdfContext->fPdfDoc->podofo(), sMask); |
| 1353 return getImageFromObject(pdfContext, &skxobjmask, true); | 980 return getImageFromObject(pdfContext, &skxobjmask, true); |
| 1354 } | 981 } |
| 1355 | 982 |
| 1356 // TODO(edisonn): implement GS SMask. Default to empty right now. | 983 // TODO(edisonn): implement GS SMask. Default to empty right now. |
| 1357 return pdfContext->fGraphicsState.fSMask; | 984 return pdfContext->fGraphicsState.fSMask; |
| 1358 } | 985 } |
| 1359 | 986 |
| 1360 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfI
mageDictionary* skpdfimage) { | 987 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfI
mageDictionary* skpdfimage) { |
| 1361 if (skpdfimage == NULL || !skpdfimage->valid()) { | 988 if (skpdfimage == NULL || !skpdfimage->valid()) { |
| 1362 return kIgnoreError_PdfResult; | 989 return kIgnoreError_PdfResult; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1379 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode | 1006 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode |
| 1380 canvas->drawBitmapRect(sMask, dst, &xfer); | 1007 canvas->drawBitmapRect(sMask, dst, &xfer); |
| 1381 canvas->restore(); | 1008 canvas->restore(); |
| 1382 } | 1009 } |
| 1383 | 1010 |
| 1384 canvas->restore(); | 1011 canvas->restore(); |
| 1385 | 1012 |
| 1386 return kPartial_PdfResult; | 1013 return kPartial_PdfResult; |
| 1387 } | 1014 } |
| 1388 | 1015 |
| 1389 bool SkMatrixFromDictionary(PdfContext* pdfContext, | 1016 bool SkMatrixFromDictionary(const PdfMemDocument* pdfDoc, |
| 1390 const PdfDictionary& dict, | 1017 const PdfDictionary& dict, |
| 1391 const char* key, | 1018 const char* key, |
| 1392 SkMatrix* matrix) { | 1019 SkMatrix** matrix) { |
| 1393 const PdfObject* value = resolveReferenceObject(&pdfContext->fPdfDoc.podofo(
), | 1020 const PdfObject* value = resolveReferenceObject(pdfDoc, |
| 1394 dict.GetKey(PdfName(key))); | 1021 dict.GetKey(PdfName(key))); |
| 1395 | 1022 |
| 1396 if (value == NULL || !value->IsArray()) { | 1023 if (value == NULL || !value->IsArray()) { |
| 1397 return false; | 1024 return false; |
| 1398 } | 1025 } |
| 1399 | 1026 |
| 1400 if (value->GetArray().GetSize() != 6) { | 1027 if (value->GetArray().GetSize() != 6) { |
| 1401 return false; | 1028 return false; |
| 1402 } | 1029 } |
| 1403 | 1030 |
| 1404 double array[6]; | 1031 double array[6]; |
| 1405 for (int i = 0; i < 6; i++) { | 1032 for (int i = 0; i < 6; i++) { |
| 1406 const PdfObject* elem = resolveReferenceObject(&pdfContext->fPdfDoc.podo
fo(), &value->GetArray()[i]); | 1033 const PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray(
)[i]); |
| 1407 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { | 1034 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { |
| 1408 return false; | 1035 return false; |
| 1409 } | 1036 } |
| 1410 array[i] = elem->GetReal(); | 1037 array[i] = elem->GetReal(); |
| 1411 } | 1038 } |
| 1412 | 1039 |
| 1413 *matrix = SkMatrixFromPdfMatrix(array); | 1040 *matrix = new SkMatrix(); |
| 1041 **matrix = SkMatrixFromPdfMatrix(array); |
| 1414 return true; | 1042 return true; |
| 1415 } | 1043 } |
| 1416 | 1044 |
| 1045 bool SkMatrixFromDictionary(const PdfMemDocument* pdfDoc, |
| 1046 const PdfDictionary& dict, |
| 1047 const char* key, |
| 1048 const char* abr, |
| 1049 SkMatrix** data) { |
| 1050 if (SkMatrixFromDictionary(pdfDoc, dict, key, data)) return true; |
| 1051 if (abr == NULL || *abr == '\0') return false; |
| 1052 return SkMatrixFromDictionary(pdfDoc, dict, abr, data); |
| 1053 |
| 1054 } |
| 1055 |
| 1417 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, | 1056 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, |
| 1418 const PdfDictionary& dict, | 1057 const PdfDictionary& dict, |
| 1419 const char* key, | 1058 const char* key, |
| 1420 SkRect* rect) { | 1059 SkRect** rect) { |
| 1421 const PdfObject* value = resolveReferenceObject(pdfDoc, | 1060 const PdfObject* value = resolveReferenceObject(pdfDoc, |
| 1422 dict.GetKey(PdfName(key))); | 1061 dict.GetKey(PdfName(key))); |
| 1423 | 1062 |
| 1424 if (value == NULL || !value->IsArray()) { | 1063 if (value == NULL || !value->IsArray()) { |
| 1425 return false; | 1064 return false; |
| 1426 } | 1065 } |
| 1427 | 1066 |
| 1428 if (value->GetArray().GetSize() != 4) { | 1067 if (value->GetArray().GetSize() != 4) { |
| 1429 return false; | 1068 return false; |
| 1430 } | 1069 } |
| 1431 | 1070 |
| 1432 double array[4]; | 1071 double array[4]; |
| 1433 for (int i = 0; i < 4; i++) { | 1072 for (int i = 0; i < 4; i++) { |
| 1434 const PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray(
)[i]); | 1073 const PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray(
)[i]); |
| 1435 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { | 1074 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { |
| 1436 return false; | 1075 return false; |
| 1437 } | 1076 } |
| 1438 array[i] = elem->GetReal(); | 1077 array[i] = elem->GetReal(); |
| 1439 } | 1078 } |
| 1440 | 1079 |
| 1441 *rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]), | 1080 *rect = new SkRect(); |
| 1442 SkDoubleToScalar(array[1]), | 1081 **rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]), |
| 1443 SkDoubleToScalar(array[2]), | 1082 SkDoubleToScalar(array[1]), |
| 1444 SkDoubleToScalar(array[3])); | 1083 SkDoubleToScalar(array[2]), |
| 1084 SkDoubleToScalar(array[3])); |
| 1445 return true; | 1085 return true; |
| 1446 } | 1086 } |
| 1447 | 1087 |
| 1448 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, | 1088 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, |
| 1449 const PdfDictionary& dict, | 1089 const PdfDictionary& dict, |
| 1450 const char* key, | 1090 const char* key, |
| 1451 const char* abr, | 1091 const char* abr, |
| 1452 SkRect* data) { | 1092 SkRect** data) { |
| 1453 if (SkRectFromDictionary(pdfDoc, dict, key, data)) return true; | 1093 if (SkRectFromDictionary(pdfDoc, dict, key, data)) return true; |
| 1454 if (abr == NULL || *abr == '\0') return false; | 1094 if (abr == NULL || *abr == '\0') return false; |
| 1455 return SkRectFromDictionary(pdfDoc, dict, abr, data); | 1095 return SkRectFromDictionary(pdfDoc, dict, abr, data); |
| 1456 | 1096 |
| 1457 } | 1097 } |
| 1458 | 1098 |
| 1459 | 1099 |
| 1460 SkPdfObject* get(const SkPdfObject* obj, const char* key, const char* abr = "")
{ | 1100 SkPdfObject* get(const SkPdfObject* obj, const char* key, const char* abr = "")
{ |
| 1461 SkPdfObject* ret = NULL; | 1101 SkPdfObject* ret = NULL; |
| 1462 if (obj == NULL) return NULL; | 1102 if (obj == NULL) return NULL; |
| 1463 const SkPdfDictionary* dict = obj->asDictionary(); | 1103 const SkPdfDictionary* dict = obj->asDictionary(); |
| 1464 if (dict == NULL) return NULL; | 1104 if (dict == NULL) return NULL; |
| 1465 if (!dict->podofo()->IsDictionary()) return NULL; | 1105 if (!dict->podofo()->IsDictionary()) return NULL; |
| 1466 ObjectFromDictionary(dict->doc(), dict->podofo()->GetDictionary(), key, abr,
&ret); | 1106 ObjectFromDictionary(dict->doc(), dict->podofo()->GetDictionary(), key, abr,
&ret); |
| 1467 return ret; | 1107 return ret; |
| 1468 } | 1108 } |
| 1469 | 1109 |
| 1470 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfType1For
mDictionary* skobj) { | 1110 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfType1For
mDictionary* skobj) { |
| 1471 if (!skobj || !skobj->podofo() || !skobj->podofo()->HasStream() || skobj->po
dofo()->GetStream() == NULL || skobj->podofo()->GetStream()->GetLength() == 0) { | 1111 if (!skobj || !skobj->podofo() || !skobj->podofo()->HasStream() || skobj->po
dofo()->GetStream() == NULL || skobj->podofo()->GetStream()->GetLength() == 0) { |
| 1472 return kOK_PdfResult; | 1112 return kOK_PdfResult; |
| 1473 } | 1113 } |
| 1474 | 1114 |
| 1475 PdfOp_q(pdfContext, canvas, NULL); | 1115 PdfOp_q(pdfContext, canvas, NULL); |
| 1476 canvas->save(); | 1116 canvas->save(); |
| 1477 | 1117 |
| 1478 if (get(skobj, "Resources")) { | |
| 1479 SkPdfResourceDictionary* res = NULL; | |
| 1480 | 1118 |
| 1481 PodofoMapper::map(*get(skobj, "Resources"), &res); | 1119 if (skobj->Resources()) { |
| 1482 | 1120 pdfContext->fGraphicsState.fResources = skobj->Resources(); |
| 1483 if (res) { | |
| 1484 pdfContext->fGraphicsState.fResources = res; | |
| 1485 } | |
| 1486 } | 1121 } |
| 1487 | 1122 |
| 1488 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Current matrix"); | 1123 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Current matrix"); |
| 1489 | 1124 |
| 1490 SkMatrix matrix; | 1125 if (skobj->Matrix()) { |
| 1491 if (SkMatrixFromDictionary(pdfContext, skobj->podofo()->GetDictionary(), "Ma
trix", &matrix)) { | 1126 pdfContext->fGraphicsState.fMatrix.preConcat(*skobj->Matrix()); |
| 1492 pdfContext->fGraphicsState.fMatrix.preConcat(matrix); | |
| 1493 pdfContext->fGraphicsState.fMatrixTm = pdfContext->fGraphicsState.fMatri
x; | 1127 pdfContext->fGraphicsState.fMatrixTm = pdfContext->fGraphicsState.fMatri
x; |
| 1494 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatr
ix; | 1128 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatr
ix; |
| 1495 // TODO(edisonn) reset matrixTm and matricTlm also? | 1129 // TODO(edisonn) reset matrixTm and matricTlm also? |
| 1496 } | 1130 } |
| 1497 | 1131 |
| 1498 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); | 1132 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); |
| 1499 | 1133 |
| 1500 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 1134 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
| 1501 | 1135 |
| 1502 SkRect bbox; | 1136 if (skobj->BBox()) { |
| 1503 if (SkRectFromDictionary(&pdfContext->fPdfDoc.podofo(), skobj->podofo()->Get
Dictionary(), "BBox", &bbox)) { | 1137 canvas->clipRect(*skobj->BBox(), SkRegion::kIntersect_Op, true); // TOD
O(edisonn): AA from settings. |
| 1504 canvas->clipRect(bbox, SkRegion::kIntersect_Op, true); // TODO(edisonn)
: AA from settings. | |
| 1505 } | 1138 } |
| 1506 | 1139 |
| 1507 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. | 1140 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. |
| 1508 // For this PdfContentsTokenizer needs to be extended. | 1141 // For this PdfContentsTokenizer needs to be extended. |
| 1509 | 1142 |
| 1510 PdfResult ret = kPartial_PdfResult; | 1143 PdfResult ret = kPartial_PdfResult; |
| 1511 SkPdfTokenizer tokenizer(skobj); | 1144 SkPdfTokenizer tokenizer(skobj); |
| 1512 PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas); | 1145 PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas); |
| 1513 looper.loop(); | 1146 looper.loop(); |
| 1514 | 1147 |
| 1515 // TODO(edisonn): should we restore the variable stack at the same state? | 1148 // TODO(edisonn): should we restore the variable stack at the same state? |
| 1516 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | 1149 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. |
| 1517 canvas->restore(); | 1150 canvas->restore(); |
| 1518 PdfOp_Q(pdfContext, canvas, NULL); | 1151 PdfOp_Q(pdfContext, canvas, NULL); |
| 1519 return ret; | 1152 return ret; |
| 1520 } | 1153 } |
| 1521 | 1154 |
| 1522 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
& obj) { | 1155 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
& obj) { |
| 1523 return kNYI_PdfResult; | 1156 return kNYI_PdfResult; |
| 1524 } | 1157 } |
| 1525 | 1158 |
| 1159 PdfResult doType3Char(PdfContext* pdfContext, SkCanvas* canvas, SkPdfObject* sko
bj, SkRect bBox, SkMatrix matrix, double textSize) { |
| 1160 if (!skobj || !skobj->podofo() || !skobj->podofo()->HasStream() || skobj->po
dofo()->GetStream() == NULL || skobj->podofo()->GetStream()->GetLength() == 0) { |
| 1161 return kOK_PdfResult; |
| 1162 } |
| 1163 |
| 1164 PdfOp_q(pdfContext, canvas, NULL); |
| 1165 canvas->save(); |
| 1166 |
| 1167 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
| 1168 pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), Sk
DoubleToScalar(textSize)); |
| 1169 |
| 1170 pdfContext->fGraphicsState.fMatrix = pdfContext->fGraphicsState.fMatrixTm; |
| 1171 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix; |
| 1172 |
| 1173 SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); |
| 1174 |
| 1175 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
| 1176 |
| 1177 SkRect rm = bBox; |
| 1178 pdfContext->fGraphicsState.fMatrix.mapRect(&rm); |
| 1179 |
| 1180 SkTraceRect(rm, "bbox mapped"); |
| 1181 |
| 1182 canvas->clipRect(bBox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA
from settings. |
| 1183 |
| 1184 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. |
| 1185 // For this PdfContentsTokenizer needs to be extended. |
| 1186 |
| 1187 PdfResult ret = kPartial_PdfResult; |
| 1188 SkPdfTokenizer tokenizer(skobj); |
| 1189 PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas); |
| 1190 looper.loop(); |
| 1191 |
| 1192 // TODO(edisonn): should we restore the variable stack at the same state? |
| 1193 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. |
| 1194 canvas->restore(); |
| 1195 PdfOp_Q(pdfContext, canvas, NULL); |
| 1196 return ret; |
| 1197 } |
| 1198 |
| 1199 |
| 1526 // TODO(edisonn): faster, have the property on the SkPdfObject itself? | 1200 // TODO(edisonn): faster, have the property on the SkPdfObject itself? |
| 1527 std::set<const PdfObject*> gInRendering; | 1201 std::set<const PdfObject*> gInRendering; |
| 1528 | 1202 |
| 1529 class CheckRecursiveRendering { | 1203 class CheckRecursiveRendering { |
| 1530 const PdfObject& fObj; | 1204 const PdfObject& fObj; |
| 1531 public: | 1205 public: |
| 1532 CheckRecursiveRendering(const PdfObject& obj) : fObj(obj) { | 1206 CheckRecursiveRendering(const PdfObject& obj) : fObj(obj) { |
| 1533 gInRendering.insert(&obj); | 1207 gInRendering.insert(&obj); |
| 1534 } | 1208 } |
| 1535 | 1209 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1644 | 1318 |
| 1645 return kPartial_PdfResult; | 1319 return kPartial_PdfResult; |
| 1646 } | 1320 } |
| 1647 | 1321 |
| 1648 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1322 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1649 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 1323 double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); |
| 1650 double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); | 1324 double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
>fObjectStack.pop(); |
| 1651 | 1325 |
| 1652 // TODO(edisonn): Create factory methods or constructors so podofo is hidden | 1326 // TODO(edisonn): Create factory methods or constructors so podofo is hidden |
| 1653 PdfObject _ty(PdfVariant(-ty)); | 1327 PdfObject _ty(PdfVariant(-ty)); |
| 1654 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&_ty)); | 1328 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &_ty)); |
| 1655 | 1329 |
| 1656 PdfOp_TL(pdfContext, canvas, looper); | 1330 PdfOp_TL(pdfContext, canvas, looper); |
| 1657 | 1331 |
| 1658 PdfObject vtx(PdfVariant(-(-tx))); // TODO(edisonn): Hmm, the compiler thin
ks I have here a function pointer if we use (tx), but not -(-tx) | 1332 PdfObject vtx(PdfVariant(-(-tx))); // TODO(edisonn): Hmm, the compiler thin
ks I have here a function pointer if we use (tx), but not -(-tx) |
| 1659 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&vtx)); | 1333 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &vtx)); |
| 1660 | 1334 |
| 1661 PdfObject vty(PdfVariant(-(-ty))); | 1335 PdfObject vty(PdfVariant(-(-ty))); |
| 1662 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&vty)); | 1336 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &vty)); |
| 1663 | 1337 |
| 1664 return PdfOp_Td(pdfContext, canvas, looper); | 1338 return PdfOp_Td(pdfContext, canvas, looper); |
| 1665 } | 1339 } |
| 1666 | 1340 |
| 1667 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1341 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 1668 double f = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 1342 double f = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
| 1669 double e = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 1343 double e = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
| 1670 double d = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 1344 double d = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
| 1671 double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 1345 double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
| 1672 double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); | 1346 double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
fObjectStack.pop(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1690 return kPartial_PdfResult; | 1364 return kPartial_PdfResult; |
| 1691 } | 1365 } |
| 1692 | 1366 |
| 1693 //— T* Move to the start of the next line. This operator has the same effect as
the code | 1367 //— T* Move to the start of the next line. This operator has the same effect as
the code |
| 1694 //0 Tl Td | 1368 //0 Tl Td |
| 1695 //where Tl is the current leading parameter in the text state | 1369 //where Tl is the current leading parameter in the text state |
| 1696 PdfResult PdfOp_T_star(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper) { | 1370 PdfResult PdfOp_T_star(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper) { |
| 1697 PdfObject zero(PdfVariant(0.0)); | 1371 PdfObject zero(PdfVariant(0.0)); |
| 1698 PdfObject tl(PdfVariant(-(-pdfContext->fGraphicsState.fTextLeading))); | 1372 PdfObject tl(PdfVariant(-(-pdfContext->fGraphicsState.fTextLeading))); |
| 1699 | 1373 |
| 1700 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&zero)); | 1374 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &zero)); |
| 1701 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc.podofo(),
&tl)); | 1375 pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
, &tl)); |
| 1702 return PdfOp_Td(pdfContext, canvas, looper); | 1376 return PdfOp_Td(pdfContext, canvas, looper); |
| 1703 } | 1377 } |
| 1704 | 1378 |
| 1705 PdfResult PdfOp_m(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1379 PdfResult PdfOp_m(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1706 if (pdfContext->fGraphicsState.fPathClosed) { | 1380 if (pdfContext->fGraphicsState.fPathClosed) { |
| 1707 pdfContext->fGraphicsState.fPath.reset(); | 1381 pdfContext->fGraphicsState.fPath.reset(); |
| 1708 pdfContext->fGraphicsState.fPathClosed = false; | 1382 pdfContext->fGraphicsState.fPathClosed = false; |
| 1709 } | 1383 } |
| 1710 | 1384 |
| 1711 pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); | 1385 pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->asNumb
er()->value(); pdfContext->fObjectStack.pop(); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 SkDoubleToScalar(x + width), SkDouble
ToScalar(y + height)); | 1490 SkDoubleToScalar(x + width), SkDouble
ToScalar(y + height)); |
| 1817 | 1491 |
| 1818 pdfContext->fGraphicsState.fCurPosX = x; | 1492 pdfContext->fGraphicsState.fCurPosX = x; |
| 1819 pdfContext->fGraphicsState.fCurPosY = y + height; | 1493 pdfContext->fGraphicsState.fCurPosY = y + height; |
| 1820 | 1494 |
| 1821 return kOK_PdfResult; | 1495 return kOK_PdfResult; |
| 1822 } | 1496 } |
| 1823 | 1497 |
| 1824 PdfResult PdfOp_h(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { | 1498 PdfResult PdfOp_h(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per) { |
| 1825 pdfContext->fGraphicsState.fPath.close(); | 1499 pdfContext->fGraphicsState.fPath.close(); |
| 1826 pdfContext->fGraphicsState.fPathClosed = true; | |
| 1827 return kOK_PdfResult; | 1500 return kOK_PdfResult; |
| 1828 } | 1501 } |
| 1829 | 1502 |
| 1830 PdfResult PdfOp_fillAndStroke(PdfContext* pdfContext, SkCanvas* canvas, bool fil
l, bool stroke, bool close, bool evenOdd) { | 1503 PdfResult PdfOp_fillAndStroke(PdfContext* pdfContext, SkCanvas* canvas, bool fil
l, bool stroke, bool close, bool evenOdd) { |
| 1831 SkPath path = pdfContext->fGraphicsState.fPath; | 1504 SkPath path = pdfContext->fGraphicsState.fPath; |
| 1832 | 1505 |
| 1833 if (close) { | 1506 if (close) { |
| 1834 path.close(); | 1507 path.close(); |
| 1835 } | 1508 } |
| 1836 | 1509 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1965 printf("font name: %s\n", fontName.c_str()); | 1638 printf("font name: %s\n", fontName.c_str()); |
| 1966 std::string str; | 1639 std::string str; |
| 1967 pdfContext->fGraphicsState.fResources->podofo()->ToString(str); | 1640 pdfContext->fGraphicsState.fResources->podofo()->ToString(str); |
| 1968 printf("Print Tf Resources: %s\n", str.c_str()); | 1641 printf("Print Tf Resources: %s\n", str.c_str()); |
| 1969 pdfContext->fGraphicsState.fResources->Font()->podofo()->ToString(str); | 1642 pdfContext->fGraphicsState.fResources->Font()->podofo()->ToString(str); |
| 1970 printf("Print Tf Resources/Font: %s\n", str.c_str()); | 1643 printf("Print Tf Resources/Font: %s\n", str.c_str()); |
| 1971 #endif | 1644 #endif |
| 1972 | 1645 |
| 1973 SkPdfFontDictionary* fd = NULL; | 1646 SkPdfFontDictionary* fd = NULL; |
| 1974 if (pdfContext->fGraphicsState.fResources->Font()) { | 1647 if (pdfContext->fGraphicsState.fResources->Font()) { |
| 1975 SkPdfObject objFont = pdfContext->fGraphicsState.fResources->Font()->get
(fontName.c_str()); | 1648 SkPdfObject* objFont = pdfContext->fGraphicsState.fResources->Font()->ge
t(fontName.c_str()); |
| 1976 PodofoMapper::map(objFont, &fd); | 1649 PodofoMapper::map(*objFont, &fd); |
| 1977 | 1650 |
| 1978 #ifdef PDF_TRACE | 1651 #ifdef PDF_TRACE |
| 1979 objFont.podofo()->ToString(str); | 1652 objFont->podofo()->ToString(str); |
| 1980 printf("Print Font loaded: %s\n", str.c_str()); | 1653 printf("Print Font loaded: %s\n", str.c_str()); |
| 1981 fd->podofo()->ToString(str); | 1654 fd->podofo()->ToString(str); |
| 1982 printf("Print Font loaded and resolved and upgraded: %s\n", str.c_str())
; | 1655 printf("Print Font loaded and resolved and upgraded: %s\n", str.c_str())
; |
| 1983 #endif | 1656 #endif |
| 1984 | 1657 |
| 1985 } | 1658 } |
| 1986 | 1659 |
| 1987 SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(fd); | 1660 SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(fd); |
| 1988 | 1661 |
| 1989 if (skfont) { | 1662 if (skfont) { |
| 1990 pdfContext->fGraphicsState.fSkFont = skfont; | 1663 pdfContext->fGraphicsState.fSkFont = skfont; |
| 1991 } | 1664 } |
| 1992 | 1665 |
| 1993 // TODO(edisonn): Load font from pdfContext->fGraphicsState.fObjectWithResou
rces ? | |
| 1994 const PdfObject* pFont = resolveReferenceObject(&pdfContext->fPdfDoc.podofo(
), | |
| 1995 pdfContext->fGraphicsState.f
Resources->Font()->get(fontName.c_str()).podofo()); | |
| 1996 if( !pFont ) | |
| 1997 { | |
| 1998 // TODO(edisonn): try to ignore the error, make sure we do not crash. | |
| 1999 return kIgnoreError_PdfResult; | |
| 2000 } | |
| 2001 | |
| 2002 PdfFont* font = pdfContext->fPdfDoc.podofo().GetFont( (PdfObject*)pFont ); | |
| 2003 if (font) { | |
| 2004 pdfContext->fGraphicsState.fCurFont = font; | |
| 2005 } else { | |
| 2006 // TODO(edisonn): check ~/crasing, for one of the files PoDoFo throws ex
ception | |
| 2007 // when calling pFont->Reference(), with Linked list corruption. | |
| 2008 return kIgnoreError_PdfResult; | |
| 2009 } | |
| 2010 | |
| 2011 return kPartial_PdfResult; | 1666 return kPartial_PdfResult; |
| 2012 } | 1667 } |
| 2013 | 1668 |
| 2014 PdfResult PdfOp_Tj(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1669 PdfResult PdfOp_Tj(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 2015 if (!pdfContext->fGraphicsState.fTextBlock) { | 1670 if (!pdfContext->fGraphicsState.fTextBlock) { |
| 2016 // TODO(edisonn): try to recover and draw it any way? | 1671 // TODO(edisonn): try to recover and draw it any way? |
| 2017 return kIgnoreError_PdfResult; | 1672 return kIgnoreError_PdfResult; |
| 2018 } | 1673 } |
| 2019 | 1674 |
| 2020 PdfResult ret = DrawText(pdfContext, | 1675 PdfResult ret = DrawText(pdfContext, |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2343 //Next, get the ExtGState Dictionary from the Resource Dictionary: | 1998 //Next, get the ExtGState Dictionary from the Resource Dictionary: |
| 2344 const SkPdfDictionary* extGStateDictionary = pdfContext->fGraphicsState.fRes
ources->ExtGState(); | 1999 const SkPdfDictionary* extGStateDictionary = pdfContext->fGraphicsState.fRes
ources->ExtGState(); |
| 2345 | 2000 |
| 2346 if (extGStateDictionary == NULL) { | 2001 if (extGStateDictionary == NULL) { |
| 2347 #ifdef PDF_TRACE | 2002 #ifdef PDF_TRACE |
| 2348 printf("ExtGState is NULL!\n"); | 2003 printf("ExtGState is NULL!\n"); |
| 2349 #endif | 2004 #endif |
| 2350 return kIgnoreError_PdfResult; | 2005 return kIgnoreError_PdfResult; |
| 2351 } | 2006 } |
| 2352 | 2007 |
| 2353 SkPdfObject value = extGStateDictionary->get(name.c_str()); | 2008 SkPdfObject* value = extGStateDictionary->get(name.c_str()); |
| 2354 | 2009 |
| 2355 #ifdef PDF_TRACE | 2010 #ifdef PDF_TRACE |
| 2356 // value->ToString(str); | 2011 // value->ToString(str); |
| 2357 // printf("gs object value: %s\n", str.c_str()); | 2012 // printf("gs object value: %s\n", str.c_str()); |
| 2358 #endif | 2013 #endif |
| 2359 | 2014 |
| 2360 SkPdfGraphicsStateDictionary* gs = NULL; | 2015 SkPdfGraphicsStateDictionary* gs = NULL; |
| 2361 PodofoMapper::map(value, &gs); | 2016 PodofoMapper::map(*value, &gs); |
| 2362 | 2017 |
| 2363 // TODO(edisonn): now load all those properties in graphic state. | 2018 // TODO(edisonn): now load all those properties in graphic state. |
| 2364 if (gs == NULL) { | 2019 if (gs == NULL) { |
| 2365 return kIgnoreError_PdfResult; | 2020 return kIgnoreError_PdfResult; |
| 2366 } | 2021 } |
| 2367 | 2022 |
| 2368 if (gs->has_CA()) { | 2023 if (gs->has_CA()) { |
| 2369 pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(); | 2024 pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(); |
| 2370 } | 2025 } |
| 2371 | 2026 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2413 return kNYI_PdfResult; | 2068 return kNYI_PdfResult; |
| 2414 } | 2069 } |
| 2415 | 2070 |
| 2416 //render Tr Set the text rendering mode, T | 2071 //render Tr Set the text rendering mode, T |
| 2417 //mode, to render, which is an integer. Initial value: 0. | 2072 //mode, to render, which is an integer. Initial value: 0. |
| 2418 PdfResult PdfOp_Tr(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 2073 PdfResult PdfOp_Tr(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 2419 double render = pdfContext->fObjectStack.top()->asNumber()->value(); pdf
Context->fObjectStack.pop(); | 2074 double render = pdfContext->fObjectStack.top()->asNumber()->value(); pdf
Context->fObjectStack.pop(); |
| 2420 | 2075 |
| 2421 return kNYI_PdfResult; | 2076 return kNYI_PdfResult; |
| 2422 } | 2077 } |
| 2423 | |
| 2424 //rise Ts Set the text rise, Trise, to rise, which is a number expressed in unsc
aled text space | 2078 //rise Ts Set the text rise, Trise, to rise, which is a number expressed in unsc
aled text space |
| 2425 //units. Initial value: 0. | 2079 //units. Initial value: 0. |
| 2426 PdfResult PdfOp_Ts(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 2080 PdfResult PdfOp_Ts(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 2427 double rise = pdfContext->fObjectStack.top()->asNumber()->value(); pdfCo
ntext->fObjectStack.pop(); | 2081 double rise = pdfContext->fObjectStack.top()->asNumber()->value(); pdfCo
ntext->fObjectStack.pop(); |
| 2428 | 2082 |
| 2429 return kNYI_PdfResult; | 2083 return kNYI_PdfResult; |
| 2430 } | 2084 } |
| 2431 | 2085 |
| 2432 //wx wy d0 | 2086 //wx wy d0 |
| 2433 PdfResult PdfOp_d0(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 2087 PdfResult PdfOp_d0(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2462 | 2116 |
| 2463 SkPdfDictionary* xObject = pdfContext->fGraphicsState.fResources->XObject()
; | 2117 SkPdfDictionary* xObject = pdfContext->fGraphicsState.fResources->XObject()
; |
| 2464 | 2118 |
| 2465 if (xObject == NULL) { | 2119 if (xObject == NULL) { |
| 2466 #ifdef PDF_TRACE | 2120 #ifdef PDF_TRACE |
| 2467 printf("XObject is NULL!\n"); | 2121 printf("XObject is NULL!\n"); |
| 2468 #endif | 2122 #endif |
| 2469 return kIgnoreError_PdfResult; | 2123 return kIgnoreError_PdfResult; |
| 2470 } | 2124 } |
| 2471 | 2125 |
| 2472 SkPdfObject value = xObject->get(name.c_str()); | 2126 SkPdfObject* value = xObject->get(name.c_str()); |
| 2473 | 2127 |
| 2474 #ifdef PDF_TRACE | 2128 #ifdef PDF_TRACE |
| 2475 // value->ToString(str); | 2129 // value->ToString(str); |
| 2476 // printf("Do object value: %s\n", str.c_str()); | 2130 // printf("Do object value: %s\n", str.c_str()); |
| 2477 #endif | 2131 #endif |
| 2478 | 2132 |
| 2479 return doXObject(pdfContext, canvas, value); | 2133 return doXObject(pdfContext, canvas, *value); |
| 2480 } | 2134 } |
| 2481 | 2135 |
| 2482 //tag MP Designate a marked-content point. tag is a name object indicating the r
ole or | 2136 //tag MP Designate a marked-content point. tag is a name object indicating the r
ole or |
| 2483 //significance of the point. | 2137 //significance of the point. |
| 2484 PdfResult PdfOp_MP(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 2138 PdfResult PdfOp_MP(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
| 2485 pdfContext->fObjectStack.pop(); | 2139 pdfContext->fObjectStack.pop(); |
| 2486 | 2140 |
| 2487 return kNYI_PdfResult; | 2141 return kNYI_PdfResult; |
| 2488 } | 2142 } |
| 2489 | 2143 |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2772 SkRect rect = doc.MediaBox(pn); | 2426 SkRect rect = doc.MediaBox(pn); |
| 2773 | 2427 |
| 2774 #ifdef PDF_TRACE | 2428 #ifdef PDF_TRACE |
| 2775 printf("Page Width: %f, Page Height: %f\n", SkScalarToDouble(rec
t.width()), SkScalarToDouble(rect.height())); | 2429 printf("Page Width: %f, Page Height: %f\n", SkScalarToDouble(rec
t.width()), SkScalarToDouble(rect.height())); |
| 2776 #endif | 2430 #endif |
| 2777 | 2431 |
| 2778 // TODO(edisonn): page->GetCropBox(), page->GetTrimBox() ... how
to use? | 2432 // TODO(edisonn): page->GetCropBox(), page->GetTrimBox() ... how
to use? |
| 2779 | 2433 |
| 2780 SkBitmap bitmap; | 2434 SkBitmap bitmap; |
| 2781 #ifdef PDF_DEBUG_3X | 2435 #ifdef PDF_DEBUG_3X |
| 2782 setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3
* (int)SkScalarToDouble(rect.height())) | 2436 setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3
* (int)SkScalarToDouble(rect.height())); |
| 2783 #else | 2437 #else |
| 2784 setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)
SkScalarToDouble(rect.height())); | 2438 setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)
SkScalarToDouble(rect.height())); |
| 2785 #endif | 2439 #endif |
| 2786 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (bitmap))); | 2440 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (bitmap))); |
| 2787 SkCanvas canvas(device); | 2441 SkCanvas canvas(device); |
| 2788 | 2442 |
| 2789 SkPdfTokenizer* tokenizer = doc.tokenizerOfPage(pn); | 2443 SkPdfTokenizer* tokenizer = doc.tokenizerOfPage(pn); |
| 2790 | 2444 |
| 2791 PdfContext pdfContext(doc); | 2445 PdfContext pdfContext(&doc); |
| 2792 pdfContext.fOriginalMatrix = SkMatrix::I(); | 2446 pdfContext.fOriginalMatrix = SkMatrix::I(); |
| 2793 pdfContext.fGraphicsState.fResources = NULL; | 2447 pdfContext.fGraphicsState.fResources = NULL; |
| 2794 PodofoMapper::map(*page->Resources(), &pdfContext.fGraphicsState
.fResources); | 2448 PodofoMapper::map(*page->Resources(), &pdfContext.fGraphicsState
.fResources); |
| 2795 | 2449 |
| 2796 gPdfContext = &pdfContext; | 2450 gPdfContext = &pdfContext; |
| 2797 gDumpBitmap = &bitmap; | 2451 gDumpBitmap = &bitmap; |
| 2798 gDumpCanvas = &canvas; | 2452 gDumpCanvas = &canvas; |
| 2799 | 2453 |
| 2800 | 2454 |
| 2801 // TODO(edisonn): get matrix stuff right. | 2455 // TODO(edisonn): get matrix stuff right. |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3071 } | 2725 } |
| 3072 | 2726 |
| 3073 return 0; | 2727 return 0; |
| 3074 } | 2728 } |
| 3075 | 2729 |
| 3076 #if !defined SK_BUILD_FOR_IOS | 2730 #if !defined SK_BUILD_FOR_IOS |
| 3077 int main(int argc, char * const argv[]) { | 2731 int main(int argc, char * const argv[]) { |
| 3078 return tool_main(argc, (char**) argv); | 2732 return tool_main(argc, (char**) argv); |
| 3079 } | 2733 } |
| 3080 #endif | 2734 #endif |
| OLD | NEW |