[cairo] updated,
hopefully with propr line-wrapping [PATCH] add extents to
clone_similar
Christopher "Monty" Montgomery
xiphmont at gmail.com
Thu Oct 5 12:28:16 PDT 2006
Carl said previous attempt got its line wrapping slagged. One more try...
Monty
---
src/cairo-clip.c | 11 ++++++++++-
src/cairo-directfb-surface.c | 17 +++++++++++++----
src/cairo-glitz-surface.c | 30 ++++++++++++++++++++++--------
src/cairo-image-surface.c | 4 ++++
src/cairo-nquartz-surface.c | 9 +++++++--
src/cairo-pattern.c | 38 ++++++++++++++++++++------------------
src/cairo-surface.c | 14 ++++++++++++--
src/cairo-xcb-surface.c | 9 +++++++++
src/cairo-xlib-surface.c | 18 ++++++++++++++----
src/cairoint.h | 8 ++++++++
10 files changed, 119 insertions(+), 39 deletions(-)
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 3f7c0c0..fcb96a6 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -563,7 +563,16 @@ _cairo_clip_init_deep_copy (cairo_clip_t
}
if (other->surface) {
- _cairo_surface_clone_similar (target, clip->surface,
&clip->surface);
+ _cairo_surface_clone_similar (target, clip->surface,
+ // is this more or less
+ // correct than just cloning
+ // the entire surface
+ // rectangle? --Monty
+ clip->surface_rect.x,
+ clip->surface_rect.y,
+ clip->surface_rect.width,
+ clip->surface_rect.height,
+ &clip->surface);
clip->surface_rect = other->surface_rect;
}
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index fdff40a..ef5954c 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -548,6 +548,10 @@ _cairo_directfb_surface_release_dest_ima
static cairo_status_t
_cairo_directfb_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
cairo_surface_t **clone_out)
{
cairo_directfb_surface_t *surface = abstract_surface;
@@ -584,18 +588,23 @@ _cairo_directfb_surface_clone_similar (v
return CAIRO_STATUS_NO_MEMORY;
}
+
+ dst += pitch * src_y;
+ src += image_src->stride * src_y;
+
if (image_src->format == CAIRO_FORMAT_A1) {
/* A1 -> A8 */
- for (i = 0; i < image_src->height; i++) {
- for (j = 0; j < image_src->width; j++)
+ for (i = 0; i < height; i++) {
+ for (j = src_x; j < src_x + width; j++)
dst[j] = (src[j>>3] & (1 << (j&7))) ? 0xff : 0x00;
dst += pitch;
src += image_src->stride;
}
}
else {
- for (i = 0; i < image_src->height; i++) {
- direct_memcpy( dst, src, image_src->stride );
+ /* A8 -> A8 */
+ for (i = 0; i < height; i++) {
+ direct_memcpy( dst+src_x, src+src_x, sizeof(*dst)*width );
dst += pitch;
src += image_src->stride;
}
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index c7d6aa3..713270c 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -243,8 +243,12 @@ _cairo_glitz_surface_get_image (cairo_gl
static cairo_status_t
_cairo_glitz_surface_set_image (void *abstract_surface,
cairo_image_surface_t *image,
- int x_dst,
- int y_dst)
+ int src_x,
+ int src_y,
+ int width,
+ int height,
+ int x_dst,
+ int y_dst)
{
cairo_glitz_surface_t *surface = abstract_surface;
glitz_buffer_t *buffer;
@@ -264,8 +268,8 @@ _cairo_glitz_surface_set_image (void
pf.masks.red_mask = rm;
pf.masks.green_mask = gm;
pf.masks.blue_mask = bm;
- pf.xoffset = 0;
- pf.skip_lines = 0;
+ pf.xoffset = src_x;
+ pf.skip_lines = src_y;
/* check for negative stride */
if (image->stride < 0)
@@ -287,7 +291,7 @@ _cairo_glitz_surface_set_image (void
glitz_set_pixels (surface->surface,
x_dst, y_dst,
- image->width, image->height,
+ width, height,
&pf,
buffer);
@@ -347,7 +351,8 @@ _cairo_glitz_surface_release_dest_image
{
cairo_glitz_surface_t *surface = abstract_surface;
- _cairo_glitz_surface_set_image (surface, image,
+ _cairo_glitz_surface_set_image (surface, image, 0, 0,
+ image->width, image->height,
image_rect->x, image_rect->y);
cairo_surface_destroy (&image->base);
@@ -356,6 +361,10 @@ _cairo_glitz_surface_release_dest_image
static cairo_status_t
_cairo_glitz_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
cairo_surface_t **clone_out)
{
cairo_glitz_surface_t *surface = abstract_surface;
@@ -384,7 +393,8 @@ _cairo_glitz_surface_clone_similar (void
if (clone->base.status)
return CAIRO_STATUS_NO_MEMORY;
- _cairo_glitz_surface_set_image (clone, image_src, 0, 0);
+ _cairo_glitz_surface_set_image (clone, image_src, src_x, src_y,
+ width, height, src_x, src_y);
*clone_out = &clone->base;
@@ -1183,7 +1193,7 @@ _cairo_glitz_surface_composite_trapezoid
return CAIRO_STATUS_NO_MEMORY;
}
- _cairo_glitz_surface_set_image (mask, image, 0, 0);
+ _cairo_glitz_surface_set_image (mask, image, src_x, src_y, width,
height, 0, 0);
}
_cairo_glitz_surface_set_attributes (src, &attributes);
@@ -2024,6 +2034,10 @@ _cairo_glitz_surface_old_show_glyphs (ca
status =
_cairo_glitz_surface_clone_similar (abstract_surface,
image,
+ src_x,
+ src_y,
+ width,
+ height,
(cairo_surface_t **)
&clone);
if (status)
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 62040d8..74fccdb 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -617,6 +617,10 @@ _cairo_image_surface_release_dest_image
static cairo_status_t
_cairo_image_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
cairo_surface_t **clone_out)
{
cairo_image_surface_t *surface = abstract_surface;
diff --git a/src/cairo-nquartz-surface.c b/src/cairo-nquartz-surface.c
index 1c300b1..aef5a62 100644
--- a/src/cairo-nquartz-surface.c
+++ b/src/cairo-nquartz-surface.c
@@ -498,7 +498,8 @@ SurfacePatternDrawFunc (void *info, CGCo
cairo_surface_t *new_surf = NULL;
- _cairo_surface_clone_similar (dummy, pat_surf, &new_surf);
+ _cairo_surface_clone_similar (dummy, pat_surf, rect.x, rect.y,
+ rect.width, rect.height, &new_surf);
cairo_surface_destroy(dummy);
@@ -1025,6 +1026,10 @@ _cairo_nquartz_surface_create_similar (v
static cairo_status_t
_cairo_nquartz_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
cairo_surface_t **clone_out)
{
cairo_nquartz_surface_t *surface = (cairo_nquartz_surface_t *)
abstract_surface;
@@ -1104,7 +1109,7 @@ _cairo_nquartz_surface_clone_similar (vo
nquartz_image_to_png (quartz_image, NULL);
CGContextDrawImage (new_surface->cgContext,
- CGRectMake (0, 0, CGImageGetWidth (quartz_image), CGImageGetHeight
(quartz_image)),
+ CGRectMake (src_x, src_y, width, height),
quartz_image);
CGImageRelease (quartz_image);
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index a2a08e0..db5d297 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1024,7 +1024,8 @@ _cairo_pattern_acquire_surface_for_gradi
pixman_image_destroy (pixman_image);
- status = _cairo_surface_clone_similar (dst, &image->base, out);
+ status = _cairo_surface_clone_similar (dst, &image->base,
+ 0, 0, width, height, out);
cairo_surface_destroy (&image->base);
@@ -1144,6 +1145,22 @@ _cairo_pattern_acquire_surface_for_surfa
attr->acquired = FALSE;
+ attr->extend = pattern->base.extend;
+ attr->filter = pattern->base.filter;
+ if (_cairo_matrix_is_integer_translation (&pattern->base.matrix,
+ &tx, &ty))
+ {
+ cairo_matrix_init_identity (&attr->matrix);
+ attr->x_offset = tx;
+ attr->y_offset = ty;
+ attr->filter = CAIRO_FILTER_NEAREST;
+ }
+ else
+ {
+ attr->matrix = pattern->base.matrix;
+ attr->x_offset = attr->y_offset = 0;
+ }
+
if (_cairo_surface_is_image (dst))
{
cairo_image_surface_t *image;
@@ -1159,23 +1176,8 @@ _cairo_pattern_acquire_surface_for_surfa
}
else
{
- status = _cairo_surface_clone_similar (dst, pattern->surface, out);
- }
-
- attr->extend = pattern->base.extend;
- attr->filter = pattern->base.filter;
- if (_cairo_matrix_is_integer_translation (&pattern->base.matrix,
- &tx, &ty))
- {
- cairo_matrix_init_identity (&attr->matrix);
- attr->x_offset = tx;
- attr->y_offset = ty;
- attr->filter = CAIRO_FILTER_NEAREST;
- }
- else
- {
- attr->matrix = pattern->base.matrix;
- attr->x_offset = attr->y_offset = 0;
+ status = _cairo_surface_clone_similar (dst, pattern->surface,
+ x+tx, y+ty, width, height, out);
}
return status;
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index cbbe89a..b6e92f2 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -987,6 +987,10 @@ _cairo_surface_release_dest_image (cairo
* _cairo_surface_clone_similar:
* @surface: a #cairo_surface_t
* @src: the source image
+ * @src_x: extent for the rectangle in src we actually care about
+ * @src_y: extent for the rectangle in src we actually care about
+ * @width: extent for the rectangle in src we actually care about
+ * @height: extent for the rectangle in src we actually care about
* @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.
@@ -1002,6 +1006,10 @@ _cairo_surface_release_dest_image (cairo
cairo_status_t
_cairo_surface_clone_similar (cairo_surface_t *surface,
cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
cairo_surface_t **clone_out)
{
cairo_status_t status;
@@ -1014,7 +1022,8 @@ _cairo_surface_clone_similar (cairo_surf
if (surface->backend->clone_similar == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
- status = surface->backend->clone_similar (surface, src, clone_out);
+ status = surface->backend->clone_similar (surface, src, src_x, src_y,
+ width, height, clone_out);
if (status == CAIRO_STATUS_SUCCESS)
(*clone_out)->device_transform = src->device_transform;
@@ -1025,7 +1034,8 @@ _cairo_surface_clone_similar (cairo_surf
if (status != CAIRO_STATUS_SUCCESS)
return status;
- status = surface->backend->clone_similar (surface, &image->base,
clone_out);
+ status = surface->backend->clone_similar (surface, &image->base, src_x,
+ src_y, width, height, clone_out);
if (status == CAIRO_STATUS_SUCCESS)
(*clone_out)->device_transform = src->device_transform;
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index f60bc3b..4bdf837 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -588,6 +588,10 @@ _cairo_xcb_surface_same_screen (cairo_xc
static cairo_status_t
_cairo_xcb_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
cairo_surface_t **clone_out)
{
cairo_xcb_surface_t *surface = abstract_surface;
@@ -614,6 +618,11 @@ _cairo_xcb_surface_clone_similar (void
if (clone->base.status)
return CAIRO_STATUS_NO_MEMORY;
+ /* can't apply extents; no manpages for XCBPutImage and xcb
+ source from freedesktop currently won't build. XCBPutImage is not
+ referenced in the XCB source from xcb.freedesktop.org/dist
+ anywhere. */
+
_draw_image_surface (clone, image_src, 0, 0);
*clone_out = &clone->base;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index d0f9158..aaf43e4 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -744,6 +744,10 @@ _cairo_xlib_surface_ensure_gc (cairo_xli
static cairo_status_t
_draw_image_surface (cairo_xlib_surface_t *surface,
cairo_image_surface_t *image,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
int dst_x,
int dst_y)
{
@@ -774,8 +778,8 @@ _draw_image_surface (cairo_xlib_surface_
_cairo_xlib_surface_ensure_gc (surface);
XPutImage(surface->dpy, surface->drawable, surface->gc,
- &ximage, 0, 0, dst_x, dst_y,
- image->width, image->height);
+ &ximage, src_x, src_y, dst_x, dst_y,
+ width, height);
return CAIRO_STATUS_SUCCESS;
@@ -839,7 +843,8 @@ _cairo_xlib_surface_release_dest_image (
cairo_xlib_surface_t *surface = abstract_surface;
/* ignore errors */
- _draw_image_surface (surface, image, image_rect->x, image_rect->y);
+ _draw_image_surface (surface, image, 0, 0, image->width, image->height,
+ image_rect->x, image_rect->y);
cairo_surface_destroy (&image->base);
}
@@ -859,6 +864,10 @@ _cairo_xlib_surface_same_screen (cairo_x
static cairo_status_t
_cairo_xlib_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
cairo_surface_t **clone_out)
{
cairo_xlib_surface_t *surface = abstract_surface;
@@ -884,7 +893,8 @@ _cairo_xlib_surface_clone_similar (void
if (clone->base.status)
return CAIRO_STATUS_NO_MEMORY;
- _draw_image_surface (clone, image_src, 0, 0);
+ _draw_image_surface (clone, image_src, src_x, src_y,
+ width, height, src_x, src_y);
*clone_out = &clone->base;
diff --git a/src/cairoint.h b/src/cairoint.h
index 6a3bc31..8781774 100755
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -723,6 +723,10 @@ struct _cairo_surface_backend {
cairo_status_t
(*clone_similar) (void *surface,
cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
cairo_surface_t **clone_out);
/* XXX: dst should be the first argument for consistency */
@@ -1885,6 +1889,10 @@ _cairo_surface_release_dest_image (cairo
cairo_private cairo_status_t
_cairo_surface_clone_similar (cairo_surface_t *surface,
cairo_surface_t *src,
+ int src_x,
+ int src_y,
+ int width,
+ int height,
cairo_surface_t **clone_out);
cairo_private cairo_surface_t *
--
1.4.1.1
More information about the cairo
mailing list