aboutsummaryrefslogtreecommitdiffstats
path: root/src/pdf/SkPDFStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdf/SkPDFStream.cpp')
-rw-r--r--src/pdf/SkPDFStream.cpp124
1 files changed, 90 insertions, 34 deletions
diff --git a/src/pdf/SkPDFStream.cpp b/src/pdf/SkPDFStream.cpp
index b1bd5ff..0bd63f3 100644
--- a/src/pdf/SkPDFStream.cpp
+++ b/src/pdf/SkPDFStream.cpp
@@ -1,61 +1,117 @@
+
/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * Copyright 2010 Google Inc.
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
*/
+
+#include "SkData.h"
#include "SkFlate.h"
#include "SkPDFCatalog.h"
#include "SkPDFStream.h"
#include "SkStream.h"
-SkPDFStream::SkPDFStream(SkStream* stream) {
- if (SkFlate::HaveFlate())
- SkAssertResult(SkFlate::Deflate(stream, &fCompressedData));
-
- if (SkFlate::HaveFlate() &&
- fCompressedData.getOffset() < stream->getLength()) {
- fLength = fCompressedData.getOffset();
- insert("Filter", new SkPDFName("FlateDecode"))->unref();
- } else {
- fCompressedData.reset();
- fPlainData = stream;
- fLength = fPlainData->getLength();
- }
- insert("Length", new SkPDFInt(fLength))->unref();
+static bool skip_compression(SkPDFCatalog* catalog) {
+ return catalog->getDocumentFlags() & SkPDFDocument::kNoCompression_Flag;
+}
+
+SkPDFStream::SkPDFStream(SkStream* stream)
+ : fState(kUnused_State),
+ fData(stream) {
+}
+
+SkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) {
+ SkMemoryStream* stream = new SkMemoryStream;
+ stream->setData(data);
+ fData = stream;
+ fData->unref(); // SkRefPtr and new both took a reference.
}
-SkPDFStream::~SkPDFStream() {
+SkPDFStream::SkPDFStream(const SkPDFStream& pdfStream)
+ : SkPDFDict(),
+ fState(kUnused_State),
+ fData(pdfStream.fData) {
+ bool removeLength = true;
+ // Don't uncompress an already compressed stream, but we could.
+ if (pdfStream.fState == kCompressed_State) {
+ fState = kCompressed_State;
+ removeLength = false;
+ }
+ SkPDFDict::Iter dict(pdfStream);
+ SkPDFName* key;
+ SkPDFObject* value;
+ SkPDFName lengthName("Length");
+ for (key = dict.next(&value); key != NULL; key = dict.next(&value)) {
+ if (removeLength && *key == lengthName) {
+ continue;
+ }
+ this->insert(key, value);
+ }
}
+SkPDFStream::~SkPDFStream() {}
+
void SkPDFStream::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect) {
- if (indirect)
+ if (indirect) {
return emitIndirectObject(stream, catalog);
+ }
+ if (!this->populate(catalog)) {
+ return fSubstitute->emitObject(stream, catalog, indirect);
+ }
this->INHERITED::emitObject(stream, catalog, false);
stream->writeText(" stream\n");
- if (fPlainData.get())
- stream->write(fPlainData->getMemoryBase(), fLength);
- else
- stream->write(fCompressedData.getStream(), fLength);
+ stream->write(fData->getMemoryBase(), fData->getLength());
stream->writeText("\nendstream");
}
size_t SkPDFStream::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
- if (indirect)
+ if (indirect) {
return getIndirectOutputSize(catalog);
+ }
+ if (!this->populate(catalog)) {
+ return fSubstitute->getOutputSize(catalog, indirect);
+ }
return this->INHERITED::getOutputSize(catalog, false) +
- strlen(" stream\n\nendstream") + fLength;
+ strlen(" stream\n\nendstream") + fData->getLength();
+}
+
+SkPDFStream::SkPDFStream() : fState(kUnused_State) {}
+
+void SkPDFStream::setData(SkStream* stream) {
+ fData = stream;
+}
+
+bool SkPDFStream::populate(SkPDFCatalog* catalog) {
+ if (fState == kUnused_State) {
+ if (!skip_compression(catalog) && SkFlate::HaveFlate()) {
+ SkDynamicMemoryWStream compressedData;
+
+ SkAssertResult(SkFlate::Deflate(fData.get(), &compressedData));
+ if (compressedData.getOffset() < fData->getLength()) {
+ SkMemoryStream* stream = new SkMemoryStream;
+ stream->setData(compressedData.copyToData());
+ fData = stream;
+ fData->unref(); // SkRefPtr and new both took a reference.
+ insertName("Filter", "FlateDecode");
+ }
+ fState = kCompressed_State;
+ } else {
+ fState = kNoCompression_State;
+ }
+ insertInt("Length", fData->getLength());
+ } else if (fState == kNoCompression_State && !skip_compression(catalog) &&
+ SkFlate::HaveFlate()) {
+ if (!fSubstitute.get()) {
+ fSubstitute = new SkPDFStream(*this);
+ fSubstitute->unref(); // SkRefPtr and new both took a reference.
+ catalog->setSubstitute(this, fSubstitute.get());
+ }
+ return false;
+ }
+ return true;
}