| 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 19 matching lines...) Expand all  Loading... | 
| 30 | 30 | 
| 31 // TODO(edisonn): tool, show what objects were read at least, show the ones not 
      even read | 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 | 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 | 33 // plug in for VS? syntax coloring, show selected object ... from the text, or f
      rom rendered x,y | 
| 34 | 34 | 
| 35 // TODO(edisonn): security - validate all the user input, all pdf! | 35 // TODO(edisonn): security - validate all the user input, all pdf! | 
| 36 | 36 | 
| 37 // TODO(edisonn): put drawtext in #ifdefs, so comparations will ignore minor cha
      nges in text positioning and font | 37 // TODO(edisonn): put drawtext in #ifdefs, so comparations will ignore minor cha
      nges in text positioning and font | 
| 38 // this way, we look more at other features and layout in diffs | 38 // this way, we look more at other features and layout in diffs | 
| 39 | 39 | 
|  | 40 // TODO(edisonn): move trace dump in the get functions, and mapper ones too so i
      t ghappens automatically | 
|  | 41 /* | 
|  | 42 #ifdef PDF_TRACE | 
|  | 43     std::string str; | 
|  | 44     pdfContext->fGraphicsState.fResources->podofo()->ToString(str); | 
|  | 45     printf("Print Tf Resources: %s\n", str.c_str()); | 
|  | 46 #endif | 
|  | 47  */ | 
|  | 48 | 
| 40 #include "SkPdfHeaders_autogen.h" | 49 #include "SkPdfHeaders_autogen.h" | 
| 41 #include "SkPdfPodofoMapper_autogen.h" | 50 #include "SkPdfMapper_autogen.h" | 
| 42 #include "SkPdfParser.h" | 51 #include "SkPdfParser.h" | 
| 43 | 52 | 
| 44 #include "SkPdfBasics.h" | 53 #include "SkPdfBasics.h" | 
| 45 #include "SkPdfUtils.h" | 54 #include "SkPdfUtils.h" | 
| 46 | 55 | 
| 47 #include "SkPdfFont.h" | 56 #include "SkPdfFont.h" | 
| 48 | 57 | 
| 49 bool skpdfmap(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdf
      Object** out) { |  | 
| 50     return mapObject(podofoDoc, podofoObj, out); |  | 
| 51 } |  | 
| 52 |  | 
| 53 |  | 
| 54 /* | 58 /* | 
| 55  * TODO(edisonn): | 59  * TODO(edisonn): | 
| 56  * - all font types and all ppdf font features | 60  * - all font types and all ppdf font features | 
| 57  *      - word spacing | 61  *      - word spacing | 
| 58  *      - load font for baidu.pdf | 62  *      - load font for baidu.pdf | 
| 59  *      - load font for youtube.pdf | 63  *      - load font for youtube.pdf | 
| 60  *      - parser for pdf from the definition already available in pdfspec_autoge
      n.py | 64  *      - parser for pdf from the definition already available in pdfspec_autoge
      n.py | 
| 61  *      - all docs from ~/work | 65  *      - all docs from ~/work | 
| 62  * - encapsulate podofo in the pdf api so the skpdf does not know anything about
       podofo ... in progress | 66  * - encapsulate podofo in the pdf api so the skpdf does not know anything about
       podofo ... in progress | 
| 63  * - load gs/ especially smask and already known prop (skp) ... in progress | 67  * - load gs/ especially smask and already known prop (skp) ... in progress | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 90         return 1; | 94         return 1; | 
| 91     } else if (colorSpace == "DeviceRGB" || | 95     } else if (colorSpace == "DeviceRGB" || | 
| 92             colorSpace == "CalRGB" || | 96             colorSpace == "CalRGB" || | 
| 93             colorSpace == "Lab") { | 97             colorSpace == "Lab") { | 
| 94         return 3; | 98         return 3; | 
| 95     } else { | 99     } else { | 
| 96         return 0; | 100         return 0; | 
| 97     } | 101     } | 
| 98 } | 102 } | 
| 99 | 103 | 
| 100 const PdfObject* resolveReferenceObject(const PdfMemDocument* pdfDoc, | 104 SkMatrix SkMatrixFromPdfMatrix(double array[6]) { | 
| 101                                   const PdfObject* obj, |  | 
| 102                                   bool resolveOneElementArrays) { |  | 
| 103     while (obj && (obj->IsReference() || (resolveOneElementArrays && |  | 
| 104                                           obj->IsArray() && |  | 
| 105                                           obj->GetArray().GetSize() == 1))) { |  | 
| 106         if (obj->IsReference()) { |  | 
| 107             // We need to force the non const, the only update we will do is for
       recurssion checks. |  | 
| 108             PdfReference& ref = (PdfReference&)obj->GetReference(); |  | 
| 109             obj = pdfDoc->GetObjects().GetObject(ref); |  | 
| 110         } else { |  | 
| 111             obj = &obj->GetArray()[0]; |  | 
| 112         } |  | 
| 113     } |  | 
| 114 |  | 
| 115     return obj; |  | 
| 116 } |  | 
| 117 |  | 
| 118 static SkMatrix SkMatrixFromPdfMatrix(double array[6]) { |  | 
| 119     SkMatrix matrix; | 105     SkMatrix matrix; | 
| 120     matrix.setAll(SkDoubleToScalar(array[0]), | 106     matrix.setAll(SkDoubleToScalar(array[0]), | 
| 121                   SkDoubleToScalar(array[2]), | 107                   SkDoubleToScalar(array[2]), | 
| 122                   SkDoubleToScalar(array[4]), | 108                   SkDoubleToScalar(array[4]), | 
| 123                   SkDoubleToScalar(array[1]), | 109                   SkDoubleToScalar(array[1]), | 
| 124                   SkDoubleToScalar(array[3]), | 110                   SkDoubleToScalar(array[3]), | 
| 125                   SkDoubleToScalar(array[5]), | 111                   SkDoubleToScalar(array[5]), | 
| 126                   SkDoubleToScalar(0), | 112                   SkDoubleToScalar(0), | 
| 127                   SkDoubleToScalar(0), | 113                   SkDoubleToScalar(0), | 
| 128                   SkDoubleToScalar(1)); | 114                   SkDoubleToScalar(1)); | 
| 129 | 115 | 
| 130     return matrix; | 116     return matrix; | 
| 131 } | 117 } | 
| 132 | 118 | 
| 133 SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { | 119 SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { | 
| 134     double array[6]; | 120     double array[6]; | 
| 135 | 121 | 
| 136     // TODO(edisonn): security issue, ret if size() != 6 | 122     // TODO(edisonn): security issue, ret if size() != 6 | 
| 137     for (int i = 0; i < 6; i++) { | 123     for (int i = 0; i < 6; i++) { | 
| 138         const PdfObject* elem = resolveReferenceObject(pdfArray->doc(), (*pdfArr
      ay)[i]->podofo()); | 124         const SkPdfObject* elem = pdfArray->operator [](i); | 
| 139         if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { | 125         if (elem == NULL || (!elem->asNumber() && !elem->asInteger())) { | 
| 140             return SkMatrix::I();  // TODO(edisonn): report issue | 126             return SkMatrix::I();  // TODO(edisonn): report issue | 
| 141         } | 127         } | 
| 142         array[i] = elem->GetReal(); | 128         array[i] = elem->asNumber() ? elem->asNumber()->value() : elem->asIntege
      r()->value(); | 
| 143     } | 129     } | 
| 144 | 130 | 
| 145     return SkMatrixFromPdfMatrix(array); | 131     return SkMatrixFromPdfMatrix(array); | 
| 146 } | 132 } | 
| 147 | 133 | 
| 148 PdfContext* gPdfContext = NULL; |  | 
| 149 SkBitmap* gDumpBitmap = NULL; | 134 SkBitmap* gDumpBitmap = NULL; | 
| 150 SkCanvas* gDumpCanvas = NULL; | 135 SkCanvas* gDumpCanvas = NULL; | 
| 151 char gLastKeyword[100] = ""; | 136 char gLastKeyword[100] = ""; | 
| 152 int gLastOpKeyword = -1; | 137 int gLastOpKeyword = -1; | 
| 153 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
      ,EI,Do,EX,"; | 138 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
      ,EI,Do,EX,"; | 
| 154 int gReadOp = 0; | 139 int gReadOp = 0; | 
| 155 | 140 | 
| 156 | 141 | 
| 157 | 142 | 
| 158 bool hasVisualEffect(const char* pdfOp) { | 143 bool hasVisualEffect(const char* pdfOp) { | 
| 159     return true; | 144     return true; | 
| 160     if (*pdfOp == '\0') return false; | 145     if (*pdfOp == '\0') return false; | 
| 161 | 146 | 
| 162     char markedPdfOp[100] = ","; | 147     char markedPdfOp[100] = ","; | 
| 163     strcat(markedPdfOp, pdfOp); | 148     strcat(markedPdfOp, pdfOp); | 
| 164     strcat(markedPdfOp, ","); | 149     strcat(markedPdfOp, ","); | 
| 165 | 150 | 
| 166     return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); | 151     return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); | 
| 167 } | 152 } | 
| 168 | 153 | 
| 169 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum
      entation. | 154 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum
      entation. | 
| 170 static bool readToken(SkPdfTokenizer* fTokenizer, PdfToken* token) { | 155 static bool readToken(SkPdfPodofoTokenizer* fTokenizer, PdfToken* token) { | 
| 171     bool ret = fTokenizer->readToken(token); | 156     bool ret = fTokenizer->readToken(token); | 
| 172 | 157 | 
| 173     gReadOp++; | 158     gReadOp++; | 
| 174 | 159 | 
| 175 #ifdef PDF_TRACE_DIFF_IN_PNG | 160 #ifdef PDF_TRACE_DIFF_IN_PNG | 
| 176     // TODO(edisonn): compare with old bitmap, and save only new bits are availa
      ble, and save | 161     // TODO(edisonn): compare with old bitmap, and save only new bits are availa
      ble, and save | 
| 177     // the numbar and name of last operation, so the file name will reflect op t
      hat changed. | 162     // the numbar and name of last operation, so the file name will reflect op t
      hat changed. | 
| 178     if (hasVisualEffect(gLastKeyword)) {  // TODO(edisonn): and has dirty bits. | 163     if (hasVisualEffect(gLastKeyword)) {  // TODO(edisonn): and has dirty bits. | 
| 179         gDumpCanvas->flush(); | 164         gDumpCanvas->flush(); | 
| 180 | 165 | 
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 326 #endif | 311 #endif | 
| 327 | 312 | 
| 328     // TODO(edisonn): Report Warning, NYI | 313     // TODO(edisonn): Report Warning, NYI | 
| 329     return SkTypeface::CreateFromName( | 314     return SkTypeface::CreateFromName( | 
| 330                 "Times New Roman", | 315                 "Times New Roman", | 
| 331                 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | | 316                 SkTypeface::Style((font->IsBold() ? SkTypeface::kBold : 0) | | 
| 332                                   (font->IsItalic() ? SkTypeface::kItalic : 0)))
      ; | 317                                   (font->IsItalic() ? SkTypeface::kItalic : 0)))
      ; | 
| 333 } | 318 } | 
| 334 | 319 | 
| 335 PdfResult DrawText(PdfContext* pdfContext, | 320 PdfResult DrawText(PdfContext* pdfContext, | 
| 336                    const SkPdfObject* str, | 321                    const SkPdfObject* _str, | 
| 337                    SkCanvas* canvas) | 322                    SkCanvas* canvas) | 
| 338 { | 323 { | 
| 339 | 324 | 
| 340     SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; | 325     SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; | 
| 341     if (skfont == NULL) { | 326     if (skfont == NULL) { | 
| 342         skfont = SkPdfFont::Default(); | 327         skfont = SkPdfFont::Default(); | 
| 343     } | 328     } | 
| 344 | 329 | 
|  | 330     const SkPdfString* str = _str->asString(); | 
|  | 331 | 
|  | 332     if (str == NULL) { | 
|  | 333         // TODO(edisonn): report warning | 
|  | 334         return kIgnoreError_PdfResult; | 
|  | 335     } | 
|  | 336 | 
| 345     SkUnencodedText binary(str); | 337     SkUnencodedText binary(str); | 
| 346 | 338 | 
| 347     SkDecodedText decoded; | 339     SkDecodedText decoded; | 
| 348 | 340 | 
| 349     if (skfont->encoding() == NULL) { | 341     if (skfont->encoding() == NULL) { | 
| 350         // TODO(edisonn): report warning | 342         // TODO(edisonn): report warning | 
| 351         return kNYI_PdfResult; | 343         return kNYI_PdfResult; | 
| 352     } | 344     } | 
| 353 | 345 | 
| 354     skfont->encoding()->decodeText(binary, &decoded); | 346     skfont->encoding()->decodeText(binary, &decoded); | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 393 | 385 | 
| 394     return kPartial_PdfResult; | 386     return kPartial_PdfResult; | 
| 395 } | 387 } | 
| 396 | 388 | 
| 397 // TODO(edisonn): create header files with declarations! | 389 // TODO(edisonn): create header files with declarations! | 
| 398 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per); | 390 PdfResult PdfOp_q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per); | 
| 399 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per); | 391 PdfResult PdfOp_Q(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per); | 
| 400 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper); | 392 PdfResult PdfOp_Tw(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper); | 
| 401 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper); | 393 PdfResult PdfOp_Tc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper); | 
| 402 | 394 | 
| 403 // TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in Get
      Key? |  | 
| 404 // Always pass long form in key, and have a map of long -> short key |  | 
| 405 bool LongFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 406                         const PdfDictionary& dict, |  | 
| 407                         const char* key, |  | 
| 408                         long* data) { |  | 
| 409     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 410                                               dict.GetKey(PdfName(key))); |  | 
| 411 |  | 
| 412     if (value == NULL || !value->IsNumber()) { |  | 
| 413         return false; |  | 
| 414     } |  | 
| 415     if (data == NULL) { |  | 
| 416         return true; |  | 
| 417     } |  | 
| 418 |  | 
| 419     *data = value->GetNumber(); |  | 
| 420     return true; |  | 
| 421 } |  | 
| 422 |  | 
| 423 bool LongFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 424                         const PdfDictionary& dict, |  | 
| 425                         const char* key, |  | 
| 426                         const char* abr, |  | 
| 427                         long* data) { |  | 
| 428     if (LongFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 429     if (abr == NULL || *abr == '\0') return false; |  | 
| 430     return LongFromDictionary(pdfDoc, dict, abr, data); |  | 
| 431 } |  | 
| 432 |  | 
| 433 bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 434                           const PdfDictionary& dict, |  | 
| 435                           const char* key, |  | 
| 436                           double* data) { |  | 
| 437     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 438                                               dict.GetKey(PdfName(key))); |  | 
| 439 |  | 
| 440     if (value == NULL || (!value->IsReal() && !value->IsNumber())) { |  | 
| 441         return false; |  | 
| 442     } |  | 
| 443     if (data == NULL) { |  | 
| 444         return true; |  | 
| 445     } |  | 
| 446 |  | 
| 447     *data = value->GetReal(); |  | 
| 448     return true; |  | 
| 449 } |  | 
| 450 |  | 
| 451 bool DoubleFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 452                           const PdfDictionary& dict, |  | 
| 453                           const char* key, |  | 
| 454                           const char* abr, |  | 
| 455                           double* data) { |  | 
| 456     if (DoubleFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 457     if (abr == NULL || *abr == '\0') return false; |  | 
| 458     return DoubleFromDictionary(pdfDoc, dict, abr, data); |  | 
| 459 } |  | 
| 460 |  | 
| 461 |  | 
| 462 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 463                         const PdfDictionary& dict, |  | 
| 464                         const char* key, |  | 
| 465                         bool* data) { |  | 
| 466     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 467                                               dict.GetKey(PdfName(key))); |  | 
| 468 |  | 
| 469     if (value == NULL || !value->IsBool()) { |  | 
| 470         return false; |  | 
| 471     } |  | 
| 472     if (data == NULL) { |  | 
| 473         return true; |  | 
| 474     } |  | 
| 475 |  | 
| 476     *data = value->GetBool(); |  | 
| 477     return true; |  | 
| 478 } |  | 
| 479 |  | 
| 480 bool BoolFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 481                         const PdfDictionary& dict, |  | 
| 482                         const char* key, |  | 
| 483                         const char* abr, |  | 
| 484                         bool* data) { |  | 
| 485     if (BoolFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 486     if (abr == NULL || *abr == '\0') return false; |  | 
| 487     return BoolFromDictionary(pdfDoc, dict, abr, data); |  | 
| 488 } |  | 
| 489 |  | 
| 490 bool NameFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 491                         const PdfDictionary& dict, |  | 
| 492                         const char* key, |  | 
| 493                         std::string* data) { |  | 
| 494     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 495                                               dict.GetKey(PdfName(key)), |  | 
| 496                                               true); |  | 
| 497     if (value == NULL || !value->IsName()) { |  | 
| 498         return false; |  | 
| 499     } |  | 
| 500     if (data == NULL) { |  | 
| 501         return true; |  | 
| 502     } |  | 
| 503 |  | 
| 504     *data = value->GetName().GetName(); |  | 
| 505     return true; |  | 
| 506 } |  | 
| 507 |  | 
| 508 bool NameFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 509                         const PdfDictionary& dict, |  | 
| 510                         const char* key, |  | 
| 511                         const char* abr, |  | 
| 512                         std::string* data) { |  | 
| 513     if (NameFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 514     if (abr == NULL || *abr == '\0') return false; |  | 
| 515     return NameFromDictionary(pdfDoc, dict, abr, data); |  | 
| 516 } |  | 
| 517 |  | 
| 518 bool StringFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 519                           const PdfDictionary& dict, |  | 
| 520                           const char* key, |  | 
| 521                           std::string* data) { |  | 
| 522     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 523                                               dict.GetKey(PdfName(key)), |  | 
| 524                                               true); |  | 
| 525     if (value == NULL || (!value->IsString() && !value->IsHexString())) { |  | 
| 526         return false; |  | 
| 527     } |  | 
| 528     if (data == NULL) { |  | 
| 529         return true; |  | 
| 530     } |  | 
| 531 |  | 
| 532     *data = value->GetString().GetString(); |  | 
| 533     return true; |  | 
| 534 } |  | 
| 535 |  | 
| 536 bool StringFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 537                           const PdfDictionary& dict, |  | 
| 538                           const char* key, |  | 
| 539                           const char* abr, |  | 
| 540                           std::string* data) { |  | 
| 541     if (StringFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 542     if (abr == NULL || *abr == '\0') return false; |  | 
| 543     return StringFromDictionary(pdfDoc, dict, abr, data); |  | 
| 544 } |  | 
| 545 |  | 
| 546 /* |  | 
| 547 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 548                               const PdfDictionary& dict, |  | 
| 549                               const char* key, |  | 
| 550                               SkPdfArray** data) { |  | 
| 551     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 552                                               dict.GetKey(PdfName(key)), |  | 
| 553                                               true); |  | 
| 554     if (value == NULL || !value->IsArray()) { |  | 
| 555         return false; |  | 
| 556     } |  | 
| 557     if (data == NULL) { |  | 
| 558         return true; |  | 
| 559     } |  | 
| 560 |  | 
| 561     return mapArray(*pdfDoc, *value, data); |  | 
| 562 } |  | 
| 563 |  | 
| 564 |  | 
| 565 bool ArrayFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 566                         const PdfDictionary& dict, |  | 
| 567                         const char* key, |  | 
| 568                         const char* abr, |  | 
| 569                         SkPdfArray** data) { |  | 
| 570     if (ArrayFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 571     if (abr == NULL || *abr == '\0') return false; |  | 
| 572     return ArrayFromDictionary(pdfDoc, dict, abr, data); |  | 
| 573 } |  | 
| 574 |  | 
| 575 |  | 
| 576 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 577                               const PdfDictionary& dict, |  | 
| 578                               const char* key, |  | 
| 579                               SkPdfDictionary** data) { |  | 
| 580     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 581                                               dict.GetKey(PdfName(key)), |  | 
| 582                                               true); |  | 
| 583     if (value == NULL || !value->IsDictionary()) { |  | 
| 584         return false; |  | 
| 585     } |  | 
| 586     if (data == NULL) { |  | 
| 587         return true; |  | 
| 588     } |  | 
| 589 |  | 
| 590     return mapDictionary(*pdfDoc, *value, data); |  | 
| 591 } |  | 
| 592 |  | 
| 593 bool DictionaryFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 594                         const PdfDictionary& dict, |  | 
| 595                         const char* key, |  | 
| 596                         const char* abr, |  | 
| 597                         SkPdfDictionary** data) { |  | 
| 598     if (DictionaryFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 599     if (abr == NULL || *abr == '\0') return false; |  | 
| 600     return DictionaryFromDictionary(pdfDoc, dict, abr, data); |  | 
| 601 } |  | 
| 602 |  | 
| 603 |  | 
| 604 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 605                           const PdfDictionary& dict, |  | 
| 606                           const char* key, |  | 
| 607                           SkPdfObject** data) { |  | 
| 608     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 609                                               dict.GetKey(PdfName(key)), |  | 
| 610                                               true); |  | 
| 611     if (value == NULL) { |  | 
| 612         return false; |  | 
| 613     } |  | 
| 614     if (data == NULL) { |  | 
| 615         return true; |  | 
| 616     } |  | 
| 617     return mapObject(*pdfDoc, *value, data); |  | 
| 618 } |  | 
| 619 |  | 
| 620 bool ObjectFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 621                         const PdfDictionary& dict, |  | 
| 622                         const char* key, |  | 
| 623                         const char* abr, |  | 
| 624                         SkPdfObject** data) { |  | 
| 625     if (ObjectFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 626     if (abr == NULL || *abr == '\0') return false; |  | 
| 627     return ObjectFromDictionary(pdfDoc, dict, abr, data); |  | 
| 628 } |  | 
| 629 |  | 
| 630 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 631                           const PdfDictionary& dict, |  | 
| 632                           const char* key, |  | 
| 633                           SkPdfStream** data) { |  | 
| 634     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 635                                               dict.GetKey(PdfName(key)), |  | 
| 636                                               true); |  | 
| 637     if (value == NULL) { |  | 
| 638         return false; |  | 
| 639     } |  | 
| 640     if (data == NULL) { |  | 
| 641         return true; |  | 
| 642     } |  | 
| 643     return mapStream(*pdfDoc, *value, data); |  | 
| 644 } |  | 
| 645 |  | 
| 646 bool StreamFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 647                         const PdfDictionary& dict, |  | 
| 648                         const char* key, |  | 
| 649                         const char* abr, |  | 
| 650                         SkPdfStream** data) { |  | 
| 651     if (StreamFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 652     if (abr == NULL || *abr == '\0') return false; |  | 
| 653     return StreamFromDictionary(pdfDoc, dict, abr, data); |  | 
| 654 } |  | 
| 655 */ |  | 
| 656 |  | 
| 657 // TODO(edisonn): perf!!! | 395 // TODO(edisonn): perf!!! | 
| 658 | 396 | 
| 659 static SkColorTable* getGrayColortable() { | 397 static SkColorTable* getGrayColortable() { | 
| 660     static SkColorTable* grayColortable = NULL; | 398     static SkColorTable* grayColortable = NULL; | 
| 661     if (grayColortable == NULL) { | 399     if (grayColortable == NULL) { | 
| 662         SkPMColor* colors = new SkPMColor[256]; | 400         SkPMColor* colors = new SkPMColor[256]; | 
| 663         for (int i = 0 ; i < 256; i++) { | 401         for (int i = 0 ; i < 256; i++) { | 
| 664             colors[i] = SkPreMultiplyARGB(255, i, i, i); | 402             colors[i] = SkPreMultiplyARGB(255, i, i, i); | 
| 665         } | 403         } | 
| 666         grayColortable = new SkColorTable(colors, 256); | 404         grayColortable = new SkColorTable(colors, 256); | 
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 774 // utils | 512 // utils | 
| 775 | 513 | 
| 776 // TODO(edisonn): add cache, or put the bitmap property directly on the PdfObjec
      t | 514 // TODO(edisonn): add cache, or put the bitmap property directly on the PdfObjec
      t | 
| 777 // TODO(edisonn): deal with colorSpaces, we could add them to SkBitmap::Config | 515 // TODO(edisonn): deal with colorSpaces, we could add them to SkBitmap::Config | 
| 778 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
      22, 444 to closest | 516 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
      22, 444 to closest | 
| 779 // skia format, through a table | 517 // skia format, through a table | 
| 780 | 518 | 
| 781 // this functions returns the image, it does not look at the smask. | 519 // this functions returns the image, it does not look at the smask. | 
| 782 | 520 | 
| 783 SkBitmap getImageFromObject(PdfContext* pdfContext, const SkPdfImageDictionary* 
      image, bool transparencyMask) { | 521 SkBitmap getImageFromObject(PdfContext* pdfContext, const SkPdfImageDictionary* 
      image, bool transparencyMask) { | 
| 784     if (image == NULL || !image->valid()) { | 522     if (image == NULL) { | 
| 785         // TODO(edisonn): report warning to be used in testing. | 523         // TODO(edisonn): report warning to be used in testing. | 
| 786         return SkBitmap(); | 524         return SkBitmap(); | 
| 787     } | 525     } | 
| 788 | 526 | 
| 789     // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw 
      ... | 527     // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw 
      ... | 
| 790 //    PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 528 //    PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | 
| 791 //                                              obj.GetDictionary().GetKey(PdfNa
      me("Filter"))); | 529 //                                              obj.GetDictionary().GetKey(PdfNa
      me("Filter"))); | 
| 792 //    if (value && value->IsArray() && value->GetArray().GetSize() == 1) { | 530 //    if (value && value->IsArray() && value->GetArray().GetSize() == 1) { | 
| 793 //        value = resolveReferenceObject(pdfContext->fPdfDoc, | 531 //        value = resolveReferenceObject(pdfContext->fPdfDoc, | 
| 794 //                                       &value->GetArray()[0]); | 532 //                                       &value->GetArray()[0]); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 813 | 551 | 
| 814     if (imageMask) { | 552     if (imageMask) { | 
| 815         if (bpc != 0 && bpc != 1) { | 553         if (bpc != 0 && bpc != 1) { | 
| 816             // TODO(edisonn): report warning to be used in testing. | 554             // TODO(edisonn): report warning to be used in testing. | 
| 817             return SkBitmap(); | 555             return SkBitmap(); | 
| 818         } | 556         } | 
| 819         bpc = 1; | 557         bpc = 1; | 
| 820     } | 558     } | 
| 821 */ | 559 */ | 
| 822 | 560 | 
| 823     const PdfObject* obj = image->podofo(); |  | 
| 824 |  | 
| 825     char* uncompressedStream = NULL; | 561     char* uncompressedStream = NULL; | 
| 826     pdf_long uncompressedStreamLength = 0; | 562     pdf_long uncompressedStreamLength = 0; | 
| 827 | 563 | 
| 828     PdfResult ret = kPartial_PdfResult; | 564     PdfResult ret = kPartial_PdfResult; | 
| 829     // TODO(edisonn): get rid of try/catch exceptions! We should not throw on us
      er data! | 565     SkPdfStream* stream = NULL; | 
| 830     try { | 566     image->doc()->mapper()->mapStream(image, &stream); | 
| 831         obj->GetStream()->GetFilteredCopy(&uncompressedStream, &uncompressedStre
      amLength); | 567 | 
| 832     } catch (PdfError& e) { | 568     if (!stream || !stream->GetFilteredCopy(&uncompressedStream, &uncompressedSt
      reamLength) || | 
|  | 569             uncompressedStream == NULL || uncompressedStreamLength == 0) { | 
| 833         // TODO(edisonn): report warning to be used in testing. | 570         // TODO(edisonn): report warning to be used in testing. | 
| 834         return SkBitmap(); | 571         return SkBitmap(); | 
| 835     } | 572     } | 
| 836 | 573 | 
| 837     int bytesPerLine = uncompressedStreamLength / height; | 574     int bytesPerLine = uncompressedStreamLength / height; | 
| 838 #ifdef PDF_TRACE | 575 #ifdef PDF_TRACE | 
| 839     if (uncompressedStreamLength % height != 0) { | 576     if (uncompressedStreamLength % height != 0) { | 
| 840         printf("Warning uncompressedStreamLength % height != 0 !!!\n"); | 577         printf("Warning uncompressedStreamLength % height != 0 !!!\n"); | 
| 841     } | 578     } | 
| 842 #endif | 579 #endif | 
| 843 | 580 | 
| 844     SkBitmap bitmap = transferImageStreamToBitmap( | 581     SkBitmap bitmap = transferImageStreamToBitmap( | 
| 845             (unsigned char*)uncompressedStream, uncompressedStreamLength, | 582             (unsigned char*)uncompressedStream, uncompressedStreamLength, | 
| 846             width, height, bytesPerLine, | 583             width, height, bytesPerLine, | 
| 847             bpc, colorSpace, | 584             bpc, colorSpace, | 
| 848             transparencyMask); | 585             transparencyMask); | 
| 849 | 586 | 
| 850     free(uncompressedStream); | 587     free(uncompressedStream); | 
| 851 | 588 | 
| 852     return bitmap; | 589     return bitmap; | 
| 853 } | 590 } | 
| 854 | 591 | 
| 855 SkBitmap getSmaskFromObject(PdfContext* pdfContext, const SkPdfImageDictionary* 
      obj) { | 592 SkBitmap getSmaskFromObject(PdfContext* pdfContext, const SkPdfImageDictionary* 
      obj) { | 
| 856     const PdfObject* sMask = resolveReferenceObject(&pdfContext->fPdfDoc->podofo
      (), | 593     const SkPdfImageDictionary* sMask = obj->SMask(); | 
| 857                                               obj->podofo()->GetDictionary().Get
      Key(PdfName("SMask"))); |  | 
| 858 |  | 
| 859 #ifdef PDF_TRACE |  | 
| 860     std::string str; |  | 
| 861     if (sMask) { |  | 
| 862         sMask->ToString(str); |  | 
| 863         printf("/SMask of /Subtype /Image: %s\n", str.c_str()); |  | 
| 864     } |  | 
| 865 #endif |  | 
| 866 | 594 | 
| 867     if (sMask) { | 595     if (sMask) { | 
| 868         SkPdfImageDictionary skxobjmask(&pdfContext->fPdfDoc->podofo(), sMask); | 596         return getImageFromObject(pdfContext, sMask, true); | 
| 869         return getImageFromObject(pdfContext, &skxobjmask, true); |  | 
| 870     } | 597     } | 
| 871 | 598 | 
| 872     // TODO(edisonn): implement GS SMask. Default to empty right now. | 599     // TODO(edisonn): implement GS SMask. Default to empty right now. | 
| 873     return pdfContext->fGraphicsState.fSMask; | 600     return pdfContext->fGraphicsState.fSMask; | 
| 874 } | 601 } | 
| 875 | 602 | 
| 876 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfI
      mageDictionary* skpdfimage) { | 603 PdfResult doXObject_Image(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfI
      mageDictionary* skpdfimage) { | 
| 877     if (skpdfimage == NULL || !skpdfimage->valid()) { | 604     if (skpdfimage == NULL) { | 
| 878         return kIgnoreError_PdfResult; | 605         return kIgnoreError_PdfResult; | 
| 879     } | 606     } | 
| 880 | 607 | 
| 881     SkBitmap image = getImageFromObject(pdfContext, skpdfimage, false); | 608     SkBitmap image = getImageFromObject(pdfContext, skpdfimage, false); | 
| 882     SkBitmap sMask = getSmaskFromObject(pdfContext, skpdfimage); | 609     SkBitmap sMask = getSmaskFromObject(pdfContext, skpdfimage); | 
| 883 | 610 | 
| 884     canvas->save(); | 611     canvas->save(); | 
| 885     canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 612     canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 
| 886     SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0), 
      SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); | 613     SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0), 
      SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); | 
