[cairo-commit] 2 commits - src/cairo-image-surface.c src/cairo-matrix.c src/cairo-pattern.c test/scale-offset-image.ps.ref.png test/scale-offset-image.ref.png test/scale-offset-similar.ps.ref.png test/scale-offset-similar.ref.png
Chris Wilson
ickle at kemper.freedesktop.org
Wed Nov 5 03:36:18 PST 2008
src/cairo-image-surface.c | 4 +-
src/cairo-matrix.c | 53 +++++++++++++++++++++--------------
src/cairo-pattern.c | 7 +++-
test/scale-offset-image.ps.ref.png |binary
test/scale-offset-image.ref.png |binary
test/scale-offset-similar.ps.ref.png |binary
test/scale-offset-similar.ref.png |binary
7 files changed, 39 insertions(+), 25 deletions(-)
New commits:
commit e811173311ebe76d47eebcf5c6c5c798f9d3ea72
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Nov 5 10:59:15 2008 +0000
[matrix] Compensate pixman_matrix in device space.
We wish to reduce the visible error when converting to a pixman matrix, so
perform the compensation in device space instead of pattern space.
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index f84cf7f..0efdb7a 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1159,8 +1159,8 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
goto finish;
status = _cairo_image_surface_set_attributes (src, &attributes,
- src_x + width / 2.,
- src_y + height / 2.);
+ dst_x + width / 2.,
+ dst_y + height / 2.);
if (status)
goto CLEANUP_SOURCE;
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 555c4fe..0c7f305 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -879,8 +879,6 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
*pixman_transform = pixman_identity_transform;
} else {
cairo_matrix_t inv;
- double x,y;
- 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);
@@ -913,24 +911,37 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
if (cairo_matrix_invert (&inv) != CAIRO_STATUS_SUCCESS)
return;
- /* find the device space coordinate that maps to (xc, yc) */
- x = xc, y = yc;
- 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;
-
- /* Ideally, the vector should now be (xc, yc). We can now compensate
- * for the resulting error */
- pixman_transform->matrix[0][2] +=
- _cairo_fixed_16_16_from_double (xc) - vector.vector[0];
- pixman_transform->matrix[1][2] +=
- _cairo_fixed_16_16_from_double (yc) - vector.vector[1];
+ /* find the pattern space coordinate that maps to (xc, yc) */
+ xc += .5; yc += .5; /* offset for the pixel centre */
+ do {
+ double x,y;
+ pixman_vector_t vector;
+ cairo_fixed_16_16_t dx, dy;
+
+ vector.vector[0] = _cairo_fixed_16_16_from_double (xc);
+ vector.vector[1] = _cairo_fixed_16_16_from_double (yc);
+ vector.vector[2] = 1 << 16;
+
+ if (! pixman_transform_point_3d (pixman_transform, &vector))
+ return;
+
+ x = pixman_fixed_to_double (vector.vector[0]);
+ y = pixman_fixed_to_double (vector.vector[1]);
+ cairo_matrix_transform_point (&inv, &x, &y);
+
+ /* Ideally, the vector should now be (xc, yc) [offset for pixel
+ * centre]. We can now compensate for the resulting error.
+ */
+ x -= xc; x += .5;
+ y -= yc; y += .5;
+ cairo_matrix_transform_distance (matrix, &x, &y);
+ dx = _cairo_fixed_16_16_from_double (x);
+ dy = _cairo_fixed_16_16_from_double (y);
+ pixman_transform->matrix[0][2] -= dx;
+ pixman_transform->matrix[1][2] -= dy;
+
+ if (dx == 0 && dy == 0)
+ break;
+ } while (TRUE);
}
}
commit c95eebc92316ad50840fab1cec6c14b6c3e50fa5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Nov 5 09:56:02 2008 +0000
[pattern] Split the translation between the matrix and [xy]_offset
pixman limits the src] co-ordinates (and thus [xy]_offset] to 16bits,
so we need to be careful how much of the translation vector to push into
[xy]_offset. Since the range is the same for both, split the integer
component between the matrix and the offset.
test/scale-offset* now at least shows the source image, even if it is
misplaced.
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 5a6bf6c..9d476cd 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -2000,8 +2000,11 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
assert (invert_status == CAIRO_STATUS_SUCCESS);
if (m.x0 != 0. || m.y0 != 0.) {
- x = floor (m.x0);
- y = floor (m.y0);
+ /* pixman also limits the [xy]_offset to 16 bits so evenly
+ * spread the bits between the two.
+ */
+ x = floor (m.x0 / 2);
+ y = floor (m.y0 / 2);
attr->x_offset -= x;
attr->y_offset -= y;
cairo_matrix_init_translate (&m, x, y);
diff --git a/test/scale-offset-image.ps.ref.png b/test/scale-offset-image.ps.ref.png
index b87612a..1aed28d 100644
Binary files a/test/scale-offset-image.ps.ref.png and b/test/scale-offset-image.ps.ref.png differ
diff --git a/test/scale-offset-image.ref.png b/test/scale-offset-image.ref.png
index 325bdf4..8c6b0fe 100644
Binary files a/test/scale-offset-image.ref.png and b/test/scale-offset-image.ref.png differ
diff --git a/test/scale-offset-similar.ps.ref.png b/test/scale-offset-similar.ps.ref.png
index a60e9ad..7002b2e 100644
Binary files a/test/scale-offset-similar.ps.ref.png and b/test/scale-offset-similar.ps.ref.png differ
diff --git a/test/scale-offset-similar.ref.png b/test/scale-offset-similar.ref.png
index 325bdf4..8c6b0fe 100644
Binary files a/test/scale-offset-similar.ref.png and b/test/scale-offset-similar.ref.png differ
More information about the cairo-commit
mailing list