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 |