| 887 | 614 | 
| 888     if (sMask.empty()) { | 615     if (sMask.empty()) { | 
| 889         canvas->drawBitmapRect(image, dst, NULL); | 616         canvas->drawBitmapRect(image, dst, NULL); | 
| 890     } else { | 617     } else { | 
| 891         canvas->saveLayer(&dst, NULL); | 618         canvas->saveLayer(&dst, NULL); | 
| 892         canvas->drawBitmapRect(image, dst, NULL); | 619         canvas->drawBitmapRect(image, dst, NULL); | 
| 893         SkPaint xfer; | 620         SkPaint xfer; | 
| 894         pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); | 621         pdfContext->fGraphicsState.applyGraphicsState(&xfer, false); | 
| 895         xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
      ode | 622         xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
      ode | 
| 896         canvas->drawBitmapRect(sMask, dst, &xfer); | 623         canvas->drawBitmapRect(sMask, dst, &xfer); | 
| 897         canvas->restore(); | 624         canvas->restore(); | 
| 898     } | 625     } | 
| 899 | 626 | 
| 900     canvas->restore(); | 627     canvas->restore(); | 
| 901 | 628 | 
| 902     return kPartial_PdfResult; | 629     return kPartial_PdfResult; | 
| 903 } | 630 } | 
| 904 | 631 | 
| 905 bool SkMatrixFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 906                             const PdfDictionary& dict, |  | 
| 907                             const char* key, |  | 
| 908                             SkMatrix** matrix) { |  | 
| 909     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 910                                                     dict.GetKey(PdfName(key))); |  | 
| 911 |  | 
| 912     if (value == NULL || !value->IsArray()) { |  | 
| 913         return false; |  | 
| 914     } |  | 
| 915 |  | 
| 916     if (value->GetArray().GetSize() != 6) { |  | 
| 917         return false; |  | 
| 918     } |  | 
| 919 |  | 
| 920     double array[6]; |  | 
| 921     for (int i = 0; i < 6; i++) { |  | 
| 922         const PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray(
      )[i]); |  | 
