[cairo-commit] 3 commits - NEWS src/cairo.c src/cairo-pattern.c src/cairo-scaled-font.c src/cairo-surface.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 test/.gitignore test/Makefile.am

Chris Wilson ickle at kemper.freedesktop.org
Mon Oct 13 15:53:26 PDT 2008


 NEWS                                          |    2 
 src/cairo-pattern.c                           |   35 ++++++++
 src/cairo-scaled-font.c                       |    3 
 src/cairo-surface.c                           |    3 
 src/cairo.c                                   |    6 -
 test/.gitignore                               |    1 
 test/Makefile.am                              |    5 +
 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             |  103 ++++++++++++++++++++++++++
 12 files changed, 149 insertions(+), 9 deletions(-)

New commits:
commit 6aa1143d5a8ec45fc793102a64e956d7d1c7ad01
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 13 23:49:17 2008 +0100

    Update documentation to remove references to cairo_has_show_text_glyphs().
    
    With the addition of cairo_show_text_glyphs() came a couple of functions
    to query whether the target supported the extended attributes. However,
    at Carl's request cairo_has_show_text_glyphs() was removed - but the
    documentation was not updated to reflect that.

diff --git a/NEWS b/NEWS
index 22c0774..fe26db1 100644
--- a/NEWS
+++ b/NEWS
@@ -369,7 +369,7 @@ cairo_glyph_free
 cairo_text_cluster_t
 cairo_text_cluster_allocate
 cairo_text_cluster_free
-cairo_has_show_text_glyphs
+cairo_surface_has_show_text_glyphs
 
 
 cairo_user_font_face_create
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 24db00a..06bd41b 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -2176,9 +2176,6 @@ _cairo_surface_get_extents (cairo_surface_t         *surface,
  * function to avoid computing UTF-8 text and cluster mapping if the
  * target surface does not use it.
  *
- * There is a convenience function for this that takes a #cairo_t,
- * namely cairo_has_show_text_glyphs().
- *
  * Return value: %TRUE if @surface supports
  *               cairo_show_text_glyphs(), %FALSE otherwise
  *
diff --git a/src/cairo.c b/src/cairo.c
index 12b3968..cefc925 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -3190,9 +3190,9 @@ cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs)
  * This operation has rendering effects similar to cairo_show_glyphs()
  * but, if the target surface supports it, uses the provided text and
  * cluster mapping to embed the text for the glyphs shown in the output.
- * The cairo_has_show_text_glyphs() function can be used to query that.
- * If the target does not support it, this function acts like
- * cairo_show_glyphs().
+ * If the target does not support the extended attributes, this function
+ * acts like the basic cairo_show_glyphs() as if it had been passed
+ * @glyphs and @num_glyphs.
  *
  * The mapping between @utf8 and @glyphs is provided by an array of
  * <firstterm>clusters</firstterm>.  Each cluster covers a number of
commit b2053945df35d4d7eea9fe3200e9c018705309d1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 13 23:39:47 2008 +0100

    [scaled-font] Correct documentation for cairo_scaled_font_create().
    
    Fix the documentation not to suggest that NULL is a legal value for
    font_options (as we temporarily made it during the 1.[57] dev cycle).

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index caa345f..584dd4c 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -735,8 +735,7 @@ _cairo_scaled_font_fini (cairo_scaled_font_t *scaled_font)
  * @ctm: user to device transformation matrix with which the font will
  *       be used.
  * @options: options to use when getting metrics for the font and
- *           rendering with it. A %NULL pointer will be interpreted as
- *           meaning the default options.
+ *           rendering with it.
  *
  * Creates a #cairo_scaled_font_t object from a font face and matrices that
  * describe the size of the font and the environment in which it will
commit 3eb4bc37577e905d93a1935e7a9cd33ae8dbda15
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Oct 13 23:26:04 2008 +0100

    [pattern] Optimize away fractional translation for NEAREST patterns.
    
    As identified in bug 15479,
      Unpredictable performance of cairo-xlib with non-integer translations of a
      source surface pattern
      (https://bugs.freedesktop.org/show_bug.cgi?id=15479),
    source surfaces with a fractional translation hit slow paths for some
    drivers, causing seemingly random performance variations. As a work-around
    Owen Taylor proposed that cairo could convert non-integer translations on
    NEAREST sources patterns to their integer equivalents.
    
    The messy detail involved here is replicating the rounding mode used by
    pixman for the sample offset, but otherwise the conversion is fairly
    trivial.

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index c60b1f6..995f49a 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1756,6 +1756,13 @@ _cairo_pattern_analyze_filter (cairo_surface_pattern_t *pattern,
     return optimized_filter;
 }
 
+
+static double
+_pixman_nearest_sample (double d)
+{
+    return ceil (d - .5);
+}
+
 static cairo_int_status_t
 _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t   *pattern,
 					    cairo_surface_t	       *dst,
@@ -1782,6 +1789,34 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t   *pattern,
 	attr->x_offset = tx;
 	attr->y_offset = ty;
     }
