[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cairo
Subject:    Re: [cairo] Clip region problems (pixman fixes)
From:       Keith Packard <keithp () keithp ! com>
Date:       2005-05-19 19:33:18
Message-ID: 1116531199.14688.421.camel () evo ! keithp ! com
[Download RAW message or body]

[Attachment #2 (multipart/mixed)]


As promised, here is a patch which makes the source clipping behaviour
in libpixman configurable.

-keith


["pixman-sourceclip.diff" (pixman-sourceclip.diff)]

Index: src/iccompose.c
===================================================================
RCS file: /cvs/cairo/libpixman/src/iccompose.c,v
retrieving revision 1.17
diff -u -p -r1.17 iccompose.c
--- src/iccompose.c	2 Mar 2005 15:43:33 -0000	1.17
+++ src/iccompose.c	19 May 2005 19:18:05 -0000
@@ -2265,7 +2265,7 @@ IcFetch_transform (pixman_compositeOpera
 	    y = MOD (y, op->u.transform.height);
 	    x = MOD (x, op->u.transform.width);
 	}
-	if (pixman_region_contains_point (op->clip, x, y, &box))
+	if (pixman_region_contains_point (op->src_clip, x, y, &box))
 	{
 	    (*op[1].set) (&op[1], x, y);
 	    bits = (*op[1].fetch) (&op[1]);
@@ -2302,7 +2302,7 @@ IcFetch_transform (pixman_compositeOpera
 		else
 		    tx = x;
 
-		if (pixman_region_contains_point (op->clip, tx, ty, &box))
+		if (pixman_region_contains_point (op->src_clip, tx, ty, &box))
 		{
 		    (*op[1].set) (&op[1], tx, ty);
 		    bits = (*op[1].fetch) (&op[1]);
@@ -2364,7 +2364,7 @@ IcFetcha_transform (pixman_compositeOper
 	    y = MOD (y, op->u.transform.height);
 	    x = MOD (x, op->u.transform.width);
 	}
-	if (pixman_region_contains_point (op->clip, x, y, &box))
+	if (pixman_region_contains_point (op->src_clip, x, y, &box))
 	{
 	    (*op[1].set) (&op[1], x, y);
 	    bits = (*op[1].fetcha) (&op[1]);
@@ -2402,7 +2402,7 @@ IcFetcha_transform (pixman_compositeOper
 		else
 		    tx = x;
 		
-		if (pixman_region_contains_point (op->clip, tx, ty, &box))
+		if (pixman_region_contains_point (op->src_clip, tx, ty, &box))
 		{
 		    (*op[1].set) (&op[1], tx, ty);
 		    bits = (*op[1].fetcha) (&op[1]);
@@ -2579,7 +2579,8 @@ IcBuildCompositeOperand (pixman_image_t	
 	op->down = IcStepDown_transform;
 	op->set = IcSet_transform;
 
-	op->clip = op[1].clip;
+	op->src_clip = op[1].src_clip;
+	op->dst_clip = op[1].dst_clip;
 	
 	return 1;
     }
@@ -2603,7 +2604,8 @@ IcBuildCompositeOperand (pixman_image_t	
 	op->down = IcStepDown_external;
 	op->set = IcSet_external;
 
-	op->clip = op[1].clip;
+	op->src_clip = op[1].dst_clip;
+	op->dst_clip = op[1].dst_clip;
 	
 	return 1;
     }
@@ -2627,7 +2629,11 @@ IcBuildCompositeOperand (pixman_image_t	
 		op->down = IcStepDown;
 		op->set = IcSet;
 
-		op->clip = image->pCompositeClip;
+		op->dst_clip = image->pCompositeClip;
+		if (image->compositeClipSource)
+		    op->src_clip = image->pCompositeClip;
+		else
+		    op->src_clip = image->pSourceClip;
 
 		IcGetPixels (image->pixels, bits, stride, bpp,
 			     xoff, yoff);
Index: src/icimage.c
===================================================================
RCS file: /cvs/cairo/libpixman/src/icimage.c,v
retrieving revision 1.26
diff -u -p -r1.26 icimage.c
--- src/icimage.c	28 Apr 2005 18:16:52 -0000	1.26
+++ src/icimage.c	19 May 2005 19:19:18 -0000
@@ -110,10 +110,15 @@ pixman_image_init (pixman_image_t *image
     image->subWindowMode = ClipByChildren;
     image->polyEdge = PolyEdgeSharp;
     image->polyMode = PolyModePrecise;
-    /* XXX: In the server this was 0. Why? */
-    image->freeCompClip = 1;
+    /* 
+     * In the server this was 0 because the composite clip list
+     * can be referenced from a window (and often is)
+     */
+    image->freeCompClip = 0;
+    image->freeSourceClip = 0;
     image->clientClipType = CT_NONE;
     image->componentAlpha = 0;
+    image->compositeClipSource = 0;
 
     image->alphaMap = 0;
     image->alphaOrigin.x = 0;
@@ -133,7 +138,13 @@ pixman_image_init (pixman_image_t *image
     image->pCompositeClip = pixman_region_create();
     pixman_region_union_rect (image->pCompositeClip, image->pCompositeClip,
 			0, 0, image->pixels->width, image->pixels->height);
+    image->freeCompClip = 1;
 
+    image->pSourceClip = pixman_region_create ();
+    pixman_region_union_rect (image->pSourceClip, image->pSourceClip,
+			0, 0, image->pixels->width, image->pixels->height);
+    image->freeSourceClip = 1;
+    
     image->transform = NULL;
 
     image->filter = PIXMAN_FILTER_NEAREST;
@@ -245,6 +256,9 @@ pixman_image_destroy (pixman_image_t *im
 {
     if (image->freeCompClip)
 	pixman_region_destroy (image->pCompositeClip);
+    
+    if (image->freeSourceClip)
+	pixman_region_destroy (image->pSourceClip);
 
     if (image->owns_pixels)
 	IcPixelsDestroy (image->pixels);
@@ -275,7 +289,7 @@ pixman_image_destroyClip (pixman_image_t
 
 int
 pixman_image_set_clip_region (pixman_image_t	*image,
-		      pixman_region16_t	*region)
+			      pixman_region16_t	*region)
 {
     pixman_image_destroyClip (image);
     if (region) {
@@ -284,9 +298,12 @@ pixman_image_set_clip_region (pixman_ima
 	image->clientClipType = CT_REGION;
     }
     
+    if (image->freeCompClip)
+	pixman_region_destroy (image->pCompositeClip);
     image->pCompositeClip = pixman_region_create();
     pixman_region_union_rect (image->pCompositeClip, image->pCompositeClip,
 			      0, 0, image->pixels->width, image->pixels->height);
+    image->freeCompClip = 1;
     if (region) {
 	pixman_region_translate (image->pCompositeClip,
 				 - image->clipOrigin.x,
@@ -352,7 +369,9 @@ IcClipImageSrc (pixman_region16_t	*regio
 	return 1;
     if (image->repeat)
     {
-	if (image->clientClipType != CT_NONE)
+	/* XXX no source clipping */
+	if (image->compositeClipSource &&
+	    image->clientClipType != CT_NONE)
 	{
 	    pixman_region_translate (region, 
 			   dx - image->clipOrigin.x,
@@ -366,8 +385,14 @@ IcClipImageSrc (pixman_region16_t	*regio
     }
     else
     {
+	pixman_region16_t   *clip;
+
+	if (image->compositeClipSource)
+	    clip = image->pCompositeClip;
+	else
+	    clip = image->pSourceClip;
 	return IcClipImageReg (region,
-			       image->pCompositeClip,
+			       clip,
 			       dx,
 			       dy);
     }
Index: src/icimage.h
===================================================================
RCS file: /cvs/cairo/libpixman/src/icimage.h,v
retrieving revision 1.22
diff -u -p -r1.22 icimage.h
--- src/icimage.h	3 Mar 2005 22:27:31 -0000	1.22
+++ src/icimage.h	19 May 2005 19:16:42 -0000
@@ -97,11 +97,12 @@ struct pixman_image {
     unsigned int    subWindowMode : 1;
     unsigned int    polyEdge : 1;
     unsigned int    polyMode : 1;
-    /* XXX: Do we need this field */
     unsigned int    freeCompClip : 1;
+    unsigned int    freeSourceClip : 1;
     unsigned int    clientClipType : 2;
     unsigned int    componentAlpha : 1;
-    unsigned int    unused : 23;
+    unsigned int    compositeClipSource : 1;
+    unsigned int    unused : 21;
 
     struct pixman_image *alphaMap;
     IcPoint	    alphaOrigin;
@@ -115,6 +116,7 @@ struct pixman_image {
     unsigned long   serialNumber;
 
     pixman_region16_t	    *pCompositeClip;
+    pixman_region16_t	    *pSourceClip;
     
     pixman_transform_t     *transform;
 
@@ -289,7 +291,8 @@ struct _pixman_compositeOperand {
 /* XXX: We're not supporting indexed operations, right?
     IcIndexedPtr	indexed;
 */
-    pixman_region16_t		*clip;
+    pixman_region16_t		*dst_clip;
+    pixman_region16_t		*src_clip;
 };
 
 typedef void (*IcCombineFunc) (pixman_compositeOperand	*src,

["signature.asc" (application/pgp-signature)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic