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" |
11 #include "SkGraphics.h" | 11 #include "SkGraphics.h" |
12 #include "SkImageDecoder.h" | 12 #include "SkImageDecoder.h" |
13 #include "SkImageEncoder.h" | 13 #include "SkImageEncoder.h" |
14 #include "SkOSFile.h" | 14 #include "SkOSFile.h" |
15 #include "SkPicture.h" | 15 #include "SkPicture.h" |
16 #include "SkStream.h" | 16 #include "SkStream.h" |
17 #include "SkTypeface.h" | 17 #include "SkTypeface.h" |
18 #include "SkTArray.h" | 18 #include "SkTArray.h" |
19 #include "picture_utils.h" | 19 #include "picture_utils.h" |
20 | 20 |
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 __SK_FORCE_IMAGE_DECODER_LINKING; | 29 __SK_FORCE_IMAGE_DECODER_LINKING; |
29 | 30 |
| 31 |
| 32 //#define PDF_TRACE |
| 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 |
| 38 |
30 const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, | 39 const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, |
31 const PdfObject* obj, | 40 const PdfObject* obj, |
32 bool resolveOneElementArrays = false); | 41 bool resolveOneElementArrays = false); |
33 | 42 |
34 bool LongFromDictionary(const PdfMemDocument* pdfDoc, | 43 bool LongFromDictionary(const PdfMemDocument* pdfDoc, |
35 const PdfDictionary& dict, | 44 const PdfDictionary& dict, |
36 const char* key, | 45 const char* key, |
37 const char* abr, | 46 const char* abr, |
38 long* data); | 47 long* data); |
39 | 48 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 class SkPdfObject; | 87 class SkPdfObject; |
79 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, | 88 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, |
80 const PdfDictionary& dict, | 89 const PdfDictionary& dict, |
81 const char* key, | 90 const char* key, |
82 const char* abr, | 91 const char* abr, |
83 SkPdfObject** data); | 92 SkPdfObject** data); |
84 | 93 |
85 | 94 |
86 struct SkPdfFileSpec {}; | 95 struct SkPdfFileSpec {}; |
87 class SkPdfArray; | 96 class SkPdfArray; |
88 struct SkPdfStream {}; | 97 class SkPdfStream; |
89 struct SkPdfDate {}; | 98 struct SkPdfDate {}; |
90 struct SkPdfTree {}; | 99 struct SkPdfTree {}; |
91 struct SkPdfFunction {}; | 100 struct SkPdfFunction {}; |
92 | 101 |
93 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, | 102 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |
94 const PdfDictionary& dict, | 103 const PdfDictionary& dict, |
95 const char* key, | 104 const char* key, |
96 const char* abr, | 105 const char* abr, |
97 SkPdfArray* data); | 106 SkPdfArray* data); |
98 | 107 |
99 | 108 |
100 bool FileSpecFromDictionary(const PdfMemDocument* pdfDoc, | 109 bool FileSpecFromDictionary(const PdfMemDocument* pdfDoc, |
101 const PdfDictionary& dict, | 110 const PdfDictionary& dict, |
102 const char* key, | 111 const char* key, |
103 const char* abr, | 112 const char* abr, |
104 SkPdfFileSpec* data); | 113 SkPdfFileSpec* data); |
105 | 114 |
106 | 115 |
107 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, | 116 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, |
108 const PdfDictionary& dict, | 117 const PdfDictionary& dict, |
109 const char* key, | 118 const char* key, |
110 const char* abr, | 119 const char* abr, |
111 SkPdfStream* data); | 120 SkPdfStream** data); |
112 | 121 |
113 bool TreeFromDictionary(const PdfMemDocument* pdfDoc, | 122 bool TreeFromDictionary(const PdfMemDocument* pdfDoc, |
114 const PdfDictionary& dict, | 123 const PdfDictionary& dict, |
115 const char* key, | 124 const char* key, |
116 const char* abr, | 125 const char* abr, |
117 SkPdfTree** data); | 126 SkPdfTree** data); |
118 | 127 |
119 bool DateFromDictionary(const PdfMemDocument* pdfDoc, | 128 bool DateFromDictionary(const PdfMemDocument* pdfDoc, |
120 const PdfDictionary& dict, | 129 const PdfDictionary& dict, |
121 const char* key, | 130 const char* key, |
122 const char* abr, | 131 const char* abr, |
123 SkPdfDate* data); | 132 SkPdfDate* data); |
124 | 133 |
125 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, | 134 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, |
126 const PdfDictionary& dict, | 135 const PdfDictionary& dict, |
127 const char* key, | 136 const char* key, |
128 const char* abr, | 137 const char* abr, |
129 SkRect* data); | 138 SkRect* data); |
130 | 139 |
131 bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, | 140 bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, |
132 const PdfDictionary& dict, | 141 const PdfDictionary& dict, |
133 const char* key, | 142 const char* key, |
134 const char* abr, | 143 const char* abr, |
135 SkPdfFunction* data); | 144 SkPdfFunction* data); |
136 | 145 |
137 | 146 |
138 #include "SkPdfHeaders_autogen.h" | 147 #include "SkPdfHeaders_autogen.h" |
139 #include "SkPdfPodofoMapper_autogen.h" | 148 #include "SkPdfPodofoMapper_autogen.h" |
140 #include "SkPdfParser.h" | 149 #include "SkPdfParser.h" |
| 150 #include "SkPdfFont.h" |
| 151 |
| 152 // TODO(edisonn): fix the mess with the files. |
| 153 #include "SkPdfFont.cpp" |
141 | 154 |
142 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, | 155 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |
143 const PdfDictionary& dict, | 156 const PdfDictionary& dict, |
144 const char* key, | 157 const char* key, |
145 const char* abr, | 158 const char* abr, |
146 SkPdfArray* data) {return false;} | 159 SkPdfArray* data) {return false;} |
147 | 160 |
148 bool FileSpecFromDictionary(const PdfMemDocument* pdfDoc, | 161 bool FileSpecFromDictionary(const PdfMemDocument* pdfDoc, |
149 const PdfDictionary& dict, | 162 const PdfDictionary& dict, |
150 const char* key, | 163 const char* key, |
151 const char* abr, | 164 const char* abr, |
152 SkPdfFileSpec* data) {return false;} | 165 SkPdfFileSpec* data) {return false;} |
153 | 166 |
154 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, | 167 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, |
155 const PdfDictionary& dict, | 168 const PdfDictionary& dict, |
156 const char* key, | 169 const char* key, |
157 const char* abr, | 170 const char* abr, |
158 SkPdfStream* data) {return false;} | 171 SkPdfStream** data); |
159 | 172 |
160 bool TreeFromDictionary(const PdfMemDocument* pdfDoc, | 173 bool TreeFromDictionary(const PdfMemDocument* pdfDoc, |
161 const PdfDictionary& dict, | 174 const PdfDictionary& dict, |
162 const char* key, | 175 const char* key, |
163 const char* abr, | 176 const char* abr, |
164 SkPdfTree** data) {return false;} | 177 SkPdfTree** data) {return false;} |
165 | 178 |
166 bool DateFromDictionary(const PdfMemDocument* pdfDoc, | 179 bool DateFromDictionary(const PdfMemDocument* pdfDoc, |
167 const PdfDictionary& dict, | 180 const PdfDictionary& dict, |
168 const char* key, | 181 const char* key, |
169 const char* abr, | 182 const char* abr, |
170 SkPdfDate* data) {return false;} | 183 SkPdfDate* data) {return false;} |
171 | 184 |
172 bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, | 185 bool FunctionFromDictionary(const PdfMemDocument* pdfDoc, |
173 const PdfDictionary& dict, | 186 const PdfDictionary& dict, |
174 const char* key, | 187 const char* key, |
175 const char* abr, | 188 const char* abr, |
176 SkPdfFunction* data) {return false;} | 189 SkPdfFunction* data) {return false;} |
177 | 190 |
178 | 191 |
179 | 192 |
180 /* | 193 /* |
181 * TODO(edisonn): | 194 * TODO(edisonn): |
182 * - encapsulate podofo in the pdf api so the skpdf does not know anything about
podofo ... in progress | |
183 * - ASAP so skp -> pdf -> png looks great | |
184 * - load gs/ especially smask and already known prop (skp)... | |
185 * - all font types and all ppdf font features | 195 * - all font types and all ppdf font features |
186 * - word spacing | 196 * - word spacing |
187 * - load font for baidu.pdf | 197 * - load font for baidu.pdf |
188 * - load font for youtube.pdf | 198 * - load font for youtube.pdf |
189 * - parser for pdf from the definition already available in pdfspec_autoge
n.py | 199 * - parser for pdf from the definition already available in pdfspec_autoge
n.py |
| 200 * - all docs from ~/work |
| 201 * - encapsulate podofo in the pdf api so the skpdf does not know anything about
podofo ... in progress |
| 202 * - load gs/ especially smask and already known prop (skp) ... in progress |
190 * - wrapper on classes for customizations? e.g. | 203 * - wrapper on classes for customizations? e.g. |
191 * SkPdfPageObjectVanila - has only the basic loaders/getters | 204 * SkPdfPageObjectVanila - has only the basic loaders/getters |
192 * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add custom
izations here | 205 * 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 | 206 * need to find a nice object model for all this with constructors and factories |
194 * - deal with inheritable automatically ? | 207 * - deal with inheritable automatically ? |
195 * - deal with specific type in spec directly, add all dictionary types to known
types | 208 * - deal with specific type in spec directly, add all dictionary types to known
types |
196 */ | 209 */ |
197 | 210 |
198 //#define PDF_TRACE | |
199 //#define PDF_TRACE_DIFF_IN_PNG | |
200 //#define PDF_DEBUG_NO_CLIPING | |
201 //#define PDF_DEBUG_NO_PAGE_CLIPING | |
202 //#define PDF_DEBUG_3X | |
203 | 211 |
204 // TODO(edisonn): move in trace util. | 212 // TODO(edisonn): move in trace util. |
205 #ifdef PDF_TRACE | 213 #ifdef PDF_TRACE |
206 static void SkTraceMatrix(const SkMatrix& matrix, const char* sz = "") { | 214 static void SkTraceMatrix(const SkMatrix& matrix, const char* sz = "") { |
207 printf("SkMatrix %s ", sz); | 215 printf("SkMatrix %s ", sz); |
208 for (int i = 0 ; i < 9 ; i++) { | 216 for (int i = 0 ; i < 9 ; i++) { |
209 printf("%f ", SkScalarToDouble(matrix.get(i))); | 217 printf("%f ", SkScalarToDouble(matrix.get(i))); |
210 } | 218 } |
211 printf("\n"); | 219 printf("\n"); |
212 } | 220 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 SkMatrix fMatrix; | 308 SkMatrix fMatrix; |
301 SkMatrix fMatrixTm; | 309 SkMatrix fMatrixTm; |
302 SkMatrix fMatrixTlm; | 310 SkMatrix fMatrixTlm; |
303 | 311 |
304 double fCurPosX; | 312 double fCurPosX; |
305 double fCurPosY; | 313 double fCurPosY; |
306 | 314 |
307 double fCurFontSize; | 315 double fCurFontSize; |
308 bool fTextBlock; | 316 bool fTextBlock; |
309 PdfFont* fCurFont; | 317 PdfFont* fCurFont; |
| 318 SkPdfFont* fSkFont; |
310 SkPath fPath; | 319 SkPath fPath; |
311 bool fPathClosed; | 320 bool fPathClosed; |
312 | 321 |
313 // Clip that is applied after the drawing is done!!! | 322 // Clip that is applied after the drawing is done!!! |
314 bool fHasClipPathToApply; | 323 bool fHasClipPathToApply; |
315 SkPath fClipPath; | 324 SkPath fClipPath; |
316 | 325 |
317 PdfColorOperator fStroking; | 326 PdfColorOperator fStroking; |
318 PdfColorOperator fNonStroking; | 327 PdfColorOperator fNonStroking; |
319 | 328 |
(...skipping 15 matching lines...) Expand all Loading... |
335 fMatrix = SkMatrix::I(); | 344 fMatrix = SkMatrix::I(); |
336 fMatrixTm = SkMatrix::I(); | 345 fMatrixTm = SkMatrix::I(); |
337 fMatrixTlm = SkMatrix::I(); | 346 fMatrixTlm = SkMatrix::I(); |
338 fPathClosed = true; | 347 fPathClosed = true; |
339 fLineWidth = 0; | 348 fLineWidth = 0; |
340 fTextLeading = 0; | 349 fTextLeading = 0; |
341 fWordSpace = 0; | 350 fWordSpace = 0; |
342 fCharSpace = 0; | 351 fCharSpace = 0; |
343 fHasClipPathToApply = false; | 352 fHasClipPathToApply = false; |
344 fResources = NULL; | 353 fResources = NULL; |
| 354 fSkFont = NULL; |
345 } | 355 } |
346 | 356 |
347 void applyGraphicsState(SkPaint* paint, bool stroking) { | 357 void applyGraphicsState(SkPaint* paint, bool stroking) { |
348 if (stroking) { | 358 if (stroking) { |
349 fStroking.applyGraphicsState(paint); | 359 fStroking.applyGraphicsState(paint); |
350 } else { | 360 } else { |
351 fNonStroking.applyGraphicsState(paint); | 361 fNonStroking.applyGraphicsState(paint); |
352 } | 362 } |
353 | 363 |
354 // TODO(edisonn): get this from pdfContext->options, | 364 // TODO(edisonn): get this from pdfContext->options, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 if (*pdfOp == '\0') return false; | 418 if (*pdfOp == '\0') return false; |
409 | 419 |
410 char markedPdfOp[100] = ","; | 420 char markedPdfOp[100] = ","; |
411 strcat(markedPdfOp, pdfOp); | 421 strcat(markedPdfOp, pdfOp); |
412 strcat(markedPdfOp, ","); | 422 strcat(markedPdfOp, ","); |
413 | 423 |
414 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); | 424 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); |
415 } | 425 } |
416 | 426 |
417 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum
entation. | 427 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum
entation. |
418 static bool readToken(SkPdfTokenizer fTokenizer, PdfToken* token) { | 428 static bool readToken(SkPdfTokenizer* fTokenizer, PdfToken* token) { |
419 bool ret = fTokenizer.readToken(token); | 429 bool ret = fTokenizer->readToken(token); |
420 | 430 |
421 gReadOp++; | 431 gReadOp++; |
422 | 432 |
423 #ifdef PDF_TRACE_DIFF_IN_PNG | 433 #ifdef PDF_TRACE_DIFF_IN_PNG |
424 // TODO(edisonn): compare with old bitmap, and save only new bits are availa
ble, and save | 434 // TODO(edisonn): compare with old bitmap, and save only new bits are availa
ble, and save |
425 // the numbar and name of last operation, so the file name will reflect op t
hat changed. | 435 // the numbar and name of last operation, so the file name will reflect op t
hat changed. |
426 if (hasVisualEffect(gLastKeyword)) { // TODO(edisonn): and has dirty bits. | 436 if (hasVisualEffect(gLastKeyword)) { // TODO(edisonn): and has dirty bits. |
427 gDumpCanvas->flush(); | 437 gDumpCanvas->flush(); |
428 | 438 |
429 SkBitmap bitmap; | 439 SkBitmap bitmap; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 } | 513 } |
504 #endif | 514 #endif |
505 | 515 |
506 return ret; | 516 return ret; |
507 } | 517 } |
508 | 518 |
509 // TODO(edisonn): Document PdfTokenLooper and subclasses. | 519 // TODO(edisonn): Document PdfTokenLooper and subclasses. |
510 class PdfTokenLooper { | 520 class PdfTokenLooper { |
511 protected: | 521 protected: |
512 PdfTokenLooper* fParent; | 522 PdfTokenLooper* fParent; |
513 SkPdfTokenizer fTokenizer; | 523 SkPdfTokenizer* fTokenizer; |
514 PdfContext* fPdfContext; | 524 PdfContext* fPdfContext; |
515 SkCanvas* fCanvas; | 525 SkCanvas* fCanvas; |
516 | 526 |
517 public: | 527 public: |
518 PdfTokenLooper(PdfTokenLooper* parent, | 528 PdfTokenLooper(PdfTokenLooper* parent, |
519 SkPdfTokenizer tokenizer, | 529 SkPdfTokenizer* tokenizer, |
520 PdfContext* pdfContext, | 530 PdfContext* pdfContext, |
521 SkCanvas* canvas) | 531 SkCanvas* canvas) |
522 : fParent(parent), fTokenizer(tokenizer), fPdfContext(pdfContext), fCanv
as(canvas) {} | 532 : fParent(parent), fTokenizer(tokenizer), fPdfContext(pdfContext), fCanv
as(canvas) {} |
523 | 533 |
524 virtual PdfResult consumeToken(PdfToken& token) = 0; | 534 virtual PdfResult consumeToken(PdfToken& token) = 0; |
525 virtual void loop() = 0; | 535 virtual void loop() = 0; |
526 | 536 |
527 void setUp(PdfTokenLooper* parent) { | 537 void setUp(PdfTokenLooper* parent) { |
528 fParent = parent; | 538 fParent = parent; |
529 fTokenizer = parent->fTokenizer; | 539 fTokenizer = parent->fTokenizer; |
530 fPdfContext = parent->fPdfContext; | 540 fPdfContext = parent->fPdfContext; |
531 fCanvas = parent->fCanvas; | 541 fCanvas = parent->fCanvas; |
532 } | 542 } |
533 }; | 543 }; |
534 | 544 |
535 class PdfMainLooper : public PdfTokenLooper { | 545 class PdfMainLooper : public PdfTokenLooper { |
536 public: | 546 public: |
537 PdfMainLooper(PdfTokenLooper* parent, | 547 PdfMainLooper(PdfTokenLooper* parent, |
538 SkPdfTokenizer tokenizer, | 548 SkPdfTokenizer* tokenizer, |
539 PdfContext* pdfContext, | 549 PdfContext* pdfContext, |
540 SkCanvas* canvas) | 550 SkCanvas* canvas) |
541 : PdfTokenLooper(parent, tokenizer, pdfContext, canvas) {} | 551 : PdfTokenLooper(parent, tokenizer, pdfContext, canvas) {} |
542 | 552 |
543 virtual PdfResult consumeToken(PdfToken& token); | 553 virtual PdfResult consumeToken(PdfToken& token); |
544 virtual void loop(); | 554 virtual void loop(); |
545 }; | 555 }; |
546 | 556 |
547 class PdfInlineImageLooper : public PdfTokenLooper { | 557 class PdfInlineImageLooper : public PdfTokenLooper { |
548 public: | 558 public: |
549 PdfInlineImageLooper() | 559 PdfInlineImageLooper() |
550 : PdfTokenLooper(NULL, SkPdfTokenizer(), NULL, NULL) {} | 560 : PdfTokenLooper(NULL, NULL, NULL, NULL) {} |
551 | 561 |
552 virtual PdfResult consumeToken(PdfToken& token); | 562 virtual PdfResult consumeToken(PdfToken& token); |
553 virtual void loop(); | 563 virtual void loop(); |
554 PdfResult done(); | 564 PdfResult done(); |
555 }; | 565 }; |
556 | 566 |
557 class PdfCompatibilitySectionLooper : public PdfTokenLooper { | 567 class PdfCompatibilitySectionLooper : public PdfTokenLooper { |
558 public: | 568 public: |
559 PdfCompatibilitySectionLooper() | 569 PdfCompatibilitySectionLooper() |
560 : PdfTokenLooper(NULL, SkPdfTokenizer(), NULL, NULL) {} | 570 : PdfTokenLooper(NULL, NULL, NULL, NULL) {} |
561 | 571 |
562 virtual PdfResult consumeToken(PdfToken& token); | 572 virtual PdfResult consumeToken(PdfToken& token); |
563 virtual void loop(); | 573 virtual void loop(); |
564 }; | 574 }; |
565 | 575 |
566 typedef PdfResult (*PdfOperatorRenderer)(PdfContext*, SkCanvas*, PdfTokenLooper*
*); | 576 typedef PdfResult (*PdfOperatorRenderer)(PdfContext*, SkCanvas*, PdfTokenLooper*
*); |
567 | 577 |
568 map<std::string, PdfOperatorRenderer> gPdfOps; | 578 map<std::string, PdfOperatorRenderer> gPdfOps; |
569 | 579 |
570 map<std::string, int> gRenderStats[kCount_PdfResult]; | 580 map<std::string, int> gRenderStats[kCount_PdfResult]; |
571 | 581 |
572 char* gRenderStatsNames[kCount_PdfResult] = { | 582 char* gRenderStatsNames[kCount_PdfResult] = { |
573 "Success", | 583 "Success", |
574 "Partially implemented", | 584 "Partially implemented", |
575 "Not yet implemented", | 585 "Not yet implemented", |
576 "Ignore Error", | 586 "Ignore Error", |
577 "Error", | 587 "Error", |
578 "Unsupported/Unknown" | 588 "Unsupported/Unknown" |
579 }; | 589 }; |
580 | 590 |
581 struct SkPdfStandardFont { | 591 static SkTypeface* SkTypefaceFromPdfFont(PdfFont* font) { |
582 const char* fName; | 592 if (font == NULL) { |
583 bool fIsBold; | 593 return SkTypeface::CreateFromName("Times New Roman", SkTypeface::kNormal
); |
584 bool fIsItalic; | |
585 }; | |
586 | |
587 static map<std::string, SkPdfStandardFont>& getStandardFonts() { | |
588 static std::map<std::string, SkPdfStandardFont> gPdfStandardFonts; | |
589 | |
590 // TODO (edisonn): , vs - ? what does it mean? | |
591 // TODO (edisonn): MT, PS, Oblique=italic?, ... what does it mean? | |
592 if (gPdfStandardFonts.empty()) { | |
593 gPdfStandardFonts["Arial"] = {"Arial", false, false}; | |
594 gPdfStandardFonts["Arial,Bold"] = {"Arial", true, false}; | |
595 gPdfStandardFonts["Arial,BoldItalic"] = {"Arial", true, true}; | |
596 gPdfStandardFonts["Arial,Italic"] = {"Arial", false, true}; | |
597 gPdfStandardFonts["Arial-Bold"] = {"Arial", true, false}; | |
598 gPdfStandardFonts["Arial-BoldItalic"] = {"Arial", true, true}; | |
599 gPdfStandardFonts["Arial-BoldItalicMT"] = {"Arial", true, true}; | |
600 gPdfStandardFonts["Arial-BoldMT"] = {"Arial", true, false}; | |
601 gPdfStandardFonts["Arial-Italic"] = {"Arial", false, true}; | |
602 gPdfStandardFonts["Arial-ItalicMT"] = {"Arial", false, true}; | |
603 gPdfStandardFonts["ArialMT"] = {"Arial", false, false}; | |
604 gPdfStandardFonts["Courier"] = {"Courier New", false, false}; | |
605 gPdfStandardFonts["Courier,Bold"] = {"Courier New", true, false}; | |
606 gPdfStandardFonts["Courier,BoldItalic"] = {"Courier New", true, true}; | |
607 gPdfStandardFonts["Courier,Italic"] = {"Courier New", false, true}; | |
608 gPdfStandardFonts["Courier-Bold"] = {"Courier New", true, false}; | |
609 gPdfStandardFonts["Courier-BoldOblique"] = {"Courier New", true, true}; | |
610 gPdfStandardFonts["Courier-Oblique"] = {"Courier New", false, true}; | |
611 gPdfStandardFonts["CourierNew"] = {"Courier New", false, false}; | |
612 gPdfStandardFonts["CourierNew,Bold"] = {"Courier New", true, false}; | |
613 gPdfStandardFonts["CourierNew,BoldItalic"] = {"Courier New", true, true}
; | |
614 gPdfStandardFonts["CourierNew,Italic"] = {"Courier New", false, true}; | |
615 gPdfStandardFonts["CourierNew-Bold"] = {"Courier New", true, false}; | |
616 gPdfStandardFonts["CourierNew-BoldItalic"] = {"Courier New", true, true}
; | |
617 gPdfStandardFonts["CourierNew-Italic"] = {"Courier New", false, true}; | |
618 gPdfStandardFonts["CourierNewPS-BoldItalicMT"] = {"Courier New", true, t
rue}; | |
619 gPdfStandardFonts["CourierNewPS-BoldMT"] = {"Courier New", true, false}; | |
620 gPdfStandardFonts["CourierNewPS-ItalicMT"] = {"Courier New", false, true
}; | |
621 gPdfStandardFonts["CourierNewPSMT"] = {"Courier New", false, false}; | |
622 gPdfStandardFonts["Helvetica"] = {"Helvetica", false, false}; | |
623 gPdfStandardFonts["Helvetica,Bold"] = {"Helvetica", true, false}; | |
624 gPdfStandardFonts["Helvetica,BoldItalic"] = {"Helvetica", true, true}; | |
625 gPdfStandardFonts["Helvetica,Italic"] = {"Helvetica", false, true}; | |
626 gPdfStandardFonts["Helvetica-Bold"] = {"Helvetica", true, false}; | |
627 gPdfStandardFonts["Helvetica-BoldItalic"] = {"Helvetica", true, true}; | |
628 gPdfStandardFonts["Helvetica-BoldOblique"] = {"Helvetica", true, true}; | |
629 gPdfStandardFonts["Helvetica-Italic"] = {"Helvetica", false, true}; | |
630 gPdfStandardFonts["Helvetica-Oblique"] = {"Helvetica", false, true}; | |
631 gPdfStandardFonts["Times-Bold"] = {"Times", true, false}; | |
632 gPdfStandardFonts["Times-BoldItalic"] = {"Times", true, true}; | |
633 gPdfStandardFonts["Times-Italic"] = {"Times", false, true}; | |
634 gPdfStandardFonts["Times-Roman"] = {"Times New Roman", false, false}; | |
635 gPdfStandardFonts["TimesNewRoman"] = {"Times New Roman", false, false}; | |
636 gPdfStandardFonts["TimesNewRoman,Bold"] = {"Times New Roman", true, fals
e}; | |
637 gPdfStandardFonts["TimesNewRoman,BoldItalic"] = {"Times New Roman", true
, true}; | |
638 gPdfStandardFonts["TimesNewRoman,Italic"] = {"Times New Roman", false, t
rue}; | |
639 gPdfStandardFonts["TimesNewRoman-Bold"] = {"Times New Roman", true, fals
e}; | |
640 gPdfStandardFonts["TimesNewRoman-BoldItalic"] = {"Times New Roman", true
, true}; | |
641 gPdfStandardFonts["TimesNewRoman-Italic"] = {"Times New Roman", false, t
rue}; | |
642 gPdfStandardFonts["TimesNewRomanPS"] = {"Times New Roman", false, false}
; | |
643 gPdfStandardFonts["TimesNewRomanPS-Bold"] = {"Times New Roman", true, fa
lse}; | |
644 gPdfStandardFonts["TimesNewRomanPS-BoldItalic"] = {"Times New Roman", tr
ue, true}; | |
645 gPdfStandardFonts["TimesNewRomanPS-BoldItalicMT"] = {"Times New Roman",
true, true}; | |
646 gPdfStandardFonts["TimesNewRomanPS-BoldMT"] = {"Times New Roman", true,
false}; | |
647 gPdfStandardFonts["TimesNewRomanPS-Italic"] = {"Times New Roman", false,
true}; | |
648 gPdfStandardFonts["TimesNewRomanPS-ItalicMT"] = {"Times New Roman", fals
e, true}; | |
649 gPdfStandardFonts["TimesNewRomanPSMT"] = {"Times New Roman", false, fals
e}; | |
650 } | 594 } |
651 | 595 |
652 return gPdfStandardFonts; | |
653 } | |
654 | |
655 static SkTypeface* SkTypefaceFromPdfStandardFont(const char* fontName, bool bold
, bool italic) { | |
656 map<std::string, SkPdfStandardFont>& standardFontMap = getStandardFonts(); | |
657 | |
658 if (standardFontMap.find(fontName) != standardFontMap.end()) { | |
659 SkPdfStandardFont fontData = standardFontMap[fontName]; | |
660 | |
661 // TODO(edisonn): How does the bold/italic specified in standard definit
ion combines with | |
662 // the one in /font key? use OR for now. | |
663 bold = bold || fontData.fIsBold; | |
664 italic = italic || fontData.fIsItalic; | |
665 | |
666 SkTypeface* typeface = SkTypeface::CreateFromName( | |
667 fontData.fName, | |
668 SkTypeface::Style((bold ? SkTypeface::kBold : 0) | | |
669 (italic ? SkTypeface::kItalic : 0))); | |
670 if (typeface) { | |
671 typeface->ref(); | |
672 } | |
673 return typeface; | |
674 } | |
675 return NULL; | |
676 } | |
677 | |
678 static SkTypeface* SkTypefaceFromPdfFont(PdfFont* font) { | |
679 PdfObject* fontObject = font->GetObject(); | 596 PdfObject* fontObject = font->GetObject(); |
680 | 597 |
681 PdfObject* pBaseFont = NULL; | 598 PdfObject* pBaseFont = NULL; |
682 // TODO(edisonn): warning, PoDoFo has a bug in PdfFont constructor, does not
call InitVars() | 599 // TODO(edisonn): warning, PoDoFo has a bug in PdfFont constructor, does not
call InitVars() |
683 // for now fixed locally. | 600 // for now fixed locally. |
684 pBaseFont = fontObject->GetIndirectKey( "BaseFont" ); | 601 pBaseFont = fontObject->GetIndirectKey( "BaseFont" ); |
685 const char* pszBaseFontName = pBaseFont->GetName().GetName().c_str(); | 602 const char* pszBaseFontName = pBaseFont->GetName().GetName().c_str(); |
686 | 603 |
687 #ifdef PDF_TRACE | 604 #ifdef PDF_TRACE |
688 std::string str; | 605 std::string str; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 printf("FONT_NOT_FOUND %s\n", pszBaseFontName); | 638 printf("FONT_NOT_FOUND %s\n", pszBaseFontName); |
722 #endif | 639 #endif |
723 | 640 |
724 // TODO(edisonn): Report Warning, NYI | 641 // TODO(edisonn): Report Warning, NYI |
725 return SkTypeface::CreateFromName( | 642 return SkTypeface::CreateFromName( |
726 "Times New Roman", | 643 "Times New Roman", |
727 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | | 644 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | |
728 (font->IsItalic() ? SkTypeface::kItalic : 0)))
; | 645 (font->IsItalic() ? SkTypeface::kItalic : 0)))
; |
729 } | 646 } |
730 | 647 |
| 648 |
731 // TODO(edisonn): move this code in podofo, so we don't have to fix the font. | 649 // TODO(edisonn): move this code in podofo, so we don't have to fix the font. |
732 // This logic needs to be moved in PdfEncodingObjectFactory::CreateEncoding | 650 // This logic needs to be moved in PdfEncodingObjectFactory::CreateEncoding |
733 std::map<PdfFont*, PdfCMapEncoding*> gFontsFixed; | 651 std::map<PdfFont*, PdfCMapEncoding*> gFontsFixed; |
734 PdfEncoding* FixPdfFont(PdfContext* pdfContext, PdfFont* fCurFont) { | 652 PdfEncoding* FixPdfFont(PdfContext* pdfContext, PdfFont* fCurFont) { |
735 // TODO(edisonn): and is Identity-H | 653 // TODO(edisonn): and is Identity-H |
736 if (gFontsFixed.find(fCurFont) == gFontsFixed.end()) { | 654 if (gFontsFixed.find(fCurFont) == gFontsFixed.end()) { |
737 if (fCurFont->GetObject()->IsDictionary() && fCurFont->GetObject()->GetD
ictionary().HasKey(PdfName("ToUnicode"))) { | 655 if (fCurFont->GetObject()->IsDictionary() && fCurFont->GetObject()->GetD
ictionary().HasKey(PdfName("ToUnicode"))) { |
738 PdfCMapEncoding* enc = new PdfCMapEncoding( | 656 PdfCMapEncoding* enc = new PdfCMapEncoding( |
739 fCurFont->GetObject(), | 657 fCurFont->GetObject(), |
740 (PdfObject*)resolveReferenceObject(&pdfContext->fPdfDoc.podo
fo(), | 658 (PdfObject*)resolveReferenceObject(&pdfContext->fPdfDoc.podo
fo(), |
741 fCurFont->GetObject()->GetDictionary(
).GetKey(PdfName("ToUnicode"))), | 659 fCurFont->GetObject()->GetDictionary(
).GetKey(PdfName("ToUnicode"))), |
742 PdfCMapEncoding::eBaseEncoding_Identity); // todo, read the
base encoding | 660 PdfCMapEncoding::eBaseEncoding_Identity); // todo, read the
base encoding |
743 gFontsFixed[fCurFont] = enc; | 661 gFontsFixed[fCurFont] = enc; |
744 return enc; | 662 return enc; |
745 } | 663 } |
746 | 664 |
747 return NULL; | 665 return NULL; |
748 } | 666 } |
749 | 667 |
750 return gFontsFixed[fCurFont]; | 668 return gFontsFixed[fCurFont]; |
751 } | 669 } |
752 | 670 |
753 PdfResult DrawText(PdfContext* pdfContext, | 671 PdfResult DrawText(PdfContext* pdfContext, |
754 PdfFont* fCurFont, | 672 const SkPdfObject* str, |
755 const PdfString& rString, | |
756 SkCanvas* canvas) | 673 SkCanvas* canvas) |
757 { | 674 { |
| 675 |
| 676 SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; |
| 677 if (skfont == NULL) { |
| 678 skfont = SkPdfFont::Default(); |
| 679 } |
| 680 |
| 681 SkUnencodedText binary(str); |
| 682 |
| 683 SkDecodedText decoded; |
| 684 skfont->encoding()->decodeText(binary, &decoded); |
| 685 |
| 686 SkUnicodeText unicode; |
| 687 skfont->ToUnicode(decoded, &unicode); |
| 688 |
| 689 SkPaint paint; |
| 690 // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCur
FontSize == 0? |
| 691 // Or maybe just not call setTextSize at all? |
| 692 if (pdfContext->fGraphicsState.fCurFontSize != 0) { |
| 693 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); |
| 694 } |
| 695 |
| 696 // if (fCurFont && fCurFont->GetFontScale() != 0) { |
| 697 // paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0))
; |
| 698 // } |
| 699 |
| 700 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
| 701 |
| 702 canvas->save(); |
| 703 |
| 704 #if 1 |
| 705 SkMatrix matrix = pdfContext->fGraphicsState.fMatrixTm; |
| 706 |
| 707 SkPoint point1; |
| 708 pdfContext->fGraphicsState.fMatrixTm.mapXY(SkIntToScalar(0), SkIntToScalar(0
), &point1); |
| 709 |
| 710 SkMatrix mirror; |
| 711 mirror.setTranslate(0, -point1.y()); |
| 712 // TODO(edisonn): fix rotated text, and skewed too |
| 713 mirror.postScale(SK_Scalar1, -SK_Scalar1); |
| 714 // TODO(edisonn): post rotate, skew |
| 715 mirror.postTranslate(0, point1.y()); |
| 716 |
| 717 matrix.postConcat(mirror); |
| 718 |
| 719 canvas->setMatrix(matrix); |
| 720 |
| 721 SkTraceMatrix(matrix, "mirrored"); |
| 722 #endif |
| 723 |
| 724 skfont->drawText(unicode, &paint, canvas, &pdfContext->fGraphicsState.fMatri
xTm); |
| 725 canvas->restore(); |
| 726 |
| 727 /* |
| 728 PdfString& rString = str->podofo()->GetString(); |
| 729 |
| 730 //pdfContext->fGraphicsState.fSkFont->GetDecoding()->ToUnicode(rString); |
| 731 //void* text; |
| 732 //int len; |
| 733 //SkPaint paint; |
| 734 //pdfContext->fGraphicsState.fSkFont->drawText(text, len, paint, canvas, &pd
fContext->fGraphicsState.fMatrixTm); |
| 735 |
| 736 PdfFont* fCurFont = pdfContext->fGraphicsState.fCurFont; |
| 737 |
758 if (!fCurFont) | 738 if (!fCurFont) |
759 { | 739 { |
760 // TODO(edisonn): ignore the error, use the default font? | 740 // TODO(edisonn): ignore the error, use the default font? |
761 return kError_PdfResult; | 741 // return kError_PdfResult; |
762 } | 742 } |
763 | 743 |
764 const PdfEncoding* enc = FixPdfFont(pdfContext, fCurFont); | 744 const PdfEncoding* enc = fCurFont ? FixPdfFont(pdfContext, fCurFont) : NULL; |
765 bool cMapUnicodeFont = enc != NULL; | 745 bool cMapUnicodeFont = enc != NULL; |
766 if (!enc) enc = fCurFont->GetEncoding(); | 746 if (!enc) enc = fCurFont ? fCurFont->GetEncoding() : NULL; |
767 if (!enc) | 747 if (!enc) |
768 { | 748 { |
769 // TODO(edisonn): Can we recover from this error? | 749 // TODO(edisonn): Can we recover from this error? |
770 return kError_PdfResult; | 750 //return kError_PdfResult; |
771 } | 751 } |
772 | 752 |
773 PdfString r2 = rString; | 753 PdfString r2 = rString; |
774 PdfString unicode; | 754 PdfString unicode; |
775 | 755 |
776 if (cMapUnicodeFont) { | 756 if (cMapUnicodeFont) { |
777 r2 = PdfString((pdf_utf16be*)rString.GetString(), rString.GetLength() /
2); | 757 r2 = PdfString((pdf_utf16be*)rString.GetString(), rString.GetLength() /
2); |
778 } | 758 } |
779 | 759 |
780 unicode = enc->ConvertToUnicode( r2, fCurFont ); | 760 unicode = enc ? enc->ConvertToUnicode( r2, fCurFont ) : r2.ToUnicode(); |
781 | 761 |
782 #ifdef PDF_TRACE | 762 #ifdef PDF_TRACE |
783 printf("%i %i ? %c rString.len = %i\n", (int)rString.GetString()[0], (int)rS
tring.GetString()[1], (int)rString.GetString()[1], rString.GetLength()); | 763 printf("%i %i ? %c rString.len = %i\n", (int)rString.GetString()[0], (int)rS
tring.GetString()[1], (int)rString.GetString()[1], rString.GetLength()); |
784 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()); | 764 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()); |
785 #endif | 765 #endif |
786 | 766 |
787 SkPaint paint; | 767 SkPaint paint; |
788 // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCur
FontSize == 0? | 768 // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCur
FontSize == 0? |
789 // Or maybe just not call setTextSize at all? | 769 // Or maybe just not call setTextSize at all? |
790 if (pdfContext->fGraphicsState.fCurFontSize != 0) { | 770 if (pdfContext->fGraphicsState.fCurFontSize != 0) { |
791 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); | 771 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); |
792 } | 772 } |
793 if (fCurFont->GetFontScale() != 0) { | 773 if (fCurFont && fCurFont->GetFontScale() != 0) { |
794 paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0)); | 774 paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0)); |
795 } | 775 } |
796 | 776 |
797 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); | 777 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
798 | 778 |
799 paint.setTypeface(SkTypefaceFromPdfFont(fCurFont)); | 779 paint.setTypeface(SkTypefaceFromPdfFont(fCurFont)); |
800 | 780 |
801 paint.setAntiAlias(true); | |
802 // TODO(edisonn): paint.setStyle(...); | |
803 | |
804 canvas->save(); | 781 canvas->save(); |
805 SkMatrix matrix = pdfContext->fGraphicsState.fMatrixTm; | 782 SkMatrix matrix = pdfContext->fGraphicsState.fMatrixTm; |
806 | 783 |
807 #if 0 | 784 #if 0 |
808 // Reverse now the space, otherwise the text is upside down. | 785 // Reverse now the space, otherwise the text is upside down. |
809 SkScalar z = SkIntToScalar(0); | 786 SkScalar z = SkIntToScalar(0); |
810 SkScalar one = SkIntToScalar(1); | 787 SkScalar one = SkIntToScalar(1); |
811 | 788 |
812 SkPoint normalSpace1[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), SkPoi
nt::Make(one, one), SkPoint::Make(z, one)}; | 789 SkPoint normalSpace1[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), SkPoi
nt::Make(one, one), SkPoint::Make(z, one)}; |
813 SkPoint mirrorSpace1[4]; | 790 SkPoint mirrorSpace1[4]; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 // unsigned char ch = *(unicode.GetString() + 3); | 862 // unsigned char ch = *(unicode.GetString() + 3); |
886 // if ((ch & 0xC0) != 0x80 && ch < 0x80) { | 863 // if ((ch & 0xC0) != 0x80 && ch < 0x80) { |
887 // printf("x%i", ch); | 864 // printf("x%i", ch); |
888 // SkScalar textWidth = paint.measureText(&ch, 1); | 865 // SkScalar textWidth = paint.measureText(&ch, 1); |
889 // pdfContext->fGraphicsState.fMatrixTm.preTranslate(textWidth, SkDoubleT
oScalar(0.0)); | 866 // pdfContext->fGraphicsState.fMatrixTm.preTranslate(textWidth, SkDoubleT
oScalar(0.0)); |
890 // canvas->drawText(&ch, 1, SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
paint); | 867 // canvas->drawText(&ch, 1, SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
paint); |
891 // } | 868 // } |
892 | 869 |
893 canvas->restore(); | 870 canvas->restore(); |
894 | 871 |
895 | 872 */ |
896 return kPartial_PdfResult; | 873 return kPartial_PdfResult; |
897 } | 874 } |
898 | 875 |
899 // TODO(edisonn): create header files with declarations! | 876 // TODO(edisonn): create header files with declarations! |
900 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); | 877 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); |
901 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); | 878 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
per); |
902 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); | 879 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); |
903 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); | 880 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper); |
904 | 881 |
905 // TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in Get
Key? | 882 // TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in Get
Key? |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, | 1098 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, |
1122 const PdfDictionary& dict, | 1099 const PdfDictionary& dict, |
1123 const char* key, | 1100 const char* key, |
1124 const char* abr, | 1101 const char* abr, |
1125 SkPdfObject** data) { | 1102 SkPdfObject** data) { |
1126 if (ObjectFromDictionary(pdfDoc, dict, key, data)) return true; | 1103 if (ObjectFromDictionary(pdfDoc, dict, key, data)) return true; |
1127 if (abr == NULL || *abr == '\0') return false; | 1104 if (abr == NULL || *abr == '\0') return false; |
1128 return ObjectFromDictionary(pdfDoc, dict, abr, data); | 1105 return ObjectFromDictionary(pdfDoc, dict, abr, data); |
1129 } | 1106 } |
1130 | 1107 |
| 1108 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, |
| 1109 const PdfDictionary& dict, |
| 1110 const char* key, |
| 1111 SkPdfStream** data) { |
| 1112 const PdfObject* value = resolveReferenceObject(pdfDoc, |
| 1113 dict.GetKey(PdfName(key)), |
| 1114 true); |
| 1115 if (value == NULL) { |
| 1116 return false; |
| 1117 } |
| 1118 if (data == NULL) { |
| 1119 return true; |
| 1120 } |
| 1121 return PodofoMapper::map(*pdfDoc, *value, data); |
| 1122 } |
| 1123 |
| 1124 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, |
| 1125 const PdfDictionary& dict, |
| 1126 const char* key, |
| 1127 const char* abr, |
| 1128 SkPdfStream** data) { |
| 1129 if (StreamFromDictionary(pdfDoc, dict, key, data)) return true; |
| 1130 if (abr == NULL || *abr == '\0') return false; |
| 1131 return StreamFromDictionary(pdfDoc, dict, abr, data); |
| 1132 } |
1131 | 1133 |
1132 | 1134 |
1133 // TODO(edisonn): perf!!! | 1135 // TODO(edisonn): perf!!! |
1134 | 1136 |
1135 static SkColorTable* getGrayColortable() { | 1137 static SkColorTable* getGrayColortable() { |
1136 static SkColorTable* grayColortable = NULL; | 1138 static SkColorTable* grayColortable = NULL; |
1137 if (grayColortable == NULL) { | 1139 if (grayColortable == NULL) { |
1138 SkPMColor* colors = new SkPMColor[256]; | 1140 SkPMColor* colors = new SkPMColor[256]; |
1139 for (int i = 0 ; i < 256; i++) { | 1141 for (int i = 0 ; i < 256; i++) { |
1140 colors[i] = SkPreMultiplyARGB(255, i, i, i); | 1142 colors[i] = SkPreMultiplyARGB(255, i, i, i); |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 1494 canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); |
1493 | 1495 |
1494 SkRect bbox; | 1496 SkRect bbox; |
1495 if (SkRectFromDictionary(&pdfContext->fPdfDoc.podofo(), skobj->podofo()->Get
Dictionary(), "BBox", &bbox)) { | 1497 if (SkRectFromDictionary(&pdfContext->fPdfDoc.podofo(), skobj->podofo()->Get
Dictionary(), "BBox", &bbox)) { |
1496 canvas->clipRect(bbox, SkRegion::kIntersect_Op, true); // TODO(edisonn)
: AA from settings. | 1498 canvas->clipRect(bbox, SkRegion::kIntersect_Op, true); // TODO(edisonn)
: AA from settings. |
1497 } | 1499 } |
1498 | 1500 |
1499 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. | 1501 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. |
1500 // For this PdfContentsTokenizer needs to be extended. | 1502 // For this PdfContentsTokenizer needs to be extended. |
1501 | 1503 |
1502 char* uncompressedStream = NULL; | |
1503 pdf_long uncompressedStreamLength = 0; | |
1504 | |
1505 PdfResult ret = kPartial_PdfResult; | 1504 PdfResult ret = kPartial_PdfResult; |
1506 | 1505 SkPdfTokenizer tokenizer(skobj); |
1507 // TODO(edisonn): get rid of try/catch exceptions! We should not throw on us
er data! | 1506 PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas); |
1508 try { | 1507 looper.loop(); |
1509 skobj->podofo()->GetStream()->GetFilteredCopy(&uncompressedStream, &unco
mpressedStreamLength); | |
1510 if (uncompressedStream != NULL && uncompressedStreamLength != 0) { | |
1511 SkPdfTokenizer tokenizer = pdfContext->fPdfDoc.tokenizerOfStream(unc
ompressedStream, uncompressedStreamLength); | |
1512 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); | |
1513 looper.loop(); | |
1514 } | |
1515 free(uncompressedStream); | |
1516 } catch (PdfError& e) { | |
1517 ret = kIgnoreError_PdfResult; | |
1518 } | |
1519 | 1508 |
1520 // TODO(edisonn): should we restore the variable stack at the same state? | 1509 // TODO(edisonn): should we restore the variable stack at the same state? |
1521 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | 1510 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. |
1522 canvas->restore(); | 1511 canvas->restore(); |
1523 PdfOp_Q(pdfContext, canvas, NULL); | 1512 PdfOp_Q(pdfContext, canvas, NULL); |
1524 return ret; | 1513 return ret; |
1525 } | 1514 } |
1526 | 1515 |
1527 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
& obj) { | 1516 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
& obj) { |
1528 return kNYI_PdfResult; | 1517 return kNYI_PdfResult; |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 //a number representing a scale factor. There is no initial value for either fon
t or | 1952 //a number representing a scale factor. There is no initial value for either fon
t or |
1964 //size; they must be specified explicitly using Tf before any text is shown. | 1953 //size; they must be specified explicitly using Tf before any text is shown. |
1965 PdfResult PdfOp_Tf(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 1954 PdfResult PdfOp_Tf(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1966 pdfContext->fGraphicsState.fCurFontSize = pdfContext->fObjectStack.top()->as
Number()->value(); pdfContext->fObjectStack.pop(); | 1955 pdfContext->fGraphicsState.fCurFontSize = pdfContext->fObjectStack.top()->as
Number()->value(); pdfContext->fObjectStack.pop(); |
1967 std::string fontName = pdfContext->fObjectStack.top()->asName()->value();
pdfContext->fObjectStack.pop(); | 1956 std::string fontName = pdfContext->fObjectStack.top()->asName()->value();
pdfContext->fObjectStack.pop(); |
1968 | 1957 |
1969 #ifdef PDF_TRACE | 1958 #ifdef PDF_TRACE |
1970 printf("font name: %s\n", fontName.c_str()); | 1959 printf("font name: %s\n", fontName.c_str()); |
1971 std::string str; | 1960 std::string str; |
1972 pdfContext->fGraphicsState.fResources->podofo()->ToString(str); | 1961 pdfContext->fGraphicsState.fResources->podofo()->ToString(str); |
1973 printf("Print Tf font Resources: %s\n", str.c_str()); | 1962 printf("Print Tf Resources: %s\n", str.c_str()); |
| 1963 pdfContext->fGraphicsState.fResources->Font()->podofo()->ToString(str); |
| 1964 printf("Print Tf Resources/Font: %s\n", str.c_str()); |
1974 #endif | 1965 #endif |
1975 | 1966 |
| 1967 SkPdfFontDictionary* fd = NULL; |
| 1968 if (pdfContext->fGraphicsState.fResources->Font()) { |
| 1969 SkPdfObject objFont = pdfContext->fGraphicsState.fResources->Font()->get
(fontName.c_str()); |
| 1970 PodofoMapper::map(objFont, &fd); |
| 1971 |
| 1972 #ifdef PDF_TRACE |
| 1973 objFont.podofo()->ToString(str); |
| 1974 printf("Print Font loaded: %s\n", str.c_str()); |
| 1975 fd->podofo()->ToString(str); |
| 1976 printf("Print Font loaded and resolved and upgraded: %s\n", str.c_str())
; |
| 1977 #endif |
| 1978 |
| 1979 } |
| 1980 |
| 1981 SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(fd); |
| 1982 |
| 1983 if (skfont) { |
| 1984 pdfContext->fGraphicsState.fSkFont = skfont; |
| 1985 } |
| 1986 |
1976 // TODO(edisonn): Load font from pdfContext->fGraphicsState.fObjectWithResou
rces ? | 1987 // TODO(edisonn): Load font from pdfContext->fGraphicsState.fObjectWithResou
rces ? |
1977 const PdfObject* pFont = resolveReferenceObject(&pdfContext->fPdfDoc.podofo(
), | 1988 const PdfObject* pFont = resolveReferenceObject(&pdfContext->fPdfDoc.podofo(
), |
1978 pdfContext->fGraphicsState.f
Resources->Font()->get(fontName.c_str()).podofo()); | 1989 pdfContext->fGraphicsState.f
Resources->Font()->get(fontName.c_str()).podofo()); |
1979 if( !pFont ) | 1990 if( !pFont ) |
1980 { | 1991 { |
1981 // TODO(edisonn): try to ignore the error, make sure we do not crash. | 1992 // TODO(edisonn): try to ignore the error, make sure we do not crash. |
1982 return kIgnoreError_PdfResult; | 1993 return kIgnoreError_PdfResult; |
1983 } | 1994 } |
1984 | 1995 |
1985 pdfContext->fGraphicsState.fCurFont = pdfContext->fPdfDoc.podofo().GetFont(
(PdfObject*)pFont ); | 1996 PdfFont* font = pdfContext->fPdfDoc.podofo().GetFont( (PdfObject*)pFont ); |
1986 if( !pdfContext->fGraphicsState.fCurFont ) | 1997 if (font) { |
1987 { | 1998 pdfContext->fGraphicsState.fCurFont = font; |
| 1999 } else { |
1988 // TODO(edisonn): check ~/crasing, for one of the files PoDoFo throws ex
ception | 2000 // TODO(edisonn): check ~/crasing, for one of the files PoDoFo throws ex
ception |
1989 // when calling pFont->Reference(), with Linked list corruption. | 2001 // when calling pFont->Reference(), with Linked list corruption. |
1990 return kIgnoreError_PdfResult; | 2002 return kIgnoreError_PdfResult; |
1991 } | 2003 } |
1992 | 2004 |
1993 return kPartial_PdfResult; | 2005 return kPartial_PdfResult; |
1994 } | 2006 } |
1995 | 2007 |
1996 PdfResult PdfOp_Tj(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { | 2008 PdfResult PdfOp_Tj(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
oper) { |
1997 if (!pdfContext->fGraphicsState.fTextBlock) { | 2009 if (!pdfContext->fGraphicsState.fTextBlock) { |
1998 // TODO(edisonn): try to recover and draw it any way? | 2010 // TODO(edisonn): try to recover and draw it any way? |
1999 return kIgnoreError_PdfResult; | 2011 return kIgnoreError_PdfResult; |
2000 } | 2012 } |
2001 | 2013 |
2002 PdfResult ret = DrawText(pdfContext, | 2014 PdfResult ret = DrawText(pdfContext, |
2003 pdfContext->fGraphicsState.fCurFont, | 2015 pdfContext->fObjectStack.top(), |
2004 pdfContext->fObjectStack.top()->podofo()->GetString
(), | |
2005 canvas); | 2016 canvas); |
2006 pdfContext->fObjectStack.pop(); | 2017 pdfContext->fObjectStack.pop(); |
2007 | 2018 |
2008 return ret; | 2019 return ret; |
2009 } | 2020 } |
2010 | 2021 |
2011 PdfResult PdfOp_quote(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper) { | 2022 PdfResult PdfOp_quote(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper) { |
2012 if (!pdfContext->fGraphicsState.fTextBlock) { | 2023 if (!pdfContext->fGraphicsState.fTextBlock) { |
2013 // TODO(edisonn): try to recover and draw it any way? | 2024 // TODO(edisonn): try to recover and draw it any way? |
2014 return kIgnoreError_PdfResult; | 2025 return kIgnoreError_PdfResult; |
(...skipping 30 matching lines...) Expand all Loading... |
2045 if (!pdfContext->fGraphicsState.fTextBlock) { | 2056 if (!pdfContext->fGraphicsState.fTextBlock) { |
2046 // TODO(edisonn): try to recover and draw it any way? | 2057 // TODO(edisonn): try to recover and draw it any way? |
2047 return kIgnoreError_PdfResult; | 2058 return kIgnoreError_PdfResult; |
2048 } | 2059 } |
2049 | 2060 |
2050 SkPdfArray* array = pdfContext->fObjectStack.top()->asArray(); | 2061 SkPdfArray* array = pdfContext->fObjectStack.top()->asArray(); |
2051 pdfContext->fObjectStack.pop(); | 2062 pdfContext->fObjectStack.pop(); |
2052 | 2063 |
2053 for( int i=0; i<static_cast<int>(array->size()); i++ ) | 2064 for( int i=0; i<static_cast<int>(array->size()); i++ ) |
2054 { | 2065 { |
2055 if( (*array)[i].asString()) { | 2066 if( (*array)[i]->asString()) { |
| 2067 SkPdfObject* obj = (*array)[i]; |
2056 DrawText(pdfContext, | 2068 DrawText(pdfContext, |
2057 pdfContext->fGraphicsState.fCurFont, | 2069 obj, |
2058 (*array)[i].podofo()->GetString(), | 2070 canvas); |
2059 canvas); | 2071 } else if ((*array)[i]->asInteger() || (*array)[i]->asNumber()) { |
2060 } else if ((*array)[i].asInteger() || (*array)[i].asNumber()) { | 2072 double dx = (*array)[i]->asNumber()->value(); |
2061 double dx = (*array)[i].asNumber()->value(); | |
2062 SkMatrix matrix; | 2073 SkMatrix matrix; |
2063 matrix.setAll(SkDoubleToScalar(1), | 2074 matrix.setAll(SkDoubleToScalar(1), |
2064 SkDoubleToScalar(0), | 2075 SkDoubleToScalar(0), |
2065 // TODO(edisonn): use writing mode, vertical/horizonta
l. | 2076 // TODO(edisonn): use writing mode, vertical/horizonta
l. |
2066 SkDoubleToScalar(-dx), // amount is substracted!!! | 2077 SkDoubleToScalar(-dx), // amount is substracted!!! |
2067 SkDoubleToScalar(0), | 2078 SkDoubleToScalar(0), |
2068 SkDoubleToScalar(1), | 2079 SkDoubleToScalar(1), |
2069 SkDoubleToScalar(0), | 2080 SkDoubleToScalar(0), |
2070 SkDoubleToScalar(0), | 2081 SkDoubleToScalar(0), |
2071 SkDoubleToScalar(0), | 2082 SkDoubleToScalar(0), |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2610 for (iter = gRenderStats[i].begin(); iter != gRenderStats[i].end(); ++it
er) { | 2621 for (iter = gRenderStats[i].begin(); iter != gRenderStats[i].end(); ++it
er) { |
2611 printf("%s: %s -> count %i\n", gRenderStatsNames[i], iter->first.c_s
tr(), iter->second); | 2622 printf("%s: %s -> count %i\n", gRenderStatsNames[i], iter->first.c_s
tr(), iter->second); |
2612 } | 2623 } |
2613 } | 2624 } |
2614 } | 2625 } |
2615 | 2626 |
2616 PdfResult PdfMainLooper::consumeToken(PdfToken& token) { | 2627 PdfResult PdfMainLooper::consumeToken(PdfToken& token) { |
2617 if (token.fType == kKeyword_TokenType) | 2628 if (token.fType == kKeyword_TokenType) |
2618 { | 2629 { |
2619 // TODO(edisonn): log trace flag (verbose, error, info, warning, ...) | 2630 // TODO(edisonn): log trace flag (verbose, error, info, warning, ...) |
2620 #ifdef PDF_TRACE | |
2621 printf("KEYWORD: %s\n", token.fKeyword); | |
2622 #endif | |
2623 PdfOperatorRenderer pdfOperatorRenderer = gPdfOps[token.fKeyword]; | 2631 PdfOperatorRenderer pdfOperatorRenderer = gPdfOps[token.fKeyword]; |
2624 if (pdfOperatorRenderer) { | 2632 if (pdfOperatorRenderer) { |
2625 // caller, main work is done by pdfOperatorRenderer(...) | 2633 // caller, main work is done by pdfOperatorRenderer(...) |
2626 PdfTokenLooper* childLooper = NULL; | 2634 PdfTokenLooper* childLooper = NULL; |
2627 gRenderStats[pdfOperatorRenderer(fPdfContext, fCanvas, &childLooper)
][token.fKeyword]++; | 2635 gRenderStats[pdfOperatorRenderer(fPdfContext, fCanvas, &childLooper)
][token.fKeyword]++; |
2628 | 2636 |
2629 if (childLooper) { | 2637 if (childLooper) { |
2630 childLooper->setUp(this); | 2638 childLooper->setUp(this); |
2631 childLooper->loop(); | 2639 childLooper->loop(); |
2632 delete childLooper; | 2640 delete childLooper; |
2633 } | 2641 } |
2634 } else { | 2642 } else { |
2635 gRenderStats[kUnsupported_PdfResult][token.fKeyword]++; | 2643 gRenderStats[kUnsupported_PdfResult][token.fKeyword]++; |
2636 } | 2644 } |
2637 } | 2645 } |
2638 else if (token.fType == kObject_TokenType) | 2646 else if (token.fType == kObject_TokenType) |
2639 { | 2647 { |
2640 #ifdef PDF_TRACE | |
2641 std::string _var; | |
2642 token.fObject->podofo()->ToString(_var); | |
2643 printf("var: %s\n", _var.c_str()); | |
2644 #endif | |
2645 fPdfContext->fObjectStack.push( token.fObject ); | 2648 fPdfContext->fObjectStack.push( token.fObject ); |
2646 } | 2649 } |
2647 else if ( token.fType == kImageData_TokenType) { | 2650 else if ( token.fType == kImageData_TokenType) { |
2648 // TODO(edisonn): implement inline image. | 2651 // TODO(edisonn): implement inline image. |
2649 } | 2652 } |
2650 else { | 2653 else { |
2651 return kIgnoreError_PdfResult; | 2654 return kIgnoreError_PdfResult; |
2652 } | 2655 } |
2653 return kOK_PdfResult; | 2656 return kOK_PdfResult; |
2654 } | 2657 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2770 | 2773 |
2771 SkBitmap bitmap; | 2774 SkBitmap bitmap; |
2772 #ifdef PDF_DEBUG_3X | 2775 #ifdef PDF_DEBUG_3X |
2773 setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3
* (int)SkScalarToDouble(rect.height())) | 2776 setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3
* (int)SkScalarToDouble(rect.height())) |
2774 #else | 2777 #else |
2775 setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)
SkScalarToDouble(rect.height())); | 2778 setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)
SkScalarToDouble(rect.height())); |
2776 #endif | 2779 #endif |
2777 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (bitmap))); | 2780 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (bitmap))); |
2778 SkCanvas canvas(device); | 2781 SkCanvas canvas(device); |
2779 | 2782 |
2780 SkPdfTokenizer tokenizer = doc.tokenizerOfPage(pn); | 2783 SkPdfTokenizer* tokenizer = doc.tokenizerOfPage(pn); |
2781 | 2784 |
2782 PdfContext pdfContext(doc); | 2785 PdfContext pdfContext(doc); |
2783 pdfContext.fOriginalMatrix = SkMatrix::I(); | 2786 pdfContext.fOriginalMatrix = SkMatrix::I(); |
2784 pdfContext.fGraphicsState.fResources = NULL; | 2787 pdfContext.fGraphicsState.fResources = NULL; |
2785 PodofoMapper::map(*page->Resources(), &pdfContext.fGraphicsState
.fResources); | 2788 PodofoMapper::map(*page->Resources(), &pdfContext.fGraphicsState
.fResources); |
2786 | 2789 |
2787 gPdfContext = &pdfContext; | 2790 gPdfContext = &pdfContext; |
2788 gDumpBitmap = &bitmap; | 2791 gDumpBitmap = &bitmap; |
2789 gDumpCanvas = &canvas; | 2792 gDumpCanvas = &canvas; |
2790 | 2793 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2827 | 2830 |
2828 canvas.setMatrix(pdfContext.fOriginalMatrix); | 2831 canvas.setMatrix(pdfContext.fOriginalMatrix); |
2829 | 2832 |
2830 #ifndef PDF_DEBUG_NO_PAGE_CLIPING | 2833 #ifndef PDF_DEBUG_NO_PAGE_CLIPING |
2831 canvas.clipRect(SkRect::MakeXYWH(z, z, w, h), SkRegion::kInterse
ct_Op, true); | 2834 canvas.clipRect(SkRect::MakeXYWH(z, z, w, h), SkRegion::kInterse
ct_Op, true); |
2832 #endif | 2835 #endif |
2833 | 2836 |
2834 PdfMainLooper looper(NULL, tokenizer, &pdfContext, &canvas); | 2837 PdfMainLooper looper(NULL, tokenizer, &pdfContext, &canvas); |
2835 looper.loop(); | 2838 looper.loop(); |
2836 | 2839 |
| 2840 delete tokenizer; |
| 2841 |
2837 canvas.flush(); | 2842 canvas.flush(); |
2838 | 2843 |
2839 SkString out; | 2844 SkString out; |
2840 out.appendf("%s-%i.png", inputFileName.c_str(), pn); | 2845 out.appendf("%s-%i.png", inputFileName.c_str(), pn); |
2841 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::
kPNG_Type, 100); | 2846 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::
kPNG_Type, 100); |
2842 } | 2847 } |
2843 return true; | 2848 return true; |
2844 } | 2849 } |
2845 } | 2850 } |
2846 catch( PdfError & e ) | 2851 catch( PdfError & e ) |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3060 } | 3065 } |
3061 | 3066 |
3062 return 0; | 3067 return 0; |
3063 } | 3068 } |
3064 | 3069 |
3065 #if !defined SK_BUILD_FOR_IOS | 3070 #if !defined SK_BUILD_FOR_IOS |
3066 int main(int argc, char * const argv[]) { | 3071 int main(int argc, char * const argv[]) { |
3067 return tool_main(argc, (char**) argv); | 3072 return tool_main(argc, (char**) argv); |
3068 } | 3073 } |
3069 #endif | 3074 #endif |
OLD | NEW |