[cairo-commit] 7 commits - boilerplate/Makefile.win32.features build/configure.ac.features build/Makefile.win32.features-h src/cairo.c src/cairoint.h src/cairo-pdf-operators.c src/Makefile.win32.features test/clip-empty-group.c test/clip-empty-group.ref.png test/Makefile.am test/Makefile.sources

Chris Wilson ickle at kemper.freedesktop.org
Fri Apr 23 06:49:07 PDT 2010


 boilerplate/Makefile.win32.features |    8 ---
 build/Makefile.win32.features-h     |    1 
 build/configure.ac.features         |    2 
 src/Makefile.win32.features         |    8 ---
 src/cairo-pdf-operators.c           |   12 ++--
 src/cairo.c                         |   92 ++++++++++++++++++------------------
 src/cairoint.h                      |    3 -
 test/Makefile.am                    |    1 
 test/Makefile.sources               |    1 
 test/clip-empty-group.c             |   65 +++++++++++++++++++++++++
 test/clip-empty-group.ref.png       |binary
 11 files changed, 121 insertions(+), 72 deletions(-)

New commits:
commit c63e3490a5fc2836837e7adcb5ecad62bdfd18ab
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 22 20:33:06 2010 +0100

    cairo: Handle the all-clipped state in cairo_push_group()
    
    Yet another bug reported by Jeff Muizelaar, thanks!
    
    Fixes: test/clip-empty-group

