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