| Index: src/pdf/SkPDFTypes.cpp
|
| diff --git a/src/pdf/SkPDFTypes.cpp b/src/pdf/SkPDFTypes.cpp
|
| index 8c59a4a0085c1da9b0ca918457937e8ea2cfb37f..f16e56f436270c2641ac6cfef98c1c74be7fab2c 100644
|
| --- a/src/pdf/SkPDFTypes.cpp
|
| +++ b/src/pdf/SkPDFTypes.cpp
|
| @@ -5,6 +5,7 @@
|
| * found in the LICENSE file.
|
| */
|
|
|
| +#include "SkData.h"
|
| #include "SkDeflate.h"
|
| #include "SkPDFTypes.h"
|
| #include "SkPDFUtils.h"
|
| @@ -456,18 +457,16 @@ void SkPDFDict::insertString(const char key[], const SkString& value) {
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| -SkPDFSharedStream::SkPDFSharedStream(SkStreamAsset* data)
|
| - : fAsset(data), fDict(new SkPDFDict) {
|
| - SkDEBUGCODE(fDumped = false;)
|
| - SkASSERT(data);
|
| +SkPDFSharedStream::SkPDFSharedStream(std::unique_ptr<SkStreamAsset> data)
|
| + : fAsset(std::move(data)) {
|
| + SkASSERT(fAsset);
|
| }
|
|
|
| SkPDFSharedStream::~SkPDFSharedStream() { this->drop(); }
|
|
|
| void SkPDFSharedStream::drop() {
|
| - fAsset.reset();
|
| - fDict.reset(nullptr);
|
| - SkDEBUGCODE(fDumped = true;)
|
| + fAsset = nullptr;;
|
| + fDict.drop();
|
| }
|
|
|
| #ifdef SK_PDF_LESS_COMPRESSION
|
| @@ -475,12 +474,12 @@ void SkPDFSharedStream::emitObject(
|
| SkWStream* stream,
|
| const SkPDFObjNumMap& objNumMap,
|
| const SkPDFSubstituteMap& substitutes) const {
|
| - SkASSERT(!fDumped);
|
| + SkASSERT(fAsset);
|
| std::unique_ptr<SkStreamAsset> dup(fAsset->duplicate());
|
| SkASSERT(dup && dup->hasLength());
|
| size_t length = dup->getLength();
|
| stream->writeText("<<");
|
| - fDict->emitAll(stream, objNumMap, substitutes);
|
| + fDict.emitAll(stream, objNumMap, substitutes);
|
| stream->writeText("\n");
|
| SkPDFUnion::Name("Length").emitObject(
|
| stream, objNumMap, substitutes);
|
| @@ -496,7 +495,7 @@ void SkPDFSharedStream::emitObject(
|
| SkWStream* stream,
|
| const SkPDFObjNumMap& objNumMap,
|
| const SkPDFSubstituteMap& substitutes) const {
|
| - SkASSERT(!fDumped);
|
| + SkASSERT(fAsset);
|
| SkDynamicMemoryWStream buffer;
|
| SkDeflateWStream deflateWStream(&buffer);
|
| // Since emitObject is const, this function doesn't change the dictionary.
|
| @@ -506,7 +505,7 @@ void SkPDFSharedStream::emitObject(
|
| deflateWStream.finalize();
|
| size_t length = buffer.bytesWritten();
|
| stream->writeText("<<");
|
| - fDict->emitAll(stream, objNumMap, substitutes);
|
| + fDict.emitAll(stream, objNumMap, substitutes);
|
| stream->writeText("\n");
|
| SkPDFUnion::Name("Length").emitObject(stream, objNumMap, substitutes);
|
| stream->writeText(" ");
|
| @@ -524,8 +523,80 @@ void SkPDFSharedStream::emitObject(
|
|
|
| void SkPDFSharedStream::addResources(
|
| SkPDFObjNumMap* catalog, const SkPDFSubstituteMap& substitutes) const {
|
| - SkASSERT(!fDumped);
|
| - fDict->addResources(catalog, substitutes);
|
| + SkASSERT(fAsset);
|
| + fDict.addResources(catalog, substitutes);
|
| +}
|
| +
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +SkPDFStream:: SkPDFStream(sk_sp<SkData> data) {
|
| + this->setData(std::unique_ptr<SkStreamAsset>(
|
| + new SkMemoryStream(std::move(data))));
|
| +}
|
| +
|
| +SkPDFStream::SkPDFStream(std::unique_ptr<SkStreamAsset> stream) {
|
| + this->setData(std::move(stream));
|
| +}
|
| +
|
| +SkPDFStream::SkPDFStream() {}
|
| +
|
| +SkPDFStream::~SkPDFStream() {}
|
| +
|
| +void SkPDFStream::addResources(
|
| + SkPDFObjNumMap* catalog, const SkPDFSubstituteMap& substitutes) const {
|
| + SkASSERT(fCompressedData);
|
| + fDict.addResources(catalog, substitutes);
|
| +}
|
| +
|
| +void SkPDFStream::drop() {
|
| + fCompressedData.reset(nullptr);
|
| + fDict.drop();
|
| +}
|
| +
|
| +void SkPDFStream::emitObject(SkWStream* stream,
|
| + const SkPDFObjNumMap& objNumMap,
|
| + const SkPDFSubstituteMap& substitutes) const {
|
| + SkASSERT(fCompressedData);
|
| + fDict.emitObject(stream, objNumMap, substitutes);
|
| + // duplicate (a cheap operation) preserves const on fCompressedData.
|
| + std::unique_ptr<SkStreamAsset> dup(fCompressedData->duplicate());
|
| + SkASSERT(dup);
|
| + SkASSERT(dup->hasLength());
|
| + stream->writeText(" stream\n");
|
| + stream->writeStream(dup.get(), dup->getLength());
|
| + stream->writeText("\nendstream");
|
| +}
|
| +
|
| +void SkPDFStream::setData(std::unique_ptr<SkStreamAsset> stream) {
|
| + SkASSERT(!fCompressedData); // Only call this function once.
|
| + SkASSERT(stream);
|
| + // Code assumes that the stream starts at the beginning.
|
| +
|
| + #ifdef SK_PDF_LESS_COMPRESSION
|
| + fCompressedData = std::move(stream);
|
| + SkASSERT(fCompressedData && fCompressedData->hasLength());
|
| + fDict.insertInt("Length", fCompressedData->getLength());
|
| + #else
|
| +
|
| + SkASSERT(stream->hasLength());
|
| + SkDynamicMemoryWStream compressedData;
|
| + SkDeflateWStream deflateWStream(&compressedData);
|
| + SkStreamCopy(&deflateWStream, stream.get());
|
| + deflateWStream.finalize();
|
| + size_t compressedLength = compressedData.bytesWritten();
|
| + size_t originalLength = stream->getLength();
|
| +
|
| + if (originalLength <= compressedLength + strlen("/Filter_/FlateDecode_")) {
|
| + SkAssertResult(stream->rewind());
|
| + fCompressedData = std::move(stream);
|
| + fDict.insertInt("Length", originalLength);
|
| + return;
|
| + }
|
| + fCompressedData.reset(compressedData.detachAsStream());
|
| + fDict.insertName("Filter", "FlateDecode");
|
| + fDict.insertInt("Length", compressedLength);
|
| + #endif
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|