[cairo] [PATCH] XCB: implement set_clip_region

Ian Osgood iano at quirkster.com
Wed Jun 21 07:15:11 PDT 2006


No breakage, but no new passes either.

Ian

-------------- next part --------------
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



More information about the cairo mailing list