[cairo] [PATCH] XCB: implement set_clip_region

Jamey Sharp jamey at minilop.net
Mon Jul 31 10:15:03 PDT 2006


I've applied and pushed this patch. Thanks, Ian!

In other commits, I've converted the XCB backend to use the new(ish)
xcb_renderutil library that provides the same convenience interfaces
that libXrender offers on top of the actual protocol. That makes the XCB
backend a fair bit simpler and eliminates comments like:

/* XXX: Why is this ridiculously complex compared to the equivalent
 * function in cairo-xlib-surface.c */

--Jamey

> From nobody Mon Sep 17 00:00:00 2001
> From: Ian Osgood <iano at quirkster.com>
> Date: Wed Jun 21 07:06:20 2006 -0700
> Subject: [PATCH] XCB: implement set_clip_region
> 
> ---
> 
>  src/cairo-xcb-surface.c |   94 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 93 insertions(+), 1 deletions(-)
> 
> e4992094a224bd2b04ec80f252f39badc2c19a39
> diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
> index 657509d..4f5042a 100644
> --- a/src/cairo-xcb-surface.c
> +++ b/src/cairo-xcb-surface.c
> @@ -209,6 +209,9 @@ typedef struct cairo_xcb_surface {
>      int height;
>      int depth;
>  
> +    XCBRECTANGLE *clip_rects;
> +    int num_clip_rects;
> +
>      XCBRenderPICTURE picture;
>      XCBRenderPICTFORMINFO format;
>      int has_format;
> @@ -307,6 +310,8 @@ _cairo_xcb_surface_finish (void *abstrac
>      if (surface->gc.xid)
>  	XCBFreeGC (surface->dpy, surface->gc);
>  
> +    free (surface->clip_rects);
> +
>      surface->dpy = NULL;
>  
>      return CAIRO_STATUS_SUCCESS;
> @@ -566,6 +571,26 @@ _get_image_surface (cairo_xcb_surface_t 
>  }
>  
>  static void
> +_cairo_xcb_surface_set_picture_clip_rects (cairo_xcb_surface_t *surface)
> +{
> +    if (surface->num_clip_rects)
> +	XCBRenderSetPictureClipRectangles (surface->dpy, surface->picture,
> +					   0, 0,
> +					   surface->num_clip_rects,
> +					   surface->clip_rects);
> +}
> +
> +static void
> +_cairo_xcb_surface_set_gc_clip_rects (cairo_xcb_surface_t *surface)
> +{
> +    if (surface->num_clip_rects)
> +	XCBSetClipRectangles(surface->dpy, XCBClipOrderingYXSorted, surface->gc,
> +			     0, 0,
> +			     surface->num_clip_rects,
> +			     surface->clip_rects );
> +}
> +
> +static void
>  _cairo_xcb_surface_ensure_gc (cairo_xcb_surface_t *surface)
>  {
>      if (surface->gc.xid)
> @@ -573,6 +598,7 @@ _cairo_xcb_surface_ensure_gc (cairo_xcb_
>  
>      surface->gc = XCBGCONTEXTNew(surface->dpy);
>      XCBCreateGC (surface->dpy, surface->gc, surface->drawable, 0, 0);
> +    _cairo_xcb_surface_set_gc_clip_rects(surface);
>  }
>  
>  static cairo_status_t
> @@ -1050,6 +1076,69 @@ _cairo_xcb_surface_composite_trapezoids 
>  }
>  
>  static cairo_int_status_t
> +_cairo_xcb_surface_set_clip_region (void              *abstract_surface,
> +				    pixman_region16_t *region)
> +{
> +    cairo_xcb_surface_t *surface = abstract_surface;
> +
> +    if (surface->clip_rects) {
> +	free (surface->clip_rects);
> +	surface->clip_rects = NULL;
> +    }
> +
> +    surface->num_clip_rects = 0;
> +
> +    if (region == NULL) {
> +	if (surface->gc.xid) {
> +	    CARD32 mask = XCBGCClipMask;
> +	    CARD32 pa[] = { XCBNone };
> +
> +	    XCBChangeGC (surface->dpy, surface->gc, mask, pa);
> +	}
> +
> +	if (surface->has_format && surface->picture.xid) {
> +	    CARD32 mask = XCBRenderCPClipMask;
> +	    CARD32 pa[] = { XCBNone };
> +
> +	    XCBRenderChangePicture (surface->dpy, surface->picture, mask, pa);
> +	}
> +    } else {
> +	pixman_box16_t *boxes;
> +	XCBRECTANGLE *rects = NULL;
> +	int n_boxes, i;
> +
> +	n_boxes = pixman_region_num_rects (region);
> +	if (n_boxes > 0) {
> +	    rects = malloc (sizeof(XCBRECTANGLE) * n_boxes);
> +	    if (rects == NULL)
> +		return CAIRO_STATUS_NO_MEMORY;
> +	} else {
> +	    rects = NULL;
> +	}
> +
> +	boxes = pixman_region_rects (region);
> +
> +	for (i = 0; i < n_boxes; i++) {
> +	    rects[i].x = boxes[i].x1;
> +	    rects[i].y = boxes[i].y1;
> +	    rects[i].width = boxes[i].x2 - boxes[i].x1;
> +	    rects[i].height = boxes[i].y2 - boxes[i].y1;
> +	}
> +
> +	surface->clip_rects = rects;
> +	surface->num_clip_rects = n_boxes;
> +
> +	if (surface->gc.xid)
> +	    _cairo_xcb_surface_set_gc_clip_rects (surface);
> +
> +	if (surface->picture.xid)
> +	    _cairo_xcb_surface_set_picture_clip_rects (surface);
> +    }
> +
> +    return CAIRO_STATUS_SUCCESS;
> +}
> +
> +static cairo_int_status_t
>  _cairo_xcb_surface_get_extents (void		        *abstract_surface,
>  				cairo_rectangle_int16_t *rectangle)
>  {
> @@ -1086,7 +1175,7 @@ static const cairo_surface_backend_t cai
>      _cairo_xcb_surface_composite_trapezoids,
>      NULL, /* copy_page */
>      NULL, /* show_page */
> -    NULL, /* _cairo_xcb_surface_set_clip_region */
> +    _cairo_xcb_surface_set_clip_region,
>      NULL, /* intersect_clip_path */
>      _cairo_xcb_surface_get_extents,
>      NULL, /* old_show_glyphs */
> @@ -1171,6 +1260,9 @@ _cairo_xcb_surface_create_internal (XCBC
>      surface->height = height;
>      surface->depth = depth;
>  
> +    surface->clip_rects = NULL;
> +    surface->num_clip_rects = 0;
> +
>      if (format) {
>  	surface->depth = format->depth;
>      } else if (visual) {
> -- 
> 1.2.3
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.freedesktop.org/archives/cairo/attachments/20060731/444ba16a/attachment.pgp


More information about the cairo mailing list