[PDF] Change the way flip origin is done.

The PDF shader matrix is dependent on flip origin or not, so we need to set it at device creation time.

Review URL: http://codereview.appspot.com/4216046

git-svn-id: http://skia.googlecode.com/svn/trunk@855 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 5bcc8e3..f9247a7 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -42,12 +42,24 @@
 */
 class SkPDFDevice : public SkDevice {
 public:
+    /** Skia generally uses the top left as the origin and PDFs natively use
+        the bottom left.  We can move the origin to the top left in the PDF
+        with a transform, but we have to be careful to apply the transform
+        only once.
+     */
+    enum OriginTransform {
+        kFlip_OriginTransform,
+        kNoFlip_OriginTransform,
+    };
+
     /** Create a PDF drawing context with the given width and height.
      *  72 points/in means letter paper is 612x792.
      *  @param width  Page width in points.
      *  @param height Page height in points.
+     *  @param flipOrigin Flip the origin from lower left to upper left.
      */
-    SkPDFDevice(int width, int height);
+    SkPDFDevice(int width, int height,
+                OriginTransform flipOrigin = kFlip_OriginTransform);
     virtual ~SkPDFDevice();
 
     virtual SkDeviceFactory* getDeviceFactory() {
@@ -121,13 +133,13 @@
     SkRefPtr<SkPDFArray> getMediaBox() const;
 
     /** Returns a string with the page contents.
-     *  @param flipOrigin  Flip the origin between top and bottom.
      */
-    SkString content(bool flipOrigin) const;
+    SkString content() const;
 
 private:
     int fWidth;
     int fHeight;
+    OriginTransform fFlipOrigin;
     SkRefPtr<SkPDFDict> fResourceDict;
 
     SkTDArray<SkPDFGraphicState*> fGraphicStateResources;
diff --git a/include/pdf/SkPDFFormXObject.h b/include/pdf/SkPDFFormXObject.h
index ed16566..41719f0 100644
--- a/include/pdf/SkPDFFormXObject.h
+++ b/include/pdf/SkPDFFormXObject.h
@@ -28,7 +28,7 @@
 
 /** \class SkPDFFormXObject
 
-    A form XObject; a self containted description of graphics objects.  A form
+    A form XObject; a self contained description of graphics objects.  A form
     XObject is basically a page object with slightly different syntax, that
     can be drawn onto a page.
 */
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 72b2e1b..1c6477f 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -120,8 +120,12 @@
 
 SkDevice* SkPDFDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
                                         int width, int height, bool isOpaque,
-                                        bool /*isForLayer*/) {
-    return SkNEW_ARGS(SkPDFDevice, (width, height));
+                                        bool isForLayer) {
+    SkPDFDevice::OriginTransform flip = SkPDFDevice::kFlip_OriginTransform;
+    if (isForLayer) {
+        flip = SkPDFDevice::kNoFlip_OriginTransform;
+    }
+    return SkNEW_ARGS(SkPDFDevice, (width, height, flip));
 }
 
 static inline SkBitmap makeABitmap(int width, int height) {
@@ -130,10 +134,11 @@
     return bitmap;
 }
 
-SkPDFDevice::SkPDFDevice(int width, int height)
+SkPDFDevice::SkPDFDevice(int width, int height, OriginTransform flipOrigin)
     : SkDevice(NULL, makeABitmap(width, height), false),
       fWidth(width),
       fHeight(height),
+      fFlipOrigin(flipOrigin),
       fGraphicStackIndex(0) {
     fGraphicStack[0].fColor = SK_ColorBLACK;
     fGraphicStack[0].fTextSize = SK_ScalarNaN;  // This has no default value.
@@ -143,6 +148,10 @@
     fGraphicStack[0].fGraphicState = NULL;
     fGraphicStack[0].fClip.setRect(0,0, width, height);
     fGraphicStack[0].fTransform.reset();
+
+    if (flipOrigin == kFlip_OriginTransform) {
+        fContent.printf("1 0 0 -1 0 %d cm\n", fHeight);
+    }
 }
 
 SkPDFDevice::~SkPDFDevice() {
@@ -549,13 +558,8 @@
     return mediaBox;
 }
 
-SkString SkPDFDevice::content(bool flipOrigin) const {
-    SkString result;
-    // Scale and translate to move the origin from the lower left to the
-    // upper left.
-    if (flipOrigin)
-        result.printf("1 0 0 -1 0 %d cm\n", fHeight);
-    result.append(fContent);
+SkString SkPDFDevice::content() const {
+    SkString result = fContent;
     for (int i = 0; i < fGraphicStackIndex; i++)
         result.append("Q\n");
     return result;
diff --git a/src/pdf/SkPDFFormXObject.cpp b/src/pdf/SkPDFFormXObject.cpp
index ef839a3..40bfad7 100644
--- a/src/pdf/SkPDFFormXObject.cpp
+++ b/src/pdf/SkPDFFormXObject.cpp
@@ -28,7 +28,7 @@
     // resources).
     device->getResources(&fResources);
 
-    SkString content = device->content(false);
+    SkString content = device->content();
     SkMemoryStream* stream_data = new SkMemoryStream(content.c_str(),
                                                      content.size());
     SkAutoUnref stream_data_unref(stream_data);
diff --git a/src/pdf/SkPDFPage.cpp b/src/pdf/SkPDFPage.cpp
index 1c470c7..2bec907 100644
--- a/src/pdf/SkPDFPage.cpp
+++ b/src/pdf/SkPDFPage.cpp
@@ -32,7 +32,7 @@
         insert("Resources", fDevice->getResourceDict().get());
         insert("MediaBox", fDevice->getMediaBox().get());
 
-        fContent = fDevice->content(true);
+        fContent = fDevice->content();
         SkRefPtr<SkMemoryStream> contentStream = new SkMemoryStream(
                 fContent.c_str(), fContent.size());
         contentStream->unref();  // SkRefPtr and new both took a reference.