[PDF] Make stream compression optional on a per device basis.
There are a lot of small pieces to make this change work:
- SkPDFDocument (and SkPDFCatalog) take flags to disable compression (and font embedding - not implemented yet, can disable font subsetting for now).
- SkPDFStream now defers compression until the size/emit step.
- Classes that *had* a stream (because they didn't know the stream size at construction time) now *are* streams to make the substitution work correctly.
- The SkPDFShader implementation got pulled apart into two classes, one that is a SkPDFDict, and one that is a SkPDFStream (making the common ancestor SkPDFObject).
- Added helper methods in SkPDFObject for children that have simple resource lists.
- Added an iterator to SkPDFDict so that a substitute SkPDFStream can get a copy of the stream dictionary.
- Change SkPDFDocument to have a pointer to an SkPDFCatalog to remove a new circular header reference.
Review URL: http://codereview.appspot.com/4700045
git-svn-id: http://skia.googlecode.com/svn/trunk@1911 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pdf/SkPDFTypes.cpp b/src/pdf/SkPDFTypes.cpp
index 810d860..a026d69 100644
--- a/src/pdf/SkPDFTypes.cpp
+++ b/src/pdf/SkPDFTypes.cpp
@@ -48,14 +48,32 @@
stream->writeText("\nendobj\n");
}
-SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) {}
-SkPDFObjRef::~SkPDFObjRef() {}
-
size_t SkPDFObject::getIndirectOutputSize(SkPDFCatalog* catalog) {
return catalog->getObjectNumberSize(this) + strlen(" obj\n") +
this->getOutputSize(catalog, false) + strlen("\nendobj\n");
}
+void SkPDFObject::AddResourceHelper(SkPDFObject* resource,
+ SkTDArray<SkPDFObject*>* list) {
+ list->push(resource);
+ resource->ref();
+}
+
+void SkPDFObject::GetResourcesHelper(SkTDArray<SkPDFObject*>* resources,
+ SkTDArray<SkPDFObject*>* result) {
+ if (resources->count()) {
+ result->setReserve(result->count() + resources->count());
+ for (int i = 0; i < resources->count(); i++) {
+ result->push((*resources)[i]);
+ (*resources)[i]->ref();
+ (*resources)[i]->getResources(result);
+ }
+ }
+}
+
+SkPDFObjRef::SkPDFObjRef(SkPDFObject* obj) : fObj(obj) {}
+SkPDFObjRef::~SkPDFObjRef() {}
+
void SkPDFObjRef::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect) {
SkASSERT(!indirect);
@@ -258,6 +276,10 @@
SkPDFName::SkPDFName(const SkString& name) : fValue(FormatName(name)) {}
SkPDFName::~SkPDFName() {}
+bool SkPDFName::operator==(const SkPDFName& b) const {
+ return fValue == b.fValue;
+}
+
void SkPDFName::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect) {
SkASSERT(!indirect);
@@ -433,3 +455,19 @@
}
fValue.reset();
}
+
+SkPDFDict::Iter::Iter(const SkPDFDict& dict)
+ : fIter(dict.fValue.begin()),
+ fStop(dict.fValue.end()) {
+}
+
+SkPDFName* SkPDFDict::Iter::next(SkPDFObject** value) {
+ if (fIter != fStop) {
+ Rec* cur = fIter;
+ fIter++;
+ *value = cur->value;
+ return cur->key;
+ }
+ *value = NULL;
+ return NULL;
+}