[PATCH] Use NEAREST filter when possible

Bill Spitzak <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index ba975be..ba73b53 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -748,23 +748,26 @@ _cairo_matrix_is_integer_translation (const cairo_matrix_t *matrix,
     return FALSE;
 }
 
+/* This only returns true if the matrix is 90 degree rotations or
+ * flips. It appears calling code is relying on this. It will return
+ * false for other rotations even if the scale is one. Approximations
+ * are allowed to handle matricies filled in using trig functions
+ * such as sin(M_PI_2).
+ */
 cairo_bool_t
 _cairo_matrix_has_unity_scale (const cairo_matrix_t *matrix)
 {
-    if (matrix->xy == 0.0 && matrix->yx == 0.0) {
-	if (! (matrix->xx == 1.0 || matrix->xx == -1.0))
-	    return FALSE;
-	if (! (matrix->yy == 1.0 || matrix->yy == -1.0))
-	    return FALSE;
-    } else if (matrix->xx == 0.0 && matrix->yy == 0.0) {
-	if (! (matrix->xy == 1.0 || matrix->xy == -1.0))
-	    return FALSE;
-	if (! (matrix->yx == 1.0 || matrix->yx == -1.0))
-	    return FALSE;
-    } else
-	return FALSE;
+    /* check that the determinant is near +/-1 */
+    double v = matrix->xx * matrix->yy - matrix->xy * matrix->yx;
+    v = v * v;
+    if (v < 0.99999 || v > 1.00001) return FALSE;
 
-    return TRUE;
+    /* check that one axis is close to zero */
+    if (fabs (matrix->xy) < 0.0001  &&  fabs (matrix->yx) < 0.0001)
+	return TRUE;
+    if (fabs (matrix->xx) < 0.0001  &&  fabs (matrix->yy) < 0.0001)
+	return TRUE;
+    return FALSE;
 }
 
 /* By pixel exact here, we mean a matrix that is composed only of
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index e104440..6905e15 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -3363,6 +3363,7 @@ _cairo_pattern_analyze_filter (const cairo_pattern_t	*pattern,
     case CAIRO_FILTER_GOOD:
     case CAIRO_FILTER_BEST:
     case CAIRO_FILTER_BILINEAR:
+    case CAIRO_FILTER_FAST:
 	/* If source pixels map 1:1 onto destination pixels, we do
 	 * not need to filter (and do not want to filter, since it
 	 * will cause blurriness)
@@ -3381,7 +3382,6 @@ _cairo_pattern_analyze_filter (const cairo_pattern_t	*pattern,
 	}
 	break;
 
-    case CAIRO_FILTER_FAST:
     case CAIRO_FILTER_NEAREST:
     case CAIRO_FILTER_GAUSSIAN:
     default:
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 3f2fc43..a127000 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -414,8 +414,7 @@ _pattern_is_supported (uint32_t flags,
 	cairo_filter_t filter;
 
 	filter = pattern->filter;
-	if (_cairo_matrix_has_unity_scale (&pattern->matrix) &&
-	    _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL))
+	if (_cairo_matrix_is_pixel_exact (&pattern->matrix))
 	{
 	    filter = CAIRO_FILTER_NEAREST;
 	}
@@ -1033,9 +1032,7 @@ _cairo_xcb_surface_setup_surface_picture(cairo_xcb_picture_t *picture,
 
     filter = pattern->base.filter;
     if (filter != CAIRO_FILTER_NEAREST &&
-	_cairo_matrix_has_unity_scale (&pattern->base.matrix) &&
-	_cairo_fixed_is_integer (_cairo_fixed_from_double (pattern->base.matrix.x0)) &&
-	_cairo_fixed_is_integer (_cairo_fixed_from_double (pattern->base.matrix.y0)))
+        _cairo_matrix_is_pixel_exact (&pattern->base.matrix))
     {
 	filter = CAIRO_FILTER_NEAREST;
     }
-- 
1.7.9.5

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.