1 
2 /*
3  * Copyright 2010 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #include "SkData.h"
11 #include "SkFlate.h"
12 #include "SkPDFStream.h"
13 #include "SkStream.h"
14 #include "SkStreamPriv.h"
15 
SkPDFStream(SkStream * stream)16 SkPDFStream::SkPDFStream(SkStream* stream) : fState(kUnused_State) {
17     this->setData(stream);
18 }
19 
SkPDFStream(SkData * data)20 SkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) {
21     this->setData(data);
22 }
23 
~SkPDFStream()24 SkPDFStream::~SkPDFStream() {}
25 
emitObject(SkWStream * stream,const SkPDFObjNumMap & objNumMap,const SkPDFSubstituteMap & substitutes)26 void SkPDFStream::emitObject(SkWStream* stream,
27                              const SkPDFObjNumMap& objNumMap,
28                              const SkPDFSubstituteMap& substitutes) {
29     if (fState == kUnused_State) {
30         fState = kNoCompression_State;
31         SkDynamicMemoryWStream compressedData;
32 
33         SkAssertResult(
34                 SkFlate::Deflate(fDataStream.get(), &compressedData));
35         SkAssertResult(fDataStream->rewind());
36         if (compressedData.getOffset() < this->dataSize()) {
37             SkAutoTDelete<SkStream> compressed(
38                     compressedData.detachAsStream());
39             this->setData(compressed.get());
40             this->insertName("Filter", "FlateDecode");
41         }
42         fState = kCompressed_State;
43         this->insertInt("Length", this->dataSize());
44     }
45     this->INHERITED::emitObject(stream, objNumMap, substitutes);
46     stream->writeText(" stream\n");
47     stream->writeStream(fDataStream.get(), fDataStream->getLength());
48     SkAssertResult(fDataStream->rewind());
49     stream->writeText("\nendstream");
50 }
51 
SkPDFStream()52 SkPDFStream::SkPDFStream() : fState(kUnused_State) {}
53 
setData(SkData * data)54 void SkPDFStream::setData(SkData* data) {
55     // FIXME: Don't swap if the data is the same.
56     fDataStream.reset(SkNEW_ARGS(SkMemoryStream, (data)));
57 }
58 
setData(SkStream * stream)59 void SkPDFStream::setData(SkStream* stream) {
60     SkASSERT(stream);
61     // Code assumes that the stream starts at the beginning and is rewindable.
62     // SkStreamRewindableFromSkStream will try stream->duplicate().
63     fDataStream.reset(SkStreamRewindableFromSkStream(stream));
64     SkASSERT(fDataStream.get());
65 }
66 
dataSize() const67 size_t SkPDFStream::dataSize() const {
68     SkASSERT(fDataStream->hasLength());
69     return fDataStream->getLength();
70 }
71