| 923         if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { |  | 
| 924             return false; |  | 
| 925         } |  | 
| 926         array[i] = elem->GetReal(); |  | 
| 927     } |  | 
| 928 |  | 
| 929     *matrix = new SkMatrix(); |  | 
| 930     **matrix = SkMatrixFromPdfMatrix(array); |  | 
| 931     return true; |  | 
| 932 } |  | 
| 933 |  | 
| 934 bool SkMatrixFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 935                         const PdfDictionary& dict, |  | 
| 936                         const char* key, |  | 
| 937                         const char* abr, |  | 
| 938                         SkMatrix** data) { |  | 
| 939     if (SkMatrixFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 940     if (abr == NULL || *abr == '\0') return false; |  | 
| 941     return SkMatrixFromDictionary(pdfDoc, dict, abr, data); |  | 
| 942 |  | 
| 943 } |  | 
| 944 |  | 
| 945 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 946                           const PdfDictionary& dict, |  | 
| 947                           const char* key, |  | 
| 948                           SkRect** rect) { |  | 
| 949     const PdfObject* value = resolveReferenceObject(pdfDoc, |  | 
| 950                                                     dict.GetKey(PdfName(key))); |  | 
| 951 |  | 
| 952     if (value == NULL || !value->IsArray()) { |  | 
| 953         return false; |  | 
| 954     } |  | 
| 955 |  | 
| 956     if (value->GetArray().GetSize() != 4) { |  | 
| 957         return false; |  | 
| 958     } |  | 
| 959 |  | 
| 960     double array[4]; |  | 
| 961     for (int i = 0; i < 4; i++) { |  | 
| 962         const PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray(
      )[i]); |  | 
| 963         if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) { |  | 
| 964             return false; |  | 
| 965         } |  | 
| 966         array[i] = elem->GetReal(); |  | 
| 967     } |  | 
| 968 |  | 
| 969     *rect = new SkRect(); |  | 
| 970     **rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]), |  | 
| 971                               SkDoubleToScalar(array[1]), |  | 
| 972                               SkDoubleToScalar(array[2]), |  | 
| 973                               SkDoubleToScalar(array[3])); |  | 
| 974     return true; |  | 
| 975 } |  | 
| 976 |  | 
| 977 bool SkRectFromDictionary(const PdfMemDocument* pdfDoc, |  | 
| 978                         const PdfDictionary& dict, |  | 
| 979                         const char* key, |  | 
| 980                         const char* abr, |  | 
| 981                         SkRect** data) { |  | 
| 982     if (SkRectFromDictionary(pdfDoc, dict, key, data)) return true; |  | 
| 983     if (abr == NULL || *abr == '\0') return false; |  | 
| 984     return SkRectFromDictionary(pdfDoc, dict, abr, data); |  | 
| 985 |  | 
| 986 } |  | 
| 987 | 632 | 
| 988 | 633 | 
| 989 SkPdfObject* get(const SkPdfObject* obj, const char* key, const char* abr = "") 
      { |  | 
| 990     SkPdfObject* ret = NULL; |  | 
| 991     if (obj == NULL) return NULL; |  | 
| 992     const SkPdfDictionary* dict = obj->asDictionary(); |  | 
| 993     if (dict == NULL) return NULL; |  | 
| 994     if (!dict->podofo()->IsDictionary()) return NULL; |  | 
| 995     ObjectFromDictionary(dict->doc(), dict->podofo()->GetDictionary(), key, abr,
       &ret); |  | 
| 996     return ret; |  | 
| 997 } |  | 
| 998 | 634 | 
| 999 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfType1For
      mDictionary* skobj) { | 635 PdfResult doXObject_Form(PdfContext* pdfContext, SkCanvas* canvas, SkPdfType1For
      mDictionary* skobj) { | 
| 1000     if (!skobj || !skobj->podofo() || !skobj->podofo()->HasStream() || skobj->po
      dofo()->GetStream() == NULL || skobj->podofo()->GetStream()->GetLength() == 0) { | 636     if (!skobj) { | 
| 1001         return kOK_PdfResult; | 637         return kIgnoreError_PdfResult; | 
| 1002     } | 638     } | 
| 1003 | 639 | 
| 1004     PdfOp_q(pdfContext, canvas, NULL); | 640     PdfOp_q(pdfContext, canvas, NULL); | 
| 1005     canvas->save(); | 641     canvas->save(); | 
| 1006 | 642 | 
| 1007 | 643 | 
| 1008     if (skobj->Resources()) { | 644     if (skobj->Resources()) { | 
| 1009         pdfContext->fGraphicsState.fResources = skobj->Resources(); | 645         pdfContext->fGraphicsState.fResources = skobj->Resources(); | 
| 1010     } | 646     } | 
| 1011 | 647 | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 1022 | 658 | 
| 1023     canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 659     canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 
| 1024 | 660 | 
| 1025     if (skobj->BBox()) { | 661     if (skobj->BBox()) { | 
| 1026         canvas->clipRect(*skobj->BBox(), SkRegion::kIntersect_Op, true);  // TOD
      O(edisonn): AA from settings. | 662         canvas->clipRect(*skobj->BBox(), SkRegion::kIntersect_Op, true);  // TOD
      O(edisonn): AA from settings. | 
| 1027     } | 663     } | 
| 1028 | 664 | 
| 1029     // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
      nize it as we go. | 665     // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
      nize it as we go. | 
| 1030     // For this PdfContentsTokenizer needs to be extended. | 666     // For this PdfContentsTokenizer needs to be extended. | 
| 1031 | 667 | 
| 1032     PdfResult ret = kPartial_PdfResult; | 668     SkPdfStream* stream = NULL; | 
| 1033     SkPdfTokenizer tokenizer(skobj); | 669     skobj->doc()->mapper()->mapStream(skobj, &stream); | 
| 1034     PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas); | 670 | 
| 1035     looper.loop(); | 671     SkPdfPodofoTokenizer* tokenizer = skobj->doc()->tokenizerOfStream(stream); | 
|  | 672     if (tokenizer != NULL) { | 
|  | 673         PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); | 
|  | 674         looper.loop(); | 
|  | 675         delete tokenizer; | 
|  | 676     } | 
| 1036 | 677 | 
| 1037     // TODO(edisonn): should we restore the variable stack at the same state? | 678     // TODO(edisonn): should we restore the variable stack at the same state? | 
| 1038     // There could be operands left, that could be consumed by a parent tokenize
      r when we pop. | 679     // There could be operands left, that could be consumed by a parent tokenize
      r when we pop. | 
