[cairo-commit] libpixman/src icrect.c,1.10,1.11

Alexander Larsson commit at pdx.freedesktop.org
Mon Dec 20 06:15:23 PST 2004


Committed by: alexl

Update of /cvs/cairo/libpixman/src
In directory gabe:/tmp/cvs-serv16778/src

Modified Files:
	icrect.c 
Log Message:
2004-12-20  Alexander Larsson  <alexl at redhat.com>

	* src/icrect.c: (pixman_fill_rect_8bbp), (pixman_fill_rect_32bbp),
	(pixman_fill_rect_general), (pixman_color_rects),
	(pixman_fill_rectangles):
	Special case solid color rectangle fills.




Index: icrect.c
===================================================================
RCS file: /cvs/cairo/libpixman/src/icrect.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- icrect.c	16 Apr 2004 15:32:53 -0000	1.10
+++ icrect.c	20 Dec 2004 14:15:21 -0000	1.11
@@ -22,7 +22,90 @@
 
 #include "icint.h"
 
-/* XXX: I haven't ported this yet
+typedef void	(*FillFunc) (pixman_image_t *dst,
+			     int16_t	     xDst,
+			     int16_t	     yDst,
+			     uint16_t	     width,
+			     uint16_t	     height,
+			     pixman_bits_t  *pixel);
+
+
+static void
+pixman_fill_rect_8bbp (pixman_image_t *dst,
+		       int16_t	       xDst,
+		       int16_t	       yDst,
+		       uint16_t	       width,
+		       uint16_t	       height,
+		       pixman_bits_t  *pixel)
+{
+    char *line;
+
+    line = (char *)dst->pixels->data +
+	xDst + yDst * dst->pixels->stride;
+    while (height-- > 0) {
+	memset (line, *(char *)pixel, width);
+	line += dst->pixels->stride;
+    }
+}
+
+static void
+pixman_fill_rect_32bbp (pixman_image_t *dst,
+			int16_t	        xDst,
+			int16_t	        yDst, 
+			uint16_t	width,
+			uint16_t	height,
+			pixman_bits_t  *pixel)
+{
+    uint32_t int_pixel;
+    char *line;
+    char *data;
+    int w;
+
+    line = (char *)dst->pixels->data +
+	xDst * 4 + yDst * dst->pixels->stride;
+     
+    int_pixel = *(uint32_t *)pixel;
+    while (height-- > 0) {
+	data = line;
+	w = width;
+	while (w-- > 0) {
+	    *(uint32_t *)data = int_pixel;
+	    data += 4;
+	}
+	line += dst->pixels->stride;
+    }
+}
+
+static void
+pixman_fill_rect_general (pixman_image_t *dst,
+			  int16_t	  xDst,
+			  int16_t	  yDst,
+			  uint16_t	  width,
+			  uint16_t	  height,
+			  pixman_bits_t  *pixel)
+{
+    int pixel_size;
+    char *line;
+    char *data;
+    int w;
+
+    pixel_size = dst->pixels->bpp >> 3;
+
+    line = (char *)dst->pixels->data +
+	xDst * pixel_size + yDst * dst->pixels->stride;
+     
+    while (height-- > 0) {
+	data = line;
+	w = width;
+	while (w-- > 0) {
+	    memcpy (data, pixel, pixel_size);
+	    data += pixel_size;
+	}
+	line += dst->pixels->stride;
+    }
+}
+
+
 static void
 pixman_color_rects (pixman_image_t	 *dst,
 	      pixman_image_t	 *clipPict,
@@ -32,37 +115,83 @@
 	      int	 xoff,
 	      int	 yoff)
 {
-    uint32_t		pixel;
-    uint32_t		tmpval[4];
-    Region		*clip;
-    unsigned long	mask;
+    pixman_bits_t	pixel;
+    pixman_region16_t  *clip;
+    pixman_region16_t  *rects_as_region;
+    pixman_box16_t     *clipped_rects;
+    int	                i, n_clipped_rects;
+    FillFunc            func;
 
-    IcRenderColorToPixel (dst->image_format, color, &pixel);
+    pixman_color_to_pixel (&dst->image_format,
+			   color,
+			   &pixel);
 
-    if (clipPict->clientClipType == CT_REGION)
+    /* offset to the right place on the destination image */
+    xoff -= dst->pixels->x;
+    yoff -= dst->pixels->y;
+    
+    clip = pixman_region_create();
+    pixman_region_union_rect (clip, clip,
+			      dst->pixels->x, dst->pixels->y,
+			      dst->pixels->width, dst->pixels->height);
+
+    pixman_region_intersect (clip, clip, clipPict->pCompositeClip);
+    if (clipPict->alphaMap)
     {
-	tmpval[2] = dst->clipOrigin.x - xoff;
-	tmpval[3] = dst->clipOrigin.y - yoff;
-	mask |= CPClipXOrigin|CPClipYOrigin;
-	
-	clip = pixman_region_create ();
-	pixman_region_copy (clip, pClipPict->clientClip);
-	(*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
+	pixman_region_translate (clip, 
+				 -clipPict->alphaOrigin.x,
+				 -clipPict->alphaOrigin.y);
+	pixman_region_intersect (clip, clip, clipPict->alphaMap->pCompositeClip);
+	pixman_region_translate (clip, 
+				 clipPict->alphaOrigin.x,
+				 clipPict->alphaOrigin.y);
     }
+    if (clipPict->clientClipType != CT_NONE)
+	pixman_region_intersect (clip, clip, clipPict->clientClip);
 
     if (xoff || yoff)
     {
-	int	i;
 	for (i = 0; i < nRect; i++)
 	{
 	    rects[i].x -= xoff;
 	    rects[i].y -= yoff;
 	}
     }
-    (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects);
+
+    rects_as_region = pixman_region_create ();
+    for (i = 0; i < nRect; i++)
+    {
+	pixman_region_union_rect (rects_as_region, rects_as_region,
+				  rects[i].x, rects[i].y,
+				  rects[i].width, rects[i].height);
+    }
+
+    pixman_region_intersect (rects_as_region, rects_as_region, clip);
+    pixman_region_destroy (clip);
+
+    n_clipped_rects = pixman_region_num_rects (rects_as_region);
+    clipped_rects = pixman_region_rects (rects_as_region);
+
+    if (dst->pixels->bpp == 8)
+	func = pixman_fill_rect_8bbp;
+    else if (dst->pixels->bpp == 8)
+	func = pixman_fill_rect_32bbp;
+    else 
+	func = pixman_fill_rect_general;
+    
+    for (i = 0; i < n_clipped_rects; i++) {
+	(*func) (dst,
+		 clipped_rects[i].x1, 
+		 clipped_rects[i].y1, 
+		 clipped_rects[i].x2 - clipped_rects[i].x1, 
+		 clipped_rects[i].y2 - clipped_rects[i].y1,
+		 &pixel);
+    }
+
+    pixman_region_destroy (rects_as_region);
+
     if (xoff || yoff)
     {
-	int	i;
 	for (i = 0; i < nRect; i++)
 	{
 	    rects[i].x += xoff;
@@ -70,7 +199,6 @@
 	}
     }
 }
