[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