[cairo-commit] src/cairo-pattern.c test/filter-nearest-transformed.c test/filter-nearest-transformed-pdf-ref.png test/filter-nearest-transformed-ref.png test/filter-nearest-transformed-svg11-ref.png test/filter-nearest-transformed-svg12-ref.png

Chris Wilson ickle at kemper.freedesktop.org
Tue Oct 14 02:28:33 PDT 2008


 src/cairo-pattern.c                           |   16 ++++++----------
 test/filter-nearest-transformed-pdf-ref.png   |binary
 test/filter-nearest-transformed-ref.png       |binary
 test/filter-nearest-transformed-svg11-ref.png |binary
 test/filter-nearest-transformed-svg12-ref.png |binary
 test/filter-nearest-transformed.c             |   24 ++++++++++++++++++++++++
 6 files changed, 30 insertions(+), 10 deletions(-)

New commits:
commit 9886cb3353eb02ce5b99d555a35b13b8347f8e87
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 14 10:23:41 2008 +0100

    [pattern] Only perform non-integer optimization for identity matrices.
    
    A complication I realised after pushing 3eb4bc3 was handling larger
    sampled areas.  Extending the test case revealed that the optimization
    was broken for anything but the identity transform (after removing the
    translation).  Correctness first, leaving the "pixel-exact" solution for
    interested reader...

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 995f49a..48aa56b 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1757,10 +1757,10 @@ _cairo_pattern_analyze_filter (cairo_surface_pattern_t *pattern,
 }
 
 
-static double
+static int
 _pixman_nearest_sample (double d)
 {
-    return ceil (d - .5);
+    return _cairo_lround (ceil (d - .5));
 }
 
 static cairo_int_status_t
@@ -1800,17 +1800,12 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t   *pattern,
 	attr->matrix = pattern->base.matrix;
 	attr->matrix.x0 = 0;
 	attr->matrix.y0 = 0;
-	if (_cairo_matrix_is_pixel_exact (&attr->matrix)) {
-	    double x1, y1;
-
+	if (_cairo_matrix_is_identity (&attr->matrix)) {
 	    /* The rounding here is rather peculiar as it needs to match the
 	     * rounding performed on the sample coordinate used by pixman.
 	     */
-	    x1 = _pixman_nearest_sample (pattern->base.matrix.x0);
-	    y1 = _pixman_nearest_sample (pattern->base.matrix.y0);
-	    cairo_matrix_transform_point (&attr->matrix, &x1, &y1);
-	    attr->x_offset = tx = _cairo_lround (x1);
-	    attr->y_offset = ty = _cairo_lround (y1);
+	    attr->x_offset = tx = _pixman_nearest_sample (pattern->base.matrix.x0);
+	    attr->y_offset = ty = _pixman_nearest_sample (pattern->base.matrix.y0);
 	} else {
 	    attr->matrix = pattern->base.matrix;
 	    attr->x_offset = attr->y_offset = 0;
@@ -1946,6 +1941,7 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t   *pattern,
 		sampled_area.y = floor (y1 - pad);
 		sampled_area.width  = ceil (x2 + pad) - sampled_area.x;
 		sampled_area.height = ceil (y2 + pad) - sampled_area.y;
+
 	    }
 
 	    sampled_area.x += tx;
diff --git a/test/filter-nearest-transformed-pdf-ref.png b/test/filter-nearest-transformed-pdf-ref.png
index c1e7b57..960ccc6 100644
Binary files a/test/filter-nearest-transformed-pdf-ref.png and b/test/filter-nearest-transformed-pdf-ref.png differ
diff --git a/test/filter-nearest-transformed-ref.png b/test/filter-nearest-transformed-ref.png
index 39fe4b2..dc413b4 100644
Binary files a/test/filter-nearest-transformed-ref.png and b/test/filter-nearest-transformed-ref.png differ
diff --git a/test/filter-nearest-transformed-svg11-ref.png b/test/filter-nearest-transformed-svg11-ref.png
index 39ba69f..4f18c0d 100644
Binary files a/test/filter-nearest-transformed-svg11-ref.png and b/test/filter-nearest-transformed-svg11-ref.png differ
diff --git a/test/filter-nearest-transformed-svg12-ref.png b/test/filter-nearest-transformed-svg12-ref.png
index 39ba69f..4f18c0d 100644
Binary files a/test/filter-nearest-transformed-svg12-ref.png and b/test/filter-nearest-transformed-svg12-ref.png differ
diff --git a/test/filter-nearest-transformed.c b/test/filter-nearest-transformed.c
index a6dc85a..58acf9a 100644
--- a/test/filter-nearest-transformed.c
+++ b/test/filter-nearest-transformed.c
@@ -31,6 +31,7 @@
  * for NEAREST surface patterns under a few transformations.
  */
 
+static const char png_filename[] = "romedalen.png";
 static cairo_test_draw_function_t draw;
 
 static const cairo_test_t test = {
@@ -46,6 +47,7 @@ static const uint32_t black_pixel = 0xff000000;
 static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
+    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
     unsigned int i, j, k;
     cairo_surface_t *surface;
     cairo_pattern_t *pattern;
@@ -55,6 +57,12 @@ draw (cairo_t *cr, int width, int height)
 	{  1, 0, 0, -1,  0, 8 },
 	{ -1, 0, 0, -1,  8, 8 },
     };
+    const cairo_matrix_t ctx_transform[] = {
+	{  1, 0, 0,  1,   0,  0 },
+	{ -1, 0, 0,  1,  14,  0 },
+	{  1, 0, 0, -1,   0, 14 },
+	{ -1, 0, 0, -1,  14, 14 },
+    };
     const double colour[][3] = {
 	{0, 0, 0},
 	{1, 0, 0},
@@ -71,6 +79,8 @@ draw (cairo_t *cr, int width, int height)
 
     cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
 
+    surface = cairo_test_create_surface_from_png (ctx, png_filename);
+
     /* Fill background white */
     cairo_set_source_rgb (cr, 1, 1, 1);
     cairo_paint (cr);
@@ -78,6 +88,19 @@ draw (cairo_t *cr, int width, int height)
     cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
 
     for (k = 0; k < sizeof (transform) / sizeof (transform[0]); k++) {
+	/* draw a "large" section from an image */
+	cairo_save (cr); {
+	    cairo_set_matrix(cr, &ctx_transform[k]);
+	    cairo_rectangle (cr, 0, 0, 7, 7);
+	    cairo_clip (cr);
+
+	    cairo_set_source_surface (cr, surface,
+				      -cairo_image_surface_get_width (surface)/2.,
+				      -cairo_image_surface_get_height (surface)/2.);
+	    cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+	    cairo_paint (cr);
+	} cairo_restore (cr);
+
 	cairo_set_source_rgb (cr, colour[k][0], colour[k][1], colour[k][2]);
 	for (j = 4; j <= 6; j++) {
 	    for (i = 4; i <= 6; i++) {
@@ -92,6 +115,7 @@ draw (cairo_t *cr, int width, int height)
     }
 
     cairo_pattern_destroy (pattern);
+    cairo_surface_destroy (surface);
 
     return CAIRO_TEST_SUCCESS;
 }


More information about the cairo-commit mailing list