[cairo-commit] 3 commits - src/cairo-matrix.c test/rectangle-rounding-error-ref.png test/rotate-image-surface-paint-ref.png test/unantialiased-shapes-ref.png

Carl Worth cworth at kemper.freedesktop.org
Wed Jan 23 10:30:40 PST 2008


 src/cairo-matrix.c                      |   35 ++++++++++++++++++++++++++++++++
 test/rectangle-rounding-error-ref.png   |binary
 test/rotate-image-surface-paint-ref.png |binary
 test/unantialiased-shapes-ref.png       |binary
 4 files changed, 35 insertions(+)

New commits:
commit 188765c8e857c88a66656a454a3dbd27c32170f7
Author: Bertram Felgenhauer <int-e at gmx.de>
Date:   Wed Jan 23 19:22:18 2008 +0100

    improve comments for the pixman transformation anchoring math.

diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 589566d..c3578a2 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -769,6 +769,17 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t	*matrix,
         pixman_transform->matrix[2][1] = 0;
         pixman_transform->matrix[2][2] = 1 << 16;
 
+        /* The conversion above breaks cairo's translation invariance:
+         * a translation of (a, b) in device space translates to
+         * a translation of (xx * a + xy * b, yx * a + yy * b)
+         * for cairo, while pixman uses rounded versions of xx ... yy.
+         * This error increases as a and b get larger.
+         *
+         * To compensate for this, we fix the point (0, 0) in pattern
+         * space and adjust pixman's transform to agree with cairo's at
+         * that point. */
+
+        /* Note: If we can't invert the transformation, skip the adjustment. */
         if (cairo_matrix_invert (&inv) != CAIRO_STATUS_SUCCESS)
             return;
 
@@ -784,7 +795,8 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t	*matrix,
         if (!pixman_transform_point_3d (pixman_transform, &vector))
             return;
 
-        /* and compensate for the resulting error */
+        /* Ideally, the vector should now be (0, 0). We can now compensate
+         * for the resulting error */
         pixman_transform->matrix[0][2] -= vector.vector[0];
         pixman_transform->matrix[1][2] -= vector.vector[1];
     }
commit b6c723644302c43b7aae098338092e578fe2f007
Author: Bertram Felgenhauer <int-e at gmx.de>
Date:   Wed Jan 23 18:09:20 2008 +0100

    update reference images for some non-aa testcases

diff --git a/test/rectangle-rounding-error-ref.png b/test/rectangle-rounding-error-ref.png
index c3a6840..413345d 100644
Binary files a/test/rectangle-rounding-error-ref.png and b/test/rectangle-rounding-error-ref.png differ
diff --git a/test/rotate-image-surface-paint-ref.png b/test/rotate-image-surface-paint-ref.png
index 7ccc9ac..a63e9cb 100644
Binary files a/test/rotate-image-surface-paint-ref.png and b/test/rotate-image-surface-paint-ref.png differ
diff --git a/test/unantialiased-shapes-ref.png b/test/unantialiased-shapes-ref.png
index ad79993..d350ad9 100644
Binary files a/test/unantialiased-shapes-ref.png and b/test/unantialiased-shapes-ref.png differ
commit 5a0b15d2c9b5e9ef3aed1f01e8ea28a3f2c36216
Author: Bertram Felgenhauer <int-e at gmx.de>
Date:   Wed Jan 23 18:02:02 2008 +0100

    anchor pattern transformations at the pattern origin
    This keeps the rounding errors due to the conversion to 16.16 fixed point
    numbers small and improves cairo's translation invariance.

diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index d534826..589566d 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -753,6 +753,10 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t	*matrix,
         *pixman_transform = pixman_identity_transform;
     }
     else {
+        cairo_matrix_t inv = *matrix;
+        double x = 0, y = 0;
+        pixman_vector_t vector;
+
         pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
         pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy);
         pixman_transform->matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0);
@@ -764,5 +768,24 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t	*matrix,
         pixman_transform->matrix[2][0] = 0;
         pixman_transform->matrix[2][1] = 0;
         pixman_transform->matrix[2][2] = 1 << 16;
+
+        if (cairo_matrix_invert (&inv) != CAIRO_STATUS_SUCCESS)
+            return;
+
+        /* find the device space coordinate that maps to (0, 0) */
+        cairo_matrix_transform_point (&inv, &x, &y);
+
+        /* transform the resulting device space coordinate back
+         * to the pattern space, using pixman's transform */
+        vector.vector[0] = _cairo_fixed_16_16_from_double (x);
+        vector.vector[1] = _cairo_fixed_16_16_from_double (y);
+        vector.vector[2] = 1 << 16;
+
+        if (!pixman_transform_point_3d (pixman_transform, &vector))
+            return;
+
+        /* and compensate for the resulting error */
+        pixman_transform->matrix[0][2] -= vector.vector[0];
+        pixman_transform->matrix[1][2] -= vector.vector[1];
     }
 }


More information about the cairo-commit mailing list