summaryrefslogtreecommitdiff
path: root/src/cairo-pattern.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo-pattern.c')
-rw-r--r--src/cairo-pattern.c114
1 files changed, 66 insertions, 48 deletions
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index b309e8e3..1fb17217 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -50,7 +50,7 @@ typedef struct _cairo_shader_op {
((unsigned char) \
((((unsigned char) (c1)) * (int) ((unsigned char) (c2))) / 0xff))
-static const cairo_solid_pattern_t cairo_solid_pattern_nil = {
+const cairo_solid_pattern_t cairo_solid_pattern_nil = {
{ CAIRO_PATTERN_SOLID, /* type */
(unsigned int)-1, /* ref_count */
CAIRO_STATUS_NO_MEMORY, /* status */
@@ -96,6 +96,31 @@ static const cairo_radial_pattern_t cairo_radial_pattern_nil = {
1.0, 1.0, /* radius0, radius1 */
};
+/**
+ * _cairo_pattern_set_error:
+ * @pattern: a pattern
+ * @status: a status value indicating an error, (eg. not
+ * CAIRO_STATUS_SUCCESS)
+ *
+ * Sets pattern->status to @status and calls _cairo_error;
+ *
+ * All assignments of an error status to pattern->status should happen
+ * through _cairo_pattern_set_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.
+ **/
+static void
+_cairo_pattern_set_error (cairo_pattern_t *pattern,
+ cairo_status_t status)
+{
+ pattern->status = status;
+
+ _cairo_error (status);
+}
+
static void
_cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
{
@@ -127,10 +152,13 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
*dst = *src;
}
+ if (other->base.status)
+ _cairo_pattern_set_error (&pattern->base, other->base.status);
+
if (other->n_stops)
{
pattern->stops = malloc (other->n_stops * sizeof (cairo_color_stop_t));
- if (!pattern->stops) {
+ if (pattern->stops == NULL) {
if (other->base.type == CAIRO_PATTERN_LINEAR)
_cairo_gradient_pattern_init_copy (pattern, &cairo_linear_pattern_nil.base);
else
@@ -264,37 +292,6 @@ _cairo_pattern_create_solid (const cairo_color_t *color)
}
/**
- * _cairo_pattern_create_in_error:
- * @status: an error status
- *
- * Create an empty #cairo_pattern_t object to hold an error
- * status. This is useful for propagating status values from an
- * existing object to a new #cairo_pattern_t.
- *
- * Return value: a (solid, black) #cairo_pattern_t object with status
- * of @status. If there is insufficient memory a pointer to a special,
- * static cairo_solid_pattern_nil will be returned instead with a
- * status of CAIRO_STATUS_NO_MEMORY rather than @status.
- *
- * Return value:
- **/
-cairo_pattern_t *
-_cairo_pattern_create_in_error (cairo_status_t status)
-{
- cairo_solid_pattern_t *pattern;
-
- pattern = malloc (sizeof (cairo_solid_pattern_t));
- if (pattern == NULL)
- return (cairo_pattern_t *) &cairo_solid_pattern_nil.base;
-
- _cairo_pattern_init_solid (pattern, CAIRO_COLOR_BLACK);
-
- pattern->base.status = status;
-
- return &pattern->base;
-}
-
-/**
* cairo_pattern_create_rgb:
* @red: red component of the color
* @green: green component of the color
@@ -317,6 +314,7 @@ _cairo_pattern_create_in_error (cairo_status_t status)
cairo_pattern_t *
cairo_pattern_create_rgb (double red, double green, double blue)
{
+ cairo_pattern_t *pattern;
cairo_color_t color;
_cairo_restrict_value (&red, 0.0, 1.0);
@@ -325,7 +323,11 @@ cairo_pattern_create_rgb (double red, double green, double blue)
_cairo_color_init_rgb (&color, red, green, blue);
- return _cairo_pattern_create_solid (&color);
+ pattern = _cairo_pattern_create_solid (&color);
+ if (pattern->status)
+ _cairo_pattern_set_error (pattern, pattern->status);
+
+ return pattern;
}
/**
@@ -353,6 +355,7 @@ cairo_pattern_t *
cairo_pattern_create_rgba (double red, double green, double blue,
double alpha)
{
+ cairo_pattern_t *pattern;
cairo_color_t color;
_cairo_restrict_value (&red, 0.0, 1.0);
@@ -362,7 +365,11 @@ cairo_pattern_create_rgba (double red, double green, double blue,
_cairo_color_init_rgba (&color, red, green, blue, alpha);
- return _cairo_pattern_create_solid (&color);
+ pattern = _cairo_pattern_create_solid (&color);
+ if (pattern->status)
+ _cairo_pattern_set_error (pattern, pattern->status);
+
+ return pattern;
}
/**
@@ -386,8 +393,10 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
cairo_surface_pattern_t *pattern;
pattern = malloc (sizeof (cairo_surface_pattern_t));
- if (pattern == NULL)
+ if (pattern == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *)&cairo_surface_pattern_nil.base;
+ }
_cairo_pattern_init_for_surface (pattern, surface);
@@ -422,8 +431,10 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
cairo_linear_pattern_t *pattern;
pattern = malloc (sizeof (cairo_linear_pattern_t));
- if (pattern == NULL)
+ if (pattern == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &cairo_linear_pattern_nil.base;
+ }
_cairo_pattern_init_linear (pattern, x0, y0, x1, y1);
@@ -461,8 +472,10 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
cairo_radial_pattern_t *pattern;
pattern = malloc (sizeof (cairo_radial_pattern_t));
- if (pattern == NULL)
+ if (pattern == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &cairo_radial_pattern_nil.base;
+ }
_cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1);
@@ -541,7 +554,7 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern,
new_stops = realloc (pattern->stops,
pattern->n_stops * sizeof (cairo_color_stop_t));
if (new_stops == NULL) {
- pattern->base.status = CAIRO_STATUS_NO_MEMORY;
+ _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
return;
}
@@ -568,7 +581,7 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern,
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
{
- pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+ _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
}
@@ -599,7 +612,7 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
if (pattern->type != CAIRO_PATTERN_LINEAR &&
pattern->type != CAIRO_PATTERN_RADIAL)
{
- pattern->status = CAIRO_STATUS_PATTERN_TYPE_MISMATCH;
+ _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
return;
}
@@ -619,8 +632,10 @@ void
cairo_pattern_set_matrix (cairo_pattern_t *pattern,
const cairo_matrix_t *matrix)
{
- if (pattern->status)
+ if (pattern->status) {
+ _cairo_pattern_set_error (pattern, pattern->status);
return;
+ }
pattern->matrix = *matrix;
}
@@ -634,8 +649,10 @@ cairo_pattern_get_matrix (cairo_pattern_t *pattern, cairo_matrix_t *matrix)
void
cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter)
{
- if (pattern->status)
+ if (pattern->status) {
+ _cairo_pattern_set_error (pattern, pattern->status);
return;
+ }
pattern->filter = filter;
}
@@ -649,8 +666,10 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern)
void
cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
{
- if (pattern->status)
+ if (pattern->status) {
+ _cairo_pattern_set_error (pattern, pattern->status);
return;
+ }
pattern->extend = extend;
}
@@ -1164,7 +1183,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
}
data = malloc (width * height * 4);
- if (!data)
+ if (data == NULL)
return CAIRO_STATUS_NO_MEMORY;
if (pattern->base.type == CAIRO_PATTERN_LINEAR)
@@ -1193,7 +1212,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
width, height,
width * 4);
- if (image == NULL) {
+ if (image->base.status) {
free (data);
return CAIRO_STATUS_NO_MEMORY;
}
@@ -1228,8 +1247,7 @@ _cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
CAIRO_CONTENT_COLOR_ALPHA,
1, 1,
&pattern->color);
-
- if (*out == NULL)
+ if ((*out)->status)
return CAIRO_STATUS_NO_MEMORY;
attribs->x_offset = attribs->y_offset = 0;