-*/
 
 void pixman_fill_rectangle (pixman_operator_t	op,
 		      pixman_image_t		*dst,
@@ -107,18 +235,18 @@
     if (op == PIXMAN_OPERATOR_CLEAR)
 	color_s.red = color_s.green = color_s.blue = color_s.alpha = 0;
 
-/* XXX: Really need this to optimize solid rectangles
-    if (op == PIXMAN_OPERATOR_SOURCE || op == PIXMAN_OPERATOR_CLEAR)
+    if (op == PIXMAN_OPERATOR_SRC || op == PIXMAN_OPERATOR_CLEAR)
     {
-	pixman_color_rects (dst, dst, &color_s, nRects, rects, 0, 0);
+      /* We cast away the constness of rects here, because pixman_color_rects
+	 temporarily modifies it */
+	pixman_color_rects (dst, dst, &color_s, nRects, (pixman_rectangle_t *)rects, 0, 0);
 	if (dst->alphaMap)
 	    pixman_color_rects (dst->alphaMap, dst,
-			  &color_s, nRects, rects,
+			  &color_s, nRects, (pixman_rectangle_t *)rects,
 			  dst->alphaOrigin.x,
 			  dst->alphaOrigin.y);
     }
     else
-*/
     {
 	pixman_format_t	rgbaFormat;
 	IcPixels	*pixels;




More information about the cairo-commit mailing list