2003-10-13  Adam Fedor  <fedor@gnu.org>

        * Source/xlib/XGBitmap.m: Cache color lookup to reduce use
	of XQueryColor (based on code from Marko Riedel).

Index: Source/xlib/XGBitmap.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/back/Source/xlib/XGBitmap.m,v
retrieving revision 1.5
diff -u -r1.5 XGBitmap.m
--- Source/xlib/XGBitmap.m	21 Sep 2003 03:19:17 -0000	1.5
+++ Source/xlib/XGBitmap.m	15 Oct 2003 21:22:02 -0000
@@ -94,6 +94,23 @@
 	(a) = MAX(0, MIN(255, (a))); \
     } while (0)
 
+#define CSIZE 16384
+#define GS_QUERY_COLOR(color)					\
+  do {								\
+    int centry = color.pixel % CSIZE;				\
+    if (empty[centry] == NO && pixels[centry] == color.pixel)	\
+      {								\
+	color = colors[centry];					\
+      }								\
+    else							\
+      {								\
+	empty[centry] = NO;					\
+	XQueryColor(context->dpy, context->cmap, &color);	\
+	pixels[centry] = color.pixel;				\
+	colors[centry] = color;					\
+      }								\
+  } while(0)
+
 /* Composite source image (pixmap) onto a destination image with alpha.
    Only works for op=Sover now
 
@@ -220,9 +237,18 @@
     }
   else
     {
+      unsigned long pixels[CSIZE];
+      XColor colors[CSIZE];
+      BOOL empty[CSIZE];
       XColor		c2;
       unsigned		row;
+      int cind;
 
+      for(cind = 0; cind < CSIZE; cind++)
+	{
+	  empty[cind] = YES;
+	}
+      
       /*
        * This block of code should be totally portable as it uses the
        * 'official' X mechanism for converting from pixel values to
@@ -241,7 +267,7 @@
 	      XColor pcolor, acolor, c0, c1;
 	      pcolor.pixel = XGetPixel(source_im->image, 
 				       col + srect.x, row + srect.y);
-	      XQueryColor(context->dpy, context->cmap, &pcolor);
+	      GS_QUERY_COLOR(pcolor);
 	      r = pcolor.red >> 8;
 	      g = pcolor.green >> 8;
 	      b = pcolor.blue >> 8;
@@ -250,7 +276,7 @@
 		{
 		  acolor.pixel = XGetPixel(source_alpha->image,
 				    col + srect.x, row + srect.y);
-		  XQueryColor(context->dpy, context->cmap, &acolor);
+		  GS_QUERY_COLOR(acolor);
 		  alpha = acolor.red >> 8;
 		}
 	      if (alpha == 0)
@@ -282,7 +308,7 @@
 		  if (c0.pixel != oldPixel)
 		    {
 		      oldPixel = c0.pixel;
-		      XQueryColor(context->dpy, context->cmap, &c0);
+		      GS_QUERY_COLOR(c0);
 		    }
 		      
 		  // mix in alpha to produce RGB out
@@ -316,7 +342,7 @@
 		  /* Alpha gets mixed the same as all the
 		     other color components */
 		  da.pixel = XGetPixel(dest_alpha->image, col, row);
-		  XQueryColor(context->dpy, context->cmap, &da);
+		  GS_QUERY_COLOR(da);
 		  da.red = acolor.red + da.red * (65536 - acolor.red)/65536;
 		  da.green = da.blue = da.red;
 		  XAllocColor(context->dpy, context->cmap, &da);
@@ -985,6 +1011,15 @@
       {
 	XColor		c2, a2;
 	unsigned       row, oldAlpha = 65537;
+	unsigned long pixels[CSIZE];
+	XColor colors[CSIZE];
+	BOOL empty[CSIZE];
+	int cind;
+
+	for(cind = 0; cind < CSIZE; cind++)
+	  {
+	    empty[cind] = YES;
+	  }
 
 	/*
 	 * This block of code should be totally portable as it uses the
@@ -1028,7 +1063,7 @@
 			/* Alpha gets mixed the same as all the
 			   other color components */
 			da.pixel = XGetPixel(dest_alpha->image, col, row);
-			XQueryColor(context->dpy, context->cmap, &da);
+			GS_QUERY_COLOR(da);
 			da.red = a2.red + da.red * (65536 - a2.red)/65536;
 			da.green = da.blue = da.red;
 			XAllocColor(context->dpy, context->cmap, &da);
@@ -1063,7 +1098,7 @@
 			if (c0.pixel != pixel)
 			  {
 			    pixel = c0.pixel;
-			    XQueryColor(context->dpy, context->cmap, &c0);
+			    GS_QUERY_COLOR(c0);
 			  }
 			
 			// mix in alpha to produce RGB out
@@ -1221,6 +1256,15 @@
     {
       XColor		c2;
       unsigned		row;
+      unsigned long pixels[CSIZE];
+      XColor colors[CSIZE];
+      BOOL empty[CSIZE];
+      int cind;
+      
+      for(cind = 0; cind < CSIZE; cind++)
+	{
+	  empty[cind] = YES;
+	}
 
       /*
        * This block of code should be totally portable as it uses the
@@ -1239,7 +1283,7 @@
 	      int r, g, b, alpha;
 	      XColor pcolor, acolor;
 	      pcolor.pixel = XGetPixel(source_im->image, col, row);
-	      XQueryColor(context->dpy, context->cmap, &pcolor);
+	      GS_QUERY_COLOR(pcolor);
 	      r = pcolor.red >> 8;
 	      g = pcolor.green >> 8;
 	      b = pcolor.blue >> 8;
@@ -1247,7 +1291,7 @@
 	      if (source_alpha)
 		{
 		  acolor.pixel = XGetPixel(source_alpha->image, col, row);
-		  XQueryColor(context->dpy, context->cmap, &acolor);
+		  GS_QUERY_COLOR(acolor);
 		  alpha = acolor.red >> 8;
 		}
 
