[cairo-commit] src/cairo-glitz-surface.c src/cairo-gstate.c
src/cairoint.h src/cairo-meta-surface.c src/cairo-pattern.c
src/cairo-quartz-surface.c src/cairo-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Wed May 9 02:23:14 PDT 2007
src/cairo-glitz-surface.c | 12 +++++++--
src/cairo-gstate.c | 55 +++++++++++++++++++++++++++++++--------------
src/cairo-meta-surface.c | 6 ++++
src/cairo-pattern.c | 30 ++++++++++++++++++------
src/cairo-quartz-surface.c | 6 ++++
src/cairo-surface.c | 47 +++++++++++++++++++++++++++-----------
src/cairoint.h | 2 -
7 files changed, 113 insertions(+), 45 deletions(-)
New commits:
diff-tree 8ddfc1b2e4aeefb704e05e64661b5c9985788e99 (from dbdaf0690e1121d0f810dfb035e7a9f0dae17248)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue May 8 16:13:08 2007 +0100
[cairo-pattern] Return status from _cairo_pattern_init_copy()
During the copy, allocation of the gradient may fail and so the callers
need to check for a pattern that returned in an error state. No callers
did so and in order to force all callers to check the error status,
the status return was added to _cairo_pattern_init_copy(). The early
error checking may appear redundant for an object with an embedded
structure, however it does fix an error where an uninitialised pattern
was being used:
==1922== Process terminating with default action of signal 11 (SIGSEGV)
==1922== Access not within mapped region at address 0x55555555
==1922== at 0x402CF6F: _cairo_array_index (cairo-array.c:208)
==1922== by 0x402D4F3: _cairo_user_data_array_fini (cairo-array.c:370)
==1922== by 0x4046464: _cairo_pattern_fini (cairo-pattern.c:188)
==1922== by 0x404992A: _cairo_meta_surface_paint (cairo-meta-surface.c:266)
==1922== by 0x403FCE0: _cairo_surface_paint (cairo-surface.c:1331)
==1922== by 0x405CB5E: _test_meta_surface_paint (test-meta-surface.c:195)
==1922== by 0x403FCE0: _cairo_surface_paint (cairo-surface.c:1331)
==1922== by 0x4032A60: _cairo_gstate_paint (cairo-gstate.c:822)
==1922== by 0x402B2D1: cairo_paint (cairo.c:1879)
==1922== by 0x804A4F7: draw (radial-gradient.c:73)
==1922== by 0x804AFA4: cairo_test_expecting (cairo-test.c:326)
==1922== by 0x804A57C: main (radial-gradient.c:109)
==1922== Injected fault at:
==1922== at 0x4020EA5: malloc (vg_replace_malloc.c:207)
==1922== by 0x404475C: _cairo_pattern_init_copy (cairo-pattern.c:136)
==1922== by 0x403F779: _cairo_surface_copy_pattern_for_destination (cairo-surface.c:2153)
==1922== by 0x403FCC1: _cairo_surface_paint (cairo-surface.c:1328)
==1922== by 0x405CB5E: _test_meta_surface_paint (test-meta-surface.c:195)
==1922== by 0x403FCE0: _cairo_surface_paint (cairo-surface.c:1331)
==1922== by 0x4032A60: _cairo_gstate_paint (cairo-gstate.c:822)
==1922== by 0x402B2D1: cairo_paint (cairo.c:1879)
==1922== by 0x804A4F7: draw (radial-gradient.c:73)
==1922== by 0x804AFA4: cairo_test_expecting (cairo-test.c:326)
==1922== by 0x804A57C: main (radial-gradient.c:109)
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 031c081..ab15404 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -829,7 +829,9 @@ _cairo_glitz_pattern_acquire_surfaces (c
mask = NULL;
} else {
- _cairo_pattern_init_copy (&tmp.base, src);
+ status = _cairo_pattern_init_copy (&tmp.base, src);
+ if (status)
+ return status;
}
status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,
@@ -844,7 +846,9 @@ _cairo_glitz_pattern_acquire_surfaces (c
if (mask)
{
- _cairo_pattern_init_copy (&tmp.base, mask);
+ status = _cairo_pattern_init_copy (&tmp.base, mask);
+ if (status)
+ return status;
status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,
mask_x, mask_y,
@@ -1075,7 +1079,9 @@ _cairo_glitz_surface_composite_trapezoid
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
{
- _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
+ status = _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern);
+ if (status)
+ return status;
status = _cairo_glitz_pattern_acquire_surface (&tmp_src_pattern.base,
dst,
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 0a77df4..3787aeb 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -764,7 +764,7 @@ _cairo_gstate_stroke_to_path (cairo_gsta
}
*/
-static void
+static cairo_status_t
_cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
cairo_pattern_t *pattern,
cairo_pattern_t *original,
@@ -772,8 +772,12 @@ _cairo_gstate_copy_transformed_pattern (
{
cairo_surface_pattern_t *surface_pattern;
cairo_surface_t *surface;
+ cairo_status_t status;
+
+ status = _cairo_pattern_init_copy (pattern, original);
+ if (status)
+ return status;
- _cairo_pattern_init_copy (pattern, original);
_cairo_pattern_transform (pattern, ctm_inverse);
if (cairo_pattern_get_type (original) == CAIRO_PATTERN_TYPE_SURFACE) {
@@ -783,25 +787,26 @@ _cairo_gstate_copy_transformed_pattern (
_cairo_pattern_transform (pattern, &surface->device_transform);
}
+ return CAIRO_STATUS_SUCCESS;
}
-static void
+static cairo_status_t
_cairo_gstate_copy_transformed_source (cairo_gstate_t *gstate,
cairo_pattern_t *pattern)
{
- _cairo_gstate_copy_transformed_pattern (gstate, pattern,
- gstate->source,
- &gstate->source_ctm_inverse);
+ return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
+ gstate->source,
+ &gstate->source_ctm_inverse);
}
-static void
+static cairo_status_t
_cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate,
cairo_pattern_t *pattern,
cairo_pattern_t *mask)
{
- _cairo_gstate_copy_transformed_pattern (gstate, pattern,
- mask,
- &gstate->ctm_inverse);
+ return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
+ mask,
+ &gstate->ctm_inverse);
}
cairo_status_t
@@ -817,7 +822,9 @@ _cairo_gstate_paint (cairo_gstate_t *gst
if (status)
return status;
- _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+ status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+ if (status)
+ return status;
status = _cairo_surface_paint (gstate->target,
gstate->op,
@@ -924,16 +931,22 @@ _cairo_gstate_mask (cairo_gstate_t *gst
if (status)
return status;
- _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
- _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
+ status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+ if (status)
+ return status;
+
+ status = _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
+ if (status)
+ goto CLEANUP_SOURCE;
status = _cairo_surface_mask (gstate->target,
gstate->op,
&source_pattern.base,
&mask_pattern.base);
- _cairo_pattern_fini (&source_pattern.base);
_cairo_pattern_fini (&mask_pattern.base);
+CLEANUP_SOURCE:
+ _cairo_pattern_fini (&source_pattern.base);
return status;
}
@@ -954,7 +967,10 @@ _cairo_gstate_stroke (cairo_gstate_t *gs
if (status)
return status;
- _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+ status = _cairo_gstate_copy_transformed_source (gstate,
+ &source_pattern.base);
+ if (status)
+ return status;
status = _cairo_surface_stroke (gstate->target,
gstate->op,
@@ -1021,7 +1037,9 @@ _cairo_gstate_fill (cairo_gstate_t *gsta
if (status)
return status;
- _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+ status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+ if (status)
+ return status;
status = _cairo_surface_fill (gstate->target,
gstate->op,
@@ -1561,7 +1579,9 @@ _cairo_gstate_show_glyphs (cairo_gstate_
_cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs,
transformed_glyphs);
- _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+ status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+ if (status)
+ goto CLEANUP_GLYPHS;
status = _cairo_surface_show_glyphs (gstate->target,
gstate->op,
@@ -1572,6 +1592,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_
_cairo_pattern_fini (&source_pattern.base);
+CLEANUP_GLYPHS:
if (transformed_glyphs != stack_transformed_glyphs)
free (transformed_glyphs);
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index 56c702c..98ccaaf 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -212,7 +212,11 @@ static cairo_status_t
_init_pattern_with_snapshot (cairo_pattern_t *pattern,
const cairo_pattern_t *other)
{
- _cairo_pattern_init_copy (pattern, other);
+ cairo_status_t status;
+
+ status = _cairo_pattern_init_copy (pattern, other);
+ if (status)
+ return status;
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern =
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 3c2382c..033519c 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -110,7 +110,7 @@ _cairo_pattern_init (cairo_pattern_t *pa
cairo_matrix_init_identity (&pattern->matrix);
}
-static void
+static cairo_status_t
_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
const cairo_gradient_pattern_t *other)
{
@@ -139,21 +139,23 @@ _cairo_gradient_pattern_init_copy (cairo
pattern->stops_size = 0;
pattern->n_stops = 0;
_cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY);
- return;
+ return CAIRO_STATUS_NO_MEMORY;
}
memcpy (pattern->stops, other->stops,
other->n_stops * sizeof (pixman_gradient_stop_t));
}
+
+ return CAIRO_STATUS_SUCCESS;
}
-void
+cairo_status_t
_cairo_pattern_init_copy (cairo_pattern_t *pattern,
const cairo_pattern_t *other)
{
if (other->status) {
_cairo_pattern_set_error (pattern, other->status);
- return;
+ return other->status;
}
switch (other->type) {
@@ -174,12 +176,18 @@ _cairo_pattern_init_copy (cairo_pattern_
case CAIRO_PATTERN_TYPE_RADIAL: {
cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern;
cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other;
+ cairo_status_t status;
+
+ status = _cairo_gradient_pattern_init_copy (dst, src);
+ if (status)
+ return status;
- _cairo_gradient_pattern_init_copy (dst, src);
} break;
}
pattern->ref_count = 1;
+
+ return CAIRO_STATUS_SUCCESS;
}
void
@@ -1812,7 +1820,9 @@ _cairo_pattern_acquire_surfaces (cairo_p
}
else
{
- _cairo_pattern_init_copy (&src_tmp.base, src);
+ status = _cairo_pattern_init_copy (&src_tmp.base, src);
+ if (status)
+ return status;
}
status = _cairo_pattern_acquire_surface (&src_tmp.base, dst,
@@ -1831,19 +1841,23 @@ _cairo_pattern_acquire_surfaces (cairo_p
return CAIRO_STATUS_SUCCESS;
}
- _cairo_pattern_init_copy (&mask_tmp.base, mask);
+ status = _cairo_pattern_init_copy (&mask_tmp.base, mask);
+ if (status)
+ goto CLEANUP_SOURCE;
status = _cairo_pattern_acquire_surface (&mask_tmp.base, dst,
mask_x, mask_y,
width, height,
mask_out, mask_attributes);
+ _cairo_pattern_fini (&mask_tmp.base);
+
+CLEANUP_SOURCE:
if (status)
_cairo_pattern_release_surface (&src_tmp.base,
*src_out, src_attributes);
_cairo_pattern_fini (&src_tmp.base);
- _cairo_pattern_fini (&mask_tmp.base);
return status;
}
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 5469e40..0c4414b 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -515,7 +515,11 @@ static cairo_status_t
_init_pattern_with_snapshot (cairo_pattern_t *pattern,
const cairo_pattern_t *other)
{
- _cairo_pattern_init_copy (pattern, other);
+ cairo_status_t status;
+
+ status = _cairo_pattern_init_copy (pattern, other);
+ if (status)
+ return status;
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
cairo_surface_pattern_t *surface_pattern =
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 94bb405..680ff0c 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -80,7 +80,7 @@ DEFINE_NIL_SURFACE(CAIRO_STATUS_FILE_NOT
DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error);
DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error);
-static void
+static cairo_status_t
_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
cairo_surface_t *destination,
cairo_pattern_t *pattern_out);
@@ -1325,7 +1325,9 @@ _cairo_surface_paint (cairo_surface_t *s
assert (! surface->is_snapshot);
- _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+ status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+ if (status)
+ return status;
if (surface->backend->paint) {
status = surface->backend->paint (surface, op, &dev_source.base);
@@ -1353,20 +1355,26 @@ _cairo_surface_mask (cairo_surface_t *su
assert (! surface->is_snapshot);
- _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
- _cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base);
+ status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+ if (status)
+ goto FINISH;
+ status = _cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask.base);
+ if (status)
+ goto CLEANUP_SOURCE;
if (surface->backend->mask) {
status = surface->backend->mask (surface, op, &dev_source.base, &dev_mask.base);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- goto FINISH;
+ goto CLEANUP_MASK;
}
status = _cairo_surface_fallback_mask (surface, op, &dev_source.base, &dev_mask.base);
- FINISH:
+ CLEANUP_MASK:
_cairo_pattern_fini (&dev_mask.base);
+ CLEANUP_SOURCE:
_cairo_pattern_fini (&dev_source.base);
+ FINISH:
return status;
}
@@ -1391,7 +1399,9 @@ _cairo_surface_stroke (cairo_surface_t
assert (! surface->is_snapshot);
- _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+ status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+ if (status)
+ return status;
if (surface->backend->stroke) {
status = surface->backend->stroke (surface, op, &dev_source.base,
@@ -1430,7 +1440,9 @@ _cairo_surface_fill (cairo_surface_t *su
assert (! surface->is_snapshot);
- _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+ status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source.base);
+ if (status)
+ return status;
if (surface->backend->fill) {
status = surface->backend->fill (surface, op, &dev_source.base,
@@ -1830,9 +1842,11 @@ _cairo_surface_show_glyphs (cairo_surfac
if (!num_glyphs)
return CAIRO_STATUS_SUCCESS;
- _cairo_surface_copy_pattern_for_destination (source,
- surface,
- &dev_source.base);
+ status = _cairo_surface_copy_pattern_for_destination (source,
+ surface,
+ &dev_source.base);
+ if (status)
+ return status;
cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
@@ -2145,16 +2159,19 @@ _cairo_surface_composite_shape_fixup_unb
* Copies the given pattern, taking into account device scale and offsets
* of the destination surface.
*/
-void
+static cairo_status_t
_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
cairo_surface_t *destination,
cairo_pattern_t *pattern_out)
{
- _cairo_pattern_init_copy (pattern_out, pattern);
+ cairo_status_t status;
+
+ status = _cairo_pattern_init_copy (pattern_out, pattern);
+ if (status)
+ return status;
if (_cairo_surface_has_device_transform (destination)) {
cairo_matrix_t device_to_surface = destination->device_transform;
- cairo_status_t status;
status = cairo_matrix_invert (&device_to_surface);
/* We only ever allow for scaling (under the implementation's
@@ -2164,6 +2181,8 @@ _cairo_surface_copy_pattern_for_destinat
_cairo_pattern_transform (pattern_out, &device_to_surface);
}
+
+ return CAIRO_STATUS_SUCCESS;
}
/* LocalWords: rasterized
diff --git a/src/cairoint.h b/src/cairoint.h
index a5bbb63..7b0d57e 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2254,7 +2254,7 @@ _cairo_slope_counter_clockwise (cairo_sl
/* cairo_pattern.c */
-cairo_private void
+cairo_private cairo_status_t
_cairo_pattern_init_copy (cairo_pattern_t *pattern,
const cairo_pattern_t *other);
More information about the cairo-commit
mailing list