[cairo-commit] 9 commits - boilerplate/cairo-boilerplate.c boilerplate/cairo-boilerplate-test-surfaces.c boilerplate/cairo-boilerplate-test-surfaces-private.h build/aclocal.dolt.m4 build/aclocal.shave.m4 build/configure.ac.analysis build/.gitignore build/shave.in build/shave-libtool.in configure.ac src/cairo-image-surface.c src/cairo-png.c src/cairo-surface-fallback.c src/cairo-xlib-surface.c src/Makefile.sources src/test-fallback16-surface.c src/test-fallback16-surface.h test/Makefile.am test/Makefile.sources test/test-fallback16-surface-source.c test/test-fallback16-surface-source.ref.png

Chris Wilson ickle at kemper.freedesktop.org
Wed May 6 00:04:38 PDT 2009


 boilerplate/cairo-boilerplate-test-surfaces-private.h |   11 
 boilerplate/cairo-boilerplate-test-surfaces.c         |   16 +
 boilerplate/cairo-boilerplate.c                       |   18 +
 build/.gitignore                                      |    2 
 build/aclocal.dolt.m4                                 |    1 
 build/aclocal.shave.m4                                |   77 +++++
 build/configure.ac.analysis                           |    2 
 build/shave-libtool.in                                |   69 +++++
 build/shave.in                                        |   79 ++++++
 configure.ac                                          |    4 
 src/Makefile.sources                                  |    2 
 src/cairo-image-surface.c                             |   22 -
 src/cairo-png.c                                       |   44 ++-
 src/cairo-surface-fallback.c                          |   10 
 src/cairo-xlib-surface.c                              |   16 -
 src/test-fallback16-surface.c                         |  234 ++++++++++++++++++
 src/test-fallback16-surface.h                         |   52 ++++
 test/Makefile.am                                      |    4 
 test/Makefile.sources                                 |    3 
 test/test-fallback16-surface-source.c                 |   43 +++
 test/test-fallback16-surface-source.ref.png           |binary
 21 files changed, 676 insertions(+), 33 deletions(-)

New commits:
commit 30735f790aa3cef822f132932f43a4738cd8cd95
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 5 18:37:25 2009 +0100

    [xlib] Use a similar content surface for cloning images
    
    Simply request a surface with a similar content to the source image when
    uploading pixel data. Failing to do so prevents using a 16-bit (or
    otherwise non-standard pixman image format) window as a source - in fact
    it will trigger an infinite recursion.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index d1e7391..b56b340 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -950,7 +950,8 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
     ximage.blue_mask = surface->b_mask;
     ximage.xoffset = 0;
 
