| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2011 Google Inc. | 2  * Copyright 2011 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 "SkData.h" | 
| 8 #include "SkDeflate.h" | 9 #include "SkDeflate.h" | 
| 9 #include "SkPDFTypes.h" | 10 #include "SkPDFTypes.h" | 
| 10 #include "SkPDFUtils.h" | 11 #include "SkPDFUtils.h" | 
| 11 #include "SkStream.h" | 12 #include "SkStream.h" | 
| 12 #include "SkStreamPriv.h" | 13 #include "SkStreamPriv.h" | 
| 13 | 14 | 
| 14 //////////////////////////////////////////////////////////////////////////////// | 15 //////////////////////////////////////////////////////////////////////////////// | 
| 15 | 16 | 
| 16 SkString* pun(char* x) { return reinterpret_cast<SkString*>(x); } | 17 SkString* pun(char* x) { return reinterpret_cast<SkString*>(x); } | 
| 17 const SkString* pun(const char* x) { | 18 const SkString* pun(const char* x) { | 
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 449 void SkPDFDict::insertString(const char key[], const char value[]) { | 450 void SkPDFDict::insertString(const char key[], const char value[]) { | 
| 450     fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::String(value)); | 451     fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::String(value)); | 
| 451 } | 452 } | 
| 452 | 453 | 
| 453 void SkPDFDict::insertString(const char key[], const SkString& value) { | 454 void SkPDFDict::insertString(const char key[], const SkString& value) { | 
| 454     fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::String(value)); | 455     fRecords.emplace_back(SkPDFUnion::Name(key), SkPDFUnion::String(value)); | 
| 455 } | 456 } | 
| 456 | 457 | 
| 457 //////////////////////////////////////////////////////////////////////////////// | 458 //////////////////////////////////////////////////////////////////////////////// | 
| 458 | 459 | 
| 459 SkPDFSharedStream::SkPDFSharedStream(SkStreamAsset* data) | 460 SkPDFSharedStream::SkPDFSharedStream(std::unique_ptr<SkStreamAsset> data) | 
| 460     : fAsset(data), fDict(new SkPDFDict) { | 461     : fAsset(std::move(data)) { | 
| 461     SkDEBUGCODE(fDumped = false;) | 462     SkASSERT(fAsset); | 
| 462     SkASSERT(data); |  | 
| 463 } | 463 } | 
| 464 | 464 | 
| 465 SkPDFSharedStream::~SkPDFSharedStream() { this->drop(); } | 465 SkPDFSharedStream::~SkPDFSharedStream() { this->drop(); } | 
| 466 | 466 | 
| 467 void SkPDFSharedStream::drop() { | 467 void SkPDFSharedStream::drop() { | 
| 468     fAsset.reset(); | 468     fAsset = nullptr;; | 
| 469     fDict.reset(nullptr); | 469     fDict.drop(); | 
| 470     SkDEBUGCODE(fDumped = true;) |  | 
| 471 } | 470 } | 
| 472 | 471 | 
| 473 #ifdef SK_PDF_LESS_COMPRESSION | 472 #ifdef SK_PDF_LESS_COMPRESSION | 
| 474 void SkPDFSharedStream::emitObject( | 473 void SkPDFSharedStream::emitObject( | 
| 475         SkWStream* stream, | 474         SkWStream* stream, | 
| 476         const SkPDFObjNumMap& objNumMap, | 475         const SkPDFObjNumMap& objNumMap, | 
| 477         const SkPDFSubstituteMap& substitutes) const { | 476         const SkPDFSubstituteMap& substitutes) const { | 
| 478     SkASSERT(!fDumped); | 477     SkASSERT(fAsset); | 
| 479     std::unique_ptr<SkStreamAsset> dup(fAsset->duplicate()); | 478     std::unique_ptr<SkStreamAsset> dup(fAsset->duplicate()); | 
| 480     SkASSERT(dup && dup->hasLength()); | 479     SkASSERT(dup && dup->hasLength()); | 
| 481     size_t length = dup->getLength(); | 480     size_t length = dup->getLength(); | 
| 482     stream->writeText("<<"); | 481     stream->writeText("<<"); | 
| 483     fDict->emitAll(stream, objNumMap, substitutes); | 482     fDict.emitAll(stream, objNumMap, substitutes); | 
| 484     stream->writeText("\n"); | 483     stream->writeText("\n"); | 
| 485     SkPDFUnion::Name("Length").emitObject( | 484     SkPDFUnion::Name("Length").emitObject( | 
| 486             stream, objNumMap, substitutes); | 485             stream, objNumMap, substitutes); | 
| 487     stream->writeText(" "); | 486     stream->writeText(" "); | 
| 488     SkPDFUnion::Int(length).emitObject( | 487     SkPDFUnion::Int(length).emitObject( | 
| 489             stream, objNumMap, substitutes); | 488             stream, objNumMap, substitutes); | 
| 490     stream->writeText("\n>>stream\n"); | 489     stream->writeText("\n>>stream\n"); | 
| 491     SkStreamCopy(stream, dup.get()); | 490     SkStreamCopy(stream, dup.get()); | 
| 492     stream->writeText("\nendstream"); | 491     stream->writeText("\nendstream"); | 
| 493 } | 492 } | 
| 494 #else | 493 #else | 
| 495 void SkPDFSharedStream::emitObject( | 494 void SkPDFSharedStream::emitObject( | 
| 496         SkWStream* stream, | 495         SkWStream* stream, | 
| 497         const SkPDFObjNumMap& objNumMap, | 496         const SkPDFObjNumMap& objNumMap, | 
| 498         const SkPDFSubstituteMap& substitutes) const { | 497         const SkPDFSubstituteMap& substitutes) const { | 
| 499     SkASSERT(!fDumped); | 498     SkASSERT(fAsset); | 
| 500     SkDynamicMemoryWStream buffer; | 499     SkDynamicMemoryWStream buffer; | 
| 501     SkDeflateWStream deflateWStream(&buffer); | 500     SkDeflateWStream deflateWStream(&buffer); | 
| 502     // Since emitObject is const, this function doesn't change the dictionary. | 501     // Since emitObject is const, this function doesn't change the dictionary. | 
| 503     std::unique_ptr<SkStreamAsset> dup(fAsset->duplicate());  // Cheap copy | 502     std::unique_ptr<SkStreamAsset> dup(fAsset->duplicate());  // Cheap copy | 
| 504     SkASSERT(dup); | 503     SkASSERT(dup); | 
| 505     SkStreamCopy(&deflateWStream, dup.get()); | 504     SkStreamCopy(&deflateWStream, dup.get()); | 
| 506     deflateWStream.finalize(); | 505     deflateWStream.finalize(); | 
| 507     size_t length = buffer.bytesWritten(); | 506     size_t length = buffer.bytesWritten(); | 
| 508     stream->writeText("<<"); | 507     stream->writeText("<<"); | 
| 509     fDict->emitAll(stream, objNumMap, substitutes); | 508     fDict.emitAll(stream, objNumMap, substitutes); | 
| 510     stream->writeText("\n"); | 509     stream->writeText("\n"); | 
| 511     SkPDFUnion::Name("Length").emitObject(stream, objNumMap, substitutes); | 510     SkPDFUnion::Name("Length").emitObject(stream, objNumMap, substitutes); | 
| 512     stream->writeText(" "); | 511     stream->writeText(" "); | 
| 513     SkPDFUnion::Int(length).emitObject(stream, objNumMap, substitutes); | 512     SkPDFUnion::Int(length).emitObject(stream, objNumMap, substitutes); | 
| 514     stream->writeText("\n"); | 513     stream->writeText("\n"); | 
| 515     SkPDFUnion::Name("Filter").emitObject(stream, objNumMap, substitutes); | 514     SkPDFUnion::Name("Filter").emitObject(stream, objNumMap, substitutes); | 
| 516     stream->writeText(" "); | 515     stream->writeText(" "); | 
| 517     SkPDFUnion::Name("FlateDecode").emitObject(stream, objNumMap, substitutes); | 516     SkPDFUnion::Name("FlateDecode").emitObject(stream, objNumMap, substitutes); | 
| 518     stream->writeText(">>"); | 517     stream->writeText(">>"); | 
| 519     stream->writeText(" stream\n"); | 518     stream->writeText(" stream\n"); | 
| 520     buffer.writeToStream(stream); | 519     buffer.writeToStream(stream); | 
| 521     stream->writeText("\nendstream"); | 520     stream->writeText("\nendstream"); | 
| 522 } | 521 } | 
| 523 #endif | 522 #endif | 
| 524 | 523 | 
| 525 void SkPDFSharedStream::addResources( | 524 void SkPDFSharedStream::addResources( | 
| 526         SkPDFObjNumMap* catalog, const SkPDFSubstituteMap& substitutes) const { | 525         SkPDFObjNumMap* catalog, const SkPDFSubstituteMap& substitutes) const { | 
| 527     SkASSERT(!fDumped); | 526     SkASSERT(fAsset); | 
| 528     fDict->addResources(catalog, substitutes); | 527     fDict.addResources(catalog, substitutes); | 
|  | 528 } | 
|  | 529 | 
|  | 530 | 
|  | 531 //////////////////////////////////////////////////////////////////////////////// | 
|  | 532 | 
|  | 533 SkPDFStream:: SkPDFStream(sk_sp<SkData> data) { | 
|  | 534     this->setData(std::unique_ptr<SkStreamAsset>( | 
|  | 535                           new SkMemoryStream(std::move(data)))); | 
|  | 536 } | 
|  | 537 | 
|  | 538 SkPDFStream::SkPDFStream(std::unique_ptr<SkStreamAsset> stream) { | 
|  | 539     this->setData(std::move(stream)); | 
|  | 540 } | 
|  | 541 | 
|  | 542 SkPDFStream::SkPDFStream() {} | 
|  | 543 | 
|  | 544 SkPDFStream::~SkPDFStream() {} | 
|  | 545 | 
|  | 546 void SkPDFStream::addResources( | 
|  | 547         SkPDFObjNumMap* catalog, const SkPDFSubstituteMap& substitutes) const { | 
|  | 548     SkASSERT(fCompressedData); | 
|  | 549     fDict.addResources(catalog, substitutes); | 
|  | 550 } | 
|  | 551 | 
|  | 552 void SkPDFStream::drop() { | 
|  | 553     fCompressedData.reset(nullptr); | 
|  | 554     fDict.drop(); | 
|  | 555 } | 
|  | 556 | 
|  | 557 void SkPDFStream::emitObject(SkWStream* stream, | 
|  | 558                              const SkPDFObjNumMap& objNumMap, | 
|  | 559                              const SkPDFSubstituteMap& substitutes) const { | 
|  | 560     SkASSERT(fCompressedData); | 
|  | 561     fDict.emitObject(stream, objNumMap, substitutes); | 
|  | 562     // duplicate (a cheap operation) preserves const on fCompressedData. | 
|  | 563     std::unique_ptr<SkStreamAsset> dup(fCompressedData->duplicate()); | 
|  | 564     SkASSERT(dup); | 
|  | 565     SkASSERT(dup->hasLength()); | 
|  | 566     stream->writeText(" stream\n"); | 
|  | 567     stream->writeStream(dup.get(), dup->getLength()); | 
|  | 568     stream->writeText("\nendstream"); | 
|  | 569 } | 
|  | 570 | 
|  | 571 void SkPDFStream::setData(std::unique_ptr<SkStreamAsset> stream) { | 
|  | 572     SkASSERT(!fCompressedData);  // Only call this function once. | 
|  | 573     SkASSERT(stream); | 
|  | 574     // Code assumes that the stream starts at the beginning. | 
|  | 575 | 
|  | 576     #ifdef SK_PDF_LESS_COMPRESSION | 
|  | 577     fCompressedData = std::move(stream); | 
|  | 578     SkASSERT(fCompressedData && fCompressedData->hasLength()); | 
|  | 579     fDict.insertInt("Length", fCompressedData->getLength()); | 
|  | 580     #else | 
|  | 581 | 
|  | 582     SkASSERT(stream->hasLength()); | 
|  | 583     SkDynamicMemoryWStream compressedData; | 
|  | 584     SkDeflateWStream deflateWStream(&compressedData); | 
|  | 585     SkStreamCopy(&deflateWStream, stream.get()); | 
|  | 586     deflateWStream.finalize(); | 
|  | 587     size_t compressedLength = compressedData.bytesWritten(); | 
|  | 588     size_t originalLength = stream->getLength(); | 
|  | 589 | 
|  | 590     if (originalLength <= compressedLength + strlen("/Filter_/FlateDecode_")) { | 
|  | 591         SkAssertResult(stream->rewind()); | 
|  | 592         fCompressedData = std::move(stream); | 
|  | 593         fDict.insertInt("Length", originalLength); | 
|  | 594         return; | 
|  | 595     } | 
|  | 596     fCompressedData.reset(compressedData.detachAsStream()); | 
|  | 597     fDict.insertName("Filter", "FlateDecode"); | 
|  | 598     fDict.insertInt("Length", compressedLength); | 
|  | 599     #endif | 
| 529 } | 600 } | 
| 530 | 601 | 
| 531 //////////////////////////////////////////////////////////////////////////////// | 602 //////////////////////////////////////////////////////////////////////////////// | 
| 532 | 603 | 
| 533 SkPDFSubstituteMap::~SkPDFSubstituteMap() { | 604 SkPDFSubstituteMap::~SkPDFSubstituteMap() { | 
| 534     fSubstituteMap.foreach( | 605     fSubstituteMap.foreach( | 
| 535             [](SkPDFObject*, SkPDFObject** v) { (*v)->unref(); }); | 606             [](SkPDFObject*, SkPDFObject** v) { (*v)->unref(); }); | 
| 536 } | 607 } | 
| 537 | 608 | 
| 538 void SkPDFSubstituteMap::setSubstitute(SkPDFObject* original, | 609 void SkPDFSubstituteMap::setSubstitute(SkPDFObject* original, | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 578 | 649 | 
| 579 void SkPDFImageDumpStats() { | 650 void SkPDFImageDumpStats() { | 
| 580     SkDebugf("\ntotal PDF drawImage/drawBitmap calls: %d\n" | 651     SkDebugf("\ntotal PDF drawImage/drawBitmap calls: %d\n" | 
| 581              "total PDF jpeg images: %d\n" | 652              "total PDF jpeg images: %d\n" | 
| 582              "total PDF regular images: %d\n", | 653              "total PDF regular images: %d\n", | 
| 583              gDrawImageCalls.load(), | 654              gDrawImageCalls.load(), | 
| 584              gJpegImageObjects.load(), | 655              gJpegImageObjects.load(), | 
| 585              gRegularImageObjects.load()); | 656              gRegularImageObjects.load()); | 
| 586 } | 657 } | 
| 587 #endif // SK_PDF_IMAGE_STATS | 658 #endif // SK_PDF_IMAGE_STATS | 
| OLD | NEW | 
|---|