diff --git a/src/cairo.c b/src/cairo.c
index 0719468..32c0437 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -491,46 +491,57 @@ cairo_push_group (cairo_t *cr)
 void
 cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
 {
+    cairo_surface_t *group_surface;
+    cairo_clip_t *clip;
     cairo_status_t status;
-    cairo_rectangle_int_t extents;
-    const cairo_rectangle_int_t *clip_extents;
-    cairo_surface_t *parent_surface, *group_surface = NULL;
-    cairo_bool_t is_empty;
 
     if (unlikely (cr->status))
 	return;
 
-    parent_surface = _cairo_gstate_get_target (cr->gstate);
-
-    /* Get the extents that we'll use in creating our new group surface */
-    is_empty = _cairo_surface_get_extents (parent_surface, &extents);
-    clip_extents = _cairo_clip_get_extents (_cairo_gstate_get_clip (cr->gstate));
-    if (clip_extents != NULL)
-	is_empty = _cairo_rectangle_intersect (&extents, clip_extents);
-
-    group_surface = _cairo_surface_create_similar_solid (parent_surface,
-							 content,
-							 extents.width,
-							 extents.height,
-							 CAIRO_COLOR_TRANSPARENT,
-							 TRUE);
-    status = group_surface->status;
-    if (unlikely (status))
-	goto bail;
-
-    /* Set device offsets on the new surface so that logically it appears at
-     * the same location on the parent surface -- when we pop_group this,
-     * the source pattern will get fixed up for the appropriate target surface
-     * device offsets, so we want to set our own surface offsets from /that/,
-     * and not from the device origin. */
-    cairo_surface_set_device_offset (group_surface,
-                                     parent_surface->device_transform.x0 - extents.x,
-                                     parent_surface->device_transform.y0 - extents.y);
-
-    /* If we have a current path, we need to adjust it to compensate for
-     * the device offset just applied. */
-    _cairo_path_fixed_transform (cr->path,
-				 &group_surface->device_transform);
+    clip = _cairo_gstate_get_clip (cr->gstate);
+    if (clip->all_clipped) {
+	group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
+	status = group_surface->status;
+	if (unlikely (status))
+	    goto bail;
+    } else {
+	cairo_surface_t *parent_surface;
+	const cairo_rectangle_int_t *clip_extents;
+	cairo_rectangle_int_t extents;
+	cairo_bool_t is_empty;
+
+	parent_surface = _cairo_gstate_get_target (cr->gstate);
+
+	/* Get the extents that we'll use in creating our new group surface */
+	is_empty = _cairo_surface_get_extents (parent_surface, &extents);
+	clip_extents = _cairo_clip_get_extents (_cairo_gstate_get_clip (cr->gstate));
+	if (clip_extents != NULL)
+	    is_empty = _cairo_rectangle_intersect (&extents, clip_extents);
+
+	group_surface = _cairo_surface_create_similar_solid (parent_surface,
+							     content,
+							     extents.width,
+							     extents.height,
+							     CAIRO_COLOR_TRANSPARENT,
+							     TRUE);
+	status = group_surface->status;
+	if (unlikely (status))
+	    goto bail;
+
+	/* Set device offsets on the new surface so that logically it appears at
+	 * the same location on the parent surface -- when we pop_group this,
+	 * the source pattern will get fixed up for the appropriate target surface
+	 * device offsets, so we want to set our own surface offsets from /that/,
+	 * and not from the device origin. */
+	cairo_surface_set_device_offset (group_surface,
+					 parent_surface->device_transform.x0 - extents.x,
+					 parent_surface->device_transform.y0 - extents.y);
+
+	/* If we have a current path, we need to adjust it to compensate for
+	 * the device offset just applied. */
+	_cairo_path_fixed_transform (cr->path,
+				     &group_surface->device_transform);
+    }
 
     /* create a new gstate for the redirect */
     cairo_save (cr);
commit 567e485f28716d7b72cbf864a0c573148be91cd8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Apr 23 14:37:43 2010 +0100

    test: Add clip-empty-group
    
    Exercise a bug reported by Jeff Muizelaar whereby cairo_push_group() was
    broken by everything being clipped out.

diff --git a/test/Makefile.am b/test/Makefile.am
index 2b3205b..5e2a382 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -174,6 +174,7 @@ REFERENCE_IMAGES = \
 	clip-disjoint.ref.png \
 	clip-disjoint.xlib.ref.png \
 	clip-empty.ref.png \
+	clip-empty-group.ref.png \
 	clip-empty-save.ref.png \
 	clip-fill.ref.png \
 	clip-fill.ps.xfail.png \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index 34143db..1062e25 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -21,6 +21,7 @@ test_sources = \
 	clip-disjoint.c					\
 	clip-device-offset.c				\
 	clip-empty.c					\
+	clip-empty-group.c				\
 	clip-empty-save.c				\
 	clip-fill.c					\
 	clip-fill-no-op.c				\
diff --git a/test/clip-empty-group.c b/test/clip-empty-group.c
new file mode 100644
index 0000000..20e95c2
--- /dev/null
+++ b/test/clip-empty-group.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * 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"
+
+/* Test the handling of cairo_push_group() with everything clipped. */
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_paint (cr); /* opaque background */
+
+    cairo_rectangle (cr,  20, 20, 0, 0);
+    cairo_clip (cr);
+
+    cairo_push_group (cr); /* => 0x0 group */
+    cairo_reset_clip (cr);
+
+    cairo_set_source_rgb (cr, 1, 0, 0);
+    cairo_paint (cr);
+
+    cairo_rectangle (cr, 0, 0, width, height);
+    cairo_set_source_rgba (cr, 0, 1, 0, .5);
+    cairo_fill (cr);
+
+    cairo_move_to (cr, 0, 20);
+    cairo_line_to (cr, width, 20);
+    cairo_set_source_rgb (cr, 0, 0, 1);
+    cairo_stroke (cr);
+
+    cairo_pop_group_to_source (cr);
+    cairo_reset_clip (cr);
+    cairo_paint (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (clip_empty_group,
+	    "Test handling of groups with everything clipped",
+	    "clip group", /* keywords */
+	    NULL, /* requirements */
+	    40, 40,
+	    NULL, draw)
diff --git a/test/clip-empty-group.ref.png b/test/clip-empty-group.ref.png
new file mode 100644
index 0000000..a59ca47
Binary files /dev/null and b/test/clip-empty-group.ref.png differ
commit 4438cc6a49e7e902dce045706f7125a2c3e2174b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Apr 3 18:10:57 2010 +0100

    cairo: Use explicit device flushing.
    
    Now with the concept of a cairo_device_t and the ability to flush it,
    we now longer require the heuristic of automatically flushing on behalf
    of the user at the end of every context.

diff --git a/src/cairo.c b/src/cairo.c
index 3cb9b36..0719468 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -265,8 +265,6 @@ cairo_reference (cairo_t *cr)
 void
 cairo_destroy (cairo_t *cr)
 {
-    cairo_surface_t *surface;
-
     if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count))
 	return;
 
@@ -280,15 +278,6 @@ cairo_destroy (cairo_t *cr)
 	    break;
     }
 
