summaryrefslogtreecommitdiff
path: root/src/cairo-image-surface.c
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2005-01-31 08:50:22 +0000
committerOwen Taylor <otaylor@redhat.com>2005-01-31 08:50:22 +0000
commit26148a1d15b710b8f2ce850f8704bf44b0c3d484 (patch)
treec34033737882df1e5c0083bc90be3f7607828f05 /src/cairo-image-surface.c
parent608a52ff9390f98a8e5269e6362f4ad8d07ec2c5 (diff)
downloadcairo-26148a1d15b710b8f2ce850f8704bf44b0c3d484.tar.gz
src/cairoint.h src/cairo_image_surface.c src/cairo_pdf_surface.c src/cairo_png_surface.c src/cairo_surface.c src/cairo_xlib_surface.c: Replace the get_image()/set_image() backend operations with a more specific {acquire,release}_{source,dest}_image() and clone_similar().
src/cairoint.h src/cairo_pattern.c: Replace _cairo_pattern_get_surface() with a _cairo_pattern_begin_draw()/_cairo_pattern_end_draw() pair. Save the format for which an image is created so we can access it later. (Needed for the _cairo_xlib_surface_clone_similar()) src/cairoint.h src/cairo_image_surface.c: Add _cairo_surface_is_image(). Add CAIRO_OK(status) to check for CAIRO_STATUS_SUCCESS. In the absence of of RENDER, make cairo_xlib_surface_create_similar() return an image surface. Don't try to use RENDER to composite glyphs in the absence of the RENDER extension.
Diffstat (limited to 'src/cairo-image-surface.c')
-rw-r--r--src/cairo-image-surface.c160
1 files changed, 114 insertions, 46 deletions
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 9a322fe80..8a0b8466d 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -54,7 +54,8 @@ _cairo_format_bpp (cairo_format_t format)
}
static cairo_image_surface_t *
-_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image)
+_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
+ cairo_format_t format)
{
cairo_image_surface_t *surface;
@@ -66,6 +67,7 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image)
surface->pixman_image = pixman_image;
+ surface->format = format;
surface->data = (char *) pixman_image_get_data (pixman_image);
surface->owns_data = 0;
@@ -105,7 +107,8 @@ _cairo_image_surface_create_with_masks (char *data,
if (pixman_image == NULL)
return NULL;
- surface = _cairo_image_surface_create_for_pixman_image (pixman_image);
+ surface = _cairo_image_surface_create_for_pixman_image (pixman_image,
+ (cairo_format_t)-1);
return surface;
}
@@ -150,7 +153,7 @@ cairo_image_surface_create (cairo_format_t format,
if (pixman_image == NULL)
return NULL;
- surface = _cairo_image_surface_create_for_pixman_image (pixman_image);
+ surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
return &surface->base;
}
@@ -180,7 +183,7 @@ cairo_image_surface_create_for_data (char *data,
if (pixman_image == NULL)
return NULL;
- surface = _cairo_image_surface_create_for_pixman_image (pixman_image);
+ surface = _cairo_image_surface_create_for_pixman_image (pixman_image, format);
return &surface->base;
}
@@ -224,25 +227,66 @@ _cairo_image_surface_pixels_per_inch (void *abstract_surface)
return 96.0;
}
-static cairo_image_surface_t *
-_cairo_image_surface_get_image (void *abstract_surface)
+static cairo_status_t
+_cairo_image_surface_acquire_source_image (void *abstract_surface,
+ cairo_image_surface_t **image_out,
+ void **image_extra)
+{
+ *image_out = abstract_surface;
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_image_surface_release_source_image (void *abstract_surface,
+ cairo_image_surface_t *image,
+ void *image_extra)
+{
+}
+
+static cairo_status_t
+_cairo_image_surface_acquire_dest_image (void *abstract_surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t **image_out,
+ cairo_rectangle_t *image_rect_out,
+ void **image_extra)
{
cairo_image_surface_t *surface = abstract_surface;
+
+ image_rect_out->x = 0;
+ image_rect_out->y = 0;
+ image_rect_out->width = surface->width;
+ image_rect_out->height = surface->height;
- cairo_surface_reference (&surface->base);
+ *image_out = surface;
- return surface;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_image_surface_release_dest_image (void *abstract_surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t *image,
+ cairo_rectangle_t *image_rect,
+ void *image_extra)
+{
}
static cairo_status_t
-_cairo_image_surface_set_image (void *abstract_surface,
- cairo_image_surface_t *image)
+_cairo_image_surface_clone_similar (void *abstract_surface,
+ cairo_surface_t *src,
+ cairo_surface_t **clone_out)
{
- if (image == abstract_surface)
- return CAIRO_STATUS_SUCCESS;
+ cairo_image_surface_t *surface = abstract_surface;
- /* XXX: This case has not yet been implemented. We'll lie for now. */
- return CAIRO_STATUS_SUCCESS;
+ if (src->backend == surface->base.backend) {
+ *clone_out = src;
+ cairo_surface_reference (src);
+
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_status_t
@@ -382,30 +426,40 @@ _cairo_image_surface_composite (cairo_operator_t operator,
{
cairo_image_surface_t *dst = abstract_dst;
cairo_image_surface_t *src;
- cairo_image_surface_t *mask = (cairo_image_surface_t *) generic_mask;
- int x_offset, y_offset;
-
- src = (cairo_image_surface_t *)
- _cairo_pattern_get_surface (pattern, &dst->base,
- src_x, src_y, width, height,
- &x_offset, &y_offset);
- if (src == NULL)
- return CAIRO_STATUS_NO_MEMORY; /* Or not supported? */
-
- if (generic_mask && (generic_mask->backend != dst->base.backend))
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ cairo_image_surface_t *mask = NULL;
+ void *mask_extra;
+ cairo_pattern_info_t pattern_info;
+ cairo_status_t status;
+
+ status = _cairo_pattern_begin_draw (pattern, &pattern_info,
+ &dst->base,
+ src_x, src_y, width, height);
+ if (!CAIRO_OK (status))
+ return status;
+
+ src = (cairo_image_surface_t *)pattern_info.src;
+
+ /* XXX This stuff can go when we change the mask to be a pattern also. */
+ if (generic_mask) {
+ status = _cairo_surface_acquire_source_image (generic_mask, &mask, &mask_extra);
+ if (!CAIRO_OK (status))
+ goto FAIL;
+ }
pixman_composite (_pixman_operator (operator),
src->pixman_image,
mask ? mask->pixman_image : NULL,
dst->pixman_image,
- src_x - x_offset, src_y - y_offset,
+ src_x - pattern_info.x_offset, src_y - pattern_info.y_offset,
mask_x, mask_y,
dst_x, dst_y,
width, height);
- cairo_surface_destroy (&src->base);
-
+ if (mask)
+ _cairo_surface_release_source_image (generic_mask, mask, mask_extra);
+ FAIL:
+ _cairo_pattern_end_draw (pattern, &pattern_info);
+
return CAIRO_STATUS_SUCCESS;
}
@@ -447,19 +501,18 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
{
cairo_image_surface_t *dst = abstract_dst;
cairo_image_surface_t *src;
- int x_offset, y_offset;
+ cairo_pattern_info_t pattern_info;
int render_reference_x, render_reference_y;
int render_src_x, render_src_y;
+ cairo_status_t status;
- src = (cairo_image_surface_t *)
- _cairo_pattern_get_surface (pattern, &dst->base,
- src_x, src_y,
- width, height,
- &x_offset, &y_offset);
- if (src == NULL)
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ status = _cairo_pattern_begin_draw (pattern, &pattern_info,
+ &dst->base,
+ src_x, src_y, width, height);
+ if (!CAIRO_OK (status))
+ return status;
- _cairo_pattern_prepare_surface (pattern, &src->base);
+ src = (cairo_image_surface_t *)pattern_info.src;
if (traps[0].left.p1.y < traps[0].left.p2.y) {
render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p1.x);
@@ -477,13 +530,11 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator,
pixman_composite_trapezoids (operator,
src->pixman_image,
dst->pixman_image,
- render_src_x - x_offset,
- render_src_y - y_offset,
+ render_src_x - pattern_info.x_offset,
+ render_src_y - pattern_info.y_offset,
(pixman_trapezoid_t *) traps, num_traps);
- _cairo_pattern_restore_surface (pattern, &src->base);
-
- cairo_surface_destroy (&src->base);
+ _cairo_pattern_end_draw (pattern, &pattern_info);
return CAIRO_STATUS_SUCCESS;
}
@@ -530,13 +581,30 @@ _cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
-
+
+/**
+ * _cairo_surface_is_image:
+ * @surface: a #cairo_surface_t
+ *
+ * Checks if a surface is an #cairo_image_surface_t
+ *
+ * Return value: True if the surface is an image surface
+ **/
+int
+_cairo_surface_is_image (cairo_surface_t *surface)
+{
+ return surface->backend == &cairo_image_surface_backend;
+}
+
static const cairo_surface_backend_t cairo_image_surface_backend = {
_cairo_image_surface_create_similar,
_cairo_image_abstract_surface_destroy,
_cairo_image_surface_pixels_per_inch,
- _cairo_image_surface_get_image,
- _cairo_image_surface_set_image,
+ _cairo_image_surface_acquire_source_image,
+ _cairo_image_surface_release_source_image,
+ _cairo_image_surface_acquire_dest_image,
+ _cairo_image_surface_release_dest_image,
+ _cairo_image_surface_clone_similar,
_cairo_image_abstract_surface_set_matrix,
_cairo_image_abstract_surface_set_filter,
_cairo_image_abstract_surface_set_repeat,