diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-09-29 23:31:56 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-09-29 23:31:56 -0400 |
commit | b8fe440b2fd4d91961fd3280a869a5acb7e1f38b (patch) | |
tree | 01da79e5b1b16b8466a80f3fe7d6f42490fca942 | |
parent | 14dad4229aec9f68a6610f17e99da16d93f5c576 (diff) |
raster source
-rw-r--r-- | src/cairo-pixman-surface.c | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/src/cairo-pixman-surface.c b/src/cairo-pixman-surface.c index c7b29ce6..00346e41 100644 --- a/src/cairo-pixman-surface.c +++ b/src/cairo-pixman-surface.c @@ -621,11 +621,91 @@ pimage_from_mesh_pattern (cairo_pixman_surface_t *surface, return CAIRO_INT_STATUS_SUCCESS; } +typedef struct +{ + const cairo_pattern_t *pattern; + cairo_surface_t *surface; + cairo_image_surface_t *image; + void *extra; +} raster_info_t; + +static void +raster_source_clean_up (pixman_image_t *pixman_image, + void *closure) +{ + raster_info_t *info = closure; + + _cairo_surface_release_source_image (info->surface, + info->image, + info->extra); + + _cairo_raster_source_pattern_release (info->pattern, + info->surface); + + free (info); +} + static cairo_int_status_t -pimage_from_raster_source_pattern (const cairo_raster_source_pattern_t *pattern, - pixman_image_t **image) +pimage_from_raster_source_pattern (cairo_pixman_surface_t *psurface, + const cairo_raster_source_pattern_t *pattern, + pixman_image_t **result) { - + int width, height; + cairo_surface_t *surface; + cairo_image_surface_t *image; + raster_info_t *info; + cairo_int_status_t status; + void *extra; + + *result = NULL; + + width = pixman_image_get_width (psurface->pimage); + height = pixman_image_get_height (psurface->pimage); + + surface = _cairo_raster_source_pattern_acquire ( + &pattern->base, &psurface->base, NULL); + + if (surface == NULL || surface->status) + return CAIRO_INT_STATUS_NO_MEMORY; + + 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; + } + + if (!(*result = pixman_image_create_bits ( + image->pixman_format, image->width, image->height, + (uint32_t *) image->data, image->stride))) + { + _cairo_surface_release_source_image (surface, image, extra); + _cairo_raster_source_pattern_release (&pattern->base, surface); + + return CAIRO_INT_STATUS_NO_MEMORY; + } + + if (!(info = malloc (sizeof (*info)))) + { + 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; + } + + info->pattern = &pattern->base; + info->surface = surface; + info->image = image; + info->extra = extra; + + pixman_image_set_destroy_function ( + *result, raster_source_clean_up, info); + + set_properties (*result, (cairo_pattern_t *)pattern); + + return CAIRO_INT_STATUS_SUCCESS; } static cairo_int_status_t @@ -658,6 +738,7 @@ pimage_from_pattern (cairo_pixman_surface_t *surface, case CAIRO_PATTERN_TYPE_RASTER_SOURCE: return pimage_from_raster_source_pattern ( + surface, (cairo_raster_source_pattern_t *)pattern, image); break; } |