| 1039     canvas->restore(); | 680     canvas->restore(); | 
| 1040     PdfOp_Q(pdfContext, canvas, NULL); | 681     PdfOp_Q(pdfContext, canvas, NULL); | 
| 1041     return ret; | 682     return kPartial_PdfResult; | 
| 1042 } | 683 } | 
| 1043 | 684 | 
| 1044 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
      & obj) { | 685 PdfResult doXObject_PS(PdfContext* pdfContext, SkCanvas* canvas, const PdfObject
      & obj) { | 
| 1045     return kNYI_PdfResult; | 686     return kNYI_PdfResult; | 
| 1046 } | 687 } | 
| 1047 | 688 | 
| 1048 PdfResult doType3Char(PdfContext* pdfContext, SkCanvas* canvas, SkPdfObject* sko
      bj, SkRect bBox, SkMatrix matrix, double textSize) { | 689 PdfResult doType3Char(PdfContext* pdfContext, SkCanvas* canvas, SkPdfObject* sko
      bj, SkRect bBox, SkMatrix matrix, double textSize) { | 
| 1049     if (!skobj || !skobj->podofo() || !skobj->podofo()->HasStream() || skobj->po
      dofo()->GetStream() == NULL || skobj->podofo()->GetStream()->GetLength() == 0) { | 690     if (!skobj) { | 
| 1050         return kOK_PdfResult; | 691         return kIgnoreError_PdfResult; | 
| 1051     } | 692     } | 
| 1052 | 693 | 
| 1053     PdfOp_q(pdfContext, canvas, NULL); | 694     PdfOp_q(pdfContext, canvas, NULL); | 
| 1054     canvas->save(); | 695     canvas->save(); | 
| 1055 | 696 | 
| 1056     pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 697     pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 
| 1057     pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), Sk
      DoubleToScalar(textSize)); | 698     pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), Sk
      DoubleToScalar(textSize)); | 
