summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-09-29 23:31:56 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-09-29 23:31:56 -0400
commitb8fe440b2fd4d91961fd3280a869a5acb7e1f38b (patch)
tree01da79e5b1b16b8466a80f3fe7d6f42490fca942
parent14dad4229aec9f68a6610f17e99da16d93f5c576 (diff)
raster source
-rw-r--r--src/cairo-pixman-surface.c87
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;
}