[cairo-commit] 3 commits - src/cairo.c src/cairo-path-data.c src/cairo-path-data-private.h src/cairo-surface-fallback.c test/copy-path.c test/copy-path-ps-argb32-ref.png test/copy-path-ref.png test/Makefile.am test/path-data.c test/path-data-ps-argb32-ref.png test/path-data-ref.png

Carl Worth cworth at kemper.freedesktop.org
Tue Sep 26 15:48:19 PDT 2006


 src/cairo-path-data-private.h |    3 +++
 src/cairo-path-data.c         |   16 ++++++++++++++++
 src/cairo-surface-fallback.c  |    4 ----
 src/cairo.c                   |   16 ++++++++++------
 test/Makefile.am              |    6 +++---
 test/copy-path.c              |   30 ++++++++++++++++++++++++++++--
 6 files changed, 60 insertions(+), 15 deletions(-)

New commits:
diff-tree 17eeacfba844ea5f9592dff4621e6f721c27d6c5 (from e4dc73ab1cafeb8dd77d3ee3dc92d9a92be69542)
Author: Robert O'Callahan <rocallahan at novell.com>
Date:   Mon Sep 25 16:24:33 2006 -0700

    Remove redundant call to _cairo_surface_get_extents
    
    We called it just above with the same parameters.

diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 090da70..2d23411 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -548,10 +548,6 @@ _clip_and_composite_trapezoids (cairo_pa
 	     * _cairo_surface_fill_rectangles() or to drawing with a
 	     * clip region, then we have an additional region to clear.
 	     */
-	    status = _cairo_surface_get_extents (dst, &extents);
-	    if (status)
-		return status;
-
 	    clear_region = _cairo_region_create_from_rectangle (&extents);
 	    if (clear_region == NULL)
 		return CAIRO_STATUS_NO_MEMORY;
diff-tree e4dc73ab1cafeb8dd77d3ee3dc92d9a92be69542 (from 5f833c134bd002853b9d1458b58350cfb1d40a94)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Sep 25 16:16:35 2006 -0700

    Rename test from stale path-data name to copy-path

diff --git a/test/Makefile.am b/test/Makefile.am
index 763203b..c513949 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -17,6 +17,7 @@ close-path			\
 composite-integer-translate-source \
 composite-integer-translate-over \
 composite-integer-translate-over-repeat \
+copy-path			\
 create-for-stream		\
 create-from-png			\
 create-from-png-stream		\
@@ -59,7 +60,6 @@ operator-source			\
 paint				\
 paint-source-alpha		\
 paint-with-alpha		\
-path-data			\
 pattern-get-type		\
 pattern-getters			\
 pixman-rotate			\
@@ -189,6 +189,8 @@ composite-integer-translate-over-pdf-arg
 composite-integer-translate-over-svg-ref.png		\
 composite-integer-translate-over-repeat-ref.png		\
 composite-integer-translate-source-ref.png		\
+copy-path-ref.png					\
+copy-path-ps-argb32-ref.png				\
 create-from-png-ref.png					\
 create-from-png-stream-ref.png				\
 dash-caps-joins-ref.png					\
@@ -274,8 +276,6 @@ paint-source-alpha-pdf-argb32-ref.png			
 paint-source-alpha-svg-ref.png				\
 paint-with-alpha-ref.png				\
 paint-with-alpha-svg-ref.png				\
-path-data-ref.png					\
-path-data-ps-argb32-ref.png				\
 pixman-rotate-ref.png					\
 pixman-rotate-rgb24-ref.png				\
 push-group-ref.png					\
diff --git a/test/copy-path-ps-argb32-ref.png b/test/copy-path-ps-argb32-ref.png
new file mode 100644
index 0000000..647fafb
Binary files /dev/null and b/test/copy-path-ps-argb32-ref.png differ
diff --git a/test/copy-path-ref.png b/test/copy-path-ref.png
new file mode 100644
index 0000000..3e9c304
Binary files /dev/null and b/test/copy-path-ref.png differ
diff --git a/test/copy-path.c b/test/copy-path.c
new file mode 100644
index 0000000..b763546
--- /dev/null
+++ b/test/copy-path.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * 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
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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: Carl D. Worth <cworth at cworth.org>
+ */
+
+#include <stdlib.h>
+#include "cairo-test.h"
+
+static cairo_test_draw_function_t draw;
+
+cairo_test_t test = {
+    "copy-path",
+    "Tests calls to path_data functions: cairo_copy_path, cairo_copy_path_flat, and cairo_append_path",
+    45, 53,
+    draw
+};
+
+static void
+scale_by_two (double *x, double *y)
+{
+    *x = *x * 2.0;
+    *y = *y * 2.0;
+}
+
+typedef void (*munge_func_t) (double *x, double *y);
+
+static void
+munge_and_set_path (cairo_t	 *cr,
+		    cairo_path_t *path,
+		    munge_func_t  munge)
+{
+    int i;
+    cairo_path_data_t *p;
+    double x1, y1, x2, y2, x3, y3;
+
+    for (i=0; i < path->num_data; i += path->data[i].header.length) {
+	p = &path->data[i];
+	switch (p->header.type) {
+	case CAIRO_PATH_MOVE_TO:
+	    x1 = p[1].point.x; y1 = p[1].point.y;
+	    (munge) (&x1, &y1);
+	    cairo_move_to (cr, x1, y1);
+	    break;
+	case CAIRO_PATH_LINE_TO:
+	    x1 = p[1].point.x; y1 = p[1].point.y;
+	    (munge) (&x1, &y1);
+	    cairo_line_to (cr, x1, y1);
+	    break;
+	case CAIRO_PATH_CURVE_TO:
+	    x1 = p[1].point.x; y1 = p[1].point.y;
+	    x2 = p[2].point.x; y2 = p[2].point.y;
+	    x3 = p[3].point.x; y3 = p[3].point.y;
+	    (munge) (&x1, &y1);
+	    (munge) (&x2, &y2);
+	    (munge) (&x3, &y3);
+	    cairo_curve_to (cr,
+			    x1, y1,
+			    x2, y2,
+			    x3, y3);
+	    break;
+	case CAIRO_PATH_CLOSE_PATH:
+	    cairo_close_path (cr);
+	    break;
+	}
+    }
+}
+
+static void
+make_path (cairo_t *cr)
+{
+    cairo_rectangle (cr, 0, 0, 5, 5);
+    cairo_move_to (cr, 15, 2.5);
+    cairo_arc (cr, 12.5, 2.5, 2.5, 0, 2 * M_PI);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_path_t *path;
+    cairo_t *cr_error;
+
+    /* Ensure that calling cairo_copy_path on an in-error cairo_t will
+     * propagate the error. */
+    cr_error = cairo_create (NULL);
+    path = cairo_copy_path (cr_error);
+    if (path->status == CAIRO_STATUS_SUCCESS ||
+	path->status != cairo_status (cr_error)) {
+	cairo_test_log ("Error: cairo_copy_path returned status of %s rather than propagating %s\n",
+			cairo_status_to_string (path->status),
+			cairo_status_to_string (cairo_status (cr_error)));
+	cairo_path_destroy (path);
+	return CAIRO_TEST_FAILURE;
+    }
+    cairo_path_destroy (path);
+
+    path = cairo_copy_path_flat (cr_error);
+    if (path->status == CAIRO_STATUS_SUCCESS ||
+	path->status != cairo_status (cr_error)) {
+	cairo_test_log ("Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n",
+			cairo_status_to_string (path->status),
+			cairo_status_to_string (cairo_status (cr_error)));
+	cairo_path_destroy (path);
+	return CAIRO_TEST_FAILURE;
+    }
+    cairo_path_destroy (path);
+
+    /* We draw in the default black, so paint white first. */
+    cairo_save (cr);
+    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+    cairo_paint (cr);
+    cairo_restore (cr);
+
+    /* copy path, munge, and fill */
+    cairo_translate (cr, 5, 5);
+    make_path (cr);
+    path = cairo_copy_path (cr);
+
+    cairo_new_path (cr);
+    munge_and_set_path (cr, path, scale_by_two);
+    cairo_path_destroy (path);
+    cairo_fill (cr);
+
+    /* copy flattened path, munge, and fill */
+    cairo_translate (cr, 0, 15);
+    make_path (cr);
+    path = cairo_copy_path_flat (cr);
+
+    cairo_new_path (cr);
+    munge_and_set_path (cr, path, scale_by_two);
+    cairo_path_destroy (path);
+    cairo_fill (cr);
+
+    /* append two copies of path, and fill */
+    cairo_translate (cr, 0, 15);
+    cairo_scale (cr, 2.0, 2.0);
+    make_path (cr);
+    path = cairo_copy_path (cr);
+
+    cairo_new_path (cr);
+    cairo_append_path (cr, path);
+    cairo_translate (cr, 2.5, 2.5);
+    cairo_append_path (cr, path);
+
+    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+    cairo_fill (cr);
+
+    cairo_path_destroy (path);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+    cairo_t *cr;
+    cairo_path_data_t data;
+    cairo_path_t path;
+    cairo_surface_t *surface;
+
+    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
+
+    /* Test a few error cases for cairo_append_path_data */
+    cr = cairo_create (surface);
+    cairo_append_path (cr, NULL);
+    if (cairo_status (cr) != CAIRO_STATUS_NULL_POINTER)
+	return 1;
+    cairo_destroy (cr);
+
+    cr = cairo_create (surface);
+    path.status = -1;
+    cairo_append_path (cr, &path);
+    if (cairo_status (cr) != CAIRO_STATUS_INVALID_STATUS)
+	return 1;
+    cairo_destroy (cr);
+
+    cr = cairo_create (surface);
+    path.status = CAIRO_STATUS_NO_MEMORY;
+    cairo_append_path (cr, &path);
+    if (cairo_status (cr) != CAIRO_STATUS_NO_MEMORY)
+	return 1;
+    cairo_destroy (cr);
+
+    cr = cairo_create (surface);
+    path.data = NULL;
+    path.num_data = 0;
+    path.status = CAIRO_STATUS_SUCCESS;
+    cairo_append_path (cr, &path);
+    if (cairo_status (cr) != CAIRO_STATUS_NULL_POINTER)
+	return 1;
+    cairo_destroy (cr);
+
+    cr = cairo_create (surface);
+    /* Intentionally insert bogus header.length value (otherwise would be 2) */
+    data.header.type = CAIRO_PATH_MOVE_TO;
+    data.header.length = 1;
+    path.data = &data;
+    path.num_data = 1;
+    cairo_append_path (cr, &path);
+    if (cairo_status (cr) != CAIRO_STATUS_INVALID_PATH_DATA)
+	return 1;
+    cairo_destroy (cr);
+
+    /* And test the degnerate case */
+    cr = cairo_create (surface);
+    path.num_data = 0;
+    cairo_append_path (cr, &path);
+    if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+	return 1;
+    cairo_destroy (cr);
+
+    cairo_surface_destroy (surface);
+
+    return cairo_test (&test);
+}
diff --git a/test/path-data-ps-argb32-ref.png b/test/path-data-ps-argb32-ref.png
deleted file mode 100644
index 647fafb..0000000
Binary files a/test/path-data-ps-argb32-ref.png and /dev/null differ
diff --git a/test/path-data-ref.png b/test/path-data-ref.png
deleted file mode 100644
index 3e9c304..0000000
Binary files a/test/path-data-ref.png and /dev/null differ
diff --git a/test/path-data.c b/test/path-data.c
deleted file mode 100644
index f1e0442..0000000
--- a/test/path-data.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright © 2005 Red Hat, Inc.
- *
- * 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
- * Red Hat, Inc. not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Red Hat, Inc. makes no representations about the
- * suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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: Carl D. Worth <cworth at cworth.org>
- */
-
-#include <stdlib.h>
-#include "cairo-test.h"
-
-static cairo_test_draw_function_t draw;
-
-cairo_test_t test = {
-    "path-data",
-    "Tests calls to path_data functions: cairo_copy_path, cairo_copy_path_flat, and cairo_append_path",
-    45, 53,
-    draw
-};
-
-static void
-scale_by_two (double *x, double *y)
-{
-    *x = *x * 2.0;
-    *y = *y * 2.0;
-}
-
-typedef void (*munge_func_t) (double *x, double *y);
-
-static void
-munge_and_set_path (cairo_t	 *cr,
-		    cairo_path_t *path,
-		    munge_func_t  munge)
-{
-    int i;
-    cairo_path_data_t *p;
-    double x1, y1, x2, y2, x3, y3;
-
-    for (i=0; i < path->num_data; i += path->data[i].header.length) {
-	p = &path->data[i];
-	switch (p->header.type) {
-	case CAIRO_PATH_MOVE_TO:
-	    x1 = p[1].point.x; y1 = p[1].point.y;
-	    (munge) (&x1, &y1);
-	    cairo_move_to (cr, x1, y1);
-	    break;
-	case CAIRO_PATH_LINE_TO:
-	    x1 = p[1].point.x; y1 = p[1].point.y;
-	    (munge) (&x1, &y1);
-	    cairo_line_to (cr, x1, y1);
-	    break;
-	case CAIRO_PATH_CURVE_TO:
-	    x1 = p[1].point.x; y1 = p[1].point.y;
-	    x2 = p[2].point.x; y2 = p[2].point.y;
-	    x3 = p[3].point.x; y3 = p[3].point.y;
-	    (munge) (&x1, &y1);
-	    (munge) (&x2, &y2);
-	    (munge) (&x3, &y3);
-	    cairo_curve_to (cr,
-			    x1, y1,
-			    x2, y2,
-			    x3, y3);
-	    break;
-	case CAIRO_PATH_CLOSE_PATH:
-	    cairo_close_path (cr);
-	    break;
-	}
-    }
-}
-
-static void
-make_path (cairo_t *cr)
-{
-    cairo_rectangle (cr, 0, 0, 5, 5);
-    cairo_move_to (cr, 15, 2.5);
-    cairo_arc (cr, 12.5, 2.5, 2.5, 0, 2 * M_PI);
-}
-
-static cairo_test_status_t
-draw (cairo_t *cr, int width, int height)
-{
-    cairo_path_t *path;
-    cairo_t *cr_error;
-
-    /* Ensure that calling cairo_copy_path on an in-error cairo_t will
-     * propagate the error. */
-    cr_error = cairo_create (NULL);
-    path = cairo_copy_path (cr_error);
-    if (path->status == CAIRO_STATUS_SUCCESS ||
-	path->status != cairo_status (cr_error)) {
-	cairo_test_log ("Error: cairo_copy_path returned status of %s rather than propagating %s\n",
-			cairo_status_to_string (path->status),
-			cairo_status_to_string (cairo_status (cr_error)));
-	cairo_path_destroy (path);
-	return CAIRO_TEST_FAILURE;
-    }
-    cairo_path_destroy (path);
-
-    path = cairo_copy_path_flat (cr_error);
-    if (path->status == CAIRO_STATUS_SUCCESS ||
-	path->status != cairo_status (cr_error)) {
-	cairo_test_log ("Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n",
-			cairo_status_to_string (path->status),
-			cairo_status_to_string (cairo_status (cr_error)));
-	cairo_path_destroy (path);
-	return CAIRO_TEST_FAILURE;
-    }
-    cairo_path_destroy (path);
-
-    /* We draw in the default black, so paint white first. */
-    cairo_save (cr);
-    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
-    cairo_paint (cr);
-    cairo_restore (cr);
-
-    /* copy path, munge, and fill */
-    cairo_translate (cr, 5, 5);
-    make_path (cr);
-    path = cairo_copy_path (cr);
-
-    cairo_new_path (cr);
-    munge_and_set_path (cr, path, scale_by_two);
-    cairo_path_destroy (path);
-    cairo_fill (cr);
-
-    /* copy flattened path, munge, and fill */
-    cairo_translate (cr, 0, 15);
-    make_path (cr);
-    path = cairo_copy_path_flat (cr);
-
-    cairo_new_path (cr);
-    munge_and_set_path (cr, path, scale_by_two);
-    cairo_path_destroy (path);
-    cairo_fill (cr);
-
-    /* append two copies of path, and fill */
-    cairo_translate (cr, 0, 15);
-    cairo_scale (cr, 2.0, 2.0);
-    make_path (cr);
-    path = cairo_copy_path (cr);
-
-    cairo_new_path (cr);
-    cairo_append_path (cr, path);
-    cairo_translate (cr, 2.5, 2.5);
-    cairo_append_path (cr, path);
-
-    cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
-    cairo_fill (cr);
-
-    cairo_path_destroy (path);
-
-    return CAIRO_TEST_SUCCESS;
-}
-
-int
-main (void)
-{
-    cairo_t *cr;
-    cairo_path_data_t data;
-    cairo_path_t path;
-    cairo_surface_t *surface;
-
-    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
-
-    /* Test a few error cases for cairo_append_path_data */
-    cr = cairo_create (surface);
-    cairo_append_path (cr, NULL);
-    if (cairo_status (cr) != CAIRO_STATUS_NULL_POINTER)
-	return 1;
-    cairo_destroy (cr);
-
-    cr = cairo_create (surface);
-    path.status = -1;
-    cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_INVALID_STATUS)
-	return 1;
-    cairo_destroy (cr);
-
-    cr = cairo_create (surface);
-    path.status = CAIRO_STATUS_NO_MEMORY;
-    cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_NO_MEMORY)
-	return 1;
-    cairo_destroy (cr);
-
-    cr = cairo_create (surface);
-    path.data = NULL;
-    path.num_data = 0;
-    path.status = CAIRO_STATUS_SUCCESS;
-    cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_NULL_POINTER)
-	return 1;
-    cairo_destroy (cr);
-
-    cr = cairo_create (surface);
-    /* Intentionally insert bogus header.length value (otherwise would be 2) */
-    data.header.type = CAIRO_PATH_MOVE_TO;
-    data.header.length = 1;
-    path.data = &data;
-    path.num_data = 1;
-    cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_INVALID_PATH_DATA)
-	return 1;
-    cairo_destroy (cr);
-
-    /* And test the degnerate case */
-    cr = cairo_create (surface);
-    path.num_data = 0;
-    cairo_append_path (cr, &path);
-    if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
-	return 1;
-    cairo_destroy (cr);
-
-    cairo_surface_destroy (surface);
-
-    return cairo_test (&test);
-}
diff-tree 5f833c134bd002853b9d1458b58350cfb1d40a94 (from f9165638bf485591abae52b759fba82caf048dc5)
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Sep 25 16:03:02 2006 -0700

    Fix cairo_copy_path and cairo_copy_path_flat to propagate errors.
    
    One of these functions was already documented to be doing this, and
    the other one should have been. Now the documentation and behavior
    for both are consistent, (and the path-data test case verifies this).