| 1058 | 699 | 
| 1059     pdfContext->fGraphicsState.fMatrix = pdfContext->fGraphicsState.fMatrixTm; | 700     pdfContext->fGraphicsState.fMatrix = pdfContext->fGraphicsState.fMatrixTm; | 
| 1060     pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix; | 701     pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrix; | 
| 1061 | 702 | 
| 1062     SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); | 703     SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "Total matrix"); | 
| 1063 | 704 | 
| 1064     canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 705     canvas->setMatrix(pdfContext->fGraphicsState.fMatrix); | 
| 1065 | 706 | 
| 1066     SkRect rm = bBox; | 707     SkRect rm = bBox; | 
| 1067     pdfContext->fGraphicsState.fMatrix.mapRect(&rm); | 708     pdfContext->fGraphicsState.fMatrix.mapRect(&rm); | 
| 1068 | 709 | 
| 1069     SkTraceRect(rm, "bbox mapped"); | 710     SkTraceRect(rm, "bbox mapped"); | 
| 1070 | 711 | 
| 1071     canvas->clipRect(bBox, SkRegion::kIntersect_Op, true);  // TODO(edisonn): AA
       from settings. | 712     canvas->clipRect(bBox, SkRegion::kIntersect_Op, true);  // TODO(edisonn): AA
       from settings. | 
| 1072 | 713 | 
| 1073     // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
      nize it as we go. | 714     // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
      nize it as we go. | 
| 1074     // For this PdfContentsTokenizer needs to be extended. | 715     // For this PdfContentsTokenizer needs to be extended. | 
| 1075 | 716 | 
| 1076     PdfResult ret = kPartial_PdfResult; | 717     SkPdfStream* stream = NULL; | 
| 1077     SkPdfTokenizer tokenizer(skobj); | 718     skobj->doc()->mapper()->mapStream(skobj, &stream); | 
| 1078     PdfMainLooper looper(NULL, &tokenizer, pdfContext, canvas); | 719 | 
| 1079     looper.loop(); | 720     SkPdfPodofoTokenizer* tokenizer = skobj->doc()->tokenizerOfStream(stream); | 
|  | 721     if (tokenizer != NULL) { | 
|  | 722         PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); | 
|  | 723         looper.loop(); | 
|  | 724         delete tokenizer; | 
|  | 725     } | 
| 1080 | 726 | 
| 1081     // TODO(edisonn): should we restore the variable stack at the same state? | 727     // TODO(edisonn): should we restore the variable stack at the same state? | 
| 1082     // There could be operands left, that could be consumed by a parent tokenize
      r when we pop. | 728     // There could be operands left, that could be consumed by a parent tokenize
      r when we pop. | 
| 1083     canvas->restore(); | 729     canvas->restore(); | 
| 1084     PdfOp_Q(pdfContext, canvas, NULL); | 730     PdfOp_Q(pdfContext, canvas, NULL); | 
| 1085     return ret; | 731 | 
|  | 732     return kPartial_PdfResult; | 
| 1086 } | 733 } | 
| 1087 | 734 | 
| 1088 | 735 | 
| 1089 // TODO(edisonn): faster, have the property on the SkPdfObject itself? | 736 // TODO(edisonn): faster, have the property on the SkPdfObject itself? | 
| 1090 std::set<const PdfObject*> gInRendering; | 737 std::set<const void*> gInRendering; | 
| 1091 | 738 | 
| 1092 class CheckRecursiveRendering { | 739 class CheckRecursiveRendering { | 
| 1093     const PdfObject& fObj; | 740     const void* fUniqueData; | 
| 1094 public: | 741 public: | 
| 1095     CheckRecursiveRendering(const PdfObject& obj) : fObj(obj) { | 742     CheckRecursiveRendering(const SkPdfObject* obj) : fUniqueData(obj->data()) { | 
| 1096         gInRendering.insert(&obj); | 743         gInRendering.insert(obj); | 
| 1097     } | 744     } | 
| 1098 | 745 | 
| 1099     ~CheckRecursiveRendering() { | 746     ~CheckRecursiveRendering() { | 
| 1100         //SkASSERT(fObj.fInRendering); | 747         //SkASSERT(fObj.fInRendering); | 
| 1101         gInRendering.erase(&fObj); | 748         gInRendering.erase(fUniqueData); | 
| 1102     } | 749     } | 
| 1103 | 750 | 
| 1104     static bool IsInRendering(const PdfObject& obj) { | 751     static bool IsInRendering(const SkPdfObject* obj) { | 
| 1105         return gInRendering.find(&obj) != gInRendering.end(); | 752         return gInRendering.find(obj->data()) != gInRendering.end(); | 
| 1106     } | 753     } | 
| 1107 }; | 754 }; | 
| 1108 | 755 | 
| 1109 PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfObject&
       obj) { | 756 PdfResult doXObject(PdfContext* pdfContext, SkCanvas* canvas, const SkPdfObject&
       obj) { | 
| 1110     if (CheckRecursiveRendering::IsInRendering(*obj.podofo())) { | 757     if (CheckRecursiveRendering::IsInRendering(&obj)) { | 
| 1111         // Oops, corrupt PDF! | 758         // Oops, corrupt PDF! | 
| 1112         return kIgnoreError_PdfResult; | 759         return kIgnoreError_PdfResult; | 
| 1113     } | 760     } | 
| 1114 | 761 | 
| 1115     CheckRecursiveRendering checkRecursion(*obj.podofo()); | 762     CheckRecursiveRendering checkRecursion(&obj); | 
| 1116 | 763 | 
| 1117     // TODO(edisonn): check type | 764     // TODO(edisonn): check type | 
| 1118     SkPdfXObjectDictionary* skobj = NULL; | 765     SkPdfXObjectDictionary* skobj = NULL; | 
| 1119     if (!mapXObjectDictionary(obj, &skobj)) return kIgnoreError_PdfResult; | 766     if (!obj.doc()->mapper()->mapXObjectDictionary(&obj, &skobj)) return kIgnore
      Error_PdfResult; | 
| 1120 | 767 | 
| 1121     if (!skobj || !skobj->valid()) return kIgnoreError_PdfResult; | 768     if (!skobj) return kIgnoreError_PdfResult; | 
| 1122 | 769 | 
| 1123     PdfResult ret = kIgnoreError_PdfResult; | 770     PdfResult ret = kIgnoreError_PdfResult; | 
| 1124     switch (skobj->getType()) | 771     switch (skobj->getType()) | 
| 1125     { | 772     { | 
| 1126         case kImageDictionary_SkPdfObjectType: | 773         case kImageDictionary_SkPdfObjectType: | 
| 1127             ret = doXObject_Image(pdfContext, canvas, skobj->asImageDictionary()
      ); | 774             ret = doXObject_Image(pdfContext, canvas, skobj->asImageDictionary()
      ); | 
| 1128             break; | 775             break; | 
| 1129         case kType1FormDictionary_SkPdfObjectType: | 776         case kType1FormDictionary_SkPdfObjectType: | 
| 1130             ret = doXObject_Form(pdfContext, canvas, skobj->asType1FormDictionar
      y()); | 777             ret = doXObject_Form(pdfContext, canvas, skobj->asType1FormDictionar
      y()); | 
| 1131             break; | 778             break; | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1171     SkMatrix matrix = SkMatrixFromPdfMatrix(array); | 818     SkMatrix matrix = SkMatrixFromPdfMatrix(array); | 
| 1172 | 819 | 
| 1173     pdfContext->fGraphicsState.fMatrix.preConcat(matrix); | 820     pdfContext->fGraphicsState.fMatrix.preConcat(matrix); | 
| 1174 | 821 | 
| 1175 #ifdef PDF_TRACE | 822 #ifdef PDF_TRACE | 
| 1176     printf("cm "); | 823     printf("cm "); | 
| 1177     for (int i = 0 ; i < 6 ; i++) { | 824     for (int i = 0 ; i < 6 ; i++) { | 
| 1178         printf("%f ", array[i]); | 825         printf("%f ", array[i]); | 
| 1179     } | 826     } | 
| 1180     printf("\n"); | 827     printf("\n"); | 
| 1181     SkTraceMatrix(pdfContext->fGraphicsState.fMatrix); | 828     SkTraceMatrix(pdfContext->fGraphicsState.fMatrix, "cm"); | 
| 1182 #endif | 829 #endif | 
| 1183 | 830 | 
| 1184     return kOK_PdfResult; | 831     return kOK_PdfResult; | 
| 1185 } | 832 } | 
| 1186 | 833 | 
| 1187 //leading TL Set the text leading, Tl | 834 //leading TL Set the text leading, Tl | 
| 1188 //, to leading, which is a number expressed in unscaled text | 835 //, to leading, which is a number expressed in unscaled text | 
| 1189 //space units. Text leading is used only by the T*, ', and " operators. Initial 
      value: 0. | 836 //space units. Text leading is used only by the T*, ', and " operators. Initial 
      value: 0. | 
| 1190 PdfResult PdfOp_TL(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 837 PdfResult PdfOp_TL(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1191     double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
      >fObjectStack.pop(); | 838     double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
      >fObjectStack.pop(); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 1206     pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); | 853     pdfContext->fGraphicsState.fMatrixTlm.preConcat(matrix); | 
| 1207 | 854 | 
| 1208     return kPartial_PdfResult; | 855     return kPartial_PdfResult; | 
| 1209 } | 856 } | 
| 1210 | 857 | 
| 1211 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 858 PdfResult PdfOp_TD(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1212     double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
      >fObjectStack.pop(); | 859     double ty = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
      >fObjectStack.pop(); | 
| 1213     double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
      >fObjectStack.pop(); | 860     double tx = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext-
      >fObjectStack.pop(); | 
| 1214 | 861 | 
| 1215     // TODO(edisonn): Create factory methods or constructors so podofo is hidden | 862     // TODO(edisonn): Create factory methods or constructors so podofo is hidden | 
| 1216     PdfObject _ty(PdfVariant(-ty)); | 863     SkPdfNumber* _ty = pdfContext->fPdfDoc->createNumber(-ty); | 
| 1217     pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
      , &_ty)); | 864     pdfContext->fObjectStack.push(_ty); | 