-    /* The context is expected (>99% of all use cases) to be held for the
-     * duration of a single expose event/sequence of graphic operations.
-     * Therefore, on destroy we explicitly flush the Cairo pipeline of any
-     * pending operations.
-     */
-    surface = _cairo_gstate_get_original_target (cr->gstate);
-    if (surface != NULL)
-	cairo_surface_flush (surface);
-
     _cairo_gstate_fini (cr->gstate);
     cr->gstate_freelist = cr->gstate_freelist->next; /* skip over tail[1] */
     while (cr->gstate_freelist != NULL) {
commit 0fc140abc3c848e72b1b2b959026355fdbd6a941
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 21 12:01:49 2010 +0100

    pdf: Suppress compiler warning.

diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index e688b02..285214e 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -500,14 +500,14 @@ _cairo_pdf_operators_clip (cairo_pdf_operators_t	*pdf_operators,
     }
 
     switch (fill_rule) {
+    default:
+	ASSERT_NOT_REACHED;
     case CAIRO_FILL_RULE_WINDING:
 	pdf_operator = "W";
 	break;
     case CAIRO_FILL_RULE_EVEN_ODD:
 	pdf_operator = "W*";
 	break;
-    default:
-	ASSERT_NOT_REACHED;
     }
 
     _cairo_output_stream_printf (pdf_operators->stream,
@@ -834,14 +834,14 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t	*pdf_operators,
 	return status;
 
     switch (fill_rule) {
+    default:
+	ASSERT_NOT_REACHED;
     case CAIRO_FILL_RULE_WINDING:
 	pdf_operator = "f";
 	break;
     case CAIRO_FILL_RULE_EVEN_ODD:
 	pdf_operator = "f*";
 	break;
-    default:
-	ASSERT_NOT_REACHED;
     }
 
     _cairo_output_stream_printf (pdf_operators->stream,
@@ -862,14 +862,14 @@ _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t		*pdf_operators,
     const char *operator;
 
     switch (fill_rule) {
+    default:
+	ASSERT_NOT_REACHED;
     case CAIRO_FILL_RULE_WINDING:
 	operator = "B";
 	break;
     case CAIRO_FILL_RULE_EVEN_ODD:
 	operator = "B*";
 	break;
-    default:
-	ASSERT_NOT_REACHED;
     }
 
     return _cairo_pdf_operators_emit_stroke (pdf_operators,
commit 1923a33a7277009b2898840d671fdc8f8d1b3922
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Apr 21 11:59:33 2010 +0100

    cairoint.h: Change ASSERT_NOT_REACHED to remove compiler warning

diff --git a/src/cairoint.h b/src/cairoint.h
index f39b9a1..b4e8196 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -138,8 +138,7 @@ _cairo_win32_tmpfile (void);
 
 #define ASSERT_NOT_REACHED		\
 do {					\
-    static const int NOT_REACHED = 0;	\
-    assert (NOT_REACHED);		\
+    assert (!"reached");		\
 } while (0)
 #define COMPILE_TIME_ASSERT1(condition, line)		\
     typedef int compile_time_assertion_at_line_##line##_failed [(condition)?1:-1]
commit d366da7d8c46b08673b9e36dd130608a311ded4b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Apr 23 14:38:42 2010 +0100

    Win32 features update

diff --git a/boilerplate/Makefile.win32.features b/boilerplate/Makefile.win32.features
index 4781d8a..31bd4e0 100644
--- a/boilerplate/Makefile.win32.features
+++ b/boilerplate/Makefile.win32.features
@@ -199,14 +199,6 @@ enabled_cairo_boilerplate_private += $(cairo_boilerplate_png_private)
 enabled_cairo_boilerplate_sources += $(cairo_boilerplate_png_sources)
 endif
 
-supported_cairo_boilerplate_headers += $(cairo_boilerplate_glew_headers)
-all_cairo_boilerplate_headers += $(cairo_boilerplate_glew_headers)
-all_cairo_boilerplate_private += $(cairo_boilerplate_glew_private)
-all_cairo_boilerplate_sources += $(cairo_boilerplate_glew_sources)
-enabled_cairo_boilerplate_headers += $(cairo_boilerplate_glew_headers)
-enabled_cairo_boilerplate_private += $(cairo_boilerplate_glew_private)
-enabled_cairo_boilerplate_sources += $(cairo_boilerplate_glew_sources)
-
 unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_gl_headers)
 all_cairo_boilerplate_headers += $(cairo_boilerplate_gl_headers)
 all_cairo_boilerplate_private += $(cairo_boilerplate_gl_private)
diff --git a/src/Makefile.win32.features b/src/Makefile.win32.features
index 05efd04..42fb696 100644
--- a/src/Makefile.win32.features
+++ b/src/Makefile.win32.features
@@ -273,14 +273,6 @@ ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1)
 enabled_cairo_pkgconf += cairo-png.pc
 endif
 
-supported_cairo_headers += $(cairo_glew_headers)
-all_cairo_headers += $(cairo_glew_headers)
-all_cairo_private += $(cairo_glew_private)
-all_cairo_sources += $(cairo_glew_sources)
-enabled_cairo_headers += $(cairo_glew_headers)
-enabled_cairo_private += $(cairo_glew_private)
-enabled_cairo_sources += $(cairo_glew_sources)
-
 unsupported_cairo_headers += $(cairo_gl_headers)
 all_cairo_headers += $(cairo_gl_headers)
 all_cairo_private += $(cairo_gl_private)
commit c1e51a0264d204716f7706fbc66c2a7786b7947c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Apr 23 14:33:53 2010 +0100

    build: Spelling correction

diff --git a/build/Makefile.win32.features-h b/build/Makefile.win32.features-h
index c2a5332..f7c07ac 100644
--- a/build/Makefile.win32.features-h
+++ b/build/Makefile.win32.features-h
@@ -59,7 +59,6 @@ endif
 ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1)
 	@echo "#define CAIRO_HAS_PNG_FUNCTIONS 1" >> src/cairo-features.h
 endif
-	@echo "#define CAIRO_HAS_GLEW_FUNCTIONS 1" >> src/cairo-features.h
 ifeq ($(CAIRO_HAS_GL_SURFACE),1)
 	@echo "#define CAIRO_HAS_GL_SURFACE 1" >> src/cairo-features.h
 endif
diff --git a/build/configure.ac.features b/build/configure.ac.features
index 34406d7..593f4a6 100644
--- a/build/configure.ac.features
+++ b/build/configure.ac.features
@@ -395,7 +395,7 @@ AC_DEFUN([CAIRO_REPORT],
 	echo "  XCB-drm functions: $use_xcb_drm"
 	echo "  XCB-shm functions: $use_xcb_shm"
 	echo ""
-	echo "The following features and utilies:"
+	echo "The following features and utilities:"
 	echo "  cairo-trace:                $use_trace"
 	echo "  cairo-script-interpreter:   $use_interpreter"
 	echo ""


More information about the cairo-commit mailing list