Cleanup/unify matrix transform for PDF backend.
authorvandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 26 Oct 2010 19:45:06 +0000 (19:45 +0000)
committervandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 26 Oct 2010 19:45:06 +0000 (19:45 +0000)
Review URL: http://codereview.appspot.com/2719041

git-svn-id: http://skia.googlecode.com/svn/trunk@617 2bbb7eff-a529-9590-31e7-b0007b416f81

include/core/SkMatrix.h
include/pdf/SkPDFDevice.h
src/core/SkMatrix.cpp
src/pdf/SkPDFDevice.cpp
src/pdf/SkPDFPage.cpp

index 7ef7d8c..5c82d78 100644 (file)
@@ -292,6 +292,13 @@ public:
     */
     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[]
index 5421299..fb74c63 100644 (file)
@@ -110,8 +110,9 @@ public:
     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;
index aba84c7..e85c6ec 100644 (file)
@@ -717,6 +717,24 @@ bool SkMatrix::postConcat(const SkMatrix& mat) {
     }
 #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;
index 79f0967..00c05e4 100644 (file)
@@ -76,13 +76,6 @@ SkPDFDevice::SkPDFDevice(int width, int height)
       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 @@ SkRefPtr<SkPDFArray> SkPDFDevice::getMediaBox() {
     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::removeTempTransform() {
 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;
 }
index 4183387..c648472 100644 (file)
@@ -32,7 +32,7 @@ void SkPDFPage::finalizePage(SkPDFCatalog* catalog, bool firstPage,
         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.