| 1218 | 865 | 
| 1219     PdfOp_TL(pdfContext, canvas, looper); | 866     PdfOp_TL(pdfContext, canvas, looper); | 
| 1220 | 867 | 
| 1221     PdfObject vtx(PdfVariant(-(-tx)));  // TODO(edisonn): Hmm, the compiler thin
      ks I have here a function pointer if we use (tx), but not -(-tx) | 868     SkPdfNumber* vtx = pdfContext->fPdfDoc->createNumber(tx); | 
| 1222     pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
      , &vtx)); | 869     pdfContext->fObjectStack.push(vtx); | 
| 1223 | 870 | 
| 1224     PdfObject vty(PdfVariant(-(-ty))); | 871     SkPdfNumber* vty = pdfContext->fPdfDoc->createNumber(ty); | 
| 1225     pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
      , &vty)); | 872     pdfContext->fObjectStack.push(vty); | 
| 1226 | 873 | 
| 1227     return PdfOp_Td(pdfContext, canvas, looper); | 874     PdfResult ret = PdfOp_Td(pdfContext, canvas, looper); | 
|  | 875 | 
|  | 876     // TODO(edisonn): delete all the objects after rendering was complete, in th
      is way pdf is rendered faster | 
|  | 877     // and the cleanup can happen while the user looks at the image | 
|  | 878     delete _ty; | 
|  | 879     delete vtx; | 
|  | 880     delete vty; | 
|  | 881 | 
|  | 882     return ret; | 
| 1228 } | 883 } | 
| 1229 | 884 | 
| 1230 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 885 PdfResult PdfOp_Tm(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1231     double f = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 886     double f = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 
| 1232     double e = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 887     double e = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 
| 1233     double d = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 888     double d = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 
| 1234     double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 889     double c = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 
| 1235     double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 890     double b = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 
| 1236     double a = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 891     double a = pdfContext->fObjectStack.top()->asNumber()->value(); pdfContext->
      fObjectStack.pop(); | 
| 1237 | 892 | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 1250     pdfContext->fGraphicsState.fMatrixTm = matrix; | 905     pdfContext->fGraphicsState.fMatrixTm = matrix; | 
| 1251     pdfContext->fGraphicsState.fMatrixTlm = matrix;; | 906     pdfContext->fGraphicsState.fMatrixTlm = matrix;; | 
| 1252 | 907 | 
| 1253     return kPartial_PdfResult; | 908     return kPartial_PdfResult; | 
| 1254 } | 909 } | 
| 1255 | 910 | 
| 1256 //— T* Move to the start of the next line. This operator has the same effect as 
      the code | 911 //— T* Move to the start of the next line. This operator has the same effect as 
      the code | 
| 1257 //0 Tl Td | 912 //0 Tl Td | 
| 1258 //where Tl is the current leading parameter in the text state | 913 //where Tl is the current leading parameter in the text state | 
| 1259 PdfResult PdfOp_T_star(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
      * looper) { | 914 PdfResult PdfOp_T_star(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
      * looper) { | 
| 1260     PdfObject zero(PdfVariant(0.0)); | 915     SkPdfNumber* zero = pdfContext->fPdfDoc->createNumber(0.0); | 
| 1261     PdfObject tl(PdfVariant(-(-pdfContext->fGraphicsState.fTextLeading))); | 916     SkPdfNumber* tl = pdfContext->fPdfDoc->createNumber(pdfContext->fGraphicsSta
      te.fTextLeading); | 
| 1262 | 917 | 
| 1263     pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
      , &zero)); | 918     pdfContext->fObjectStack.push(zero); | 
| 1264     pdfContext->fObjectStack.push(new SkPdfNumber(&pdfContext->fPdfDoc->podofo()
      , &tl)); | 919     pdfContext->fObjectStack.push(tl); | 
| 1265     return PdfOp_Td(pdfContext, canvas, looper); | 920 | 
|  | 921     PdfResult ret = PdfOp_Td(pdfContext, canvas, looper); | 
|  | 922 | 
|  | 923     delete zero;  // TODO(edisonn): do not alocate and delete constants! | 
|  | 924     delete tl; | 
|  | 925 | 
|  | 926     return ret; | 
| 1266 } | 927 } | 
| 1267 | 928 | 
| 1268 PdfResult PdfOp_m(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per) { | 929 PdfResult PdfOp_m(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per) { | 
| 1269     if (pdfContext->fGraphicsState.fPathClosed) { | 930     if (pdfContext->fGraphicsState.fPathClosed) { | 
| 1270         pdfContext->fGraphicsState.fPath.reset(); | 931         pdfContext->fGraphicsState.fPath.reset(); | 
| 1271         pdfContext->fGraphicsState.fPathClosed = false; | 932         pdfContext->fGraphicsState.fPathClosed = false; | 
| 1272     } | 933     } | 
| 1273 | 934 | 
| 1274     pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->asNumb
      er()->value();    pdfContext->fObjectStack.pop(); | 935     pdfContext->fGraphicsState.fCurPosY = pdfContext->fObjectStack.top()->asNumb
      er()->value();    pdfContext->fObjectStack.pop(); | 
| 1275     pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->asNumb
      er()->value();    pdfContext->fObjectStack.pop(); | 936     pdfContext->fGraphicsState.fCurPosX = pdfContext->fObjectStack.top()->asNumb
      er()->value();    pdfContext->fObjectStack.pop(); | 
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1518 //, to font and the text font size, Tfs, to size. font is the name of a | 1179 //, to font and the text font size, Tfs, to size. font is the name of a | 
| 1519 //font resource in the Fontsubdictionary of the current resource dictionary; siz
      e is | 1180 //font resource in the Fontsubdictionary of the current resource dictionary; siz
      e is | 
| 1520 //a number representing a scale factor. There is no initial value for either fon
      t or | 1181 //a number representing a scale factor. There is no initial value for either fon
      t or | 
| 1521 //size; they must be specified explicitly using Tf before any text is shown. | 1182 //size; they must be specified explicitly using Tf before any text is shown. | 
| 1522 PdfResult PdfOp_Tf(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 1183 PdfResult PdfOp_Tf(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1523     pdfContext->fGraphicsState.fCurFontSize = pdfContext->fObjectStack.top()->as
      Number()->value();     pdfContext->fObjectStack.pop(); | 1184     pdfContext->fGraphicsState.fCurFontSize = pdfContext->fObjectStack.top()->as
      Number()->value();     pdfContext->fObjectStack.pop(); | 
| 1524     std::string fontName = pdfContext->fObjectStack.top()->asName()->value();   
                              pdfContext->fObjectStack.pop(); | 1185     std::string fontName = pdfContext->fObjectStack.top()->asName()->value();   
                              pdfContext->fObjectStack.pop(); | 
| 1525 | 1186 | 
| 1526 #ifdef PDF_TRACE | 1187 #ifdef PDF_TRACE | 
| 1527     printf("font name: %s\n", fontName.c_str()); | 1188     printf("font name: %s\n", fontName.c_str()); | 
| 1528     std::string str; |  | 
| 1529     pdfContext->fGraphicsState.fResources->podofo()->ToString(str); |  | 
| 1530     printf("Print Tf Resources: %s\n", str.c_str()); |  | 
| 1531     pdfContext->fGraphicsState.fResources->Font()->podofo()->ToString(str); |  | 
| 1532     printf("Print Tf Resources/Font: %s\n", str.c_str()); |  | 
| 1533 #endif | 1189 #endif | 
| 1534 | 1190 | 
| 1535     SkPdfFontDictionary* fd = NULL; | 1191     SkPdfFontDictionary* fd = NULL; | 
| 1536     if (pdfContext->fGraphicsState.fResources->Font()) { | 1192     if (pdfContext->fGraphicsState.fResources->Font()) { | 
| 1537         SkPdfObject* objFont = pdfContext->fGraphicsState.fResources->Font()->ge
      t(fontName.c_str()); | 1193         SkPdfObject* objFont = pdfContext->fGraphicsState.fResources->Font()->ge
      t(fontName.c_str()); | 
| 1538         mapFontDictionary(*objFont, &fd); | 1194         objFont->doc()->mapper()->mapFontDictionary(objFont, &fd); | 
| 1539 |  | 
| 1540 #ifdef PDF_TRACE |  | 
| 1541         objFont->podofo()->ToString(str); |  | 
| 1542         printf("Print Font loaded: %s\n", str.c_str()); |  | 
| 1543         fd->podofo()->ToString(str); |  | 
| 1544         printf("Print Font loaded and resolved and upgraded: %s\n", str.c_str())
      ; |  | 
| 1545 #endif |  | 
| 1546 |  | 
| 1547     } | 1195     } | 
| 1548 | 1196 | 
| 1549     SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(fd); | 1197     SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(fd); | 
| 1550 | 1198 | 
| 1551     if (skfont) { | 1199     if (skfont) { | 
| 1552         pdfContext->fGraphicsState.fSkFont = skfont; | 1200         pdfContext->fGraphicsState.fSkFont = skfont; | 
| 1553     } | 1201     } | 
| 1554 | 1202 | 
| 1555     return kPartial_PdfResult; | 1203     return kPartial_PdfResult; | 
| 1556 } | 1204 } | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1631                           SkDoubleToScalar(0), | 1279                           SkDoubleToScalar(0), | 
| 1632                           SkDoubleToScalar(0), | 1280                           SkDoubleToScalar(0), | 
| 1633                           SkDoubleToScalar(1)); | 1281                           SkDoubleToScalar(1)); | 
| 1634 | 1282 | 
| 1635             pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 1283             pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 
| 1636         } | 1284         } | 
| 1637     } | 1285     } | 
| 1638     return kPartial_PdfResult;  // TODO(edisonn): Implement fully DrawText befor
      e returing OK. | 1286     return kPartial_PdfResult;  // TODO(edisonn): Implement fully DrawText befor
      e returing OK. | 
