summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authoredisonn@google.com <edisonn@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-27 16:54:44 +0000
committeredisonn@google.com <edisonn@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-27 16:54:44 +0000
commit8d30264dd5f496b318752446f8335959762b0e8e (patch)
tree81c195a61c0fd3163c4288baea28ee4f89bd6aab /pdf
parent72fa213caca6f1624f0a9237d82cb7903391860f (diff)
downloadinclude-8d30264dd5f496b318752446f8335959762b0e8e.tar.gz
Use SkSet to fix issue when pdf generates an exp number of resources.
The problem fixed - http://code.google.com/p/skia/issues/detail?id=940 - is that getResources will recursively obtain all child resource recursively without checking for duplicates. If we have lots of duplicates, then we try to build a very large vector (exponential with the number of nodes usually) and sooner or later we end up using too much memory and crash. A possible solution could have been to make sure resources do not have duplicates, but that requirement is impractical, and it this leaves the solution fragile, if there is any issue in the tree, we crash. When we emit the pdf, the large number of duplicates is not an issue, because SkPDFCatalog::addObject will deal with duplicates. I have run the gm with --config pdf, and the images are 100% same bits, while the pdfs have the same size but some very small changes, the order of some objects. Review URL: https://codereview.appspot.com/6744050 git-svn-id: http://skia.googlecode.com/svn/trunk/include@7883 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'pdf')
-rw-r--r--pdf/SkPDFDevice.h12
-rw-r--r--pdf/SkPDFDocument.h4
2 files changed, 13 insertions, 3 deletions
diff --git a/pdf/SkPDFDevice.h b/pdf/SkPDFDevice.h
index a13d617..f42ecb8 100644
--- a/pdf/SkPDFDevice.h
+++ b/pdf/SkPDFDevice.h
@@ -29,6 +29,7 @@ class SkPDFGraphicState;
class SkPDFObject;
class SkPDFShader;
class SkPDFStream;
+template <typename T> class SK_API SkTSet;
// Private classes.
struct ContentEntry;
@@ -130,12 +131,19 @@ public:
SK_API SkPDFDict* getResourceDict();
/** Get the list of resources (PDF objects) used on this page.
- * @param resourceList A list to append the resources to.
+ * This method will add to newResourceObjects any objects that this method
+ * depends on, but not already in knownResourceObjects. This might operate
+ * recursively so if this object depends on another object and that object
+ * depends on two more, all three objects will be added.
+ *
+ * @param knownResourceObjects The set of resources to be ignored.
+ * @param newResourceObjects The set to append dependant resources to.
* @param recursive If recursive is true, get the resources of the
* device's resources recursively. (Useful for adding
* objects to the catalog.)
*/
- SK_API void getResources(SkTDArray<SkPDFObject*>* resourceList,
+ SK_API void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
+ SkTSet<SkPDFObject*>* newResourceObjects,
bool recursive) const;
/** Get the fonts used on this device.
diff --git a/pdf/SkPDFDocument.h b/pdf/SkPDFDocument.h
index 167634e..443e8c2 100644
--- a/pdf/SkPDFDocument.h
+++ b/pdf/SkPDFDocument.h
@@ -21,6 +21,7 @@ class SkPDFDict;
class SkPDFPage;
class SkPDFObject;
class SkWStream;
+template <typename T> class SK_API SkTSet;
/** \class SkPDFDocument
@@ -76,7 +77,8 @@ private:
SkTDArray<SkPDFPage*> fPages;
SkTDArray<SkPDFDict*> fPageTree;
SkPDFDict* fDocCatalog;
- SkTDArray<SkPDFObject*> fPageResources;
+ SkTSet<SkPDFObject*>* fFirstPageResources;
+ SkTSet<SkPDFObject*>* fOtherPageResources;
SkTDArray<SkPDFObject*> fSubstitutes;
int fSecondPageFirstResourceIndex;