[cairo-commit] cairo/src cairo_image_surface.c, 1.22,
1.23 cairo_pattern.c, 1.17, 1.18 cairo_pdf_surface.c, 1.10,
1.11 cairo_png_surface.c, 1.13, 1.14 cairo_ps_surface.c, 1.20,
1.21 cairo_surface.c, 1.38, 1.39 cairo_xlib_surface.c, 1.42,
1.43 cairoint.h, 1.91, 1.92
Owen Taylor
commit at pdx.freedesktop.org
Mon Jan 31 08:50:24 PST 2005
Committed by: otaylor
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv20332/src
Modified Files:
cairo_image_surface.c cairo_pattern.c cairo_pdf_surface.c
cairo_png_surface.c cairo_ps_surface.c cairo_surface.c
cairo_xlib_surface.c cairoint.h
Log Message:
2005-01-31 Owen Taylor <otaylor at redhat.com>
* 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.
* src/cairo_image_surface.c: 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().
* src/cairoint.h: Add CAIRO_OK(status) to check
for CAIRO_STATUS_SUCCESS.
* src/cairo_xlib_surface.c: In the absence of of
RENDER, make cairo_xlib_surface_create_similar()
return an image surface.
* src/cairo_xlib_surface.c: Don't try to use RENDER
to composite glyphs in the absence of the RENDER
extension.
Index: cairo_image_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_image_surface.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- cairo_image_surface.c 28 Jan 2005 03:57:32 -0000 1.22
+++ cairo_image_surface.c 31 Jan 2005 16:50:22 -0000 1.23
@@ -54,7 +54,8 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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_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;
+ cairo_image_surface_t *mask = NULL;
+ void *mask_extra;
+ cairo_pattern_info_t pattern_info;
+ 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_STATUS_NO_MEMORY; /* Or not supported? */
+ status = _cairo_pattern_begin_draw (pattern, &pattern_info,
+ &dst->base,
+ src_x, src_y, width, height);
+ if (!CAIRO_OK (status))
+ return status;
- if (generic_mask && (generic_mask->backend != dst->base.backend))
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ 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_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 @@
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 @@
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,
Index: cairo_pattern.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_pattern.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cairo_pattern.c 30 Jan 2005 19:28:14 -0000 1.17
+++ cairo_pattern.c 31 Jan 2005 16:50:22 -0000 1.18
@@ -670,164 +670,246 @@
}
}
}
-
-cairo_surface_t *
-_cairo_pattern_get_surface (cairo_pattern_t *pattern,
- cairo_surface_t *dst,
- int x,
- int y,
- unsigned int width,
- unsigned int height,
- int *x_offset,
- int *y_offset)
+
+static cairo_status_t
+_cairo_pattern_begin_draw_gradient (cairo_pattern_t *pattern,
+ cairo_pattern_info_t *info,
+ cairo_surface_t *dst,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
{
- cairo_surface_t *surface, *src;
cairo_image_surface_t *image;
cairo_status_t status;
char *data;
+
+ data = malloc (width * height * 4);
+ if (!data)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ if (pattern->type == CAIRO_PATTERN_RADIAL)
+ _cairo_image_data_set_radial (pattern, x, y, (int *) data,
+ width, height);
+ else
+ _cairo_image_data_set_linear (pattern, x, y, (int *) data,
+ width, height);
- *x_offset = 0;
- *y_offset = 0;
-
- switch (pattern->type) {
- case CAIRO_PATTERN_LINEAR:
- case CAIRO_PATTERN_RADIAL:
- data = malloc (width * height * 4);
- if (!data)
- return NULL;
-
- if (pattern->type == CAIRO_PATTERN_RADIAL)
- _cairo_image_data_set_radial (pattern, x, y, (int *) data,
- width, height);
- else
- _cairo_image_data_set_linear (pattern, x, y, (int *) data,
- width, height);
+ info->x_offset = x;
+ info->y_offset = y;
- *x_offset = x;
- *y_offset = y;
+ image = (cairo_image_surface_t *)
+ cairo_image_surface_create_for_data (data,
+ CAIRO_FORMAT_ARGB32,
+ width, height,
+ width * 4);
+
+ if (image == NULL) {
+ free (data);
+ return CAIRO_STATUS_NO_MEMORY;
+ }
- image = (cairo_image_surface_t *)
- cairo_image_surface_create_for_data (data,
- CAIRO_FORMAT_ARGB32,
- width, height,
- width * 4);
+ _cairo_image_surface_assume_ownership_of_data (image);
+
+ status = _cairo_surface_clone_similar (dst, &image->base, &info->src);
+ info->acquired = 0;
- if (image == NULL) {
- free (data);
- return NULL;
- }
-
- _cairo_image_surface_assume_ownership_of_data (image);
- if (image->base.backend == dst->backend)
- return &image->base;
-
- surface = cairo_surface_create_similar (dst,
- CAIRO_FORMAT_ARGB32,
- width, height);
- if (surface == NULL) {
- cairo_surface_destroy (&image->base);
- return NULL;
- }
-
- _cairo_surface_set_image (surface, image);
- cairo_surface_destroy (&image->base);
-
- return surface;
-
- case CAIRO_PATTERN_SOLID:
- surface = _cairo_surface_create_similar_solid (dst,
- CAIRO_FORMAT_ARGB32,
- 1, 1,
- &pattern->color);
- if (surface == NULL)
- return NULL;
-
- cairo_surface_set_repeat (surface, 1);
- return surface;
-
- case CAIRO_PATTERN_SURFACE:
- /* handle pattern opacity */
- if (pattern->color.alpha != 1.0) {
- cairo_surface_t *alpha_surface;
- double save_alpha;
- int save_repeat;
+ cairo_surface_destroy (&image->base);
+
+ return status;
+}
- surface = cairo_surface_create_similar (dst,
- CAIRO_FORMAT_ARGB32,
- width, height);
- if (surface == NULL)
- return NULL;
+static cairo_status_t
+_cairo_pattern_begin_draw_solid (cairo_pattern_t *pattern,
+ cairo_pattern_info_t *info,
+ cairo_surface_t *dst,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ info->x_offset = 0;
+ info->y_offset = 0;
- alpha_surface =
- _cairo_surface_create_similar_solid (surface,
- CAIRO_FORMAT_A8,
+ info->src = _cairo_surface_create_similar_solid (dst,
+ CAIRO_FORMAT_ARGB32,
1, 1,
&pattern->color);
- if (alpha_surface == NULL) {
- cairo_surface_destroy (surface);
- return NULL;
- }
-
- cairo_surface_set_repeat (alpha_surface, 1);
-
- save_repeat = pattern->u.surface.surface->repeat;
- if (pattern->extend == CAIRO_EXTEND_REPEAT ||
- pattern->u.surface.surface->repeat == 1)
- cairo_surface_set_repeat (pattern->u.surface.surface, 1);
- else
- cairo_surface_set_repeat (pattern->u.surface.surface, 0);
-
- save_alpha = pattern->color.alpha;
- pattern->color.alpha = 1.0;
+ info->acquired = 0;
+
+ if (info->src == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
- status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
- pattern,
- alpha_surface,
- surface,
- x, y, 0, 0, 0, 0,
- width, height);
+ cairo_surface_set_repeat (info->src, 1);
+
+ return CAIRO_STATUS_SUCCESS;
+}
- pattern->color.alpha = save_alpha;
+static cairo_status_t
+_cairo_pattern_begin_draw_surface (cairo_pattern_t *pattern,
+ cairo_pattern_info_t *info,
+ cairo_surface_t *dst,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ cairo_surface_t *surface;
+ cairo_status_t status;
- cairo_surface_set_repeat (pattern->u.surface.surface,
- save_repeat);
-
- cairo_surface_destroy (alpha_surface);
+ /* handle pattern opacity */
+ if (pattern->color.alpha != 1.0) {
+ cairo_surface_t *alpha_surface;
+ double save_alpha;
+ int save_repeat;
+
+ surface = cairo_surface_create_similar (dst,
+ CAIRO_FORMAT_ARGB32,
+ width, height);
+ if (surface == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ alpha_surface =
+ _cairo_surface_create_similar_solid (surface,
+ CAIRO_FORMAT_A8,
+ 1, 1,
+ &pattern->color);
+ if (alpha_surface == NULL) {
+ cairo_surface_destroy (surface);
+ return CAIRO_STATUS_NO_MEMORY;
+ }
+
+ cairo_surface_set_repeat (alpha_surface, 1);
+
+ save_repeat = pattern->u.surface.surface->repeat;
+ if (pattern->extend == CAIRO_EXTEND_REPEAT ||
+ pattern->u.surface.surface->repeat == 1)
+ cairo_surface_set_repeat (pattern->u.surface.surface, 1);
+ else
+ cairo_surface_set_repeat (pattern->u.surface.surface, 0);
+
+ save_alpha = pattern->color.alpha;
+ pattern->color.alpha = 1.0;
+
+ status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
+ pattern,
+ alpha_surface,
+ surface,
+ x, y, 0, 0, 0, 0,
+ width, height);
+
+ pattern->color.alpha = save_alpha;
+
+ cairo_surface_set_repeat (pattern->u.surface.surface,
+ save_repeat);
+
+ cairo_surface_destroy (alpha_surface);
- if (status == CAIRO_STATUS_SUCCESS) {
- *x_offset = x;
- *y_offset = y;
- return surface;
- }
- else {
- cairo_surface_destroy (surface);
- return NULL;
- }
+ if (status == CAIRO_STATUS_SUCCESS) {
+ info->src = surface;
+ info->acquired = 0;
+ info->x_offset = x;
+ info->y_offset = y;
} else {
- src = pattern->u.surface.surface;
- if (src->backend == dst->backend) {
- cairo_surface_reference (src);
- return src;
+ cairo_surface_destroy (surface);
+ }
+
+ return status;
+ } else {
+ if (_cairo_surface_is_image (dst)) {
+ cairo_image_surface_t *image;
+
+ status = _cairo_surface_acquire_source_image (pattern->u.surface.surface,
+ &image, &info->extra);
+ if (CAIRO_OK (status)) {
+ info->src = &image->base;
+ info->acquired = 1;
+ info->x_offset = 0;
+ info->y_offset = 0;
}
-
- image = _cairo_surface_get_image (src);
- surface = cairo_surface_create_similar (dst,
- CAIRO_FORMAT_ARGB32,
- image->width, image->height);
- if (surface == NULL)
- return NULL;
-
- cairo_surface_set_filter (surface, cairo_surface_get_filter(src));
- _cairo_surface_set_image (surface, image);
- cairo_surface_set_matrix (surface, &(image->base.matrix));
- cairo_surface_set_repeat (surface, image->base.repeat);
- cairo_surface_destroy (&image->base);
+ return status;
+ } else {
+ status = _cairo_surface_clone_similar (dst, pattern->u.surface.surface,
+ &info->src);
+ info->acquired = 0;
+ info->x_offset = 0;
+ info->y_offset = 0;
- return surface;
+ return status;
}
+ }
+}
+/**
+ * _cairo_pattern_begin_draw:
+ * @pattern: a #cairo_pattern_t
+ * @info: a structure to fill in with information about the drawing operation
+ * @dst: destination surface
+ * @x: X coordinate in source corresponding to left side of destination area
+ * @y: Y coordinate in source corresponding to top side of destination area
+ * @width: width and height of destination area
+ * @height: height of destination area
+ *
+ * A convenience function to obtain a surface (stored in @info->src) to use as
+ * the source for drawing on @dst. If the pattern contains a surface and that
+ * surface is being used directly, it's attributes may be temporarily modified
+ * to match the pattern.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS on success. Otherwise an error such
+ * as CAIRO_STATUS_NO_MEMORY or CAIRO_INT_STATUS_UNSUPPORTED.
+ **/
+cairo_status_t
+_cairo_pattern_begin_draw (cairo_pattern_t *pattern,
+ cairo_pattern_info_t *info,
+ cairo_surface_t *dst,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ cairo_status_t status;
+
+ switch (pattern->type) {
+ case CAIRO_PATTERN_LINEAR:
+ case CAIRO_PATTERN_RADIAL:
+ status = _cairo_pattern_begin_draw_gradient (pattern, info, dst, x, y, width, height);
+ break;
+ case CAIRO_PATTERN_SOLID:
+ status = _cairo_pattern_begin_draw_solid (pattern, info, dst, x, y, width, height);
+ break;
+ case CAIRO_PATTERN_SURFACE:
+ status = _cairo_pattern_begin_draw_surface (pattern, info, dst, x, y, width, height);
+ break;
default:
- return NULL;
+ return CAIRO_INT_STATUS_UNSUPPORTED;
}
+
+ if (CAIRO_OK (status))
+ _cairo_pattern_prepare_surface (pattern, info->src);
+
+ return status;
+}
+
+/**
+ * _cairo_pattern_end_draw:
+ * @pattern: a #cairo_pattern_t
+ * @info: pointer to #cairo_pattern_info_t filled in by
+ * _cairo_pattern_begin_draw
+ *
+ * Releases resources obtained by _cairo_pattern_begin_draw() and restores
+ * the pattern to its original form.
+ **/
+void
+_cairo_pattern_end_draw (cairo_pattern_t *pattern,
+ cairo_pattern_info_t *info)
+{
+ _cairo_pattern_restore_surface (pattern, info->src);
+
+ if (info->acquired)
+ _cairo_surface_release_source_image (pattern->u.surface.surface,
+ (cairo_image_surface_t *)info->src,
+ info->extra);
+ else
+ cairo_surface_destroy (info->src);
}
Index: cairo_pdf_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_pdf_surface.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- cairo_pdf_surface.c 27 Jan 2005 18:46:20 -0000 1.10
+++ cairo_pdf_surface.c 31 Jan 2005 16:50:22 -0000 1.11
@@ -1098,15 +1098,44 @@
}
}
-static cairo_image_surface_t *
-_cairo_pdf_surface_get_image (void *abstract_surface)
+static cairo_status_t
+_cairo_pdf_surface_acquire_source_image (void *abstract_surface,
+ cairo_image_surface_t **image_out,
+ void **image_extra)
+{
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
+static void
+_cairo_pdf_surface_release_source_image (void *abstract_surface,
+ cairo_image_surface_t *image,
+ void *image_extra)
{
- return NULL;
}
static cairo_status_t
-_cairo_pdf_surface_set_image (void *abstract_surface,
- cairo_image_surface_t *image)
+_cairo_pdf_surface_acquire_dest_image (void *abstract_surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t **image_out,
+ cairo_rectangle_t *image_rect,
+ void **image_extra)
+{
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+}
+
+static void
+_cairo_pdf_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_pdf_surface_clone_similar (void *abstract_surface,
+ cairo_surface_t *src,
+ cairo_surface_t **clone_out)
{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -1303,20 +1332,29 @@
unsigned int height)
{
cairo_pdf_surface_t *dst = abstract_dst;
- cairo_pdf_surface_t *src;
- cairo_image_surface_t *image;
+ cairo_surface_t *src;
if (pattern->type != CAIRO_PATTERN_SURFACE)
return CAIRO_INT_STATUS_UNSUPPORTED;
- src = (cairo_pdf_surface_t *) pattern->u.surface.surface;
+ src = pattern->u.surface.surface;
- if (src->base.backend == &cairo_pdf_surface_backend) {
- return _cairo_pdf_surface_composite_pdf (dst, src, width, height);
+ if (src->backend == &cairo_pdf_surface_backend) {
+ return _cairo_pdf_surface_composite_pdf (dst,
+ (cairo_pdf_surface_t *)src,
+ width, height);
}
else {
- image = _cairo_surface_get_image (&src->base);
- return _cairo_pdf_surface_composite_image (dst, image);
+ cairo_status_t status;
+ cairo_image_surface_t *image;
+ void *image_extra;
+
+ status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
+ if (!CAIRO_OK (status))
+ return status;
+ status = _cairo_pdf_surface_composite_image (dst, image);
+ _cairo_surface_release_source_image (src, image, image_extra);
+ return status;
}
}
@@ -1357,6 +1395,8 @@
FILE *file = document->file;
cairo_pdf_stream_t *stream;
cairo_image_surface_t *image;
+ void *image_extra;
+ cairo_status_t status;
char entries[250];
unsigned int id, alpha;
cairo_matrix_t pm;
@@ -1364,8 +1404,10 @@
if (pattern->u.surface.surface->backend == &cairo_pdf_surface_backend) {
return;
}
-
- image = _cairo_surface_get_image (pattern->u.surface.surface);
+
+ status = _cairo_surface_acquire_source_image (pattern->u.surface.surface, &image, &image_extra);
+ if (!CAIRO_OK (status))
+ return;
_cairo_pdf_document_close_stream (document);
@@ -1402,6 +1444,8 @@
fprintf (file,
"/Pattern cs /res%d scn /a%d gs\r\n",
stream->id, alpha);
+
+ _cairo_surface_release_source_image (pattern->u.surface.surface, image, image_extra);
}
static unsigned int
@@ -1750,8 +1794,11 @@
_cairo_pdf_surface_create_similar,
_cairo_pdf_surface_destroy,
_cairo_pdf_surface_pixels_per_inch,
- _cairo_pdf_surface_get_image,
- _cairo_pdf_surface_set_image,
+ _cairo_pdf_surface_acquire_source_image,
+ _cairo_pdf_surface_release_source_image,
+ _cairo_pdf_surface_acquire_dest_image,
+ _cairo_pdf_surface_release_dest_image,
+ _cairo_pdf_surface_clone_similar,
_cairo_pdf_surface_set_matrix,
_cairo_pdf_surface_set_filter,
_cairo_pdf_surface_set_repeat,
Index: cairo_png_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_png_surface.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- cairo_png_surface.c 28 Jan 2005 20:27:23 -0000 1.13
+++ cairo_png_surface.c 31 Jan 2005 16:50:22 -0000 1.14
@@ -185,28 +185,58 @@
return 96.0;
}
-static cairo_image_surface_t *
-_cairo_png_surface_get_image (void *abstract_surface)
+static cairo_status_t
+_cairo_png_surface_acquire_source_image (void *abstract_surface,
+ cairo_image_surface_t **image_out,
+ void **image_extra)
{
cairo_png_surface_t *surface = abstract_surface;
+
+ *image_out = surface->image;
- cairo_surface_reference (&surface->image->base);
+ return CAIRO_STATUS_SUCCESS;
+}
- return surface->image;
+static void
+_cairo_png_surface_release_source_image (void *abstract_surface,
+ cairo_image_surface_t *image,
+ void *image_extra)
+{
}
static cairo_status_t
-_cairo_png_surface_set_image (void *abstract_surface,
- cairo_image_surface_t *image)
+_cairo_png_surface_acquire_dest_image (void *abstract_surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t **image_out,
+ cairo_rectangle_t *image_rect,
+ void **image_extra)
{
cairo_png_surface_t *surface = abstract_surface;
+
+ image_rect->x = 0;
+ image_rect->y = 0;
+ image_rect->width = surface->image->width;
+ image_rect->height = surface->image->height;
+
+ *image_out = surface->image;
- if (image == surface->image)
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_STATUS_SUCCESS;
+}
- /* XXX: Need to call _cairo_image_surface_set_image here, but it's
- not implemented yet. */
+static void
+_cairo_png_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_png_surface_clone_similar (void *abstract_surface,
+ cairo_surface_t *src,
+ cairo_surface_t **clone_out)
+{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -405,8 +435,11 @@
_cairo_png_surface_create_similar,
_cairo_png_surface_destroy,
_cairo_png_surface_pixels_per_inch,
- _cairo_png_surface_get_image,
- _cairo_png_surface_set_image,
+ _cairo_png_surface_acquire_source_image,
+ _cairo_png_surface_release_source_image,
+ _cairo_png_surface_acquire_dest_image,
+ _cairo_png_surface_release_dest_image,
+ _cairo_png_surface_clone_similar,
_cairo_png_surface_set_matrix,
_cairo_png_surface_set_filter,
_cairo_png_surface_set_repeat,
Index: cairo_ps_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ps_surface.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- cairo_ps_surface.c 30 Jan 2005 19:37:48 -0000 1.20
+++ cairo_ps_surface.c 31 Jan 2005 16:50:22 -0000 1.21
@@ -208,28 +208,58 @@
return surface->y_ppi;
}
-static cairo_image_surface_t *
-_cairo_ps_surface_get_image (void *abstract_surface)
+static cairo_status_t
+_cairo_ps_surface_acquire_source_image (void *abstract_surface,
+ cairo_image_surface_t **image_out,
+ void **image_extra)
{
cairo_ps_surface_t *surface = abstract_surface;
+
+ *image_out = surface->image;
- cairo_surface_reference (&surface->image->base);
+ return CAIRO_STATUS_SUCCESS;
+}
- return surface->image;
+static void
+_cairo_ps_surface_release_source_image (void *abstract_surface,
+ cairo_image_surface_t *image,
+ void *image_extra)
+{
}
static cairo_status_t
-_cairo_ps_surface_set_image (void *abstract_surface,
- cairo_image_surface_t *image)
+_cairo_ps_surface_acquire_dest_image (void *abstract_surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t **image_out,
+ cairo_rectangle_t *image_rect,
+ void **image_extra)
{
cairo_ps_surface_t *surface = abstract_surface;
+
+ image_rect->x = 0;
+ image_rect->y = 0;
+ image_rect->width = surface->image->width;
+ image_rect->height = surface->image->height;
+
+ *image_out = surface->image;
- if (image == surface->image)
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_STATUS_SUCCESS;
+}
- /* XXX: Need to call _cairo_image_surface_set_image here, but it's
- not implemented yet. */
+static void
+_cairo_ps_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_ps_surface_clone_similar (void *abstract_surface,
+ cairo_surface_t *src,
+ cairo_surface_t **clone_out)
+{
return CAIRO_INT_STATUS_UNSUPPORTED;
}
@@ -262,7 +292,7 @@
static cairo_int_status_t
_cairo_ps_surface_composite (cairo_operator_t operator,
- cairo_surface_t *generic_src,
+ cairo_pattern_t *src,
cairo_surface_t *generic_mask,
void *abstract_dst,
int src_x,
@@ -425,8 +455,11 @@
_cairo_ps_surface_create_similar,
_cairo_ps_surface_destroy,
_cairo_ps_surface_pixels_per_inch,
- _cairo_ps_surface_get_image,
- _cairo_ps_surface_set_image,
+ _cairo_ps_surface_acquire_source_image,
+ _cairo_ps_surface_release_source_image,
+ _cairo_ps_surface_acquire_dest_image,
+ _cairo_ps_surface_release_dest_image,
+ _cairo_ps_surface_clone_similar,
_cairo_ps_surface_set_matrix,
_cairo_ps_surface_set_filter,
_cairo_ps_surface_set_repeat,
Index: cairo_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_surface.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- cairo_surface.c 27 Jan 2005 18:46:20 -0000 1.38
+++ cairo_surface.c 31 Jan 2005 16:50:22 -0000 1.39
@@ -151,16 +151,151 @@
return surface->backend->pixels_per_inch (surface);
}
-cairo_image_surface_t *
-_cairo_surface_get_image (cairo_surface_t *surface)
+/**
+ * _cairo_surface_acquire_source_image:
+ * @surface: a #cairo_surface_t
+ * @image_out: location to store a pointer to an image surface that includes at least
+ * the intersection of @interest_rect with the visible area of @surface.
+ * This surface could be @surface itself, a surface held internal to @surface,
+ * or it could be a new surface with a copy of the relevant portion of @surface.
+ * @image_extra: location to store image specific backend data
+ *
+ * Gets an image surface to use when drawing as a fallback when drawing with
+ * @surface as a source. _cairo_surface_release_source_image() must be called
+ * when finished.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS if a an image was stored in @image_out.
+ * %CAIRO_INT_STATUS_UNSUPPORTED if an image cannot be retrieved for the specified
+ * surface. Or %CAIRO_STATUS_NO_MEMORY.
+ **/
+cairo_private cairo_status_t
+_cairo_surface_acquire_source_image (cairo_surface_t *surface,
+ cairo_image_surface_t **image_out,
+ void **image_extra)
{
- return surface->backend->get_image (surface);
+ return surface->backend->acquire_source_image (surface, image_out, image_extra);
}
+/**
+ * _cairo_surface_release_source_image:
+ * @surface: a #cairo_surface_t
+ * @image_extra: same as return from the matching _cairo_surface_acquire_dest_image()
+ *
+ * Releases any resources obtained with _cairo_surface_acquire_source_image()
+ **/
+cairo_private void
+_cairo_surface_release_source_image (cairo_surface_t *surface,
+ cairo_image_surface_t *image,
+ void *image_extra)
+{
+ surface->backend->release_source_image (surface, image, image_extra);
+}
+
+/**
+ * _cairo_surface_acquire_dest_image:
+ * @surface: a #cairo_surface_t
+ * @interest_rect: area of @surface for which fallback drawing is being done.
+ * A value of %NULL indicates that the entire surface is desired.
+ * @image_out: location to store a pointer to an image surface that includes at least
+ * the intersection of @interest_rect with the visible area of @surface.
+ * This surface could be @surface itself, a surface held internal to @surface,
+ * or it could be a new surface with a copy of the relevant portion of @surface.
+ * @image_rect: location to store area of the original surface occupied
+ * by the surface stored in @image.
+ * @image_extra: location to store image specific backend data
+ *
+ * Retrieves a local image for a surface for implementing a fallback drawing
+ * operation. After calling this function, the implementation of the fallback
+ * drawing operation draws the primitive to the surface stored in @image_out
+ * then calls _cairo_surface_release_dest_fallback(),
+ * which, if a temporary surface was created, copies the bits back to the
+ * main surface and frees the temporary surface.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY.
+ * %CAIRO_INT_STATUS_UNSUPPORTED can be returned but this will mean that
+ * the backend can't draw with fallbacks. It's possible for the routine
+ * to store NULL in @local_out and return %CAIRO_STATUS_SUCCESS;
+ * that indicates that no part of @interest_rect is visible, so no drawing
+ * is necessary. _cairo_surface_release_dest_fallback() should not be called in that
+ * case.
+ **/
cairo_status_t
-_cairo_surface_set_image (cairo_surface_t *surface, cairo_image_surface_t *image)
+_cairo_surface_acquire_dest_image (cairo_surface_t *surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t **image_out,
+ cairo_rectangle_t *image_rect,
+ void **image_extra)
{
- return surface->backend->set_image (surface, image);
+ return surface->backend->acquire_dest_image (surface, interest_rect,
+ image_out, image_rect, image_extra);
+}
+
+/**
+ * _cairo_surface_end_fallback:
+ * @surface: a #cairo_surface_t
+ * @interest_rect: same as passed to the matching _cairo_surface_acquire_dest_image()
+ * @image: same as returned from the matching _cairo_surface_acquire_dest_image()
+ * @image_rect: same as returned from the matching _cairo_surface_acquire_dest_image()
+ * @image_extra: same as return from the matching _cairo_surface_acquire_dest_image()
+ *
+ * Finishes the operation started with _cairo_surface_acquire_dest_image(), by, if
+ * necessary, copying the image from @image back to @surface and freeing any
+ * resources that were allocated.
+ **/
+void
+_cairo_surface_release_dest_image (cairo_surface_t *surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t *image,
+ cairo_rectangle_t *image_rect,
+ void *image_extra)
+{
+ surface->backend->release_dest_image (surface, interest_rect,
+ image, image_rect, image_extra);
+}
+
+/**
+ * _cairo_surface_clone_similar:
+ * @surface: a #cairo_surface_t
+ * @src: the source image
+ * @clone_out: location to store a surface compatible with @surface
+ * and with contents identical to @src. The caller must call
+ * cairo_surface_destroy() on the result.
+ *
+ * Creates a surface with contents identical to @src but that
+ * can be used efficiently with @surface. If @surface and @src are
+ * already compatible then it may return a new reference to @src.
+ *
+ * Return value: %CAIRO_STATUS_SUCCESS if a surface was created and stored
+ * in @clone_out. Otherwise %CAIRO_INT_STATUS_UNSUPPORTED or another
+ * error like %CAIRO_STATUS_NO_MEMORY.
+ **/
+cairo_status_t
+_cairo_surface_clone_similar (cairo_surface_t *surface,
+ cairo_surface_t *src,
+ cairo_surface_t **clone_out)
+{
+ cairo_status_t status;
+ cairo_image_surface_t *image;
+ void *image_extra;
+
+ status = surface->backend->clone_similar (surface, src, clone_out);
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+
+ status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
+ if (status != CAIRO_STATUS_SUCCESS)
+ return status;
+
+ status = surface->backend->clone_similar (surface, &image->base, clone_out);
+
+ /* If the above failed point, we could implement a full fallback
+ * using acquire_dest_image, but that's going to be very
+ * inefficient compared to a backend-specific implementation of
+ * clone_similar() with an image source. So we don't bother
+ */
+
+ _cairo_surface_release_source_image (src, image, image_extra);
+ return status;
}
cairo_status_t
@@ -228,6 +363,73 @@
}
slim_hidden_def(cairo_surface_set_repeat);
+typedef struct {
+ cairo_surface_t *dst;
+ cairo_rectangle_t extents;
+ cairo_image_surface_t *image;
+ cairo_rectangle_t image_rect;
+ void *image_extra;
+} fallback_state_t;
+
+static cairo_status_t
+_fallback_init (fallback_state_t *state,
+ cairo_surface_t *dst,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ state->extents.x = x;
+ state->extents.y = y;
+ state->extents.width = width;
+ state->extents.height = height;
+
+ state->dst = dst;
+
+ return _cairo_surface_acquire_dest_image (dst, &state->extents,
+ &state->image, &state->image_rect, &state->image_extra);
+}
+
+static void
+_fallback_cleanup (fallback_state_t *state)
+{
+ _cairo_surface_release_dest_image (state->dst, &state->extents,
+ state->image, &state->image_rect, &state->image_extra);
+}
+
+static cairo_status_t
+_fallback_composite (cairo_operator_t operator,
+ cairo_pattern_t *pattern,
+ cairo_surface_t *mask,
+ cairo_surface_t *dst,
+ int src_x,
+ int src_y,
+ int mask_x,
+ int mask_y,
+ int dst_x,
+ int dst_y,
+ unsigned int width,
+ unsigned int height)
+{
+ fallback_state_t state;
+ cairo_status_t status;
+
+ status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
+ if (!CAIRO_OK (status) || !state.image)
+ return status;
+
+ state.image->base.backend->composite (operator, pattern, mask,
+ &state.image->base,
+ src_x, src_y, mask_x, mask_y,
+ dst_x - state.image_rect.x,
+ dst_y - state.image_rect.y,
+ width, height);
+
+ _fallback_cleanup (&state);
+
+ return status;
+}
+
cairo_status_t
_cairo_surface_composite (cairo_operator_t operator,
cairo_pattern_t *pattern,
@@ -243,7 +445,6 @@
unsigned int height)
{
cairo_int_status_t status;
- cairo_image_surface_t *mask_image = 0, *dst_image;
status = dst->backend->composite (operator,
pattern, mask, dst,
@@ -254,26 +455,12 @@
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
- if (mask)
- mask_image = _cairo_surface_get_image (mask);
- dst_image = _cairo_surface_get_image (dst);
-
- dst_image->base.backend->composite (operator,
- pattern,
- mask ? &mask_image->base : NULL,
- dst_image,
- src_x, src_y,
- mask_x, mask_y,
- dst_x, dst_y,
- width, height);
-
- status = _cairo_surface_set_image (dst, dst_image);
-
- if (mask)
- cairo_surface_destroy (&mask_image->base);
- cairo_surface_destroy (&dst_image->base);
-
- return status;
+ return _fallback_composite (operator,
+ pattern, mask, dst,
+ src_x, src_y,
+ mask_x, mask_y,
+ dst_x, dst_y,
+ width, height);
}
cairo_status_t
@@ -295,6 +482,77 @@
return _cairo_surface_fill_rectangles (surface, operator, color, &rect, 1);
}
+static cairo_status_t
+_fallback_fill_rectangles (cairo_surface_t *surface,
+ cairo_operator_t operator,
+ const cairo_color_t *color,
+ cairo_rectangle_t *rects,
+ int num_rects)
+{
+ fallback_state_t state;
+ cairo_rectangle_t *offset_rects = NULL;
+ cairo_status_t status;
+ int x1, y1, x2, y2;
+ int i;
+
+ if (num_rects <= 0)
+ return CAIRO_STATUS_SUCCESS;
+
+ /* Compute the bounds of the rectangles, so that we know what area of the
+ * destination surface to fetch
+ */
+ x1 = rects[0].x;
+ y1 = rects[0].y;
+ x2 = rects[0].x + rects[0].width;
+ y2 = rects[0].y + rects[0].height;
+
+ for (i = 1; i < num_rects; i++) {
+ if (rects[0].x < x1)
+ x1 = rects[0].x;
+ if (rects[0].y < y1)
+ y1 = rects[0].y;
+
+ if (rects[0].x + rects[0].width > x2)
+ x2 = rects[0].x + rects[0].width;
+ if (rects[0].y + rects[0].height > y2)
+ y2 = rects[0].y + rects[0].height;
+ }
+
+ status = _fallback_init (&state, surface, x1, y1, x2 - x1, y2 - y1);
+ if (!CAIRO_OK (status) || !state.image)
+ return status;
+
+ /* If the fetched image isn't at 0,0, we need to offset the rectangles */
+
+ if (state.image_rect.x != 0 || state.image_rect.y != 0) {
+ offset_rects = malloc (sizeof (cairo_rectangle_t) * num_rects);
+ if (!offset_rects) {
+ status = CAIRO_STATUS_NO_MEMORY;
+ goto FAIL;
+ }
+
+ for (i = 0; i < num_rects; i++) {
+ offset_rects[i].x = rects[i].x - state.image_rect.x;
+ offset_rects[i].y = rects[i].y - state.image_rect.y;
+ offset_rects[i].width = rects[i].width;
+ offset_rects[i].height = rects[i].height;
+ }
+
+ rects = offset_rects;
+ }
+
+ state.image->base.backend->fill_rectangles (&state.image->base, operator, color,
+ rects, num_rects);
+
+ if (offset_rects)
+ free (offset_rects);
+
+ FAIL:
+ _fallback_cleanup (&state);
+
+ return status;
+}
+
cairo_status_t
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
cairo_operator_t operator,
@@ -303,7 +561,6 @@
int num_rects)
{
cairo_int_status_t status;
- cairo_image_surface_t *surface_image;
if (num_rects == 0)
return CAIRO_STATUS_SUCCESS;
@@ -315,20 +572,76 @@
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
- surface_image = _cairo_surface_get_image (surface);
+ return _fallback_fill_rectangles (surface, operator, color, rects, num_rects);
+}
- surface_image->base.backend->fill_rectangles (surface_image,
- operator,
- color,
- rects, num_rects);
+static cairo_status_t
+_fallback_composite_trapezoids (cairo_operator_t operator,
+ cairo_pattern_t *pattern,
+ cairo_surface_t *dst,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ unsigned int width,
+ unsigned int height,
+ cairo_trapezoid_t *traps,
+ int num_traps)
+{
+ fallback_state_t state;
+ cairo_trapezoid_t *offset_traps = NULL;
+ cairo_status_t status;
+ int i;
- status = _cairo_surface_set_image (surface, surface_image);
+ status = _fallback_init (&state, dst, dst_x, dst_y, width, height);
+ if (!CAIRO_OK (status) || !state.image)
+ return status;
- cairo_surface_destroy (&surface_image->base);
+ /* If the destination image isn't at 0,0, we need to offset the trapezoids */
+
+ if (state.image_rect.x != 0 || state.image_rect.y != 0) {
+
+ cairo_fixed_t xoff = _cairo_fixed_from_int (state.image_rect.x);
+ cairo_fixed_t yoff = _cairo_fixed_from_int (state.image_rect.y);
+
+ offset_traps = malloc (sizeof (cairo_trapezoid_t) * num_traps);
+ if (!offset_traps) {
+ status = CAIRO_STATUS_NO_MEMORY;
+ goto FAIL;
+ }
+ for (i = 0; i < num_traps; i++) {
+ offset_traps[i].top = traps[i].top - yoff;
+ offset_traps[i].bottom = traps[i].bottom - yoff;
+ offset_traps[i].left.p1.x = traps[i].left.p1.x - xoff;
+ offset_traps[i].left.p1.y = traps[i].left.p1.y - yoff;
+ offset_traps[i].left.p2.x = traps[i].left.p2.x - xoff;
+ offset_traps[i].left.p2.y = traps[i].left.p2.y - yoff;
+ offset_traps[i].right.p1.x = traps[i].right.p1.x - xoff;
+ offset_traps[i].right.p1.y = traps[i].right.p1.y - yoff;
+ offset_traps[i].right.p2.x = traps[i].right.p2.x - xoff;
+ offset_traps[i].right.p2.y = traps[i].right.p2.y - yoff;
+ }
+
+ traps = offset_traps;
+ }
+
+ state.image->base.backend->composite_trapezoids (operator, pattern,
+ &state.image->base,
+ src_x, src_y,
+ dst_x - state.image_rect.x,
+ dst_x - state.image_rect.y,
+ width, height, traps, num_traps);
+ if (offset_traps)
+ free (offset_traps);
+
+ FAIL:
+ _fallback_cleanup (&state);
+
return status;
}
+
cairo_status_t
_cairo_surface_composite_trapezoids (cairo_operator_t operator,
cairo_pattern_t *pattern,
@@ -343,7 +656,6 @@
int num_traps)
{
cairo_int_status_t status;
- cairo_image_surface_t *dst_image;
status = dst->backend->composite_trapezoids (operator,
pattern, dst,
@@ -354,21 +666,11 @@
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return status;
- dst_image = _cairo_surface_get_image (dst);
-
- dst_image->base.backend->composite_trapezoids (operator,
- pattern,
- dst_image,
- src_x, src_y,
- dst_x, dst_y,
- width, height,
- traps, num_traps);
-
- status = _cairo_surface_set_image (dst, dst_image);
-
- cairo_surface_destroy (&dst_image->base);
-
- return status;
+ return _fallback_composite_trapezoids (operator, pattern, dst,
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height,
+ traps, num_traps);
}
cairo_status_t
Index: cairo_xlib_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_xlib_surface.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- cairo_xlib_surface.c 28 Jan 2005 03:57:32 -0000 1.42
+++ cairo_xlib_surface.c 31 Jan 2005 16:50:22 -0000 1.43
@@ -103,6 +103,8 @@
#define CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 0)
#define CAIRO_SURFACE_RENDER_HAS_COMPOSITE(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 0)
+#define CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 0)
+
#define CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 1)
#define CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 1)
@@ -157,18 +159,13 @@
Pixmap pix;
cairo_xlib_surface_t *surface;
- /* XXX: There's a pretty lame heuristic here. This assumes that
- * all non-Render X servers do not support depth-32 pixmaps, (and
- * that they do support depths 1, 8, and 24). Obviously, it would
- * be much better to check the depths that are actually
- * supported. */
- if (!dpy
- || (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (src)
- && format == CAIRO_FORMAT_ARGB32))
- {
- return NULL;
+ /* As a good first approximation, if the display doesn't have COMPOSITE,
+ * we're better off using image surfaces for all temporary operations
+ */
+ if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE(src)) {
+ return cairo_image_surface_create (format, width, height);
}
-
+
scr = DefaultScreen (dpy);
pix = XCreatePixmap (dpy, DefaultRootWindow (dpy),
@@ -212,15 +209,17 @@
return 96.0;
}
-static cairo_image_surface_t *
-_cairo_xlib_surface_get_image (void *abstract_surface)
+static cairo_status_t
+_get_image_surface (cairo_xlib_surface_t *surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t **image_out,
+ cairo_rectangle_t *image_rect)
{
- cairo_xlib_surface_t *surface = abstract_surface;
cairo_image_surface_t *image;
-
XImage *ximage;
Window root_ignore;
int x_ignore, y_ignore, bwidth_ignore, depth_ignore;
+ int x1, y1, x2, y2;
XGetGeometry (surface->dpy,
surface->drawable,
@@ -228,11 +227,39 @@
&surface->width, &surface->height,
&bwidth_ignore, &depth_ignore);
+ x1 = 0;
+ y1 = 0;
+ x2 = surface->width;
+ y2 = surface->height;
+
+ if (interest_rect) {
+ if (interest_rect->x > x1)
+ x1 = interest_rect->x;
+ if (interest_rect->y > y1)
+ y1 = interest_rect->y;
+ if (interest_rect->x + interest_rect->width < x2)
+ x2 = interest_rect->x + interest_rect->width;
+ if (interest_rect->y + interest_rect->height < y2)
+ y2 = interest_rect->y + interest_rect->height;
+
+ if (x1 >= x2 || y1 >= y2) {
+ *image_out = NULL;
+ return CAIRO_STATUS_SUCCESS;
+ }
+ }
+
+ if (image_rect) {
+ image_rect->x = x1;
+ image_rect->y = y1;
+ image_rect->width = x2 - x1;
+ image_rect->height = y2 - y1;
+ }
+
/* XXX: This should try to use the XShm extension if availible */
ximage = XGetImage (surface->dpy,
surface->drawable,
- 0, 0,
- surface->width, surface->height,
+ x1, y1,
+ x2 - x1, y2 - y1,
AllPlanes, ZPixmap);
if (surface->visual) {
@@ -269,7 +296,8 @@
_cairo_image_surface_set_repeat (image, surface->base.repeat);
_cairo_image_surface_set_matrix (image, &(surface->base.matrix));
- return image;
+ *image_out = image;
+ return CAIRO_STATUS_SUCCESS;
}
static void
@@ -282,10 +310,11 @@
}
static cairo_status_t
-_cairo_xlib_surface_set_image (void *abstract_surface,
- cairo_image_surface_t *image)
+_draw_image_surface (cairo_xlib_surface_t *surface,
+ cairo_image_surface_t *image,
+ int dst_x,
+ int dst_y)
{
- cairo_xlib_surface_t *surface = abstract_surface;
XImage *ximage;
unsigned bitmap_pad;
@@ -311,9 +340,8 @@
_cairo_xlib_surface_ensure_gc (surface);
XPutImage(surface->dpy, surface->drawable, surface->gc,
- ximage, 0, 0, 0, 0,
- surface->width,
- surface->height);
+ ximage, 0, 0, dst_x, dst_y,
+ image->width, image->height);
/* Foolish XDestroyImage thinks it can free my data, but I won't
stand for it. */
@@ -321,6 +349,109 @@
XDestroyImage (ximage);
return CAIRO_STATUS_SUCCESS;
+
+}
+
+static cairo_status_t
+_cairo_xlib_surface_acquire_source_image (void *abstract_surface,
+ cairo_image_surface_t **image_out,
+ void **image_extra)
+{
+ cairo_xlib_surface_t *surface = abstract_surface;
+ cairo_image_surface_t *image;
+ cairo_status_t status;
+
+ status = _get_image_surface (surface, NULL, &image, NULL);
+ if (status == CAIRO_STATUS_SUCCESS) {
+ cairo_surface_set_filter (&image->base, surface->base.filter);
+ cairo_surface_set_matrix (&image->base, &surface->base.matrix);
+ cairo_surface_set_repeat (&image->base, surface->base.repeat);
+
+ *image_out = image;
+ }
+
+ return status;
+}
+
+static void
+_cairo_xlib_surface_release_source_image (void *abstract_surface,
+ cairo_image_surface_t *image,
+ void *image_extra)
+{
+ cairo_surface_destroy (&image->base);
+}
+
+static cairo_status_t
+_cairo_xlib_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_xlib_surface_t *surface = abstract_surface;
+ cairo_image_surface_t *image;
+ cairo_status_t status;
+
+ status = _get_image_surface (surface, interest_rect, &image, image_rect_out);
+ if (status == CAIRO_STATUS_SUCCESS)
+ *image_out = image;
+
+ return status;
+}
+
+static void
+_cairo_xlib_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)
+{
+ cairo_xlib_surface_t *surface = abstract_surface;
+
+ /* ignore errors */
+ _draw_image_surface (surface, image, image_rect->x, image_rect->y);
+
+ cairo_surface_destroy (&image->base);
+}
+
+static cairo_status_t
+_cairo_xlib_surface_clone_similar (void *abstract_surface,
+ cairo_surface_t *src,
+ cairo_surface_t **clone_out)
+{
+ cairo_xlib_surface_t *surface = abstract_surface;
+ cairo_xlib_surface_t *clone;
+
+ if (src->backend == surface->base.backend ) {
+ cairo_xlib_surface_t *xlib_src = (cairo_xlib_surface_t *)src;
+
+ if (xlib_src->dpy == surface->dpy) {
+ *clone_out = src;
+ cairo_surface_reference (src);
+
+ return CAIRO_STATUS_SUCCESS;
+ }
+ } else if (_cairo_surface_is_image (src)) {
+ cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;
+
+ clone = (cairo_xlib_surface_t *)
+ _cairo_xlib_surface_create_similar (surface, image_src->format, 0,
+ image_src->width, image_src->height);
+ if (clone == NULL)
+ return CAIRO_STATUS_NO_MEMORY;
+
+ _draw_image_surface (clone, image_src, 0, 0);
+
+ cairo_surface_set_filter (&clone->base, src->filter);
+ cairo_surface_set_matrix (&clone->base, &src->matrix);
+ cairo_surface_set_repeat (&clone->base, src->repeat);
+
+ *clone_out = &clone->base;
+
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_status_t
@@ -410,35 +541,6 @@
return CAIRO_STATUS_SUCCESS;
}
-static cairo_xlib_surface_t *
-_cairo_xlib_surface_clone_similar (cairo_surface_t *src,
- cairo_xlib_surface_t *template,
- cairo_format_t format,
- int depth)
-{
- cairo_xlib_surface_t *clone;
- cairo_image_surface_t *src_image;
-
- src_image = _cairo_surface_get_image (src);
-
- clone = (cairo_xlib_surface_t *)
- _cairo_xlib_surface_create_similar (template, format, 0,
- src_image->width,
- src_image->height);
- if (clone == NULL)
- return NULL;
-
- _cairo_xlib_surface_set_filter (clone, cairo_surface_get_filter(src));
-
- _cairo_xlib_surface_set_image (clone, src_image);
-
- _cairo_xlib_surface_set_matrix (clone, &(src_image->base.matrix));
-
- cairo_surface_destroy (&src_image->base);
-
- return clone;
-}
-
static int
_render_operator (cairo_operator_t operator)
{
@@ -493,27 +595,29 @@
cairo_xlib_surface_t *dst = abstract_dst;
cairo_xlib_surface_t *src;
cairo_xlib_surface_t *mask = (cairo_xlib_surface_t *) generic_mask;
- cairo_xlib_surface_t *mask_clone = NULL;
+ cairo_surface_t *mask_clone = NULL;
XGCValues gc_values;
int src_x_off, src_y_off, dst_x_off, dst_y_off;
- int x_offset, y_offset;
+ cairo_pattern_info_t pattern_info;
+ cairo_status_t status;
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
return CAIRO_INT_STATUS_UNSUPPORTED;
- src = (cairo_xlib_surface_t *)
- _cairo_pattern_get_surface (pattern, &dst->base,
- src_x, src_y,
- width, height,
- &x_offset, &y_offset);
+ status = _cairo_pattern_begin_draw (pattern, &pattern_info,
+ &dst->base,
+ src_x, src_y, width, height);
+ if (!CAIRO_OK (status))
+ return status;
+ src = (cairo_xlib_surface_t *)pattern_info.src;
+
/* XXX This stuff can go when we change the mask to be a pattern also. */
if (generic_mask && (generic_mask->backend != dst->base.backend || mask->dpy != dst->dpy)) {
- mask_clone = _cairo_xlib_surface_clone_similar (generic_mask, dst,
- CAIRO_FORMAT_A8, 8);
- if (!mask_clone)
- return CAIRO_INT_STATUS_UNSUPPORTED;
- mask = mask_clone;
+ status = _cairo_surface_clone_similar (abstract_dst, generic_mask, &mask_clone);
+ if (!CAIRO_OK (status))
+ goto FAIL;
+ mask = (cairo_xlib_surface_t *)mask_clone;
}
if (operator == CAIRO_OPERATOR_SRC
@@ -530,30 +634,31 @@
src->drawable,
dst->drawable,
dst->gc,
- src_x + src_x_off,
- src_y + src_y_off,
- width, height,
+ src_x + src_x_off - pattern_info.x_offset,
+ src_y + src_y_off - pattern_info.y_offset,
+ width, height,
dst_x + dst_x_off,
dst_y + dst_y_off);
XSetGraphicsExposures(dst->dpy, dst->gc, gc_values.graphics_exposures);
} else {
- XRenderComposite (dst->dpy,
- _render_operator (operator),
- src->picture,
- mask ? mask->picture : 0,
- dst->picture,
- src_x, src_y,
- mask_x, mask_y,
- dst_x, dst_y,
- width, height);
+ XRenderComposite (dst->dpy,
+ _render_operator (operator),
+ src->picture,
+ mask ? mask->picture : 0,
+ dst->picture,
+ src_x - pattern_info.x_offset,
+ src_y - pattern_info.y_offset,
+ mask_x, mask_y,
+ dst_x, dst_y,
+ width, height);
}
- /* XXX: This is messed up. If I can xlib_surface_create, then I
- should be able to xlib_surface_destroy. */
- cairo_surface_destroy (&src->base);
if (mask_clone)
- cairo_surface_destroy (&mask_clone->base);
+ cairo_surface_destroy (mask_clone);
+
+ FAIL:
+ _cairo_pattern_end_draw (pattern, &pattern_info);
return CAIRO_STATUS_SUCCESS;
}
@@ -600,21 +705,21 @@
{
cairo_xlib_surface_t *dst = abstract_dst;
cairo_xlib_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;
if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
return CAIRO_INT_STATUS_UNSUPPORTED;
- src = (cairo_xlib_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;
+ 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_xlib_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);
@@ -632,15 +737,11 @@
_render_operator (operator),
src->picture, dst->picture,
XRenderFindStandardFormat (dst->dpy, PictStandardA8),
- render_src_x - x_offset,
- render_src_y - y_offset,
+ render_src_x - pattern_info.x_offset,
+ render_src_y - pattern_info.y_offset,
(XTrapezoid *) traps, num_traps);
- _cairo_pattern_restore_surface (pattern, &src->base);
-
- /* XXX: This is messed up. If I can xlib_surface_create, then I
- should be able to xlib_surface_destroy. */
- cairo_surface_destroy (&src->base);
+ _cairo_pattern_end_draw (pattern, &pattern_info);
return CAIRO_STATUS_SUCCESS;
}
@@ -739,8 +840,11 @@
_cairo_xlib_surface_create_similar,
_cairo_xlib_surface_destroy,
_cairo_xlib_surface_pixels_per_inch,
- _cairo_xlib_surface_get_image,
- _cairo_xlib_surface_set_image,
+ _cairo_xlib_surface_acquire_source_image,
+ _cairo_xlib_surface_release_source_image,
+ _cairo_xlib_surface_acquire_dest_image,
+ _cairo_xlib_surface_release_dest_image,
+ _cairo_xlib_surface_clone_similar,
_cairo_xlib_surface_set_matrix,
_cairo_xlib_surface_set_filter,
_cairo_xlib_surface_set_repeat,
@@ -1300,14 +1404,18 @@
{
unsigned int elt_size;
cairo_xlib_surface_t *self = abstract_surface;
+ cairo_pattern_info_t pattern_info;
cairo_xlib_surface_t *src;
glyphset_cache_t *g;
cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
cairo_glyph_cache_key_t key;
glyphset_cache_entry_t **entries;
glyphset_cache_entry_t *stack_entries [N_STACK_BUF];
- int i, x_offset, y_offset;
+ int i;
+ if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
/* Acquire an entry array of suitable size. */
if (num_glyphs < N_STACK_BUF) {
entries = stack_entries;
@@ -1318,17 +1426,13 @@
goto FAIL;
}
- src = (cairo_xlib_surface_t *)
- _cairo_pattern_get_surface (pattern, &self->base,
- source_x, source_y,
- width, height,
- &x_offset, &y_offset);
- if (src == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
+ status = _cairo_pattern_begin_draw (pattern, &pattern_info,
+ &self->base,
+ source_x, source_y, width, height);
+ if (!CAIRO_OK (status))
goto FREE_ENTRIES;
- }
- _cairo_pattern_prepare_surface (pattern, &src->base);
+ src = (cairo_xlib_surface_t *)pattern_info.src;
_lock_xlib_glyphset_caches ();
g = _get_glyphset_cache (self->dpy);
@@ -1366,15 +1470,18 @@
if (elt_size == 8)
status = _cairo_xlib_surface_show_glyphs8 (font, operator, g, &key, src, self,
- source_x, source_y,
+ source_x - pattern_info.x_offset,
+ source_y - pattern_info.y_offset,
glyphs, entries, num_glyphs);
else if (elt_size == 16)
status = _cairo_xlib_surface_show_glyphs16 (font, operator, g, &key, src, self,
- source_x, source_y,
+ source_x - pattern_info.x_offset,
+ source_y - pattern_info.y_offset,
glyphs, entries, num_glyphs);
else
status = _cairo_xlib_surface_show_glyphs32 (font, operator, g, &key, src, self,
- source_x, source_y,
+ source_x - pattern_info.x_offset,
+ source_y - pattern_info.y_offset,
glyphs, entries, num_glyphs);
for (i = 0; i < num_glyphs; ++i)
@@ -1382,8 +1489,7 @@
UNLOCK:
_unlock_xlib_glyphset_caches ();
- _cairo_pattern_restore_surface (pattern, &src->base);
- cairo_surface_destroy (&src->base);
+ _cairo_pattern_end_draw (pattern, &pattern_info);
FREE_ENTRIES:
if (num_glyphs >= N_STACK_BUF)
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.91
retrieving revision 1.92
diff -u -d -r1.91 -r1.92
--- cairoint.h 28 Jan 2005 20:27:23 -0000 1.91
+++ cairoint.h 31 Jan 2005 16:50:22 -0000 1.92
@@ -169,6 +169,8 @@
CAIRO_INT_STATUS_UNSUPPORTED
} cairo_int_status_t;
+#define CAIRO_OK(status) ((status) == CAIRO_STATUS_SUCCESS)
+
typedef enum cairo_path_op {
CAIRO_PATH_OP_MOVE_TO = 0,
CAIRO_PATH_OP_LINE_TO = 1,
@@ -540,18 +542,35 @@
double
(*pixels_per_inch) (void *surface);
- /* XXX: We could use a better name than get_image here. Something
- to suggest the fact that the function will create a new
- surface, (and hence that it needs to be destroyed). Perhaps
- clone_image or maybe simply clone? */
+ cairo_status_t
+ (* acquire_source_image) (void *abstract_surface,
+ cairo_image_surface_t **image_out,
+ void **image_extra);
- cairo_image_surface_t *
- (*get_image) (void *surface);
+ void
+ (* release_source_image) (void *abstract_surface,
+ cairo_image_surface_t *image,
+ void *image_extra);
cairo_status_t
- (*set_image) (void *surface,
- cairo_image_surface_t *image);
+ (*acquire_dest_image) (void *abstract_surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t **image_out,
+ cairo_rectangle_t *image_rect,
+ void **image_extra);
+ void
+ (*release_dest_image) (void *abstract_surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t *image,
+ cairo_rectangle_t *image_rect,
+ void *image_extra);
+
+ cairo_status_t
+ (*clone_similar) (void *surface,
+ cairo_surface_t *src,
+ cairo_surface_t **clone_out);
+
cairo_status_t
(*set_matrix) (void *surface,
cairo_matrix_t *matrix);
@@ -655,6 +674,7 @@
cairo_surface_t base;
/* libic-specific fields */
+ cairo_format_t format;
char *data;
int owns_data;
@@ -748,6 +768,15 @@
} u;
};
+typedef struct {
+ cairo_surface_t *src;
+ int x_offset;
+ int y_offset;
+
+ int acquired; /* If we used _cairo_surface_acquire_source_image */
+ void *extra;
+} cairo_pattern_info_t;
+
typedef struct _cairo_traps {
cairo_trapezoid_t *traps;
int num_traps;
@@ -1424,12 +1453,34 @@
cairo_private double
_cairo_surface_pixels_per_inch (cairo_surface_t *surface);
-cairo_private cairo_image_surface_t *
-_cairo_surface_get_image (cairo_surface_t *surface);
+cairo_private cairo_status_t
+_cairo_surface_acquire_source_image (cairo_surface_t *urface,
+ cairo_image_surface_t **image_out,
+ void **image_extra);
+
+cairo_private void
+_cairo_surface_release_source_image (cairo_surface_t *surface,
+ cairo_image_surface_t *image,
+ void *image_extra);
cairo_private cairo_status_t
-_cairo_surface_set_image (cairo_surface_t *surface,
- cairo_image_surface_t *image);
+_cairo_surface_acquire_dest_image (cairo_surface_t *surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t **image_out,
+ cairo_rectangle_t *image_rect,
+ void **image_extra);
+
+cairo_private void
+_cairo_surface_release_dest_image (cairo_surface_t *surface,
+ cairo_rectangle_t *interest_rect,
+ cairo_image_surface_t *image,
+ cairo_rectangle_t *image_rect,
+ void *image_extra);
+
+cairo_private cairo_status_t
+_cairo_surface_clone_similar (cairo_surface_t *surface,
+ cairo_surface_t *src,
+ cairo_surface_t **clone_out);
cairo_private cairo_status_t
_cairo_surface_set_clip_region (cairo_surface_t *surface, pixman_region16_t *region);
@@ -1462,6 +1513,9 @@
_cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
pixman_region16_t *region);
+cairo_private int
+_cairo_surface_is_image (cairo_surface_t *surface);
+
/* cairo_pen.c */
cairo_private cairo_status_t
_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate);
@@ -1656,15 +1710,18 @@
cairo_fixed_t factor,
int *pixel);
-cairo_private cairo_surface_t *
-_cairo_pattern_get_surface (cairo_pattern_t *pattern,
- cairo_surface_t *dst,
- int x,
- int y,
- unsigned int width,
- unsigned int height,
- int *x_offset,
- int *y_offset);
+cairo_private cairo_status_t
+_cairo_pattern_begin_draw (cairo_pattern_t *pattern,
+ cairo_pattern_info_t *info,
+ cairo_surface_t *dst,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+
+cairo_private void
+_cairo_pattern_end_draw (cairo_pattern_t *pattern,
+ cairo_pattern_info_t *info);
/* Avoid unnecessary PLT entries. */
More information about the cairo-commit
mailing list