| 1639 } | 1287 } | 
| 1640 | 1288 | 
| 1641 PdfResult PdfOp_CS_cs(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator
      * colorOperator) { | 1289 PdfResult PdfOp_CS_cs(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
      or* colorOperator) { | 
| 1642     colorOperator->fColorSpace = pdfContext->fObjectStack.top()->asName()->value
      ();    pdfContext->fObjectStack.pop(); | 1290     colorOperator->fColorSpace = pdfContext->fObjectStack.top()->asName()->value
      ();    pdfContext->fObjectStack.pop(); | 
| 1643     return kOK_PdfResult; | 1291     return kOK_PdfResult; | 
| 1644 } | 1292 } | 
| 1645 | 1293 | 
| 1646 PdfResult PdfOp_CS(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 1294 PdfResult PdfOp_CS(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1647     return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
      ); | 1295     return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
      ); | 
| 1648 } | 1296 } | 
| 1649 | 1297 | 
| 1650 PdfResult PdfOp_cs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 1298 PdfResult PdfOp_cs(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1651     return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
      ing); | 1299     return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
      ing); | 
| 1652 } | 1300 } | 
| 1653 | 1301 | 
| 1654 PdfResult PdfOp_SC_sc(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator
      * colorOperator) { | 1302 PdfResult PdfOp_SC_sc(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
      or* colorOperator) { | 
| 1655     double c[4]; | 1303     double c[4]; | 
| 1656     pdf_int64 v[4]; | 1304     pdf_int64 v[4]; | 
| 1657 | 1305 | 
| 1658     int n = GetColorSpaceComponents(colorOperator->fColorSpace); | 1306     int n = GetColorSpaceComponents(colorOperator->fColorSpace); | 
| 1659 | 1307 | 
| 1660     bool doubles = true; | 1308     bool doubles = true; | 
| 1661     if (colorOperator->fColorSpace == "Indexed") { | 1309     if (colorOperator->fColorSpace == "Indexed") { | 
| 1662         doubles = false; | 1310         doubles = false; | 
| 1663     } | 1311     } | 
| 1664 | 1312 | 
| 1665 #ifdef PDF_TRACE | 1313 #ifdef PDF_TRACE | 
| 1666     printf("color space = %s, N = %i\n", colorOperator->fColorSpace.c_str(), n); | 1314     printf("color space = %s, N = %i\n", colorOperator->fColorSpace.c_str(), n); | 
| 1667 #endif | 1315 #endif | 
| 1668 | 1316 | 
| 1669     for (int i = n - 1; i >= 0 ; i--) { | 1317     for (int i = n - 1; i >= 0 ; i--) { | 
| 1670         if (doubles) { | 1318         if (doubles) { | 
| 1671             c[i] = pdfContext->fObjectStack.top()->asNumber()->value();     pdfC
      ontext->fObjectStack.pop(); | 1319             c[i] = pdfContext->fObjectStack.top()->asNumber()->value();         
      pdfContext->fObjectStack.pop(); | 
| 1672         } else { | 1320         } else { | 
| 1673             v[i] = pdfContext->fObjectStack.top()->asInteger()->value();   pdfCo
      ntext->fObjectStack.pop(); | 1321             v[i] = pdfContext->fObjectStack.top()->asInteger()->value();        
      pdfContext->fObjectStack.pop(); | 
| 1674         } | 1322         } | 
| 1675     } | 1323     } | 
| 1676 | 1324 | 
| 1677     // TODO(edisonn): Now, set that color. Only DeviceRGB supported. | 1325     // TODO(edisonn): Now, set that color. Only DeviceRGB supported. | 
| 1678     if (colorOperator->fColorSpace == "DeviceRGB") { | 1326     if (colorOperator->fColorSpace == "DeviceRGB") { | 
| 1679         colorOperator->setRGBColor(SkColorSetRGB(255*c[0], 255*c[1], 255*c[2])); | 1327         colorOperator->setRGBColor(SkColorSetRGB(255*c[0], 255*c[1], 255*c[2])); | 
| 1680     } | 1328     } | 
| 1681     return kPartial_PdfResult; | 1329     return kPartial_PdfResult; | 
| 1682 } | 1330 } | 
| 1683 | 1331 | 
| 1684 PdfResult PdfOp_SC(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 1332 PdfResult PdfOp_SC(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1685     return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
      ); | 1333     return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
      ); | 
| 1686 } | 1334 } | 
| 1687 | 1335 | 
| 1688 PdfResult PdfOp_sc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 1336 PdfResult PdfOp_sc(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1689     return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
      ing); | 1337     return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
      ing); | 
| 1690 } | 1338 } | 
| 1691 | 1339 | 
| 1692 PdfResult PdfOp_SCN_scn(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperat
      or* colorOperator) { | 1340 PdfResult PdfOp_SCN_scn(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOper
      ator* colorOperator) { | 
| 1693     PdfString name; | 1341     PdfString name; | 
| 1694 | 1342 | 
| 1695     if (pdfContext->fObjectStack.top()->asName()) { | 1343     if (pdfContext->fObjectStack.top()->asName()) { | 
| 1696         pdfContext->fObjectStack.pop(); | 1344         pdfContext->fObjectStack.pop(); | 
| 1697     } | 1345     } | 
| 1698 | 1346 | 
| 1699     // TODO(edisonn): SCN supports more color spaces than SCN. Read and implemen
      t spec. | 1347     // TODO(edisonn): SCN supports more color spaces than SCN. Read and implemen
      t spec. | 
| 1700     PdfOp_SC_sc(pdfContext, canvas, colorOperator); | 1348     PdfOp_SC_sc(pdfContext, canvas, colorOperator); | 
| 1701 | 1349 | 
| 1702     return kPartial_PdfResult; | 1350     return kPartial_PdfResult; | 
| 1703 } | 1351 } | 
| 1704 | 1352 | 
| 1705 PdfResult PdfOp_SCN(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
      ooper) { | 1353 PdfResult PdfOp_SCN(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
      ooper) { | 
| 1706     return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroki
      ng); | 1354     return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroki
      ng); | 
| 1707 } | 1355 } | 
| 1708 | 1356 | 
| 1709 PdfResult PdfOp_scn(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
      ooper) { | 1357 PdfResult PdfOp_scn(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** l
      ooper) { | 
| 1710     return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStr
      oking); | 1358     return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStr
      oking); | 
| 1711 } | 1359 } | 
| 1712 | 1360 | 
| 1713 PdfResult PdfOp_G_g(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator* 
      colorOperator) { | 1361 PdfResult PdfOp_G_g(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator
      * colorOperator) { | 
| 1714     double gray = pdfContext->fObjectStack.top()->asNumber()->value();     pdfCo
      ntext->fObjectStack.pop(); | 1362     double gray = pdfContext->fObjectStack.top()->asNumber()->value();     pdfCo
      ntext->fObjectStack.pop(); | 
| 1715     return kNYI_PdfResult; | 1363     return kNYI_PdfResult; | 
| 1716 } | 1364 } | 
| 1717 | 1365 | 
| 1718 PdfResult PdfOp_G(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per) { | 1366 PdfResult PdfOp_G(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per) { | 
| 1719     return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); | 1367     return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); | 
| 1720 } | 1368 } | 
| 1721 | 1369 | 
| 1722 PdfResult PdfOp_g(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per) { | 1370 PdfResult PdfOp_g(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** loo
      per) { | 
| 1723     return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
      g); | 1371     return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
      g); | 
| 1724 } | 1372 } | 
| 1725 | 1373 | 
| 1726 PdfResult PdfOp_RG_rg(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator
      * colorOperator) { | 1374 PdfResult PdfOp_RG_rg(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperat
      or* colorOperator) { | 
| 1727     double b = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 1375     double b = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 
| 1728     double g = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 1376     double g = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 
| 1729     double r = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 1377     double r = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 
| 1730 | 1378 | 
| 1731     colorOperator->fColorSpace = "DeviceRGB"; | 1379     colorOperator->fColorSpace = "DeviceRGB"; | 
| 1732     colorOperator->setRGBColor(SkColorSetRGB(255*r, 255*g, 255*b)); | 1380     colorOperator->setRGBColor(SkColorSetRGB(255*r, 255*g, 255*b)); | 
| 1733     return kOK_PdfResult; | 1381     return kOK_PdfResult; | 
| 1734 } | 1382 } | 
| 1735 | 1383 | 
| 1736 PdfResult PdfOp_RG(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 1384 PdfResult PdfOp_RG(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1737     return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
      ); | 1385     return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
      ); | 
