Add SkPDFDeviceFlatenner which extends SkPDFDevice to add support to flatten the path and the text when we have perspective.
prepare to deprecate SkPDFDevice constructor, and route gm and render_pdfs to use SkDocument::Create pdf interface instead. - controlled by a flag
add comments where we are supposed to flatten other features (paint, shaders, ... )

R=reed@google.com, bungeman@google.com, scroggo@google.com, vandebo@chromium.org, bsalomon@google.com

Author: edisonn@google.com

Review URL: https://codereview.chromium.org/24811002

git-svn-id: http://skia.googlecode.com/svn/trunk@11751 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/PdfRenderer.cpp b/tools/PdfRenderer.cpp
index 704cbea..890abde 100644
--- a/tools/PdfRenderer.cpp
+++ b/tools/PdfRenderer.cpp
@@ -13,7 +13,7 @@
 
 namespace sk_tools {
 
-void PdfRenderer::init(SkPicture* pict) {
+void PdfRenderer::init(SkPicture* pict, SkWStream* stream) {
     SkASSERT(NULL == fPicture);
     SkASSERT(NULL == fCanvas.get());
     if (fPicture != NULL || NULL != fCanvas.get()) {
@@ -26,44 +26,35 @@
     }
 
     fPicture = pict;
-    fCanvas.reset(this->setupCanvas());
+    fCanvas.reset(this->setupCanvas(stream, pict->width(), pict->height()));
 }
 
-SkCanvas* PdfRenderer::setupCanvas() {
-    return this->setupCanvas(fPicture->width(), fPicture->height());
-}
+SkCanvas* PdfRenderer::setupCanvas(SkWStream* stream, int width, int height) {
+    fPdfDoc.reset(SkDocument::CreatePDF(stream, NULL, fEncoder));
 
-SkCanvas* PdfRenderer::setupCanvas(int width, int height) {
-    SkISize pageSize = SkISize::Make(width, height);
-    fPDFDevice = SkNEW_ARGS(SkPDFDevice, (pageSize, pageSize, SkMatrix::I()));
-    fPDFDevice->setDCTEncoder(fEncoder);
-    return SkNEW_ARGS(SkCanvas, (fPDFDevice));
+    SkCanvas* canvas = fPdfDoc->beginPage(SkIntToScalar(width), SkIntToScalar(height));
+    canvas->ref();
+
+    return canvas;
 }
 
 void PdfRenderer::end() {
     fPicture = NULL;
     fCanvas.reset(NULL);
-    if (fPDFDevice) {
-        SkDELETE(fPDFDevice);
-        fPDFDevice = NULL;
-    }
+    fPdfDoc.reset(NULL);
 }
 
-void PdfRenderer::write(SkWStream* stream) const {
-    SkPDFDocument doc;
-    doc.appendPage(fPDFDevice);
-    doc.emitPDF(stream);
-}
-
-void SimplePdfRenderer::render() {
+bool SimplePdfRenderer::render() {
     SkASSERT(fCanvas.get() != NULL);
     SkASSERT(fPicture != NULL);
     if (NULL == fCanvas.get() || NULL == fPicture) {
-        return;
+        return false;
     }
 
     fCanvas->drawPicture(*fPicture);
     fCanvas->flush();
+
+    return fPdfDoc->close();
 }
 
 }
diff --git a/tools/PdfRenderer.h b/tools/PdfRenderer.h
index be338e9..d70c458 100644
--- a/tools/PdfRenderer.h
+++ b/tools/PdfRenderer.h
@@ -13,8 +13,8 @@
 // An SkPicture can be built manually, or read from an SKP file.
 //
 
+#include "SkDocument.h"
 #include "SkMath.h"
-#include "SkPDFDevice.h"
 #include "SkPicture.h"
 #include "SkTypes.h"
 #include "SkTDArray.h"
@@ -23,32 +23,30 @@
 
 class SkBitmap;
 class SkCanvas;
+class SkWStream;
 
 namespace sk_tools {
 
 class PdfRenderer : public SkRefCnt {
 public:
-    virtual void init(SkPicture* pict);
+    virtual void init(SkPicture* pict, SkWStream* stream);
     virtual void setup() {}
-    virtual void render() = 0;
+    virtual bool render() = 0;
     virtual void end();
 
     PdfRenderer(SkPicture::EncodeBitmap encoder)
         : fPicture(NULL)
-        , fPDFDevice(NULL)
         , fEncoder(encoder)
+        , fPdfDoc(NULL)
         {}
 
-    void write(SkWStream* stream) const;
-
 protected:
-    SkCanvas* setupCanvas();
-    SkCanvas* setupCanvas(int width, int height);
+    SkCanvas* setupCanvas(SkWStream* stream, int width, int height);
 
     SkAutoTUnref<SkCanvas> fCanvas;
     SkPicture* fPicture;
-    SkPDFDevice* fPDFDevice;
     SkPicture::EncodeBitmap fEncoder;
+    SkAutoTUnref<SkDocument> fPdfDoc;
 
 private:
     typedef SkRefCnt INHERITED;
@@ -58,7 +56,7 @@
 public:
     SimplePdfRenderer(SkPicture::EncodeBitmap encoder)
         : PdfRenderer(encoder) {}
-    virtual void render() SK_OVERRIDE;
+    virtual bool render() SK_OVERRIDE;
 
 private:
     typedef PdfRenderer INHERITED;
diff --git a/tools/render_pdfs_main.cpp b/tools/render_pdfs_main.cpp
index a710064..e07664c 100644
--- a/tools/render_pdfs_main.cpp
+++ b/tools/render_pdfs_main.cpp
@@ -131,28 +131,24 @@
  * @param inputFilename The skp file that was read.
  * @param renderer The object responsible to write the pdf file.
  */
-static bool write_output(const SkString& outputDir,
-                         const SkString& inputFilename,
-                         const sk_tools::PdfRenderer& renderer) {
+static SkWStream* open_stream(const SkString& outputDir,
+                              const SkString& inputFilename) {
     if (outputDir.isEmpty()) {
-        SkDynamicMemoryWStream stream;
-        renderer.write(&stream);
-        return true;
+        return SkNEW(SkDynamicMemoryWStream);
     }
 
     SkString outputPath;
     if (!make_output_filepath(&outputPath, outputDir, inputFilename)) {
-        return false;
+        return NULL;
     }
 
-    SkFILEWStream stream(outputPath.c_str());
-    if (!stream.isValid()) {
+    SkFILEWStream* stream = SkNEW_ARGS(SkFILEWStream, (outputPath.c_str()));
+    if (!stream->isValid()) {
         SkDebugf("Could not write to file %s\n", outputPath.c_str());
-        return false;
+        return NULL;
     }
-    renderer.write(&stream);
 
-    return true;
+    return stream;
 }
 
 /** Reads an skp file, renders it to pdf and writes the output to a pdf file
@@ -182,13 +178,19 @@
     SkDebugf("exporting... [%i %i] %s\n", picture->width(), picture->height(),
              inputPath.c_str());
 
-    renderer.init(picture);
+    SkWStream* stream(open_stream(outputDir, inputFilename));
 
-    renderer.render();
+    if (!stream) {
+        return false;
+    }
 
-    bool success = write_output(outputDir, inputFilename, renderer);
+    renderer.init(picture, stream);
+
+    bool success = renderer.render();
+    SkDELETE(stream);
 
     renderer.end();
+
     return success;
 }