summaryrefslogtreecommitdiff
path: root/src/cairo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo.c')
-rw-r--r--src/cairo.c778
1 files changed, 467 insertions, 311 deletions
diff --git a/src/cairo.c b/src/cairo.c
index f825c733e..73dfc2cdd 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -43,37 +43,56 @@
#define CAIRO_TOLERANCE_MINIMUM 0.0002 /* We're limited by 16 bits of sub-pixel precision */
+static const cairo_t cairo_nil = {
+ (unsigned int)-1, /* ref_count */
+ CAIRO_STATUS_NO_MEMORY, /* status */
+ { /* path */
+ NULL, NULL, /* op_buf_head, op_buf_tail */
+ NULL, NULL, /* arg_buf_head, arg_buf_tail */
+ { 0, 0 }, /* last_move_point */
+ { 0, 0 }, /* current point */
+ FALSE, /* has_current_point */
+ },
+ NULL /* gstate */
+};
+
#include <assert.h>
-#ifdef NDEBUG
-#define CAIRO_CHECK_SANITY(cr)
-#else
-static int
-cairo_sane_state (cairo_t *cr)
-{
- if (cr == NULL)
- return 0;
- switch (cr->status) {
- case CAIRO_STATUS_SUCCESS:
- case CAIRO_STATUS_NO_MEMORY:
- case CAIRO_STATUS_INVALID_RESTORE:
- case CAIRO_STATUS_INVALID_POP_GROUP:
- case CAIRO_STATUS_NO_CURRENT_POINT:
- case CAIRO_STATUS_INVALID_MATRIX:
- case CAIRO_STATUS_NO_TARGET_SURFACE:
- case CAIRO_STATUS_NULL_POINTER:
- case CAIRO_STATUS_INVALID_STRING:
- case CAIRO_STATUS_INVALID_PATH_DATA:
- break;
- default:
- return 0;
- }
- return 1;
+/* This has to be updated whenever cairo_status_t is extended. That's
+ * a bit of a pain, but it should be easy to always catch as long as
+ * one adds a new test case to test a trigger of the new status value.
+ */
+#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_SURFACE_TYPE_MISMATCH
+
+/**
+ * _cairo_error:
+ * @cr: a cairo context
+ * @status: a status value indicating an error, (eg. not
+ * CAIRO_STATUS_SUCCESS)
+ *
+ * Sets cr->status to @status.
+ *
+ * All assignments of an error status to cr->status should happen
+ * either inside of _cairo_error(), or else _cairo_error() should be
+ * called immediately after the assignment.
+ *
+ * The purpose of this function is to allow the user to set a
+ * breakpoint in _cairo_error() to generate a stack trace for when the
+ * user causes cairo to detect an error.
+ *
+ * _cairo_error also calls the error notify callback function that the
+ * user may have set with cairo_set_error_notify.
+ **/
+static void
+_cairo_error (cairo_t *cr, cairo_status_t status)
+{
+ assert (status > CAIRO_STATUS_SUCCESS &&
+ status <= CAIRO_STATUS_LAST_STATUS);
+
+ cr->status = status;
}
-#define CAIRO_CHECK_SANITY(cr) assert(cairo_sane_state ((cr)))
-#endif
-/*
+/**
* cairo_create:
* @target: target surface for the context
*
@@ -81,7 +100,7 @@ cairo_sane_state (cairo_t *cr)
* default values and with @target as a target surface. The target
* surface should be constructed with a backend-specific function such
* as cairo_image_surface_create (or any other
- * cairo_<backend>_surface_create variant).
+ * cairo_&lt;backend&gt;_surface_create variant).
*
* This function references @target, so you can immediately
* call cairo_surface_destroy() on it if you don't need to
@@ -100,7 +119,12 @@ cairo_sane_state (cairo_t *cr)
* Return value: a newly allocated #cairo_t with a reference
* count of 1. The initial reference count should be released
* with cairo_destroy() when you are done using the #cairo_t.
- */
+ * This function never returns %NULL. If memory cannot be
+ * allocated, a special #cairo_t object will be returned on
+ * which cairo_status() returns %CAIRO_STATUS_NO_MEMORY.
+ * You can use this object normally, but no drawing will
+ * be done.
+ **/
cairo_t *
cairo_create (cairo_surface_t *target)
{
@@ -108,24 +132,24 @@ cairo_create (cairo_surface_t *target)
cr = malloc (sizeof (cairo_t));
if (cr == NULL)
- return NULL;
+ return (cairo_t *) &cairo_nil;
- cr->status = CAIRO_STATUS_SUCCESS;
cr->ref_count = 1;
+ cr->status = CAIRO_STATUS_SUCCESS;
+
_cairo_path_fixed_init (&cr->path);
if (target == NULL) {
cr->gstate = NULL;
- cr->status = CAIRO_STATUS_NULL_POINTER;
+ _cairo_error (cr, CAIRO_STATUS_NULL_POINTER);
return cr;
}
cr->gstate = _cairo_gstate_create (target);
if (cr->gstate == NULL)
- cr->status = CAIRO_STATUS_NO_MEMORY;
+ _cairo_error (cr, CAIRO_STATUS_NO_MEMORY);
- CAIRO_CHECK_SANITY (cr);
return cr;
}
@@ -140,12 +164,10 @@ cairo_create (cairo_surface_t *target)
void
cairo_reference (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->ref_count == (unsigned int)-1)
return;
-
+
cr->ref_count++;
- CAIRO_CHECK_SANITY (cr);
}
/**
@@ -159,7 +181,9 @@ cairo_reference (cairo_t *cr)
void
cairo_destroy (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
+ if (cr->ref_count == (unsigned int)-1)
+ return;
+
cr->ref_count--;
if (cr->ref_count)
return;
@@ -197,21 +221,20 @@ cairo_save (cairo_t *cr)
{
cairo_gstate_t *top;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
top = _cairo_gstate_clone (cr->gstate);
if (top == NULL) {
- cr->status = CAIRO_STATUS_NO_MEMORY;
- CAIRO_CHECK_SANITY (cr);
+ _cairo_error (cr, CAIRO_STATUS_NO_MEMORY);
return;
}
top->next = cr->gstate;
cr->gstate = top;
- CAIRO_CHECK_SANITY (cr);
}
slim_hidden_def(cairo_save);
@@ -228,9 +251,10 @@ cairo_restore (cairo_t *cr)
{
cairo_gstate_t *top;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
top = cr->gstate;
cr->gstate = top->next;
@@ -238,12 +262,7 @@ cairo_restore (cairo_t *cr)
_cairo_gstate_destroy (top);
if (cr->gstate == NULL)
- cr->status = CAIRO_STATUS_INVALID_RESTORE;
-
- if (cr->status)
- return;
-
- CAIRO_CHECK_SANITY (cr);
+ _cairo_error (cr, CAIRO_STATUS_INVALID_RESTORE);
}
slim_hidden_def(cairo_restore);
@@ -291,12 +310,26 @@ cairo_pop_group (cairo_t *cr)
void
cairo_set_operator (cairo_t *cr, cairo_operator_t op)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_operator (cr->gstate, op);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
+}
+
+static void
+_cairo_set_source_solid (cairo_t *cr, const cairo_color_t *color)
+{
+ cairo_pattern_t *source;
+
+ source = _cairo_pattern_create_solid (color);
+
+ cairo_set_source (cr, source);
+
+ cairo_pattern_destroy (source);
}
/**
@@ -319,9 +352,10 @@ cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue)
{
cairo_color_t color;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_restrict_value (&red, 0.0, 1.0);
_cairo_restrict_value (&green, 0.0, 1.0);
@@ -329,9 +363,7 @@ cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue)
_cairo_color_init_rgb (&color, red, green, blue);
- cr->status = _cairo_gstate_set_source_solid (cr->gstate, &color);
-
- CAIRO_CHECK_SANITY (cr);
+ _cairo_set_source_solid (cr, &color);
}
/**
@@ -357,9 +389,10 @@ cairo_set_source_rgba (cairo_t *cr,
{
cairo_color_t color;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_restrict_value (&red, 0.0, 1.0);
_cairo_restrict_value (&green, 0.0, 1.0);
@@ -368,9 +401,7 @@ cairo_set_source_rgba (cairo_t *cr,
_cairo_color_init_rgba (&color, red, green, blue, alpha);
- cr->status = _cairo_gstate_set_source_solid (cr->gstate, &color);
-
- CAIRO_CHECK_SANITY (cr);
+ _cairo_set_source_solid (cr, &color);
}
void
@@ -382,23 +413,18 @@ cairo_set_source_surface (cairo_t *cr,
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
pattern = cairo_pattern_create_for_surface (surface);
- if (!pattern) {
- cr->status = CAIRO_STATUS_NO_MEMORY;
- return;
- }
cairo_matrix_init_translate (&matrix, -x, -y);
cairo_pattern_set_matrix (pattern, &matrix);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
-
- CAIRO_CHECK_SANITY (cr);
}
/**
@@ -418,12 +444,24 @@ cairo_set_source_surface (cairo_t *cr,
void
cairo_set_source (cairo_t *cr, cairo_pattern_t *source)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
+ return;
+ }
+
+ if (source == NULL) {
+ _cairo_error (cr, CAIRO_STATUS_NULL_POINTER);
+ return;
+ }
+
+ if (source->status) {
+ _cairo_error (cr, source->status);
return;
+ }
cr->status = _cairo_gstate_set_source (cr->gstate, source);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -439,11 +477,12 @@ cairo_set_source (cairo_t *cr, cairo_pattern_t *source)
cairo_pattern_t *
cairo_get_source (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- /* XXX: We'll want to do something like this:
- if (cr->status)
- return cairo_pattern_nil;
- */
+ if (cr->status) {
+ cairo_pattern_t *pattern;
+ pattern = _cairo_pattern_create_in_error (cr->status);
+ _cairo_error (cr, cr->status);
+ return pattern;
+ }
return _cairo_gstate_get_source (cr->gstate);
}
@@ -464,14 +503,16 @@ cairo_get_source (cairo_t *cr)
void
cairo_set_tolerance (cairo_t *cr, double tolerance)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_restrict_value (&tolerance, CAIRO_TOLERANCE_MINIMUM, tolerance);
cr->status = _cairo_gstate_set_tolerance (cr->gstate, tolerance);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -488,12 +529,14 @@ cairo_set_tolerance (cairo_t *cr, double tolerance)
void
cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_fill_rule (cr->gstate, fill_rule);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -513,14 +556,16 @@ cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule)
void
cairo_set_line_width (cairo_t *cr, double width)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_restrict_value (&width, 0.0, width);
cr->status = _cairo_gstate_set_line_width (cr->gstate, width);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -540,12 +585,14 @@ cairo_set_line_width (cairo_t *cr, double width)
void
cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_line_cap (cr->gstate, line_cap);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -565,34 +612,40 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap)
void
cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_line_join (cr->gstate, line_join);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
cairo_set_dash (cairo_t *cr, double *dashes, int ndash, double offset)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_dash (cr->gstate, dashes, ndash, offset);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
cairo_set_miter_limit (cairo_t *cr, double limit)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_miter_limit (cr->gstate, limit);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
@@ -611,12 +664,14 @@ cairo_set_miter_limit (cairo_t *cr, double limit)
void
cairo_translate (cairo_t *cr, double tx, double ty)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_translate (cr->gstate, tx, ty);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -633,12 +688,14 @@ cairo_translate (cairo_t *cr, double tx, double ty)
void
cairo_scale (cairo_t *cr, double sx, double sy)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_scale (cr->gstate, sx, sy);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
@@ -657,12 +714,14 @@ cairo_scale (cairo_t *cr, double sx, double sy)
void
cairo_rotate (cairo_t *cr, double angle)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_rotate (cr->gstate, angle);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -678,12 +737,14 @@ void
cairo_transform (cairo_t *cr,
const cairo_matrix_t *matrix)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_transform (cr->gstate, matrix);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -698,12 +759,14 @@ void
cairo_set_matrix (cairo_t *cr,
const cairo_matrix_t *matrix)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_matrix (cr->gstate, matrix);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -718,12 +781,14 @@ cairo_set_matrix (cairo_t *cr,
void
cairo_identity_matrix (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_identity_matrix (cr->gstate);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -739,12 +804,14 @@ cairo_identity_matrix (cairo_t *cr)
void
cairo_user_to_device (cairo_t *cr, double *x, double *y)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_user_to_device (cr->gstate, x, y);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -761,12 +828,14 @@ cairo_user_to_device (cairo_t *cr, double *x, double *y)
void
cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -782,12 +851,14 @@ cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy)
void
cairo_device_to_user (cairo_t *cr, double *x, double *y)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_device_to_user (cr->gstate, x, y);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -804,24 +875,25 @@ cairo_device_to_user (cairo_t *cr, double *x, double *y)
void
cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
cairo_new_path (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_path_fixed_fini (&cr->path);
-
- CAIRO_CHECK_SANITY (cr);
}
slim_hidden_def(cairo_new_path);
@@ -830,17 +902,18 @@ cairo_move_to (cairo_t *cr, double x, double y)
{
cairo_fixed_t x_fixed, y_fixed;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_gstate_user_to_backend (cr->gstate, &x, &y);
x_fixed = _cairo_fixed_from_double (x);
y_fixed = _cairo_fixed_from_double (y);
cr->status = _cairo_path_fixed_move_to (&cr->path, x_fixed, y_fixed);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
slim_hidden_def(cairo_move_to);
@@ -849,17 +922,18 @@ cairo_line_to (cairo_t *cr, double x, double y)
{
cairo_fixed_t x_fixed, y_fixed;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_gstate_user_to_backend (cr->gstate, &x, &y);
x_fixed = _cairo_fixed_from_double (x);
y_fixed = _cairo_fixed_from_double (y);
cr->status = _cairo_path_fixed_line_to (&cr->path, x_fixed, y_fixed);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
@@ -872,9 +946,10 @@ cairo_curve_to (cairo_t *cr,
cairo_fixed_t x2_fixed, y2_fixed;
cairo_fixed_t x3_fixed, y3_fixed;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_gstate_user_to_backend (cr->gstate, &x1, &y1);
_cairo_gstate_user_to_backend (cr->gstate, &x2, &y2);
@@ -893,8 +968,8 @@ cairo_curve_to (cairo_t *cr,
x1_fixed, y1_fixed,
x2_fixed, y2_fixed,
x3_fixed, y3_fixed);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -936,9 +1011,10 @@ cairo_arc (cairo_t *cr,
double radius,
double angle1, double angle2)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
/* Do nothing, successfully, if radius is <= 0 */
if (radius <= 0.0)
@@ -953,8 +1029,6 @@ cairo_arc (cairo_t *cr,
_cairo_arc_path (cr, xc, yc, radius,
angle1, angle2);
-
- CAIRO_CHECK_SANITY (cr);
}
/**
@@ -977,9 +1051,10 @@ cairo_arc_negative (cairo_t *cr,
double radius,
double angle1, double angle2)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
/* Do nothing, successfully, if radius is <= 0 */
if (radius <= 0.0)
@@ -994,8 +1069,6 @@ cairo_arc_negative (cairo_t *cr,
_cairo_arc_path_negative (cr, xc, yc, radius,
angle1, angle2);
-
- CAIRO_CHECK_SANITY (cr);
}
/* XXX: NYI
@@ -1020,17 +1093,18 @@ cairo_rel_move_to (cairo_t *cr, double dx, double dy)
{
cairo_fixed_t dx_fixed, dy_fixed;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
dx_fixed = _cairo_fixed_from_double (dx);
dy_fixed = _cairo_fixed_from_double (dy);
cr->status = _cairo_path_fixed_rel_move_to (&cr->path, dx_fixed, dy_fixed);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
@@ -1038,17 +1112,18 @@ cairo_rel_line_to (cairo_t *cr, double dx, double dy)
{
cairo_fixed_t dx_fixed, dy_fixed;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_gstate_user_to_device_distance (cr->gstate, &dx, &dy);
dx_fixed = _cairo_fixed_from_double (dx);
dy_fixed = _cairo_fixed_from_double (dy);
cr->status = _cairo_path_fixed_rel_line_to (&cr->path, dx_fixed, dy_fixed);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
slim_hidden_def(cairo_rel_line_to);
@@ -1062,9 +1137,10 @@ cairo_rel_curve_to (cairo_t *cr,
cairo_fixed_t dx2_fixed, dy2_fixed;
cairo_fixed_t dx3_fixed, dy3_fixed;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
_cairo_gstate_user_to_device_distance (cr->gstate, &dx1, &dy1);
_cairo_gstate_user_to_device_distance (cr->gstate, &dx2, &dy2);
@@ -1083,8 +1159,8 @@ cairo_rel_curve_to (cairo_t *cr,
dx1_fixed, dy1_fixed,
dx2_fixed, dy2_fixed,
dx3_fixed, dy3_fixed);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
@@ -1092,16 +1168,16 @@ cairo_rectangle (cairo_t *cr,
double x, double y,
double width, double height)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cairo_move_to (cr, x, y);
cairo_rel_line_to (cr, width, 0);
cairo_rel_line_to (cr, 0, height);
cairo_rel_line_to (cr, -width, 0);
cairo_close_path (cr);
- CAIRO_CHECK_SANITY (cr);
}
/* XXX: NYI
@@ -1112,19 +1188,22 @@ cairo_stroke_to_path (cairo_t *cr)
return;
cr->status = _cairo_gstate_stroke_path (cr->gstate);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
*/
void
cairo_close_path (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_path_fixed_close_path (&cr->path);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
slim_hidden_def(cairo_close_path);
@@ -1138,13 +1217,14 @@ slim_hidden_def(cairo_close_path);
void
cairo_paint (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_paint (cr->gstate);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1164,18 +1244,24 @@ cairo_paint_with_alpha (cairo_t *cr,
cairo_color_t color;
cairo_pattern_union_t pattern;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
+
+ if (CAIRO_ALPHA_IS_OPAQUE (alpha)) {
+ cairo_paint (cr);
+ return;
+ }
_cairo_color_init_rgba (&color, 1., 1., 1., alpha);
_cairo_pattern_init_solid (&pattern.solid, &color);
cr->status = _cairo_gstate_mask (cr->gstate, &pattern.base);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
_cairo_pattern_fini (&pattern.base);
-
- CAIRO_CHECK_SANITY (cr);
}
/**
@@ -1192,13 +1278,24 @@ void
cairo_mask (cairo_t *cr,
cairo_pattern_t *pattern)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
- cr->status = _cairo_gstate_mask (cr->gstate, pattern);
+ if (pattern == NULL) {
+ _cairo_error (cr, CAIRO_STATUS_NULL_POINTER);
+ return;
+ }
+
+ if (pattern->status) {
+ _cairo_error (cr, pattern->status);
+ return;
+ }
- CAIRO_CHECK_SANITY (cr);
+ cr->status = _cairo_gstate_mask (cr->gstate, pattern);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1222,15 +1319,12 @@ cairo_mask_surface (cairo_t *cr,
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
pattern = cairo_pattern_create_for_surface (surface);
- if (!pattern) {
- cr->status = CAIRO_STATUS_NO_MEMORY;
- return;
- }
cairo_matrix_init_translate (&matrix, - surface_x, - surface_y);
cairo_pattern_set_matrix (pattern, &matrix);
@@ -1275,13 +1369,14 @@ cairo_stroke (cairo_t *cr)
void
cairo_stroke_preserve (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_stroke (cr->gstate, &cr->path);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
slim_hidden_def(cairo_stroke_preserve);
@@ -1315,36 +1410,41 @@ cairo_fill (cairo_t *cr)
void
cairo_fill_preserve (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_fill (cr->gstate, &cr->path);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
slim_hidden_def(cairo_fill_preserve);
void
cairo_copy_page (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_copy_page (cr->gstate);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
cairo_show_page (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_show_page (cr->gstate);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
cairo_bool_t
@@ -1352,18 +1452,18 @@ cairo_in_stroke (cairo_t *cr, double x, double y)
{
int inside;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return 0;
+ }
cr->status = _cairo_gstate_in_stroke (cr->gstate,
&cr->path,
x, y, &inside);
-
- CAIRO_CHECK_SANITY (cr);
-
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return 0;
+ }
return inside;
}
@@ -1373,18 +1473,18 @@ cairo_in_fill (cairo_t *cr, double x, double y)
{
int inside;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return 0;
+ }
cr->status = _cairo_gstate_in_fill (cr->gstate,
&cr->path,
x, y, &inside);
-
- CAIRO_CHECK_SANITY (cr);
-
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return 0;
+ }
return inside;
}
@@ -1393,28 +1493,32 @@ void
cairo_stroke_extents (cairo_t *cr,
double *x1, double *y1, double *x2, double *y2)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_stroke_extents (cr->gstate,
&cr->path,
x1, y1, x2, y2);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
cairo_fill_extents (cairo_t *cr,
double *x1, double *y1, double *x2, double *y2)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_fill_extents (cr->gstate,
&cr->path,
x1, y1, x2, y2);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1472,12 +1576,14 @@ cairo_clip (cairo_t *cr)
void
cairo_clip_preserve (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_clip (cr->gstate, &cr->path);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
slim_hidden_def(cairo_clip_preserve);
@@ -1500,12 +1606,14 @@ slim_hidden_def(cairo_clip_preserve);
void
cairo_reset_clip (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_reset_clip (cr->gstate);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1529,12 +1637,14 @@ cairo_select_font_face (cairo_t *cr,
cairo_font_slant_t slant,
cairo_font_weight_t weight)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_select_font_face (cr->gstate, family, slant, weight);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1546,19 +1656,27 @@ cairo_select_font_face (cairo_t *cr,
* Return value: the current font object. Can return %NULL
* on out-of-memory or if the context is already in
* an error state. This object is owned by cairo. To keep
- * a reference to it, you must call cairo_font_reference().
+ * a reference to it, you must call cairo_font_face_reference().
**/
cairo_font_face_t *
cairo_get_font_face (cairo_t *cr)
{
cairo_font_face_t *font_face;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return NULL;
+ }
cr->status = _cairo_gstate_get_font_face (cr->gstate, &font_face);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
+ /* XXX: When available:
+ return _cairo_font_face_create_in_error (cr->status);
+ */
+ return NULL;
+ }
+
return font_face;
}
@@ -1574,12 +1692,14 @@ void
cairo_font_extents (cairo_t *cr,
cairo_font_extents_t *extents)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_get_font_extents (cr->gstate, extents);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1595,12 +1715,14 @@ void
cairo_set_font_face (cairo_t *cr,
cairo_font_face_t *font_face)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_font_face (cr->gstate, font_face);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1617,12 +1739,14 @@ cairo_set_font_face (cairo_t *cr,
void
cairo_set_font_size (cairo_t *cr, double size)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_font_size (cr->gstate, size);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1642,12 +1766,14 @@ void
cairo_set_font_matrix (cairo_t *cr,
const cairo_matrix_t *matrix)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_set_font_matrix (cr->gstate, matrix);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1661,7 +1787,6 @@ cairo_set_font_matrix (cairo_t *cr,
void
cairo_get_font_matrix (cairo_t *cr, cairo_matrix_t *matrix)
{
- CAIRO_CHECK_SANITY (cr);
_cairo_gstate_get_font_matrix (cr->gstate, matrix);
}
@@ -1694,9 +1819,10 @@ cairo_text_extents (cairo_t *cr,
int num_glyphs;
double x, y;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
if (utf8 == NULL) {
extents->x_bearing = 0.0;
@@ -1713,19 +1839,20 @@ cairo_text_extents (cairo_t *cr,
cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
x, y,
&glyphs, &num_glyphs);
- CAIRO_CHECK_SANITY (cr);
if (cr->status) {
if (glyphs)
free (glyphs);
+ _cairo_error (cr, cr->status);
return;
}
cr->status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents);
- CAIRO_CHECK_SANITY (cr);
-
if (glyphs)
free (glyphs);
+
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1752,13 +1879,15 @@ cairo_glyph_extents (cairo_t *cr,
int num_glyphs,
cairo_text_extents_t *extents)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs,
extents);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
@@ -1768,9 +1897,10 @@ cairo_show_text (cairo_t *cr, const char *utf8)
int num_glyphs;
double x, y;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
if (utf8 == NULL)
return;
@@ -1780,30 +1910,34 @@ cairo_show_text (cairo_t *cr, const char *utf8)
cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
x, y,
&glyphs, &num_glyphs);
- CAIRO_CHECK_SANITY (cr);
if (cr->status) {
if (glyphs)
free (glyphs);
+ _cairo_error (cr, cr->status);
return;
}
cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs);
- CAIRO_CHECK_SANITY (cr);
if (glyphs)
free (glyphs);
+
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
cairo_show_glyphs (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_show_glyphs (cr->gstate, glyphs, num_glyphs);
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
void
@@ -1813,44 +1947,48 @@ cairo_text_path (cairo_t *cr, const char *utf8)
int num_glyphs;
double x, y;
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cairo_get_current_point (cr, &x, &y);
cr->status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
x, y,
&glyphs, &num_glyphs);
- CAIRO_CHECK_SANITY (cr);
if (cr->status) {
if (glyphs)
free (glyphs);
+ _cairo_error (cr, cr->status);
return;
}
cr->status = _cairo_gstate_glyph_path (cr->gstate,
glyphs, num_glyphs,
&cr->path);
- CAIRO_CHECK_SANITY (cr);
-
if (glyphs)
free (glyphs);
+
+ if (cr->status)
+ _cairo_error (cr, cr->status);
+
}
void
cairo_glyph_path (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
cr->status = _cairo_gstate_glyph_path (cr->gstate,
glyphs, num_glyphs,
&cr->path);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
/**
@@ -1864,7 +2002,6 @@ cairo_glyph_path (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs)
cairo_operator_t
cairo_get_operator (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
return _cairo_gstate_get_operator (cr->gstate);
}
@@ -1879,7 +2016,6 @@ cairo_get_operator (cairo_t *cr)
double
cairo_get_tolerance (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
return _cairo_gstate_get_tolerance (cr->gstate);
}
@@ -1911,8 +2047,6 @@ cairo_get_current_point (cairo_t *cr, double *x_ret, double *y_ret)
cairo_fixed_t x_fixed, y_fixed;
double x, y;
- CAIRO_CHECK_SANITY (cr);
-
status = _cairo_path_fixed_get_current_point (&cr->path, &x_fixed, &y_fixed);
if (status == CAIRO_STATUS_NO_CURRENT_POINT) {
x = 0.0;
@@ -1927,8 +2061,6 @@ cairo_get_current_point (cairo_t *cr, double *x_ret, double *y_ret)
*x_ret = x;
if (y_ret)
*y_ret = y;
-
- CAIRO_CHECK_SANITY (cr);
}
slim_hidden_def(cairo_get_current_point);
@@ -1943,7 +2075,6 @@ slim_hidden_def(cairo_get_current_point);
cairo_fill_rule_t
cairo_get_fill_rule (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
return _cairo_gstate_get_fill_rule (cr->gstate);
}
@@ -1958,7 +2089,6 @@ cairo_get_fill_rule (cairo_t *cr)
double
cairo_get_line_width (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
return _cairo_gstate_get_line_width (cr->gstate);
}
@@ -1973,7 +2103,6 @@ cairo_get_line_width (cairo_t *cr)
cairo_line_cap_t
cairo_get_line_cap (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
return _cairo_gstate_get_line_cap (cr->gstate);
}
@@ -1988,7 +2117,6 @@ cairo_get_line_cap (cairo_t *cr)
cairo_line_join_t
cairo_get_line_join (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
return _cairo_gstate_get_line_join (cr->gstate);
}
@@ -2003,7 +2131,6 @@ cairo_get_line_join (cairo_t *cr)
double
cairo_get_miter_limit (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
return _cairo_gstate_get_miter_limit (cr->gstate);
}
@@ -2017,7 +2144,6 @@ cairo_get_miter_limit (cairo_t *cr)
void
cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix)
{
- CAIRO_CHECK_SANITY (cr);
_cairo_gstate_get_matrix (cr->gstate, matrix);
}
@@ -2030,14 +2156,18 @@ cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix)
*
* Return value: the target surface, (or NULL if @cr is in an error
* state). This object is owned by cairo. To keep a reference to it,
- * you must call cairo_pattern_reference().
+ * you must call cairo_surface_reference().
**/
cairo_surface_t *
cairo_get_target (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
+ /* XXX: Should be as follows when available:
+ return _cairo_surface_create_in_error ();
+ */
return NULL;
+ }
return _cairo_gstate_get_target (cr->gstate);
}
@@ -2053,13 +2183,25 @@ cairo_get_target (cairo_t *cr)
* Return value: the copy of the current path. The caller owns the
* returned object and should call cairo_path_destroy() when finished
* with it.
+ *
+ * This function will always return a valid pointer, but the result
+ * will have no data, (data==NULL and num_data==0), if either of the
+ * following conditions hold:
+ *
+ * 1) If there is insufficient memory to copy the path. In this case
+ * path->status will be set to CAIRO_STATUS_NO_MEMORY.
+ *
+ * 2) If @cr is already in an error state. In this case path->status
+ * will contain the same status that would be returned by
+ * cairo_status(cr).
**/
cairo_path_t *
cairo_copy_path (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
- return &_cairo_path_nil;
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
+ return _cairo_path_data_create_in_error (cr->status);
+ }
return _cairo_path_data_create (&cr->path, cr->gstate);
}
@@ -2082,15 +2224,25 @@ cairo_copy_path (cairo_t *cr)
* Return value: the copy of the current path. The caller owns the
* returned object and should call cairo_path_destroy() when finished
* with it.
+ *
+ * This function will always return a valid pointer, but the result
+ * will have no data, (data==NULL and num_data==0), if either of the
+ * following conditions hold:
+ *
+ * 1) If there is insufficient memory to copy the path. In this case
+ * path->status will be set to CAIRO_STATUS_NO_MEMORY.
+ *
+ * 2) If @cr is already in an error state. In this case path->status
+ * will contain the same status that would be returned by
+ * cairo_status(cr).
**/
cairo_path_t *
cairo_copy_path_flat (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
if (cr->status)
- return &_cairo_path_nil;
-
- return _cairo_path_data_create_flat (&cr->path, cr->gstate);
+ return _cairo_path_data_create_in_error (cr->status);
+ else
+ return _cairo_path_data_create_flat (&cr->path, cr->gstate);
}
/**
@@ -2098,43 +2250,47 @@ cairo_copy_path_flat (cairo_t *cr)
* @cr: a cairo context
* @path: path to be appended
*
- * Append the @path onto the current path. See #cairo_path_t
- * for details on how the path data structure must be initialized.
+ * Append the @path onto the current path. The @path may be either the
+ * return value from one of cairo_copy_path() or
+ * cairo_copy_path_flat() or it may be constructed manually. See
+ * #cairo_path_t for details on how the path data structure should be
+ * initialized, and note that path->status must be initialized to
+ * CAIRO_STATUS_SUCCESS.
**/
void
cairo_append_path (cairo_t *cr,
cairo_path_t *path)
{
- CAIRO_CHECK_SANITY (cr);
- if (cr->status)
+ if (cr->status) {
+ _cairo_error (cr, cr->status);
return;
+ }
if (path == NULL || path->data == NULL) {
- cr->status = CAIRO_STATUS_NULL_POINTER;
+ _cairo_error (cr, CAIRO_STATUS_NULL_POINTER);
return;
}
- if (path == &_cairo_path_nil) {
- cr->status = CAIRO_STATUS_NO_MEMORY;
+ if (path->status) {
+ _cairo_error (cr, path->status);
return;
}
cr->status = _cairo_path_data_append_to_context (path, cr);
-
- CAIRO_CHECK_SANITY (cr);
+ if (cr->status)
+ _cairo_error (cr, cr->status);
}
cairo_status_t
cairo_status (cairo_t *cr)
{
- CAIRO_CHECK_SANITY (cr);
return cr->status;
}
const char *
-cairo_status_string (cairo_t *cr)
+cairo_status_to_string (cairo_status_t status)
{
- switch (cr->status) {
+ switch (status) {
case CAIRO_STATUS_SUCCESS:
return "success";
case CAIRO_STATUS_NO_MEMORY:
@@ -2163,8 +2319,8 @@ cairo_status_string (cairo_t *cr)
return "the target surface has been finished";
case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
return "the surface type is not appropriate for the operation";
- case CAIRO_STATUS_BAD_NESTING:
- return "drawing operations interleaved for two contexts for the same surface";
+ case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
+ return "the pattern type is not appropriate for the operation";
}
return "<unknown error status>";