[cairo] [patch] quartz: align pixel when source/mask translation is either 1.0 or -1.0

Henry (Yu) Song - SISA hsong at sisa.samsung.com
Mon Jul 30 11:18:24 PDT 2012


I am not sure whether this should be a considered as a fix, or _cairo_matrix_is_abs_translation() should be moved to cairoint.h instead of in cairo-quartz-surface.c


>From a0003ab008f58f874898880e5f277a2f0fec033a Mon Sep 17 00:00:00 2001
From: Henry Song <hsong at sisa.samsung.com>
Date: Mon, 30 Jul 2012 11:06:30 -0700
Subject: [PATCH] quartz:  use absolute value when checking
 cairo_matrix_is_translation. if filter is
 CAIRO_FILTER_NEAREST and cairo_matrix_is_abs_translation,
 we can align pixel for source/mask.  This fixes XFAIL case
 for filter-nearest-transformed

---
 src/cairo-quartz-surface.c | 22 ++++++++++++++++++----
 test/a1-bug.c              |  1 -
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 1e2bbec..43e5224 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -158,6 +158,13 @@ static void quartz_ensure_symbols (void)
     _cairo_quartz_symbol_lookup_done = TRUE;
 }
 
+static inline cairo_bool_t
+_cairo_matrix_is_abs_translation (const cairo_matrix_t *matrix)
+{
+    return (fabs (matrix->xx) == 1.0 && matrix->yx == 0.0 &&
+	    matrix->xy == 0.0 && fabs (matrix->yy) == 1.0);
+}
+
 CGImageRef
 CairoQuartzCreateCGImage (cairo_format_t format,
 			  unsigned int width,
@@ -1256,9 +1263,12 @@ _cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state,
 
 	state->image = img;
 
-	if (state->filter == kCGInterpolationNone && _cairo_matrix_is_translation (&m)) {
-	    m.x0 = -ceil (m.x0 - 0.5);
-	    m.y0 = -ceil (m.y0 - 0.5);
+	/* if the filter is CAIRO_FILTER_NEAREST and the transformation
+	 * matrix scale is 1.0 or -1.0, we can align pixel
+	 */
+	if (state->filter == kCGInterpolationNone && _cairo_matrix_is_abs_translation (&m)) {
+	    m.x0 = -ceil (m.x0 - 0.5) * m.xx;
+	    m.y0 = -ceil (m.y0 - 0.5) * m.yy;
 	} else {
 	    cairo_matrix_invert (&m);
 	}
@@ -1756,8 +1766,12 @@ _cairo_quartz_cg_mask (const cairo_compositor_t *compositor,
 	matrix = mask->matrix;
 
 	mask_filter = _cairo_quartz_filter_to_quartz (mask->filter);
+	
+	/* if the filter is CAIRO_FILTER_NEAREST and the transformation
+	 * matrix scale is 1.0 or -1.0, we can align pixel
+	 */
 	if (mask_filter == kCGInterpolationNone) {
-	    simple_transform = _cairo_matrix_is_translation (&matrix);
+	    simple_transform = _cairo_matrix_is_abs_translation (&matrix);
 	    if (simple_transform) {
 		matrix.x0 = ceil (matrix.x0 - 0.5);
 		matrix.y0 = ceil (matrix.y0 - 0.5);
diff --git a/test/a1-bug.c b/test/a1-bug.c
index 9166ff5..6cc80cd 100644
--- a/test/a1-bug.c
+++ b/test/a1-bug.c
@@ -45,7 +45,6 @@ draw (cairo_t *cr, int width, int height)
 
     cairo_set_source_rgb (cr, 1, 0, 0);
     cairo_fill_preserve (cr);
-
     cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
     cairo_set_source_rgb (cr, 0, 1, 0);
     cairo_fill (cr);
-- 
1.7.11.2


More information about the cairo mailing list