| 1738 } | 1386 } | 
| 1739 | 1387 | 
| 1740 PdfResult PdfOp_rg(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 1388 PdfResult PdfOp_rg(PdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** lo
      oper) { | 
| 1741     return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
      ing); | 1389     return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
      ing); | 
| 1742 } | 1390 } | 
| 1743 | 1391 | 
| 1744 PdfResult PdfOp_K_k(PdfContext* pdfContext, SkCanvas* canvas, PdfColorOperator* 
      colorOperator) { | 1392 PdfResult PdfOp_K_k(PdfContext* pdfContext, SkCanvas* canvas, SkPdfColorOperator
      * colorOperator) { | 
| 1745     // TODO(edisonn): spec has some rules about overprint, implement them. | 1393     // TODO(edisonn): spec has some rules about overprint, implement them. | 
| 1746     double k = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 1394     double k = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 
| 1747     double y = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 1395     double y = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 
| 1748     double m = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 1396     double m = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 
| 1749     double c = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 1397     double c = pdfContext->fObjectStack.top()->asNumber()->value();     pdfConte
      xt->fObjectStack.pop(); | 
| 1750 | 1398 | 
| 1751     colorOperator->fColorSpace = "DeviceCMYK"; | 1399     colorOperator->fColorSpace = "DeviceCMYK"; | 
| 1752     // TODO(edisonn): Set color. | 1400     // TODO(edisonn): Set color. | 
| 1753     return kNYI_PdfResult; | 1401     return kNYI_PdfResult; | 
| 1754 } | 1402 } | 
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1889 | 1537 | 
| 1890     if (extGStateDictionary == NULL) { | 1538     if (extGStateDictionary == NULL) { | 
| 1891 #ifdef PDF_TRACE | 1539 #ifdef PDF_TRACE | 
| 1892         printf("ExtGState is NULL!\n"); | 1540         printf("ExtGState is NULL!\n"); | 
| 1893 #endif | 1541 #endif | 
| 1894         return kIgnoreError_PdfResult; | 1542         return kIgnoreError_PdfResult; | 
| 1895     } | 1543     } | 
| 1896 | 1544 | 
| 1897     SkPdfObject* value = extGStateDictionary->get(name.c_str()); | 1545     SkPdfObject* value = extGStateDictionary->get(name.c_str()); | 
| 1898 | 1546 | 
| 1899 #ifdef PDF_TRACE |  | 
| 1900 //    value->ToString(str); |  | 
| 1901 //    printf("gs object value: %s\n", str.c_str()); |  | 
| 1902 #endif |  | 
| 1903 |  | 
| 1904     SkPdfGraphicsStateDictionary* gs = NULL; | 1547     SkPdfGraphicsStateDictionary* gs = NULL; | 
| 1905     mapGraphicsStateDictionary(*value, &gs); | 1548     value->doc()->mapper()->mapGraphicsStateDictionary(value, &gs); | 
| 1906 | 1549 | 
| 1907     // TODO(edisonn): now load all those properties in graphic state. | 1550     // TODO(edisonn): now load all those properties in graphic state. | 
| 1908     if (gs == NULL) { | 1551     if (gs == NULL) { | 
| 1909         return kIgnoreError_PdfResult; | 1552         return kIgnoreError_PdfResult; | 
| 1910     } | 1553     } | 
| 1911 | 1554 | 
| 1912     if (gs->has_CA()) { | 1555     if (gs->has_CA()) { | 
| 1913         pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(); | 1556         pdfContext->fGraphicsState.fStroking.fOpacity = gs->CA(); | 
| 1914     } | 1557     } | 
| 1915 | 1558 | 
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2293 // e.g. SkBitmap getPage(int page); | 1936 // e.g. SkBitmap getPage(int page); | 
| 2294 //      int formsCount(); | 1937 //      int formsCount(); | 
| 2295 //      SkForm getForm(int formID); // SkForm(SkRect, .. other data) | 1938 //      SkForm getForm(int formID); // SkForm(SkRect, .. other data) | 
| 2296 // TODO (edisonn): Add intend when loading pdf, for example: for viewing, parsin
      g all content, ... | 1939 // TODO (edisonn): Add intend when loading pdf, for example: for viewing, parsin
      g all content, ... | 
| 2297 // if we load the first page, and we zoom to fit to screen horizontally, then lo
      ad only those | 1940 // if we load the first page, and we zoom to fit to screen horizontally, then lo
      ad only those | 
| 2298 // resources needed, so the preview is fast. | 1941 // resources needed, so the preview is fast. | 
| 2299 // TODO (edisonn): hide parser/tokenizer behind and interface and a query langua
      ge, and resolve | 1942 // TODO (edisonn): hide parser/tokenizer behind and interface and a query langua
      ge, and resolve | 
| 2300 // references automatically. | 1943 // references automatically. | 
| 2301 | 1944 | 
| 2302 bool SkPdfViewer::load(const SkString inputFileName, SkPicture* out) { | 1945 bool SkPdfViewer::load(const SkString inputFileName, SkPicture* out) { | 
| 2303     try | 1946     std::cout << "Init: " << inputFileName.c_str() << std::endl; | 
|  | 1947 | 
|  | 1948     SkPodofoParsedPDF* doc = new SkPodofoParsedPDF(inputFileName.c_str()); | 
|  | 1949     if (!doc->pages()) | 
| 2304     { | 1950     { | 
| 2305         std::cout << "Init: " << inputFileName.c_str() << std::endl; | 1951         std::cout << "ERROR: Empty Document" << inputFileName.c_str() << std::en
      dl; | 
|  | 1952         return false; | 
|  | 1953     } else { | 
| 2306 | 1954 | 
| 2307         SkPdfDoc doc(inputFileName.c_str()); | 1955         for (int pn = 0; pn < doc->pages(); ++pn) { | 
| 2308         if (!doc.pages()) | 1956             // TODO(edisonn): implement inheritance properties as per PDF spec | 
| 2309         { | 1957             //SkRect rect = page->MediaBox(); | 
| 2310             std::cout << "ERROR: Empty Document" << inputFileName.c_str() << std
      ::endl; | 1958             SkRect rect = doc->MediaBox(pn); | 
| 2311             return false; |  | 
| 2312         } else { |  | 
| 2313 | 1959 | 
| 2314             for (int pn = 0; pn < doc.pages(); ++pn) { | 1960 #ifdef PDF_TRACE | 
| 2315                 // TODO(edisonn): implement inheritance properties as per PDF sp
      ec | 1961             printf("Page Width: %f, Page Height: %f\n", SkScalarToDouble(rect.wi
      dth()), SkScalarToDouble(rect.height())); | 
| 2316                 //SkRect rect = page->MediaBox(); | 1962 #endif | 
| 2317                 SkRect rect = doc.MediaBox(pn); |  | 
| 2318 | 1963 | 
| 2319     #ifdef PDF_TRACE | 1964             // TODO(edisonn): page->GetCropBox(), page->GetTrimBox() ... how to 
      use? | 
| 2320                 printf("Page Width: %f, Page Height: %f\n", SkScalarToDouble(rec
      t.width()), SkScalarToDouble(rect.height())); |  | 
| 2321     #endif |  | 
| 2322 | 1965 | 
| 2323                 // TODO(edisonn): page->GetCropBox(), page->GetTrimBox() ... how
       to use? | 1966             SkBitmap bitmap; | 
|  | 1967 #ifdef PDF_DEBUG_3X | 
|  | 1968             setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3 * (
      int)SkScalarToDouble(rect.height())); | 
|  | 1969 #else | 
|  | 1970             setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)SkSc
      alarToDouble(rect.height())); | 
|  | 1971 #endif | 
|  | 1972             SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (bitmap))); | 
|  | 1973             SkCanvas canvas(device); | 
| 2324 | 1974 | 
| 2325                 SkBitmap bitmap; | 1975             gDumpBitmap = &bitmap; | 
| 2326     #ifdef PDF_DEBUG_3X |  | 
| 2327                 setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3
       * (int)SkScalarToDouble(rect.height())); |  | 
| 2328     #else |  | 
| 2329                 setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)
      SkScalarToDouble(rect.height())); |  | 
| 2330     #endif |  | 
| 2331                 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (bitmap))); |  | 
| 2332                 SkCanvas canvas(device); |  | 
| 2333 | 1976 | 
| 2334                 gDumpBitmap = &bitmap; | 1977             gDumpCanvas = &canvas; | 
|  | 1978             doc->drawPage(pn, &canvas); | 
| 2335 | 1979 | 
| 2336                 doc.drawPage(pn, &canvas); | 1980             SkString out; | 
| 2337 | 1981             if (doc->pages() > 1) { | 
| 2338                 SkString out; | 1982                 out.appendf("%s-%i.png", inputFileName.c_str(), pn); | 
| 2339                 if (doc.pages() > 1) { | 1983             } else { | 
| 2340                     out.appendf("%s-%i.png", inputFileName.c_str(), pn); | 1984                 out = inputFileName; | 
| 2341                 } else { | 1985                 // .pdf -> .png | 
| 2342                     out = inputFileName; | 1986                 out[out.size() - 2] = 'n'; | 
| 2343                     // .pdf -> .png | 1987                 out[out.size() - 1] = 'g'; | 
| 2344                     out[out.size() - 2] = 'n'; |  | 
| 2345                     out[out.size() - 1] = 'g'; |  | 
| 2346                 } |  | 
| 2347                 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::
      kPNG_Type, 100); |  | 
| 2348             } | 1988             } | 
| 2349             return true; | 1989             SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG
      _Type, 100); | 
| 2350         } | 1990         } | 
| 2351     } | 1991         return true; | 
| 2352     catch( PdfError & e ) |  | 
| 2353     { |  | 
| 2354         e.PrintErrorMsg(); |  | 
| 2355         std::cout << "ERROR: PDF can't be parsed!" << inputFileName.c_str() << s
      td::endl; |  | 
| 2356         return false; |  | 
| 2357     } | 1992     } | 
| 2358 | 1993 | 
| 2359     return true; | 1994     return true; | 
| 2360 } | 1995 } | 
| OLD | NEW | 
|---|