summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-09-30 19:45:20 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-09-30 19:45:20 -0400
commit0afc438272c4e1610342b89a654294ccb5a68ed9 (patch)
treef8d3d2fc0d3546beba4e0c0926dd8fa00ebc4101
parent5a8c34cd098f890d5cb5e6e49f38e2659d3e5edd (diff)
prtooproto
-rw-r--r--src/cairo-pixman-surface.c628
1 files changed, 349 insertions, 279 deletions
diff --git a/src/cairo-pixman-surface.c b/src/cairo-pixman-surface.c
index f6ee2600..3eb0fa10 100644
--- a/src/cairo-pixman-surface.c
+++ b/src/cairo-pixman-surface.c
@@ -343,6 +343,8 @@ typedef union proto_image_t proto_image_t;
typedef enum
{
+ BROKEN,
+ WHITE,
REGION,
TRAPS,
GLYPHS,
@@ -406,6 +408,62 @@ proto_image_new (proto_image_type_t type)
return image;
}
+static void
+proto_image_free (proto_image_t *image)
+{
+ if (image->type == BROKEN)
+ {
+ /* These are statically allocated */
+ return;
+ }
+
+ switch (image->type)
+ {
+ case BROKEN:
+ case WHITE:
+ break;
+ case REGION:
+ pixman_region32_fini (image->region.region);
+ break;
+ case TRAPS:
+ free (image->traps.traps);
+ break;
+ case GLYPHS:
+ free (image->glyphs.glyphs);
+ break;
+ case PIXMAN:
+ pixman_image_unref (image->pixman.image);
+ break;
+ case COMPOSITE:
+ proto_image_free (image->composite.left);
+ proto_image_free (image->composite.right);
+ break;
+ }
+
+ free (image);
+}
+
+static proto_image_t *
+proto_image_new_broken (void)
+{
+ static const proto_image_t broken =
+ {
+ BROKEN
+ };
+
+ return (proto_image_t *)&broken;
+}
+
+static proto_image_t *
+proto_image_new_white (void)
+{
+ proto_image_t *image;
+
+ if (!(image = proto_image_new (WHITE)))
+ return proto_image_new_broken ();
+ return image;
+}
+
static proto_image_t *
proto_image_new_traps (int n_traps, pixman_trapezoid_t *traps)
{
@@ -416,6 +474,10 @@ proto_image_new_traps (int n_traps, pixman_trapezoid_t *traps)
image->traps.n_traps = n_traps;
image->traps.traps = traps;
}
+ else
+ {
+ image = proto_image_new_broken ();
+ }
return image;
}
@@ -427,6 +489,8 @@ proto_image_new_region (pixman_region32_t *region)
if ((image = proto_image_new (REGION)))
image->region.region = region;
+ else
+ image = proto_image_new_broken ();
return image;
}
@@ -444,6 +508,10 @@ proto_image_new_glyphs (pixman_glyph_cache_t *glyph_cache,
image->glyphs.n_glyphs = n_glyphs;
image->glyphs.glyphs = glyphs;
}
+ else
+ {
+ image = proto_image_new_broken ();
+ }
return image;
}
@@ -453,9 +521,10 @@ proto_image_new_pixman (pixman_image_t *pimage)
{
proto_image_t *image;
- if ((image = proto_image_new (PIXMAN)))
- image->pixman.image = pimage;
+ if (!pimage || !(image = proto_image_new (PIXMAN)))
+ return proto_image_new_broken ();
+ image->pixman.image = pimage;
return image;
}
@@ -470,10 +539,162 @@ proto_image_new_composite (pixman_op_t op, proto_image_t *left, proto_image_t *r
image->composite.left = left;
image->composite.right = right;
}
+ else
+ {
+ proto_image_free (left);
+ proto_image_free (right);
+
+ image = proto_image_new_broken ();
+ }
return image;
}
+static const pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff };
+
+static cairo_int_status_t
+proto_image_resolve (proto_image_t *proto_image, int width, int height,
+ pixman_image_t **result)
+{
+ cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
+ pixman_image_t *white_img;
+ pixman_format_code_t format;
+ pixman_image_t *left, *right;
+
+ *result = NULL;
+
+ switch (proto_image->type)
+ {
+ case BROKEN:
+ status = CAIRO_INT_STATUS_NO_MEMORY;
+ break;
+
+ case WHITE:
+ *result = pixman_image_create_solid_fill (&white);
+ if (!*result)
+ {
+ status = CAIRO_INT_STATUS_NO_MEMORY;
+ goto out;
+ }
+ break;
+
+ case REGION:
+ if (!(*result = pixman_image_create_bits (
+ PIXMAN_a8, width, height, NULL, -1)))
+ {
+ status = CAIRO_INT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ if (!(white_img = pixman_image_create_solid_fill (&white)))
+ {
+ status = CAIRO_INT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ pixman_image_set_clip_region32 (*result, proto_image->region.region);
+ pixman_image_composite32 (
+ PIXMAN_OP_SRC, white_img, NULL, *result,
+ 0, 0, 0, 0, 0, 0, width, height);
+ break;
+
+ case TRAPS:
+ if (!(*result = pixman_image_create_bits (
+ PIXMAN_a8, width, height, NULL, -1)))
+ {
+ status = CAIRO_INT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ pixman_add_trapezoids (*result, 0, 0,
+ proto_image->traps.n_traps,
+ proto_image->traps.traps);
+ break;
+
+ case GLYPHS:
+ format = pixman_glyph_get_mask_format (
+ proto_image->glyphs.glyph_cache,
+ proto_image->glyphs.n_glyphs,
+ proto_image->glyphs.glyphs);
+
+ if (!(*result = pixman_image_create_bits (
+ format, width, height, NULL, -1)))
+ {
+ status = CAIRO_INT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ pixman_composite_glyphs (PIXMAN_OP_SRC,
+ white_img, *result, format,
+ 0, 0, 0, 0, 0, 0, width, height,
+ proto_image->glyphs.glyph_cache,
+ proto_image->glyphs.n_glyphs,
+ proto_image->glyphs.glyphs);
+ break;
+
+ case PIXMAN:
+ *result = pixman_image_ref (proto_image->pixman.image);
+ break;
+
+ case COMPOSITE:
+ status = proto_image_resolve (
+ proto_image->composite.left, width, height, &left);
+ if (status != CAIRO_INT_STATUS_SUCCESS)
+ goto out;
+
+ status = proto_image_resolve (
+ proto_image->composite.right, width, height, &right);
+ if (status != CAIRO_INT_STATUS_SUCCESS)
+ {
+ pixman_image_unref (left);
+ goto out;
+ }
+
+ pixman_image_composite32 (
+ proto_image->composite.op,
+ left, NULL, right,
+ 0, 0, 0, 0, 0, 0, width, height);
+
+ pixman_image_unref (left);
+
+ *result = right;
+ break;
+ }
+
+out:
+ if (*result != NULL)
+ pixman_image_unref (*result);
+
+ return status;
+}
+
+static cairo_int_status_t
+composite_proto_images (pixman_op_t operator,
+ proto_image_t * source,
+ proto_image_t * mask,
+ pixman_image_t * dest_img)
+{
+ pixman_image_t *src_img, *mask_img;
+ cairo_int_status_t status;
+ int width, height;
+
+ status = proto_image_resolve (source, width, height, &src_img);
+ if (status != CAIRO_INT_STATUS_SUCCESS)
+ return status;
+
+ status = proto_image_resolve (mask, width, height, &mask_img);
+ if (status != CAIRO_INT_STATUS_SUCCESS)
+ return status;
+
+ pixman_image_composite32 (operator, src_img, mask_img, dest_img,
+ 0, 0, 0, 0, 0, 0, width, height);
+
+ pixman_image_unref (src_img);
+ pixman_image_unref (mask_img);
+
+ return CAIRO_INT_STATUS_SUCCESS;
+}
+
static void
set_properties (pixman_image_t *image, cairo_pattern_t *pattern, cairo_matrix_t *matrix)
{
@@ -545,21 +766,21 @@ set_properties (pixman_image_t *image, cairo_pattern_t *pattern, cairo_matrix_t
pixman_image_set_component_alpha (image, pattern->has_component_alpha);
}
-static cairo_int_status_t
-pimage_from_solid_pattern (cairo_solid_pattern_t *solid,
- pixman_image_t **result)
+static proto_image_t *
+pimage_from_solid_pattern (cairo_solid_pattern_t *solid)
{
pixman_color_t pcolor;
+ pixman_image_t *pimage;
pcolor.red = _cairo_color_double_to_short (solid->color.red);
pcolor.green = _cairo_color_double_to_short (solid->color.green);
pcolor.blue = _cairo_color_double_to_short (solid->color.blue);
pcolor.alpha = _cairo_color_double_to_short (solid->color.alpha);
- if (!(*result = pixman_image_create_solid_fill (&pcolor)))
- return CAIRO_INT_STATUS_NO_MEMORY;
-
- return CAIRO_INT_STATUS_SUCCESS;
+ if (!(pimage = pixman_image_create_solid_fill (&pcolor)))
+ return proto_image_new_broken ();
+ else
+ return proto_image_new_pixman (pimage);
}
typedef struct acquire_source_cleanup_t
@@ -586,13 +807,12 @@ clean_up_acquire (pixman_image_t *image, void *closure)
}
}
-static cairo_int_status_t
-pimage_from_surface_pattern (cairo_surface_pattern_t *pattern,
- pixman_image_t **result)
+static proto_image_t *
+pimage_from_surface_pattern (cairo_surface_pattern_t *pattern)
{
- pixman_image_t *simage;
- cairo_int_status_t status;
acquire_source_cleanup_t *info = NULL;
+ pixman_image_t *simage, *result;
+ cairo_int_status_t status;
status = CAIRO_INT_STATUS_SUCCESS;
@@ -633,10 +853,7 @@ pimage_from_surface_pattern (cairo_surface_pattern_t *pattern,
case CAIRO_SURFACE_TYPE_COGL:
default:
if (!(info = malloc (sizeof (acquire_source_cleanup_t))))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto out;
- }
+ return proto_image_new_broken ();
info->surface = pattern->surface;
info->image = NULL;
@@ -646,51 +863,52 @@ pimage_from_surface_pattern (cairo_surface_pattern_t *pattern,
pattern->surface, &info->image, &info->extra);
if (status != CAIRO_INT_STATUS_SUCCESS)
- goto out;
+ {
+ free (info);
+ return proto_image_new_broken();
+ }
simage = info->image->pixman_image;
break;
}
/* Then create a clone of that image */
- if (!(*result = pixman_image_create_bits (
+ if (!(result = pixman_image_create_bits (
pixman_image_get_format (simage),
pixman_image_get_width (simage),
pixman_image_get_height (simage),
pixman_image_get_data (simage),
pixman_image_get_stride (simage))))
{
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto out;
+ clean_up_acquire (NULL, info);
+
+ return proto_image_new_broken ();
}
if (info)
- pixman_image_set_destroy_function (*result, clean_up_acquire, info);
+ pixman_image_set_destroy_function (result, clean_up_acquire, info);
/* Then set the right properties on the clone */
- set_properties (*result, (cairo_pattern_t *)pattern, NULL);
-
-out:
- if (status != CAIRO_INT_STATUS_SUCCESS)
- clean_up_acquire (NULL, info);
+ set_properties (result, (cairo_pattern_t *)pattern, NULL);
- return status;
+ return proto_image_new_pixman (result);
}
#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */
-static cairo_int_status_t
-pimage_from_gradient_pattern (const cairo_gradient_pattern_t *pattern, pixman_image_t **image)
+static proto_image_t *
+pimage_from_gradient_pattern (const cairo_gradient_pattern_t *pattern)
{
pixman_gradient_stop_t *pstops;
cairo_circle_double_t extremes[2];
pixman_point_fixed_t p1, p2;
cairo_int_status_t status;
cairo_matrix_t matrix;
+ pixman_image_t *image;
unsigned int i;
if (!(pstops = malloc (pattern->n_stops * sizeof (pixman_gradient_stop_t))))
- return CAIRO_INT_STATUS_NO_MEMORY;
+ return proto_image_new_broken ();
for (i = 0; i < pattern->n_stops; i++)
{
@@ -701,7 +919,8 @@ pimage_from_gradient_pattern (const cairo_gradient_pattern_t *pattern, pixman_im
pstops[i].color.alpha = pattern->stops[i].color.alpha_short;
}
- _cairo_gradient_pattern_fit_to_range (pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes);
+ _cairo_gradient_pattern_fit_to_range (
+ pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes);
p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x);
p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y);
@@ -712,11 +931,8 @@ pimage_from_gradient_pattern (const cairo_gradient_pattern_t *pattern, pixman_im
if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR)
{
- if (!(*image = pixman_image_create_linear_gradient (
- &p1, &p2, pstops, pattern->n_stops)))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- }
+ image = pixman_image_create_linear_gradient (
+ &p1, &p2, pstops, pattern->n_stops);
}
else /* CAIRO_PATTERN_TYPE_RADIAL */
{
@@ -725,41 +941,39 @@ pimage_from_gradient_pattern (const cairo_gradient_pattern_t *pattern, pixman_im
r1 = _cairo_fixed_16_16_from_double (extremes[0].radius);
r2 = _cairo_fixed_16_16_from_double (extremes[1].radius);
- if (!(*image = pixman_image_create_radial_gradient (
- &p1, &p2, r1, r2, pstops, pattern->n_stops)))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- }
+ image = pixman_image_create_radial_gradient (
+ &p1, &p2, r1, r2, pstops, pattern->n_stops);
}
- set_properties (*image, (cairo_pattern_t *)pattern, &matrix);
-
free (pstops);
- return status;
+ if (image)
+ set_properties (image, (cairo_pattern_t *)pattern, &matrix);
+
+ return proto_image_new_pixman (image);
}
-static cairo_int_status_t
+static proto_image_t *
pimage_from_mesh_pattern (cairo_pixman_surface_t *surface,
- const cairo_mesh_pattern_t *pattern,
- pixman_image_t **image)
+ const cairo_mesh_pattern_t *pattern)
{
int width, height;
+ pixman_image_t *image;
width = pixman_image_get_width (surface->pimage);
height = pixman_image_get_height (surface->pimage);
- *image = pixman_image_create_bits (PIXMAN_a8r8g8b8, width, height, NULL, 0);
- if (unlikely (*image == NULL))
- return CAIRO_INT_STATUS_NO_MEMORY;
+ image = pixman_image_create_bits (PIXMAN_a8r8g8b8, width, height, NULL, 0);
- _cairo_mesh_pattern_rasterize (pattern,
- pixman_image_get_data (*image),
- width, height,
- pixman_image_get_stride (*image),
- 0, 0);
+ if (image)
+ {
+ _cairo_mesh_pattern_rasterize (
+ pattern, pixman_image_get_data (image),
+ width, height, pixman_image_get_stride (image),
+ 0, 0);
+ }
- return CAIRO_INT_STATUS_SUCCESS;
+ return proto_image_new_pixman (image);
}
typedef struct
@@ -786,10 +1000,9 @@ raster_source_clean_up (pixman_image_t *pixman_image,
free (info);
}
-static cairo_int_status_t
+static proto_image_t *
pimage_from_raster_source_pattern (cairo_pixman_surface_t *psurface,
- const cairo_raster_source_pattern_t *pattern,
- pixman_image_t **result)
+ const cairo_raster_source_pattern_t *pattern)
{
int width, height;
cairo_surface_t *surface;
@@ -797,8 +1010,9 @@ pimage_from_raster_source_pattern (cairo_pixman_surface_t *psurface
raster_info_t *info;
cairo_int_status_t status;
void *extra;
-
- *result = NULL;
+ pixman_image_t *result;
+
+ result = NULL;
width = pixman_image_get_width (psurface->pimage);
height = pixman_image_get_height (psurface->pimage);
@@ -807,33 +1021,37 @@ pimage_from_raster_source_pattern (cairo_pixman_surface_t *psurface
&pattern->base, &psurface->base, NULL);
if (surface == NULL || surface->status)
- return CAIRO_INT_STATUS_NO_MEMORY;
+ return proto_image_new_broken ();
status = _cairo_surface_acquire_source_image (surface, &image, &extra);
if (status != CAIRO_INT_STATUS_SUCCESS)
{
_cairo_raster_source_pattern_release (&pattern->base, surface);
- return status;
+ return proto_image_new_broken ();
}
- if (!(*result = pixman_image_create_bits (
- image->pixman_format, image->width, image->height,
- (uint32_t *) image->data, image->stride)))
+ result = pixman_image_create_bits (
+ image->pixman_format, image->width, image->height,
+ (uint32_t *) image->data, image->stride);
+
+ if (!result)
{
_cairo_surface_release_source_image (surface, image, extra);
_cairo_raster_source_pattern_release (&pattern->base, surface);
- return CAIRO_INT_STATUS_NO_MEMORY;
+ return proto_image_new_broken ();
}
- if (!(info = malloc (sizeof (*info))))
+ info = malloc (sizeof (*info));
+ if (!info)
{
- pixman_image_unref (*result);
+ pixman_image_unref (result);
+
_cairo_surface_release_source_image (surface, image, extra);
_cairo_raster_source_pattern_release (&pattern->base, surface);
- return CAIRO_INT_STATUS_NO_MEMORY;
+ return proto_image_new_broken ();
}
info->pattern = &pattern->base;
@@ -842,54 +1060,41 @@ pimage_from_raster_source_pattern (cairo_pixman_surface_t *psurface
info->extra = extra;
pixman_image_set_destroy_function (
- *result, raster_source_clean_up, info);
+ result, raster_source_clean_up, info);
- set_properties (*result, (cairo_pattern_t *)pattern, NULL);
+ set_properties (result, (cairo_pattern_t *)pattern, NULL);
- return CAIRO_INT_STATUS_SUCCESS;
+ return proto_image_new_pixman (result);
}
-static cairo_int_status_t
+static proto_image_t *
pimage_from_pattern (cairo_pixman_surface_t *surface,
- const cairo_pattern_t *pattern, pixman_image_t **image)
+ const cairo_pattern_t *pattern)
{
switch (pattern->type)
{
case CAIRO_PATTERN_TYPE_SOLID:
- return pimage_from_solid_pattern (
- (cairo_solid_pattern_t *)pattern, image);
- break;
-
+ return pimage_from_solid_pattern ((cairo_solid_pattern_t *)pattern);
case CAIRO_PATTERN_TYPE_SURFACE:
- return pimage_from_surface_pattern (
- (cairo_surface_pattern_t *)pattern, image);
- break;
-
+ return pimage_from_surface_pattern ((cairo_surface_pattern_t *)pattern);
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL:
- return pimage_from_gradient_pattern (
- (cairo_gradient_pattern_t *)pattern, image);
- break;
-
+ return pimage_from_gradient_pattern ((cairo_gradient_pattern_t *)pattern);
case CAIRO_PATTERN_TYPE_MESH:
return pimage_from_mesh_pattern (
- surface,
- (cairo_mesh_pattern_t *)pattern, image);
+ surface, (cairo_mesh_pattern_t *)pattern);
break;
case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
return pimage_from_raster_source_pattern (
- surface,
- (cairo_raster_source_pattern_t *)pattern, image);
+ surface, (cairo_raster_source_pattern_t *)pattern);
break;
}
ASSERT_NOT_REACHED;
- return CAIRO_INT_STATUS_DEGENERATE;
+ return proto_image_new_broken();
}
-static const pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff };
-
#define CAIRO_FIXED_16_16_MIN _cairo_fixed_from_int (-32768)
#define CAIRO_FIXED_16_16_MAX _cairo_fixed_from_int (32767)
@@ -991,36 +1196,23 @@ traps_to_pixman_trapezoids (const cairo_traps_t *traps)
return ptraps;
}
-static cairo_int_status_t
-create_clip_image (const cairo_clip_t *clip, int width, int height,
- proto_image_t **clip_image)
+static proto_image_t *
+create_clip_image (const cairo_clip_t *clip)
{
cairo_int_status_t status;
pixman_trapezoid_t *ptraps = NULL;
- pixman_image_t *white_img = NULL;
cairo_clip_path_t *clip_path;
+ proto_image_t *clip_image;
int i;
status = CAIRO_INT_STATUS_SUCCESS;
if (!clip)
- {
- *clip_image = NULL;
- goto out;
- }
- else if (!(*clip_image = pixman_image_create_bits (
- PIXMAN_a8, width, height, NULL, -1)))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto out;
- }
-
+ return proto_image_new_white();
+
/* First add the boxes */
if (!(ptraps = malloc (clip->num_boxes * sizeof (pixman_trapezoid_t))))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto out;
- }
+ return proto_image_new_broken();
for (i = 0; i < clip->num_boxes; ++i)
{
@@ -1040,21 +1232,16 @@ create_clip_image (const cairo_clip_t *clip, int width, int height,
trap->right.p2.x = _cairo_fixed_to_16_16 (box->p2.x);
trap->right.p2.y = _cairo_fixed_to_16_16 (box->p2.y);
}
-
- pixman_add_trapezoids (*clip_image, 0, 0, clip->num_boxes, ptraps);
-
+
+ clip_image = proto_image_new_traps (clip->num_boxes, ptraps);
+
/* Then intersect with all the paths */
- if (!(white_img = pixman_image_create_solid_fill (&white)))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto out;
- }
-
for (clip_path = clip->path; clip_path != NULL; clip_path = clip_path->prev)
{
cairo_polygon_t polygon;
cairo_traps_t traps;
pixman_trapezoid_t *ptraps = NULL;
+ proto_image_t *trap_image;
_cairo_polygon_init (&polygon, NULL, 0);
_cairo_traps_init (&traps);
@@ -1063,43 +1250,36 @@ create_clip_image (const cairo_clip_t *clip, int width, int height,
&clip_path->path, clip_path->tolerance, &polygon);
if (status != CAIRO_INT_STATUS_SUCCESS)
- goto exit_loop;
+ goto err;
status = _cairo_bentley_ottmann_tessellate_polygon (
&traps, &polygon, clip_path->fill_rule);
if (status != CAIRO_INT_STATUS_SUCCESS)
- goto exit_loop;
+ goto err;
if (!(ptraps = traps_to_pixman_trapezoids (&traps)))
{
status = CAIRO_INT_STATUS_NO_MEMORY;
- goto exit_loop;
+ goto err;
}
-
- pixman_composite_trapezoids (
- PIXMAN_OP_IN, white_img, *clip_image, PIXMAN_a8, 0, 0, 0, 0,
- traps.num_traps, ptraps);
- exit_loop:
+ trap_image = proto_image_new_traps (traps.num_traps, ptraps);
+ clip_image =
+ proto_image_new_composite (PIXMAN_OP_IN, clip_image, trap_image);
+ continue;
+
+ err:
free (ptraps);
_cairo_polygon_fini (&polygon);
_cairo_traps_fini (&traps);
- if (status != CAIRO_INT_STATUS_SUCCESS)
- break;
+ proto_image_free (clip_image);
+ clip_image = proto_image_new_broken ();
+ break;
}
-
-out:
- if (status != CAIRO_INT_STATUS_SUCCESS && *clip_image)
- pixman_image_unref (*clip_image);
-
- if (white_img)
- pixman_image_unref (white_img);
-
- free (ptraps);
- return status;
+ return clip_image;
}
static pixman_op_t
@@ -1176,106 +1356,6 @@ _pixman_operator (cairo_operator_t op)
}
static cairo_int_status_t
-proto_image_resolve (proto_image_t *proto_image, int width, int height,
- pixman_image_t **result)
-{
- cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
- pixman_image_t *white_img;
- pixman_format_code_t format;
-
- if (!(white_img = pixman_image_create_solid_fill (&white)))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto out;
- }
-
- switch (proto_image->type)
- {
- case REGION:
- if (!(*result = pixman_image_create_bits (
- PIXMAN_a8, width, height, NULL, -1)))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto out;
- }
-
- pixman_image_set_clip_region32 (*result, proto_image->region.region);
- pixman_image_composite32 (
- PIXMAN_OP_SRC, white_img, NULL, *result,
- 0, 0, 0, 0, 0, 0, width, height);
- break;
-
- case TRAPS:
- if (!(*result = pixman_image_create_bits (
- PIXMAN_a8, width, height, NULL, -1)))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto out;
- }
-
- pixman_add_trapezoids (*result, 0, 0,
- proto_image->traps.n_traps,
- proto_image->traps.traps);
- break;
-
- case GLYPHS:
- format = pixman_glyph_get_mask_format (
- proto_image->glyphs.glyph_cache,
- proto_image->glyphs.n_glyphs,
- proto_image->glyphs.glyphs);
-
- if (!(*result = pixman_image_create_bits (
- format, width, height, NULL, -1)))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
- goto out;
- }
-
- pixman_composite_glyphs (PIXMAN_OP_SRC,
- white_img, *result, format,
- 0, 0, 0, 0, 0, 0, width, height,
- proto_image->glyphs.glyph_cache,
- proto_image->glyphs.n_glyphs,
- proto_image->glyphs.glyphs);
- break;
-
- case PIXMAN:
- *result = pixman_image_ref (proto_image->pixman.image);
- break;
- }
-
-out:
- return status;
-}
-
-static cairo_int_status_t
-composite_proto_images (pixman_op_t operator,
- proto_image_t * source,
- proto_image_t * mask,
- pixman_image_t * dest_img)
-{
- pixman_image_t *src_img, *mask_img;
- cairo_int_status_t status;
- int width, height;
-
- status = proto_image_resolve (source, width, height, &src_img);
- if (status != CAIRO_INT_STATUS_SUCCESS)
- return status;
-
- status = proto_image_resolve (mask, width, height, &mask_img);
- if (status != CAIRO_INT_STATUS_SUCCESS)
- return status;
-
- pixman_image_composite32 (operator, src_img, mask_img, dest_img,
- 0, 0, 0, 0, 0, 0, width, height);
-
- pixman_image_unref (src_img);
- pixman_image_unref (mask_img);
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-static cairo_int_status_t
combine_mask_and_clip (pixman_image_t *mask_image, pixman_image_t *clip_image,
pixman_image_t **combined)
{
@@ -1314,7 +1394,7 @@ combine_mask_and_clip (pixman_image_t *mask_image, pixman_image_t *clip_image,
return CAIRO_INT_STATUS_SUCCESS;
}
-static cairo_int_status_t
+static proto_image_t *
clip_and_composite (cairo_pixman_surface_t *psurface,
cairo_operator_t operator,
const cairo_pattern_t *source,
@@ -1326,6 +1406,8 @@ clip_and_composite (cairo_pixman_surface_t *psurface,
int height = pixman_image_get_height (dest_image);
proto_image_t *src_image = NULL;
proto_image_t *clip_image = NULL;
+ proto_image_t *result = NULL;
+ proto_image_t *dest_image = NULL;
pixman_image_t *combined = NULL;
cairo_int_status_t status;
pixman_op_t pop;
@@ -1335,46 +1417,23 @@ clip_and_composite (cairo_pixman_surface_t *psurface,
if (clip && _cairo_clip_is_all_clipped (clip))
goto out;
- status = create_clip_image (clip, width, height, &clip_image);
- if (status != CAIRO_INT_STATUS_SUCCESS)
- goto out;
+ clip_image = create_clip_image (clip);
- status = pimage_from_pattern (psurface, source, &src_image);
- if (status != CAIRO_INT_STATUS_SUCCESS)
- goto out;
+ src_image = pimage_from_pattern (psurface, source);
pop = _pixman_operator (operator);
+#if 0
+ FIXME
+ dest_image = proto_image_new_dest();
+#endif
+
if (pop == PIXMAN_OP_CLEAR)
{
- if (clip_image)
- {
- pixman_image_composite32 (
- PIXMAN_OP_OUT_REVERSE,
- clip_image, mask_image, dest_image,
- 0, 0, 0, 0, 0, 0, width, height);
- }
- else if (mask_image)
- {
- pixman_image_composite32 (
- PIXMAN_OP_OUT_REVERSE,
- mask_image, NULL, dest_image,
- 0, 0, 0, 0, 0, 0, width, height);
- }
- else
- {
- if (!(combined = pixman_image_create_solid_fill (&white)))
- {
- status = CAIRO_INT_STATUS_NO_MEMORY;
-
- goto out;
- }
-
- pixman_image_composite32 (
- PIXMAN_OP_OUT_REVERSE,
- combined, NULL, dest_image,
- 0, 0, 0, 0, 0, 0, width, height);
- }
+ result = proto_image_new_composite (
+ PIXMAN_OP_IN, clip_image, mask_image);
+ result = proto_image_new_composite (
+ PIXMAN_OP_OUT_REVERSE, result, dest_image);
}
else if (clip_image &&
(pop == PIXMAN_OP_IN ||
@@ -1382,6 +1441,17 @@ clip_and_composite (cairo_pixman_surface_t *psurface,
pop == PIXMAN_OP_IN_REVERSE ||
pop == PIXMAN_OP_ATOP_REVERSE))
{
+ blank = proto_image_new_blank();
+
+ result = proto_image_new_composite (
+
+
+ result = proto_image_new_composite (
+ PIXMAN_OP_SRC, dest_image,
+
+ result = proto_image_new_composite (
+ PIXMAN_OP_SRC, dest_image, proto_image_new_blank());
+
/* First composite to a temporary surface */
if (!(combined = pixman_image_create_bits (
pixman_image_get_format (psurface->pimage),