diff options
Diffstat (limited to 'src/cairo-quartz-image-surface.c')
-rw-r--r-- | src/cairo-quartz-image-surface.c | 141 |
1 files changed, 58 insertions, 83 deletions
diff --git a/src/cairo-quartz-image-surface.c b/src/cairo-quartz-image-surface.c index e05523459..5d7f96018 100644 --- a/src/cairo-quartz-image-surface.c +++ b/src/cairo-quartz-image-surface.c @@ -49,12 +49,6 @@ #define SURFACE_ERROR_INVALID_SIZE (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_SIZE))) #define SURFACE_ERROR_INVALID_FORMAT (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_FORMAT))) -static void -DataProviderReleaseCallback (void *image_info, const void *data, size_t size) -{ - free (image_info); -} - static cairo_surface_t * _cairo_quartz_image_surface_create_similar (void *asurface, cairo_content_t content, @@ -87,8 +81,9 @@ _cairo_quartz_image_surface_finish (void *asurface) { cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface; - CGImageRelease (surface->image); - cairo_surface_destroy ( (cairo_surface_t*) surface->imageSurface); + CGContextRelease (surface->cgContext); + if (surface->imageSurface) + cairo_surface_destroy ( (cairo_surface_t*) surface->imageSurface); return CAIRO_STATUS_SUCCESS; } @@ -134,47 +129,6 @@ _cairo_quartz_image_surface_get_extents (void *asurface, return TRUE; } -/* we assume some drawing happened to the image buffer; make sure it's - * represented in the CGImage on flush() - */ - -static cairo_status_t -_cairo_quartz_image_surface_flush (void *asurface, - unsigned flags) -{ - cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface; - CGImageRef oldImage = surface->image; - CGImageRef newImage = NULL; - void *image_data; - - if (flags) - return CAIRO_STATUS_SUCCESS; - - /* XXX only flush if the image has been modified. */ - - image_data = _cairo_malloc_ab ( surface->imageSurface->height, - surface->imageSurface->stride); - if (unlikely (!image_data)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (image_data, surface->imageSurface->data, - surface->imageSurface->height * surface->imageSurface->stride); - newImage = CairoQuartzCreateCGImage (surface->imageSurface->format, - surface->imageSurface->width, - surface->imageSurface->height, - surface->imageSurface->stride, - image_data, - TRUE, - NULL, - DataProviderReleaseCallback, - image_data); - - surface->image = newImage; - CGImageRelease (oldImage); - - return CAIRO_STATUS_SUCCESS; -} - static cairo_int_status_t _cairo_quartz_image_surface_paint (void *abstract_surface, cairo_operator_t op, @@ -275,7 +229,7 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = { _cairo_quartz_image_surface_get_extents, NULL, /* get_font_options */ - _cairo_quartz_image_surface_flush, + NULL, /*surface_flush */ NULL, /* mark_dirty_rectangle */ _cairo_quartz_image_surface_paint, @@ -290,12 +244,9 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = { * cairo_quartz_image_surface_create: * @image_surface: a cairo image surface to wrap with a quartz image surface * - * Creates a Quartz surface backed by a CGImageRef that references the + * Creates a Quartz surface backed by a CGBitmapContext that references the * given image surface. The resulting surface can be rendered quickly - * when used as a source when rendering to a #cairo_quartz_surface. If - * the data in the image surface is ever updated, cairo_surface_flush() - * must be called on the #cairo_quartz_image_surface to ensure that the - * CGImageRef refers to the updated data. + * when used as a source when rendering to a #cairo_quartz_surface. * * Return value: the newly created surface. * @@ -305,13 +256,11 @@ cairo_surface_t * cairo_quartz_image_surface_create (cairo_surface_t *surface) { cairo_quartz_image_surface_t *qisurf; - - CGImageRef image; - cairo_image_surface_t *image_surface; int width, height, stride; cairo_format_t format; - void *image_data; + CGBitmapInfo bitinfo = kCGBitmapByteOrder32Host; + CGColorSpaceRef colorspace; if (surface->status) return surface; @@ -338,41 +287,22 @@ cairo_quartz_image_surface_create (cairo_surface_t *surface) if (qisurf == NULL) return SURFACE_ERROR_NO_MEMORY; - memset (qisurf, 0, sizeof(cairo_quartz_image_surface_t)); - - image_data = _cairo_malloc_ab (height, stride); - if (unlikely (!image_data)) { - free(qisurf); - return SURFACE_ERROR_NO_MEMORY; - } - - memcpy (image_data, image_surface->data, height * stride); - image = CairoQuartzCreateCGImage (format, - width, height, - stride, - image_data, - TRUE, - NULL, - DataProviderReleaseCallback, - image_data); - - if (!image) { - free (qisurf); - return SURFACE_ERROR_NO_MEMORY; - } - _cairo_surface_init (&qisurf->base, &cairo_quartz_image_surface_backend, NULL, /* device */ _cairo_content_from_format (format), FALSE); /* is_vector */ + colorspace = CGColorSpaceCreateDeviceRGB (); + bitinfo |= format == CAIRO_FORMAT_ARGB32 ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; qisurf->width = width; qisurf->height = height; - qisurf->image = image; + qisurf->cgContext = CGBitmapContextCreate (image_surface->data, width, height, 8, image_surface->stride, + colorspace, bitinfo); qisurf->imageSurface = (cairo_image_surface_t*) cairo_surface_reference(surface); + CGColorSpaceRelease (colorspace); return &qisurf->base; } @@ -401,3 +331,48 @@ cairo_quartz_image_surface_get_image (cairo_surface_t *surface) return (cairo_surface_t*) qsurface->imageSurface; } + +/* + * _cairo_quartz_image_surface_get_cg_context: + * @surface: the Cairo Quartz surface + * + * Returns the CGContextRef that the given Quartz surface is backed + * by. + * + * A call to cairo_surface_flush() is required before using the + * CGContextRef to ensure that all pending drawing operations are + * finished and to restore any temporary modification cairo has made + * to its state. A call to cairo_surface_mark_dirty() is required + * after the state or the content of the CGContextRef has been + * modified. + * + * Return value: the CGContextRef for the given surface. + * + **/ +CGContextRef +_cairo_quartz_image_surface_get_cg_context (cairo_surface_t *surface) +{ + if (surface && _cairo_surface_is_quartz_image (surface)) { + cairo_quartz_surface_t *quartz = (cairo_quartz_surface_t *) surface; + return quartz->cgContext; + } else + return NULL; +} + +/* + * _cairo_surface_is_quartz_image: + * @surface: a #cairo_surface_t + * + * Checks if a surface is a #cairo_quartz_surface_t + * + * Return value: True if the surface is an quartz surface + **/ +cairo_bool_t +_cairo_surface_is_quartz_image (const cairo_surface_t *surface) { + return surface->backend == &cairo_quartz_image_surface_backend; +} + +cairo_bool_t +_cairo_quartz_image_surface_is_zero (const cairo_quartz_image_surface_t *surface) { + return surface->width == 0 || surface->height == 0; +} |