diff --git a/src/cairo-path-data-private.h b/src/cairo-path-data-private.h
index 3208bc1..28b70ee 100644
--- a/src/cairo-path-data-private.h
+++ b/src/cairo-path-data-private.h
@@ -48,6 +48,9 @@ cairo_private cairo_path_t *
 _cairo_path_data_create_flat (cairo_path_fixed_t *path,
 			      cairo_gstate_t     *gstate);
 
+cairo_private cairo_path_t *
+_cairo_path_data_create_for_status (cairo_status_t status);
+
 cairo_private cairo_status_t
 _cairo_path_data_append_to_context (cairo_path_t *path,
 				    cairo_t	 *cr);
diff --git a/src/cairo-path-data.c b/src/cairo-path-data.c
index cd15192..880a8f1 100644
--- a/src/cairo-path-data.c
+++ b/src/cairo-path-data.c
@@ -331,6 +331,22 @@ _cairo_path_data_populate (cairo_path_t 
     assert (cpdp.data - path->data == path->num_data);
 }
 
+cairo_path_t *
+_cairo_path_data_create_for_status (cairo_status_t status)
+{
+    cairo_path_t *path;
+
+    path = malloc (sizeof (cairo_path_t));
+    if (path == NULL)
+	return (cairo_path_t*) &_cairo_path_nil;
+
+    path->num_data = 0;
+    path->data = NULL;
+    path->status = status;
+
+    return path;
+}
+
 static cairo_path_t *
 _cairo_path_data_create_real (cairo_path_fixed_t *path_fixed,
 			      cairo_gstate_t     *gstate,
diff --git a/src/cairo.c b/src/cairo.c
index 1a7da53..3d574eb 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -2981,8 +2981,12 @@ cairo_get_group_target (cairo_t *cr)
  * conditions hold:
  *
  * <orderedlist>
- * <listitem>If there is insufficient memory to copy the path.</listitem>
- * <listitem>If @cr is already in an error state.</listitem>
+ * <listitem>If there is insufficient memory to copy the path. In this
+ *     case <literal>path->status</literal> will be set to
+ *     %CAIRO_STATUS_NO_MEMORY.</listitem>
+ * <listitem>If @cr is already in an error state. In this case
+ *    <literal>path->status</literal> will contain the same status that
+ *    would be returned by cairo_status().</listitem>
  * </orderedlist>
  *
  * In either case, <literal>path->status</literal> will be set to
@@ -2997,7 +3001,7 @@ cairo_path_t *
 cairo_copy_path (cairo_t *cr)
 {
     if (cr->status)
-	return (cairo_path_t*) &_cairo_path_nil;
+	return _cairo_path_data_create_for_status (cr->status);
 
     return _cairo_path_data_create (&cr->path, cr->gstate);
 }
@@ -3039,9 +3043,9 @@ cairo_path_t *
 cairo_copy_path_flat (cairo_t *cr)
 {
     if (cr->status)
-	return (cairo_path_t*) &_cairo_path_nil;
-    else
-	return _cairo_path_data_create_flat (&cr->path, cr->gstate);
+	return _cairo_path_data_create_for_status (cr->status);
+
+    return _cairo_path_data_create_flat (&cr->path, cr->gstate);
 }
 
 /**
diff --git a/test/path-data.c b/test/path-data.c
index 903e92c..f1e0442 100644
--- a/test/path-data.c
+++ b/test/path-data.c
@@ -30,7 +30,7 @@ static cairo_test_draw_function_t draw;
 
 cairo_test_t test = {
     "path-data",
-    "Tests calls to path_data functions: cairo_copy_path_data, cairo_copy_path_data_flat, and cairo_append_path_data",
+    "Tests calls to path_data functions: cairo_copy_path, cairo_copy_path_flat, and cairo_append_path",
     45, 53,
     draw
 };
@@ -97,6 +97,32 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_path_t *path;
+    cairo_t *cr_error;
+
+    /* Ensure that calling cairo_copy_path on an in-error cairo_t will
+     * propagate the error. */
+    cr_error = cairo_create (NULL);
+    path = cairo_copy_path (cr_error);
+    if (path->status == CAIRO_STATUS_SUCCESS ||
+	path->status != cairo_status (cr_error)) {
+	cairo_test_log ("Error: cairo_copy_path returned status of %s rather than propagating %s\n",
+			cairo_status_to_string (path->status),
+			cairo_status_to_string (cairo_status (cr_error)));
+	cairo_path_destroy (path);
+	return CAIRO_TEST_FAILURE;
+    }
+    cairo_path_destroy (path);
+
+    path = cairo_copy_path_flat (cr_error);
+    if (path->status == CAIRO_STATUS_SUCCESS ||
+	path->status != cairo_status (cr_error)) {
+	cairo_test_log ("Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n",
+			cairo_status_to_string (path->status),
+			cairo_status_to_string (cairo_status (cr_error)));
+	cairo_path_destroy (path);
+	return CAIRO_TEST_FAILURE;
+    }
+    cairo_path_destroy (path);
 
     /* We draw in the default black, so paint white first. */
     cairo_save (cr);


More information about the cairo-commit mailing list