summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Spitzak <spitzak@gmail.com>2014-10-09 19:46:11 -0700
committerBryce Harrington <bryce@osg.samsung.com>2014-10-10 18:08:48 -0700
commitc8b1bf55ad016de0675f4e924fdb8e17051a029c (patch)
tree46e2c99f130fb1cd7fe04f05358dd81cbe8f3fb5
parent82cd66f8330da0521c29c003ef0a4bb773d6dbc6 (diff)
downloadcairo-c8b1bf55ad016de0675f4e924fdb8e17051a029c.tar.gz
image: Move filter decision to _cairo_pattern_analyze_filter
The analysis to deterimine if the GOOD filter can be replaced with the BILINEAR filter is moved to this function so it can be used by backends other than the image backend. Reviewed-by: Bryce Harrington <b.harrington@samsung.com>
-rw-r--r--src/cairo-image-source.c22
-rw-r--r--src/cairo-pattern.c36
2 files changed, 44 insertions, 14 deletions
diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
index b6b6b9f55..950053db2 100644
--- a/src/cairo-image-source.c
+++ b/src/cairo-image-source.c
@@ -941,21 +941,17 @@ _pixman_image_set_properties (pixman_image_t *pixman_image,
pixman_filter = PIXMAN_FILTER_FAST;
break;
case CAIRO_FILTER_GOOD:
- pixman_filter = PIXMAN_FILTER_GOOD;
- if (dx > 1.35 || dy > 1.35) {
- pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
- kernel = KERNEL_BOX;
- /* Clip the filter size to prevent extreme slowness. This
- value could be raised if 2-pass filtering is done */
- if (dx > 16.0) dx = 16.0;
- /* Match the bilinear filter for dimension scaling up: */
- else if (dx < 1.0) dx = 1.0;
- if (dy > 16.0) dy = 16.0;
- else if (dy < 1.0) dy = 1.0;
- }
+ pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
+ kernel = KERNEL_BOX;
+ /* Clip the filter size to prevent extreme slowness. This
+ value could be raised if 2-pass filtering is done */
+ if (dx > 16.0) dx = 16.0;
+ if (dy > 16.0) dy = 16.0;
+ /* Match the bilinear filter for scales > .75: */
+ if (dx < 1.0/0.75) dx = 1.0;
+ if (dy < 1.0/0.75) dy = 1.0;
break;
case CAIRO_FILTER_BEST:
- pixman_filter = PIXMAN_FILTER_BEST;
pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION;
kernel = KERNEL_CATMULL_ROM; /* LANCZOS3 is better but not much */
/* Clip the filter size to prevent extreme slowness. This
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index e6fdae6a6..1a93d2ba5 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -3339,6 +3339,26 @@ _cairo_pattern_is_clear (const cairo_pattern_t *abstract_pattern)
}
/**
+ * Will given row of back-translation matrix work with bilinear scale?
+ * This is true for scales larger than 1. Also it was judged acceptable
+ * for scales larger than .75. And if there is integer translation
+ * then a scale of exactly .5 works.
+ */
+static int
+use_bilinear(double x, double y, double t)
+{
+ /* This is the inverse matrix! */
+ double h = x*x + y*y;
+ if (h < 1.0 / (0.75 * 0.75))
+ return TRUE; /* scale > .75 */
+ if ((h > 3.99 && h < 4.01) /* scale is 1/2 */
+ && !_cairo_fixed_from_double(x*y) /* parallel to an axis */
+ && _cairo_fixed_is_integer (_cairo_fixed_from_double (t)))
+ return TRUE;
+ return FALSE;
+}
+
+/**
* _cairo_pattern_analyze_filter:
* @pattern: surface pattern
* @pad_out: location to store necessary padding in the source image, or %NULL
@@ -3378,7 +3398,21 @@ _cairo_pattern_analyze_filter (const cairo_pattern_t *pattern,
* more would be defensive...
*/
pad = 0.5;
- optimized_filter = pattern->filter;
+ /* Use BILINEAR for any scale greater than .75 instead
+ * of GOOD. For scales of 1 and larger this is identical,
+ * for the smaller sizes it was judged that the artifacts
+ * were not worse than the artifacts from a box filer.
+ * BILINEAR can also be used if the scale is exactly .5
+ * and the translation in that direction is an integer.
+ */
+ if (pattern->filter == CAIRO_FILTER_GOOD &&
+ use_bilinear (pattern->matrix.xx, pattern->matrix.xy,
+ pattern->matrix.x0) &&
+ use_bilinear (pattern->matrix.yx, pattern->matrix.yy,
+ pattern->matrix.y0))
+ optimized_filter = CAIRO_FILTER_BILINEAR;
+ else
+ optimized_filter = pattern->filter;
}
break;