[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/include/pdf/SkPDFStream.h b/include/pdf/SkPDFStream.h
index 739177f..263a408 100644
--- a/include/pdf/SkPDFStream.h
+++ b/include/pdf/SkPDFStream.h
@@ -34,9 +34,15 @@
     /** Create a PDF stream. A Length entry is automatically added to the
      *  stream dictionary. The stream may be retained (stream->ref() may be
      *  called) so its contents must not be changed after calling this.
-     *  @param stream The data part of the stream.
+     *  @param data  The data part of the stream.
      */
+    explicit SkPDFStream(SkData* data);
+    /** Deprecated constructor. */
     explicit SkPDFStream(SkStream* stream);
+    /** Create a PDF stream with the same content and dictionary entries
+     *  as the passed one.
+     */
+    explicit SkPDFStream(const SkPDFStream& pdfStream);
     virtual ~SkPDFStream();
 
     // The SkPDFObject interface.
@@ -44,13 +50,33 @@
                             bool indirect);
     virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
 
+protected:
+    /* Create a PDF stream with no data.  The setData method must be called to
+     * set the data.
+     */
+    SkPDFStream();
+
+    void setData(SkStream* stream);
+
 private:
-    size_t fLength;
-    // Only one of the two streams will be valid.
-    SkRefPtr<SkStream> fPlainData;
-    SkDynamicMemoryWStream fCompressedData;
+    enum State {
+        kUnused_State,         //!< The stream hasn't been requested yet.
+        kNoCompression_State,  //!< The stream's been requested in an
+                               //   uncompressed form.
+        kCompressed_State,     //!< The stream's already been compressed.
+    };
+    // Indicates what form (or if) the stream has been requested.
+    State fState;
+
+    // TODO(vandebo) Use SkData (after removing deprecated constructor).
+    SkRefPtr<SkStream> fData;
+    SkRefPtr<SkPDFStream> fSubstitute;
 
     typedef SkPDFDict INHERITED;
+
+    // Populate the stream dictionary.  This method returns false if
+    // fSubstitute should be used.
+    bool populate(SkPDFCatalog* catalog);
 };
 
 #endif