+    else if (attr->filter == CAIRO_FILTER_NEAREST)
+    {
+	/*
+	 * For NEAREST, we can remove the fractional translation component
+	 * from the transformation - this ensures that the pattern will always
+	 * hit fast-paths in the backends for simple transformations that
+	 * become (almost) identity, without loss of quality.
+	 */
+	attr->matrix = pattern->base.matrix;
+	attr->matrix.x0 = 0;
+	attr->matrix.y0 = 0;
+	if (_cairo_matrix_is_pixel_exact (&attr->matrix)) {
+	    double x1, y1;
+
+	    /* 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);
+	} else {
+	    attr->matrix = pattern->base.matrix;
+	    attr->x_offset = attr->y_offset = 0;
+	    tx = ty = 0;
+	}
+    }
     else
     {
 	attr->matrix = pattern->base.matrix;
diff --git a/test/.gitignore b/test/.gitignore
index edcf41a..e7ec82b 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -79,6 +79,7 @@ fill-missed-stop
 fill-rule
 filter-bilinear-extents
 filter-nearest-offset
+filter-nearest-transformed
 finer-grained-fallbacks
 ft-text-antialias-none
 ft-font-create-for-ft-face
diff --git a/test/Makefile.am b/test/Makefile.am
index bd7272e..e244b55 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -64,6 +64,7 @@ fill-missed-stop$(EXEEXT)				\
 fill-rule$(EXEEXT)					\
 filter-bilinear-extents$(EXEEXT)			\
 filter-nearest-offset$(EXEEXT)				\
+filter-nearest-transformed$(EXEEXT)			\
 finer-grained-fallbacks$(EXEEXT)			\
 font-face-get-type$(EXEEXT)				\
 font-matrix-translation$(EXEEXT)			\
@@ -479,6 +480,10 @@ REFERENCE_IMAGES = \
 	filter-nearest-offset-ps3-ref.png	\
 	filter-nearest-offset-svg11-ref.png	\
 	filter-nearest-offset-svg12-ref.png	\
+	filter-nearest-transformed-ref.png	\
+	filter-nearest-transformed-pdf-ref.png	\
+	filter-nearest-transformed-svg11-ref.png	\
+	filter-nearest-transformed-svg12-ref.png	\
 	finer-grained-fallbacks-ref.png			\
 	finer-grained-fallbacks-rgb24-ref.png		\
 	finer-grained-fallbacks-ps2-ref.png	\
diff --git a/test/filter-nearest-transformed-pdf-ref.png b/test/filter-nearest-transformed-pdf-ref.png
new file mode 100644
index 0000000..c1e7b57
Binary files /dev/null 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
new file mode 100644
index 0000000..39fe4b2
Binary files /dev/null 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
new file mode 100644
index 0000000..39ba69f
Binary files /dev/null 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
new file mode 100644
index 0000000..39ba69f
Binary files /dev/null and b/test/filter-nearest-transformed-svg12-ref.png differ
diff --git a/test/filter-nearest-transformed.c b/test/filter-nearest-transformed.c
new file mode 100644
index 0000000..a6dc85a
--- /dev/null
+++ b/test/filter-nearest-transformed.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright © 2008 Chris Wilson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Author: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+
+/*
+ * We wish to check the optimization away of non-fractional translations
+ * for NEAREST surface patterns under a few transformations.
+ */
+
+static cairo_test_draw_function_t draw;
+
+static const cairo_test_t test = {
+    "filter-nearest-transformed",
+    "Test sample position when drawing transformed images with FILTER_NEAREST",
+    14, 14,
+    draw
+};
+
+/* A single, black pixel */
+static const uint32_t black_pixel = 0xff000000;
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    unsigned int i, j, k;
+    cairo_surface_t *surface;
+    cairo_pattern_t *pattern;
+    const cairo_matrix_t transform[] = {
+	{  1, 0, 0,  1,  0, 0 },
+	{ -1, 0, 0,  1,  8, 0 },
+	{  1, 0, 0, -1,  0, 8 },
+	{ -1, 0, 0, -1,  8, 8 },
+    };
+    const double colour[][3] = {
+	{0, 0, 0},
+	{1, 0, 0},
+	{0, 1, 0},
+	{0, 0, 1},
+    };
+    cairo_matrix_t m;
+
+    surface = cairo_image_surface_create_for_data ((uint8_t *) &black_pixel,
+						   CAIRO_FORMAT_ARGB32,
+						   1, 1, 4);
+    pattern = cairo_pattern_create_for_surface (surface);
+    cairo_surface_destroy (surface);
+
+    cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
+
+    /* Fill background white */
+    cairo_set_source_rgb (cr, 1, 1, 1);
+    cairo_paint (cr);
+
+    cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+    for (k = 0; k < sizeof (transform) / sizeof (transform[0]); k++) {
+	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++) {
+		cairo_matrix_init_translate (&m,
+					     -(2*(i-4) + .1*i),
+					     -(2*(j-4) + .1*j));
+		cairo_matrix_multiply (&m, &m, &transform[k]);
+		cairo_pattern_set_matrix (pattern, &m);
+		cairo_mask (cr, pattern);
+	    }
+	}
+    }
+
+    cairo_pattern_destroy (pattern);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+    return cairo_test (&test);
+}


More information about the cairo-commit mailing list