OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkData.h" | 10 #include "SkData.h" |
11 #include "SkFlate.h" | 11 #include "SkFlate.h" |
12 #include "SkPDFCatalog.h" | 12 #include "SkPDFCatalog.h" |
13 #include "SkPDFStream.h" | 13 #include "SkPDFStream.h" |
14 #include "SkStream.h" | 14 #include "SkStream.h" |
15 #include "SkStreamPriv.h" | 15 #include "SkStreamPriv.h" |
16 | 16 |
17 SkPDFStream::SkPDFStream(SkStream* stream) : fState(kUnused_State) { | 17 SkPDFStream::SkPDFStream(SkStream* stream) : fState(kUnused_State) { |
18 this->setData(stream); | 18 this->setData(stream); |
19 } | 19 } |
20 | 20 |
21 SkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) { | 21 SkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) { |
22 this->setData(data); | 22 this->setData(data); |
23 } | 23 } |
24 | 24 |
25 SkPDFStream::SkPDFStream(const SkPDFStream& pdfStream) | |
26 : SkPDFDict(), | |
27 fState(kUnused_State) { | |
28 this->setData(pdfStream.fDataStream.get()); | |
29 bool removeLength = true; | |
30 // Don't uncompress an already compressed stream, but we could. | |
31 if (pdfStream.fState == kCompressed_State) { | |
32 fState = kCompressed_State; | |
33 removeLength = false; | |
34 } | |
35 this->mergeFrom(pdfStream); | |
36 if (removeLength) { | |
37 this->remove("Length"); | |
38 } | |
39 } | |
40 | |
41 SkPDFStream::~SkPDFStream() {} | 25 SkPDFStream::~SkPDFStream() {} |
42 | 26 |
43 void SkPDFStream::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { | 27 void SkPDFStream::emitObject(SkWStream* stream, SkPDFCatalog* catalog) { |
44 if (!this->populate(catalog)) { | 28 SkAssertResult(this->populate(catalog)); |
45 return fSubstitute->emitObject(stream, catalog); | |
46 } | |
47 | |
48 this->INHERITED::emitObject(stream, catalog); | 29 this->INHERITED::emitObject(stream, catalog); |
49 stream->writeText(" stream\n"); | 30 stream->writeText(" stream\n"); |
50 stream->writeStream(fDataStream.get(), fDataStream->getLength()); | 31 stream->writeStream(fDataStream.get(), fDataStream->getLength()); |
51 SkAssertResult(fDataStream->rewind()); | 32 SkAssertResult(fDataStream->rewind()); |
52 stream->writeText("\nendstream"); | 33 stream->writeText("\nendstream"); |
53 } | 34 } |
54 | 35 |
55 SkPDFStream::SkPDFStream() : fState(kUnused_State) {} | 36 SkPDFStream::SkPDFStream() : fState(kUnused_State) {} |
56 | 37 |
57 void SkPDFStream::setData(SkData* data) { | 38 void SkPDFStream::setData(SkData* data) { |
58 // FIXME: Don't swap if the data is the same. | 39 // FIXME: Don't swap if the data is the same. |
59 fDataStream.reset(SkNEW_ARGS(SkMemoryStream, (data))); | 40 fDataStream.reset(SkNEW_ARGS(SkMemoryStream, (data))); |
60 } | 41 } |
61 | 42 |
62 void SkPDFStream::setData(SkStream* stream) { | 43 void SkPDFStream::setData(SkStream* stream) { |
| 44 SkASSERT(stream); |
63 // Code assumes that the stream starts at the beginning and is rewindable. | 45 // Code assumes that the stream starts at the beginning and is rewindable. |
64 if (stream) { | 46 // SkStreamRewindableFromSkStream will try stream->duplicate(). |
65 // SkStreamRewindableFromSkStream will try stream->duplicate(). | 47 fDataStream.reset(SkStreamRewindableFromSkStream(stream)); |
66 fDataStream.reset(SkStreamRewindableFromSkStream(stream)); | 48 SkASSERT(fDataStream.get()); |
67 SkASSERT(fDataStream.get()); | |
68 } else { | |
69 // Use an empty memory stream. | |
70 fDataStream.reset(SkNEW(SkMemoryStream)); | |
71 } | |
72 } | 49 } |
73 | 50 |
74 size_t SkPDFStream::dataSize() const { | 51 size_t SkPDFStream::dataSize() const { |
75 SkASSERT(fDataStream->hasLength()); | 52 SkASSERT(fDataStream->hasLength()); |
76 return fDataStream->getLength(); | 53 return fDataStream->getLength(); |
77 } | 54 } |
78 | 55 |
79 bool SkPDFStream::populate(SkPDFCatalog* catalog) { | 56 bool SkPDFStream::populate(SkPDFCatalog* catalog) { |
80 #ifdef SK_NO_FLATE | |
81 if (fState == kUnused_State) { | |
82 fState = kNoCompression_State; | |
83 insertInt("Length", this->dataSize()); | |
84 } | |
85 return true; | |
86 | |
87 #else // !SK_NO_FLATE | |
88 | |
89 if (fState == kUnused_State) { | 57 if (fState == kUnused_State) { |
90 fState = kNoCompression_State; | 58 fState = kNoCompression_State; |
91 SkDynamicMemoryWStream compressedData; | 59 SkDynamicMemoryWStream compressedData; |
92 | 60 |
93 SkAssertResult( | 61 SkAssertResult( |
94 SkFlate::Deflate(fDataStream.get(), &compressedData)); | 62 SkFlate::Deflate(fDataStream.get(), &compressedData)); |
95 SkAssertResult(fDataStream->rewind()); | 63 SkAssertResult(fDataStream->rewind()); |
96 if (compressedData.getOffset() < this->dataSize()) { | 64 if (compressedData.getOffset() < this->dataSize()) { |
97 SkAutoTDelete<SkStream> compressed( | 65 SkAutoTDelete<SkStream> compressed( |
98 compressedData.detachAsStream()); | 66 compressedData.detachAsStream()); |
99 this->setData(compressed.get()); | 67 this->setData(compressed.get()); |
100 insertName("Filter", "FlateDecode"); | 68 insertName("Filter", "FlateDecode"); |
101 } | 69 } |
102 fState = kCompressed_State; | 70 fState = kCompressed_State; |
103 insertInt("Length", this->dataSize()); | 71 insertInt("Length", this->dataSize()); |
104 } | 72 } |
105 else if (fState == kNoCompression_State) { | |
106 if (!fSubstitute.get()) { | |
107 fSubstitute.reset(new SkPDFStream(*this)); | |
108 catalog->setSubstitute(this, fSubstitute.get()); | |
109 } | |
110 return false; | |
111 } | |
112 return true; | 73 return true; |
113 #endif // SK_NO_FLATE | |
114 } | 74 } |
OLD | NEW |