-    if (image_masks.red_mask   == surface->r_mask &&
+    if (image_masks.alpha_mask == surface->a_mask &&
+	image_masks.red_mask   == surface->r_mask &&
 	image_masks.green_mask == surface->g_mask &&
 	image_masks.blue_mask  == surface->b_mask)
     {
@@ -1016,8 +1017,8 @@ _draw_image_surface (cairo_xlib_surface_t   *surface,
 		goto BAIL;
 	}
 
-	rowstride = cairo_image_surface_get_stride (&image->base) >> 2;
-	row = (uint32_t *) cairo_image_surface_get_data (&image->base);
+	rowstride = image->stride >> 2;
+	row = (uint32_t *) image->data;
 	x0 = dst_x + surface->base.device_transform.x0;
 	y0 = dst_y + surface->base.device_transform.y0;
 	for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern);
@@ -1194,16 +1195,17 @@ _cairo_xlib_surface_clone_similar (void			*abstract_surface,
 	}
     } else if (_cairo_surface_is_image (src)) {
 	cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;
-
-	if (! CAIRO_FORMAT_VALID (image_src->format))
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	cairo_format_t format;
 
 	if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
 	    return _cairo_error (CAIRO_STATUS_INVALID_SIZE);
 
+	format = image_src->format;
+	if (format == CAIRO_FORMAT_INVALID)
+	    format = _cairo_format_from_content (image_src->base.content);
 	clone = (cairo_xlib_surface_t *)
 	    _cairo_xlib_surface_create_similar_with_format (surface,
-		                                            image_src->format,
+							    format,
 							    width, height);
 	if (clone == NULL)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
commit 60e38d0530443aa9c78e74e47ba5574887ae220c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 5 17:05:39 2009 +0100

    [surface] Convert FORMAT_INVALID during snapshots
    
    Currently the surface snapshotting attempts to clone the source using a
    new surface of identical format. This will raise an error if the source is
    an unusual xserver, for example one operating at 16bpp. The solution to
    this is to create the surface using the content type rather than the
    format (as elsewhere within the code base). However, we also wish to
    preserve FORMAT_A1 (which is lost if we only choose the format based on
    _cairo_format_from_content) as the various backends may be able to
    trivially special case such bitmaps.

diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index a78c6ad..9019102 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -1115,6 +1115,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
 {
     cairo_surface_t *snapshot;
     cairo_status_t status;
+    cairo_format_t format;
     cairo_surface_pattern_t pattern;
     cairo_image_surface_t *image;
     void *image_extra;
@@ -1124,7 +1125,14 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
     if (unlikely (status))
 	return _cairo_surface_create_in_error (status);
 
-    snapshot = cairo_image_surface_create (image->format,
+    format = image->format;
+    if (format == CAIRO_FORMAT_INVALID) {
+	/* Non-standard images formats can be generated when retrieving
+	 * images from unusual xservers, for example.
+	 */
+	format = _cairo_format_from_content (image->base.content);
+    }
+    snapshot = cairo_image_surface_create (format,
 					   image->width,
 					   image->height);
     if (cairo_surface_status (snapshot)) {
commit 31f5a2e94d669b9d2785de944d4aee584fd1d76e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 5 15:52:55 2009 +0100

    [png] Coerce FORMAT_INVALID to a known image format
    
    It is possible for cairo_surface_write_to_png() to acquire a non-standard
    image surface when, for example, we try to dump a low bit-depth XServer.
    Handle this scenario by coercing the unknown image format to a standard
    type via pixman.

diff --git a/src/cairo-png.c b/src/cairo-png.c
index 0e8f63d..c664328 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -143,6 +143,7 @@ write_png (cairo_surface_t	*surface,
     int i;
     cairo_status_t status;
     cairo_image_surface_t *image;
+    cairo_image_surface_t * volatile clone;
     void *image_extra;
     png_struct *png;
     png_info *info;
@@ -166,40 +167,52 @@ write_png (cairo_surface_t	*surface,
 	goto BAIL1;
     }
 
-    rows = _cairo_malloc_ab (image->height, sizeof (png_byte*));
+    /* Handle the various fallback formats (e.g. low bit-depth XServers)
+     * by coercing them to a simpler format using pixman.
+     */
+    if (image->format == CAIRO_FORMAT_INVALID) {
+	clone = _cairo_image_surface_coerce (image,
+					     _cairo_format_from_content (image->base.content));
+	status = clone->base.status;
+	if (unlikely (status))
+	    goto BAIL1;
+    } else
+	clone = image;
+
+    rows = _cairo_malloc_ab (clone->height, sizeof (png_byte*));
     if (unlikely (rows == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto BAIL1;
+	goto BAIL2;
     }
 
-    for (i = 0; i < image->height; i++)
-	rows[i] = (png_byte *) image->data + i * image->stride;
+    for (i = 0; i < clone->height; i++)
+	rows[i] = (png_byte *) clone->data + i * clone->stride;
 
     png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status,
 	                           png_simple_error_callback,
 	                           png_simple_warning_callback);
     if (unlikely (png == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto BAIL2;
+	goto BAIL3;
     }
 
     info = png_create_info_struct (png);
     if (unlikely (info == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto BAIL3;
+	goto BAIL4;
     }
 
 #ifdef PNG_SETJMP_SUPPORTED
     if (setjmp (png_jmpbuf (png)))
-	goto BAIL3;
+	goto BAIL4;
 #endif
 
     png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
 
-    switch (image->format) {
+    switch (clone->format) {
     case CAIRO_FORMAT_ARGB32:
 	depth = 8;
-	if (_cairo_image_analyze_transparency (image) == CAIRO_IMAGE_IS_OPAQUE)
+	if (_cairo_image_analyze_transparency (clone) == CAIRO_IMAGE_IS_OPAQUE)
 	    png_color_type = PNG_COLOR_TYPE_RGB;
 	else
 	    png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
@@ -221,12 +234,12 @@ write_png (cairo_surface_t	*surface,
 	break;
     default:
 	status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
-	goto BAIL3;
+	goto BAIL4;
     }
 
     png_set_IHDR (png, info,
-		  image->width,
-		  image->height, depth,
+		  clone->width,
+		  clone->height, depth,
 		  png_color_type,
 		  PNG_INTERLACE_NONE,
 		  PNG_COMPRESSION_TYPE_DEFAULT,
@@ -259,10 +272,13 @@ write_png (cairo_surface_t	*surface,
     png_write_image (png, rows);
     png_write_end (png, info);
 
-BAIL3:
+BAIL4:
     png_destroy_write_struct (&png, &info);
-BAIL2:
+BAIL3:
     free (rows);
+BAIL2:
+    if (clone != image)
+	cairo_surface_destroy (&clone->base);
 BAIL1:
     _cairo_surface_release_source_image (surface, image, image_extra);
 
commit c488b336449a1a7ca4d3f90785afeec9e21784c3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 5 13:59:07 2009 +0100

    [test] Create a new fallback surface to exercise 16-bit paths.
    
    Add a variation of test-fallback-surface that forces the use of a 16-bit
    pixman format code instead of the standard 32-bit types. This creates an
    image surface akin to the fallbacks used with low bit-depth xservers.

diff --git a/boilerplate/cairo-boilerplate-test-surfaces-private.h b/boilerplate/cairo-boilerplate-test-surfaces-private.h
index 481b531..24a1ae8 100644
--- a/boilerplate/cairo-boilerplate-test-surfaces-private.h
+++ b/boilerplate/cairo-boilerplate-test-surfaces-private.h
@@ -38,6 +38,17 @@ _cairo_boilerplate_test_fallback_create_surface (const char			 *name,
 						 int                              id,
 						 void				**closure);
 
+cairo_surface_t *
+_cairo_boilerplate_test_fallback16_create_surface (const char			 *name,
+						 cairo_content_t		  content,
+						 int				  width,
+						 int				  height,
+						 int				  max_width,
+						 int				  max_height,
+						 cairo_boilerplate_mode_t	  mode,
+						 int                              id,
+						 void				**closure);
+
 
 cairo_surface_t *
 _cairo_boilerplate_test_meta_create_surface (const char			 *name,
diff --git a/boilerplate/cairo-boilerplate-test-surfaces.c b/boilerplate/cairo-boilerplate-test-surfaces.c
index f6fd63a..644b278 100644
--- a/boilerplate/cairo-boilerplate-test-surfaces.c
+++ b/boilerplate/cairo-boilerplate-test-surfaces.c
@@ -28,6 +28,7 @@
 #include "cairo-boilerplate-test-surfaces-private.h"
 
 #include <test-fallback-surface.h>
+#include <test-fallback16-surface.h>
 #include <test-meta-surface.h>
 #include <test-paginated-surface.h>
 
@@ -49,6 +50,21 @@ _cairo_boilerplate_test_fallback_create_surface (const char			 *name,
 }
 
 cairo_surface_t *
+_cairo_boilerplate_test_fallback16_create_surface (const char			 *name,
+						   cairo_content_t		  content,
+						   int				  width,
+						   int				  height,
+						   int				  max_width,
+						   int				  max_height,
+						   cairo_boilerplate_mode_t	  mode,
+						   int                              id,
+						   void				**closure)
+{
+    *closure = NULL;
+    return _cairo_test_fallback16_surface_create (content, width, height);
+}
+
+cairo_surface_t *
 _cairo_boilerplate_test_meta_create_surface (const char			 *name,
 					     cairo_content_t		  content,
 					     int			  width,
diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c
index fcc05b8..da2a618 100644
--- a/boilerplate/cairo-boilerplate.c
+++ b/boilerplate/cairo-boilerplate.c
@@ -311,6 +311,24 @@ static cairo_boilerplate_target_t targets[] =
 	cairo_surface_write_to_png
     },
     {
+	"test-fallback16", "image", NULL,
+	CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
+	CAIRO_CONTENT_COLOR_ALPHA, 0,
+	_cairo_boilerplate_test_fallback16_create_surface, NULL,
+	NULL,
+	_cairo_boilerplate_get_image_surface,
+	cairo_surface_write_to_png
+    },
+    {
+	"test-fallback16", "image", NULL,
+	CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
+	CAIRO_CONTENT_COLOR, 0,
+	_cairo_boilerplate_test_fallback16_create_surface, NULL,
+	NULL,
+	_cairo_boilerplate_get_image_surface,
+	cairo_surface_write_to_png
+    },
+    {
 	"test-meta", "image", NULL,
 	CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
 	CAIRO_CONTENT_COLOR_ALPHA, 0,
diff --git a/src/Makefile.sources b/src/Makefile.sources
index c1df770..534feec 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -190,11 +190,13 @@ cairo_ft_sources = cairo-ft-font.c
 # These are private, even though they look like public headers
 cairo_test_surfaces_private = \
 	test-fallback-surface.h \
+	test-fallback16-surface.h \
 	test-meta-surface.h \
 	test-paginated-surface.h \
 	$(NULL)
 cairo_test_surfaces_sources = \
 	test-fallback-surface.c \
+	test-fallback16-surface.c \
 	test-meta-surface.c \
 	test-paginated-surface.c \
 	$(NULL)
diff --git a/src/test-fallback16-surface.c b/src/test-fallback16-surface.c
new file mode 100644
index 0000000..7974c1f
--- /dev/null
+++ b/src/test-fallback16-surface.c
@@ -0,0 +1,234 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2005 Red Hat, Inc
+ * Copyright © 2009 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ *	Carl Worth <cworth at cworth.org>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+/* This isn't a "real" surface, but just something to be used by the
+ * test suite to force use of a non-standard pixman image fallback - as
+ * may be exposed by xlib fallbacks with weird xservers, for example.
+ */
+
+#include "cairoint.h"
+
+#include "test-fallback16-surface.h"
+
+typedef struct _test_fallback16_surface {
+    cairo_surface_t base;
+
+    /* This is a cairo_image_surface to hold the actual contents. */
+    cairo_surface_t *backing;
+} test_fallback16_surface_t;
+
+static const cairo_surface_backend_t test_fallback16_surface_backend;
+
+slim_hidden_proto (_cairo_test_fallback16_surface_create);
+
+cairo_surface_t *
+_cairo_test_fallback16_surface_create (cairo_content_t	content,
+				       int		width,
+				       int		height)
+{
+    test_fallback16_surface_t *surface;
+    cairo_surface_t *backing;
+    pixman_format_code_t format;
+
+    format = content & CAIRO_CONTENT_ALPHA ?  PIXMAN_a1r5g5b5: PIXMAN_r5g6b5;
+
+    backing = _cairo_image_surface_create_with_pixman_format (NULL, format,
+							      width, height,
+							      -1);
+    if (cairo_surface_status (backing))
+	return backing;
+
+    surface = malloc (sizeof (test_fallback16_surface_t));
+    if (unlikely (surface == NULL)) {
+	cairo_surface_destroy (backing);
+	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+    }
+
+    _cairo_surface_init (&surface->base,
+			 &test_fallback16_surface_backend,
+			 content);
+
+    surface->backing = backing;
+
+    return &surface->base;
+}
+slim_hidden_def (_cairo_test_fallback16_surface_create);
+
+static cairo_surface_t *
+_test_fallback16_surface_create_similar (void		*abstract_surface,
+					 cairo_content_t content,
+					 int		 width,
+					 int		 height)
+{
+    assert (CAIRO_CONTENT_VALID (content));
+
+    return _cairo_test_fallback16_surface_create (content, width, height);
+}
+
+static cairo_status_t
+_test_fallback16_surface_finish (void *abstract_surface)
+{
+    test_fallback16_surface_t *surface = abstract_surface;
+
+    cairo_surface_destroy (surface->backing);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_test_fallback16_surface_acquire_source_image (void	     *abstract_surface,
+					       cairo_image_surface_t **image_out,
+					       void		 **image_extra)
+{
+    test_fallback16_surface_t *surface = abstract_surface;
+
+    return _cairo_surface_acquire_source_image (surface->backing,
+						image_out, image_extra);
+}
+
+static void
+_test_fallback16_surface_release_source_image (void	     *abstract_surface,
+					       cairo_image_surface_t	*image,
+					       void		  *image_extra)
+{
+    test_fallback16_surface_t *surface = abstract_surface;
+
+    _cairo_surface_release_source_image (surface->backing,
+					 image, image_extra);
+}
+
+static cairo_status_t
+_test_fallback16_surface_acquire_dest_image (void		           *abstract_surface,
+					     cairo_rectangle_int_t   *interest_rect,
+					     cairo_image_surface_t  **image_out,
+					     cairo_rectangle_int_t   *image_rect_out,
+					     void			  **image_extra)
+{
+    test_fallback16_surface_t *surface = abstract_surface;
+
+    return _cairo_surface_acquire_dest_image (surface->backing,
+					      interest_rect,
+					      image_out,
+					      image_rect_out,
+					      image_extra);
+}
+
+static void
+_test_fallback16_surface_release_dest_image (void			   *abstract_surface,
+					     cairo_rectangle_int_t   *interest_rect,
+					     cairo_image_surface_t   *image,
+					     cairo_rectangle_int_t   *image_rect,
+					     void			   *image_extra)
+{
+    test_fallback16_surface_t *surface = abstract_surface;
+
+    _cairo_surface_release_dest_image (surface->backing,
+				       interest_rect,
+				       image,
+				       image_rect,
+				       image_extra);
+}
+
+static cairo_status_t
+_test_fallback16_surface_clone_similar (void		  *abstract_surface,
+					cairo_surface_t     *src,
+					int                  src_x,
+					int                  src_y,
+					int                  width,
+					int                  height,
+					int                 *clone_offset_x,
+					int                 *clone_offset_y,
+					cairo_surface_t    **clone_out)
+{
+    test_fallback16_surface_t *surface = abstract_surface;
+
+    if (src->backend == surface->base.backend) {
+	*clone_offset_x = 0;
+	*clone_offset_y = 0;
+	*clone_out = cairo_surface_reference (src);
+
+	return CAIRO_STATUS_SUCCESS;
+    } else {
+	return _cairo_surface_clone_similar (surface->backing, src,
+					     src_x, src_y,
+					     width, height,
+					     clone_offset_x, clone_offset_y,
+					     clone_out);
+    }
+}
+
+static cairo_int_status_t
+_test_fallback16_surface_get_extents (void		  *abstract_surface,
+				      cairo_rectangle_int_t *rectangle)
+{
+    test_fallback16_surface_t *surface = abstract_surface;
+
+    return _cairo_surface_get_extents (surface->backing, rectangle);
+}
+
+static const cairo_surface_backend_t test_fallback16_surface_backend = {
+    CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
+    _test_fallback16_surface_create_similar,
+    _test_fallback16_surface_finish,
+    _test_fallback16_surface_acquire_source_image,
+    _test_fallback16_surface_release_source_image,
+    _test_fallback16_surface_acquire_dest_image,
+    _test_fallback16_surface_release_dest_image,
+    _test_fallback16_surface_clone_similar,
+    NULL, /* composite */
+    NULL, /* fill_rectangles */
+    NULL, /* composite_trapezoids */
+    NULL, /* create_span_renderer */
+    NULL, /* check_span_renderer */
+    NULL, /* copy_page */
+    NULL, /* show_page */
+    NULL, /* set_clip_region */
+    NULL, /* intersect_clip_path */
+    _test_fallback16_surface_get_extents,
+    NULL, /* old_show_glyphs */
+    NULL, /* get_font_options */
+    NULL, /* flush */
+    NULL, /* mark_dirty_rectangle */
+    NULL, /* scaled_font_fini */
+    NULL, /* scaled_glyph_fini */
+    NULL, /* paint */
+    NULL, /* mask */
+    NULL, /* stroke */
+    NULL, /* fill */
+    NULL, /* show_glyphs */
+    NULL  /* snapshot */
+};
diff --git a/src/test-fallback16-surface.h b/src/test-fallback16-surface.h
new file mode 100644
index 0000000..2c5b2ca
--- /dev/null
+++ b/src/test-fallback16-surface.h
@@ -0,0 +1,52 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2005 Red Hat, Inc
+ * Copyright © 2009 Chris Wilson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ *	Carl Worth <cworth at cworth.org>
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#ifndef TEST_FALLBACK16_SURFACE_H
+#define TEST_FALLBACK16_SURFACE_H
+
+#include "cairo.h"
+
+CAIRO_BEGIN_DECLS
+
+cairo_surface_t *
+_cairo_test_fallback16_surface_create (cairo_content_t	content,
+				       int		width,
+				       int		height);
+
+CAIRO_END_DECLS
+
+#endif /* TEST_FALLBACK16_SURFACE_H */
diff --git a/test/Makefile.am b/test/Makefile.am
index 2a1d93b..efac53f 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -37,6 +37,10 @@ if CAIRO_HAS_SVG_SURFACE
 test_sources += $(svg_surface_test_sources)
 endif
 
+if CAIRO_HAS_TEST_SURFACES
+test_sources += $(test_fallback16_surface_test_sources)
+endif
+
 if CAIRO_HAS_XLIB_SURFACE
 test_sources += $(xlib_surface_test_sources)
 endif
diff --git a/test/Makefile.sources b/test/Makefile.sources
index f8c19fd..eeb9294 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -229,6 +229,9 @@ svg_surface_test_sources = \
 	svg-clip.c \
 	svg-surface-source.c
 
+test_fallback16_surface_test_sources = \
+	test-fallback16-surface-source.c
+
 xlib_surface_test_sources = \
 	xlib-expose-event.c \
 	xlib-surface.c \
diff --git a/test/test-fallback16-surface-source.c b/test/test-fallback16-surface-source.c
new file mode 100644
index 0000000..7e9f920
--- /dev/null
+++ b/test/test-fallback16-surface-source.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairo-test.h"
+#include <test-fallback16-surface.h>
+
+#include "surface-source.c"
+
+static cairo_surface_t *
+create_source_surface (int size)
+{
+    return _cairo_test_fallback16_surface_create (CAIRO_CONTENT_COLOR_ALPHA,
+						  size, size);
+}
+
+CAIRO_TEST (test_fallback16_surface_source,
+	    "Test using a 16-bit image (e.g. a low bit-depth XServer) surface as the source",
+	    "source", /* keywords */
+	    NULL, /* requirements */
+	    SIZE, SIZE,
+	    preamble, draw)
diff --git a/test/test-fallback16-surface-source.ref.png b/test/test-fallback16-surface-source.ref.png
new file mode 100644
index 0000000..3fa8bbe
Binary files /dev/null and b/test/test-fallback16-surface-source.ref.png differ
commit 1d609d672273da494fd596606b59ab1c0010ae6d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 5 17:11:55 2009 +0100

    [image] Treat A1 image surfaces as BILEVEL_ALPHA
    
    Categorise the transparency of FORMAT_A1 image surfaces as BILEVEL_ALPHA.

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 3225a72..a027f72 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1578,8 +1578,13 @@ _cairo_image_analyze_transparency (cairo_image_surface_t      *image)
 
     if ((image->base.content & CAIRO_CONTENT_ALPHA) == 0)
 	return image->transparency = CAIRO_IMAGE_IS_OPAQUE;
-    if ((image->base.content & CAIRO_CONTENT_COLOR) == 0)
-	return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+
+    if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) {
+	if (image->format == CAIRO_FORMAT_A1)
+	    return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
+	else
+	    return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+    }
 
     if (image->format != CAIRO_FORMAT_ARGB32)
 	return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
commit aac132a76a2af3719088678295169f1962a555e6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Apr 24 10:14:36 2009 +0100

    [image] Make _cairo_image_analayze_transparency() more format agnostic
    
    Use the content in preference to the format to determine
    CAIRO_IMAGE_IS_OPAQUE/CAIRO_IMAGE_HAS_ALPHA.

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index baead10..3225a72 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -1576,15 +1576,13 @@ _cairo_image_analyze_transparency (cairo_image_surface_t      *image)
     if (image->transparency != CAIRO_IMAGE_UNKNOWN)
 	return image->transparency;
 
-    if (image->format == CAIRO_FORMAT_RGB24) {
-	image->transparency = CAIRO_IMAGE_IS_OPAQUE;
-	return CAIRO_IMAGE_IS_OPAQUE;
-    }
+    if ((image->base.content & CAIRO_CONTENT_ALPHA) == 0)
+	return image->transparency = CAIRO_IMAGE_IS_OPAQUE;
+    if ((image->base.content & CAIRO_CONTENT_COLOR) == 0)
+	return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
 
-    if (image->format != CAIRO_FORMAT_ARGB32) {
-	image->transparency = CAIRO_IMAGE_HAS_ALPHA;
-	return CAIRO_IMAGE_HAS_ALPHA;
-    }
+    if (image->format != CAIRO_FORMAT_ARGB32)
+	return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
 
     image->transparency = CAIRO_IMAGE_IS_OPAQUE;
     for (y = 0; y < image->height; y++) {
@@ -1593,8 +1591,7 @@ _cairo_image_analyze_transparency (cairo_image_surface_t      *image)
 	for (x = 0; x < image->width; x++, pixel++) {
 	    int a = (*pixel & 0xff000000) >> 24;
 	    if (a > 0 && a < 255) {
-		image->transparency = CAIRO_IMAGE_HAS_ALPHA;
-		return CAIRO_IMAGE_HAS_ALPHA;
+		return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
 	    } else if (a == 0) {
 		image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
 	    }
commit 4be6de9fc6192d59c8d61e8edafed941e868a756
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Apr 24 10:03:20 2009 +0100

    [image] Return FORMAT_INVALID for an error surface.
    
    The default error value should be CAIRO_FORMAT_INVALID [-1] not 0 (which
    corresponds to CAIRO_FORMAT_ARGB32).

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index b601ac4..baead10 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -569,7 +569,7 @@ cairo_image_surface_get_format (cairo_surface_t *surface)
 
     if (! _cairo_surface_is_image (surface)) {
 	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
-	return 0;
+	return CAIRO_FORMAT_INVALID;
     }
 
     return image_surface->format;
commit 6675cf558719f81afe2a4331bc6adb3cda637a26
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 1 09:31:53 2009 +0100

    [build] Add lcov-1.7 to known list

diff --git a/build/configure.ac.analysis b/build/configure.ac.analysis
index 49928a5..f425a9a 100644
--- a/build/configure.ac.analysis
+++ b/build/configure.ac.analysis
@@ -25,7 +25,7 @@ if test "x$use_gcov" = "xyes"; then
     AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
   fi
 
-  ltp_version_list="1.6 1.5 1.4"
+  ltp_version_list="1.7 1.6 1.5 1.4"
   AC_CHECK_PROG(LTP, lcov, lcov)
   AC_CHECK_PROG(LTP_GENHTML, genhtml, genhtml)
 
commit 526fcdb7e6cc8b522508762b1a68a5585fddf823
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Apr 20 10:56:06 2009 +0100

    [build] Enable shave support
    
    shave transforms the messy output of autotools into a pretty (quiet!)
    Kbuild-like one.
    
    Lets see how controversial a simple change can be...

diff --git a/build/.gitignore b/build/.gitignore
index 53f31d7..ce1256a 100644
--- a/build/.gitignore
+++ b/build/.gitignore
@@ -10,3 +10,5 @@ mkinstalldirs
 #Makefile.win32.features-h
 libtool.m4
 lt*.m4
+shave
+shave-libtool
diff --git a/build/aclocal.dolt.m4 b/build/aclocal.dolt.m4
index 8f94582..ece5eea 100644
--- a/build/aclocal.dolt.m4
+++ b/build/aclocal.dolt.m4
@@ -155,6 +155,7 @@ modeok=false
 tagok=false
 for arg in "$[]@"; do
     case "$arg" in
+	--silent) ;;
         --mode=compile) modeok=true ;;
         --tag=CC|--tag=CXX) tagok=true ;;
         *) args@<:@${#args[@]}@:>@="$arg" ;;
diff --git a/build/aclocal.shave.m4 b/build/aclocal.shave.m4
new file mode 100644
index 0000000..0a3509e
--- /dev/null
+++ b/build/aclocal.shave.m4
@@ -0,0 +1,77 @@
+dnl Make automake/libtool output more friendly to humans
+dnl  Damien Lespiau <damien.lespiau at gmail.com>
+dnl
+dnl SHAVE_INIT([shavedir],[default_mode])
+dnl
+dnl shavedir: the directory where the shave scripts are, it defaults to
+dnl           $(top_builddir)
+dnl default_mode: (enable|disable) default shave mode.  This parameter
+dnl               controls shave's behaviour when no option has been
+dnl               given to configure.  It defaults to disable.
+dnl
+dnl * SHAVE_INIT should be called late in your configure.(ac|in) file (just
+dnl   before AC_CONFIG_FILE/AC_OUTPUT is perfect.  This macro rewrites CC and
+dnl   LIBTOOL, you don't want the configure tests to have these variables
+dnl   re-defined.
+dnl * This macro requires GNU make's -s option.
+
+AC_DEFUN([_SHAVE_ARG_ENABLE],
+[
+  AC_ARG_ENABLE([shave],
+    AS_HELP_STRING(
+      [--enable-shave],
+      [use shave to make the build pretty [[default=$1]]]),,
+      [enable_shave=$1]
+    )
+])
+
+AC_DEFUN([SHAVE_INIT],
+[
+  dnl you can tweak the default value of enable_shave
+  m4_if([$2], [enable], [_SHAVE_ARG_ENABLE(yes)], [_SHAVE_ARG_ENABLE(no)])
+
+  if test x"$enable_shave" = xyes; then
+    dnl where can we find the shave scripts?
+    m4_if([$1],,
+      [shavedir="$ac_pwd"],
+      [shavedir="$ac_pwd/$1"])
+    AC_SUBST(shavedir)
+
+    dnl make is now quiet
+    AC_SUBST([MAKEFLAGS], [-s])
+    AC_SUBST([AM_MAKEFLAGS], ['`test -z $V && echo -s`'])
+
+    dnl we need sed
+    AC_CHECK_PROG(SED,sed,sed,false)
+
+    dnl substitute libtool
+    SHAVE_SAVED_LIBTOOL=$LIBTOOL
+    LIBTOOL="${SHELL} ${shavedir}/shave-libtool '${SHAVE_SAVED_LIBTOOL}'"
+    AC_SUBST(LIBTOOL)
+
+    dnl substitute cc/cxx
+    SHAVE_SAVED_CC=$CC
+    SHAVE_SAVED_CXX=$CXX
+    SHAVE_SAVED_FC=$FC
+    SHAVE_SAVED_F77=$F77
+    SHAVE_SAVED_OBJC=$OBJC
+    CC="${SHELL} ${shavedir}/shave cc ${SHAVE_SAVED_CC}"
+    CXX="${SHELL} ${shavedir}/shave cxx ${SHAVE_SAVED_CXX}"
+    FC="${SHELL} ${shavedir}/shave fc ${SHAVE_SAVED_FC}"
+    F77="${SHELL} ${shavedir}/shave f77 ${SHAVE_SAVED_F77}"
+    OBJC="${SHELL} ${shavedir}/shave objc ${SHAVE_SAVED_OBJC}"
+    AC_SUBST(CC)
+    AC_SUBST(CXX)
+    AC_SUBST(FC)
+    AC_SUBST(F77)
+    AC_SUBST(OBJC)
+
+    V=@
+  else
+    V=1
+  fi
+  Q='$(V:1=)'
+  AC_SUBST(V)
+  AC_SUBST(Q)
+])
+
diff --git a/build/shave-libtool.in b/build/shave-libtool.in
new file mode 100644
index 0000000..1f3a720
--- /dev/null
+++ b/build/shave-libtool.in
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+# we need sed
+SED=@SED@
+if test -z "$SED" ; then
+SED=sed
+fi
+
+lt_unmangle ()
+{
+   last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'`
+}
+
+# the real libtool to use
+LIBTOOL="$1"
+shift
+
+# if 1, don't print anything, the underlaying wrapper will do it
+pass_though=0
+
+# scan the arguments, keep the right ones for libtool, and discover the mode
+preserved_args=
+while test "$#" -gt 0; do
+    opt="$1"
+    shift
+
+    case $opt in
+    --mode=*)
+        mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'`
+        preserved_args="$preserved_args $opt"
+        ;;
+    -o)
+        lt_output="$1"
+        preserved_args="$preserved_args $opt"
+	;;
+    *)
+        preserved_args="$preserved_args $opt"
+        ;;
+      esac
+done
+
+case "$mode" in
+compile)
+    # shave will be called and print the actual CC/CXX/LINK line
+    preserved_args="$preserved_args --shave-mode=$mode"
+    pass_though=1
+    ;;
+link)
+    preserved_args="$preserved_args --shave-mode=$mode"
+    Q="  LINK  "
+    ;;
+*)
+    # let's u
+    # echo "*** libtool: Unimplemented mode: $mode, fill a bug report"
+    ;;
+esac
+
+lt_unmangle "$lt_output"
+output=$last_result
+
+if test -z $V; then
+    if test $pass_though -eq 0; then
+        echo "$Q$output"
+    fi
+    $LIBTOOL --silent $preserved_args
+else
+    echo $LIBTOOL $preserved_args
+    $LIBTOOL $preserved_args
+fi
diff --git a/build/shave.in b/build/shave.in
new file mode 100644
index 0000000..5c16f27
--- /dev/null
+++ b/build/shave.in
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# we need sed
+SED=@SED@
+if test -z "$SED" ; then
+SED=sed
+fi
+
+lt_unmangle ()
+{
+   last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'`
+}
+
+# the tool to wrap (cc, cxx, ar, ranlib, ..)
+tool="$1"
+shift
+
+# the reel tool (to call)
+REEL_TOOL="$1"
+shift
+
+pass_through=0
+preserved_args=
+while test "$#" -gt 0; do
+    opt="$1"
+    shift
+
+    case $opt in
+    --shave-mode=*)
+        mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'`
+	;;
+    -o)
+        lt_output="$1"
+        preserved_args="$preserved_args $opt"
+	;;
+    *)
+        preserved_args="$preserved_args $opt"
+        ;;
+      esac
+done
+
+# mode=link is handled in the libtool wrapper
+case "$mode,$tool" in
+link,*)
+    pass_through=1
+    ;;
+*,cxx)
+    Q="  CXX   "
+    ;;
+*,cc)
+    Q="  CC    "
+    ;;
+*,fc)
+    Q="  FC    "
+    ;;
+*,f77)
+    Q="  F77   "
+    ;;
+*,objc)
+    Q="  OBJC   "
+    ;;
+*,*)
+    # should not happen
+    Q="  CC    "
+    ;;
+esac
+
+lt_unmangle "$lt_output"
+output=$last_result
+
+if test -z $V; then
+    if test $pass_through -eq 0; then
+        echo "$Q$output"
+    fi
+    $REEL_TOOL $preserved_args
+else
+    echo $REEL_TOOL $preserved_args
+    $REEL_TOOL $preserved_args
+fi
diff --git a/configure.ac b/configure.ac
index d0b6926..8afadcc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -539,7 +539,11 @@ dnl ===========================================================================
 # We use GTK+ for some utility/debugging tools
 PKG_CHECK_MODULES(gtk, "gtk+-2.0",, AC_MSG_RESULT(no))
 
+SHAVE_INIT([build], [enable]) # dnl Make the output pretty
+
 AC_CONFIG_FILES([
+build/shave
+build/shave-libtool
 Makefile
 boilerplate/Makefile
 src/Makefile


More information about the cairo-commit mailing list