diff options
Diffstat (limited to 'src/cairo_xlib_surface.c')
-rw-r--r-- | src/cairo_xlib_surface.c | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/src/cairo_xlib_surface.c b/src/cairo_xlib_surface.c index 19dfde503..4f4425940 100644 --- a/src/cairo_xlib_surface.c +++ b/src/cairo_xlib_surface.c @@ -111,6 +111,7 @@ _CAIRO_FORMAT_DEPTH (cairo_format_t format) static cairo_surface_t * _cairo_xlib_surface_create_similar (void *abstract_src, cairo_format_t format, + int drawable, int width, int height) { @@ -382,7 +383,7 @@ _cairo_xlib_surface_clone_similar (cairo_surface_t *src, src_image = _cairo_surface_get_image (src); clone = (cairo_xlib_surface_t *) - _cairo_xlib_surface_create_similar (template, format, + _cairo_xlib_surface_create_similar (template, format, 0, src_image->width, src_image->height); if (clone == NULL) @@ -455,7 +456,8 @@ _cairo_xlib_surface_composite (cairo_operator_t operator, cairo_xlib_surface_t *mask = (cairo_xlib_surface_t *) generic_mask; cairo_xlib_surface_t *src_clone = NULL; cairo_xlib_surface_t *mask_clone = NULL; - + XGCValues gc_values; + int src_x_off, src_y_off, dst_x_off, dst_y_off; if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -475,6 +477,28 @@ _cairo_xlib_surface_composite (cairo_operator_t operator, mask = mask_clone; } + if (operator == CAIRO_OPERATOR_SRC + && !mask + && _cairo_matrix_is_integer_translation(&(src->base.matrix), + &src_x_off, &src_y_off) + && _cairo_matrix_is_integer_translation(&(dst->base.matrix), + &dst_x_off, &dst_y_off)) { + /* Fast path for copying "raw" areas. */ + _cairo_xlib_surface_ensure_gc (dst); + XGetGCValues(dst->dpy, dst->gc, GCGraphicsExposures, &gc_values); + XSetGraphicsExposures(dst->dpy, dst->gc, False); + XCopyArea(dst->dpy, + src->drawable, + dst->drawable, + dst->gc, + src_x + src_x_off, + src_y + src_y_off, + 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, @@ -484,6 +508,7 @@ _cairo_xlib_surface_composite (cairo_operator_t operator, 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. */ @@ -577,8 +602,11 @@ static cairo_int_status_t _cairo_xlib_surface_set_clip_region (void *abstract_surface, pixman_region16_t *region) { + Region xregion; XRectangle xr; + XRectangle *rects = NULL; + XGCValues gc_values; pixman_box16_t *box; cairo_xlib_surface_t *surf; int n, m; @@ -593,13 +621,17 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, xr.width = surf->width; xr.height = surf->height; XUnionRectWithRegion (&xr, xregion, xregion); + rects = malloc(sizeof(XRectangle)); + rects[0] = xr; + m = 1; + } else { n = pixman_region_num_rects (region); /* XXX: Are we sure these are the semantics we want for an * empty, (not null) region? */ if (n == 0) return CAIRO_STATUS_SUCCESS; - + rects = malloc(sizeof(XRectangle) * n); box = pixman_region_rects (region); xregion = XCreateRegion(); @@ -609,13 +641,20 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, xr.y = (short) box->y1; xr.width = (unsigned short) (box->x2 - box->x1); xr.height = (unsigned short) (box->y2 - box->y1); + rects[n-1] = xr; XUnionRectWithRegion (&xr, xregion, xregion); } } + _cairo_xlib_surface_ensure_gc (surf); + XGetGCValues(surf->dpy, surf->gc, GCGraphicsExposures, &gc_values); + XSetGraphicsExposures(surf->dpy, surf->gc, False); + XSetClipRectangles(surf->dpy, surf->gc, 0, 0, rects, m, Unsorted); + free(rects); + if (surf->picture) XRenderSetPictureClipRegion (surf->dpy, surf->picture, xregion); XDestroyRegion(xregion); - + XSetGraphicsExposures(surf->dpy, surf->gc, gc_values.graphics_exposures); return CAIRO_STATUS_SUCCESS; } @@ -654,6 +693,8 @@ cairo_xlib_surface_create (Display *dpy, { cairo_xlib_surface_t *surface; int render_standard; + Window w; + unsigned int ignore; surface = malloc (sizeof (cairo_xlib_surface_t)); if (surface == NULL) @@ -692,6 +733,12 @@ cairo_xlib_surface_create (Display *dpy, break; } + XGetGeometry(dpy, drawable, + &w, &ignore, &ignore, + &surface->width, + &surface->height, + &ignore, &ignore); + /* XXX: I'm currently ignoring the colormap. Is that bad? */ if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface)) surface->picture = XRenderCreatePicture (dpy, drawable, |