Cleanup/unify matrix transform for PDF backend.

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

git-svn-id: http://skia.googlecode.com/svn/trunk@617 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h
index 7ef7d8c..5c82d78 100644
--- a/include/core/SkMatrix.h
+++ b/include/core/SkMatrix.h
@@ -292,6 +292,13 @@
     */
     bool invert(SkMatrix* inverse) const;
 
+    /** Fills the passed array with the tranform values in the right order
+        for PDFs.  If the matrix is a perspective transform, returns false
+        and fills the array with an identity transform.
+        @param transform  The array to fill in.
+    */
+    bool pdfTransform(SkScalar transform[6]) const;
+
     /** Apply this matrix to the array of points specified by src, and write
         the transformed points into the array of points specified by dst.
         dst[] = M * src[]
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 5421299..fb74c63 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -110,8 +110,9 @@
     SkRefPtr<SkPDFArray> getMediaBox();
 
     /** Returns a string with the page contents.
+     *  @param flipOrigin  Flip the origin between top and bottom.
      */
-    SkString content();
+    SkString content(bool flipOrigin) const;
 
 private:
     int fWidth;
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
index aba84c7..e85c6ec 100644
--- a/src/core/SkMatrix.cpp
+++ b/src/core/SkMatrix.cpp
@@ -717,6 +717,24 @@
     }
 #endif
 
+bool SkMatrix::pdfTransform(SkScalar transform[6]) const {
+    SkMatrix identity;
+    const SkMatrix* use = this;
+    bool ret = true;
+    if (has_perspective(*this)) {
+        identity.reset();
+        use = &identity;
+        ret = false;
+    }
+    transform[0] = use->fMat[kMScaleX];
+    transform[1] = use->fMat[kMSkewY];
+    transform[2] = use->fMat[kMSkewX];
+    transform[3] = use->fMat[kMScaleY];
+    transform[4] = use->fMat[kMTransX];
+    transform[5] = use->fMat[kMTransY];
+    return true;
+}
+
 bool SkMatrix::invert(SkMatrix* inv) const {
     int         isPersp = has_perspective(*this);
     int         shift;
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 79f0967..00c05e4 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -76,13 +76,6 @@
       fHeight(height),
       fCurrentColor(0),
       fCurrentTextScaleX(SK_Scalar1) {
-    // Scale and translate to move the origin from the lower left to the upper
-    // left.
-    fCurTransform.setTranslate(0, height);
-    fCurTransform.preScale(1, -1);
-    fActiveTransform.reset();
-    applyTransform(fCurTransform);
-
     fContent.append("q\n");
     fCurTransform.reset();
     fActiveTransform.reset();
@@ -314,8 +307,13 @@
     return mediaBox;
 }
 
-SkString SkPDFDevice::content() {
-    SkString result = fContent;
+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);
     result.append("Q");
     return result;
 }
@@ -475,19 +473,12 @@
 void SkPDFDevice::applyTransform(const SkMatrix& m) {
     if (m == fActiveTransform)
         return;
-    SkASSERT((m.getType() & SkMatrix::kPerspective_Mask) == 0);
-
-    fContent.appendScalar(m[SkMatrix::kMScaleX]);
-    fContent.append(" ");
-    fContent.appendScalar(m[SkMatrix::kMSkewY]);
-    fContent.append(" ");
-    fContent.appendScalar(m[SkMatrix::kMSkewX]);
-    fContent.append(" ");
-    fContent.appendScalar(m[SkMatrix::kMScaleY]);
-    fContent.append(" ");
-    fContent.appendScalar(m[SkMatrix::kMTransX]);
-    fContent.append(" ");
-    fContent.appendScalar(m[SkMatrix::kMTransY]);
-    fContent.append(" cm\n");
+    SkScalar transform[6];
+    SkAssertResult(m.pdfTransform(transform));
+    for (size_t i = 0; i < SK_ARRAY_COUNT(transform); i++) {
+        fContent.appendScalar(transform[i]);
+        fContent.append(" ");
+    }
+    fContent.append("cm\n");
     fActiveTransform = m;
 }
diff --git a/src/pdf/SkPDFPage.cpp b/src/pdf/SkPDFPage.cpp
index 4183387..c648472 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();
+        fContent = fDevice->content(true);
         SkRefPtr<SkMemoryStream> contentStream = new SkMemoryStream(
                 fContent.c_str(), fContent.size());
         contentStream->unref();  // SkRefPtr and new both took a reference.