[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