[208] in Zephyr Mailing List

home help back first fref pref prev next nref lref last post

Xserver: sunGX, GXxor, multiple clip regions fail when used together

daemon@ATHENA.MIT.EDU (Marc Horowitz)
Fri Mar 22 01:45:21 1996

To: xbugs@x.org
Cc: marc@MIT.EDU, zephyr@MIT.EDU
Date: Fri, 22 Mar 1996 01:42:54 EST
From: Marc Horowitz <marc@MIT.EDU>

     VERSION:

R6.1, public-patch-1

     CLIENT MACHINE and OPERATING SYSTEM:

Sparc/any OS

     DISPLAY TYPE:

Sun GX

     WINDOW MANAGER:

Any

     COMPILER:

Any

     AREA:

Xserver

     SYNOPSIS:

When a client requests that text be drawn with the function set to
GXxor and a clip region containing more than one rectangle, the
behavior is as if GXcopy is being used.

.../xc/programs/Xserver/hw/sun/sunGX.c

     DESCRIPTION:

The synopsis describes the bug adequately, I think.

I reported this bug about 18 months ago (1994/08/15 according to my
RCS logs).  I was told that a fix (not mine) has been integrated, but
since I was not an X Consortium member, I could not see the record
pertaining to this fix.  Given the several days I spent tracking down
and producing a fix for the bug, I considered this kind of rude, but I
was more interested in seeing the bug fixed.  Unfortunately, it is not
yet fixed in the 6.1 release.  Now, I'm at MIT, which is an X
Consortium member.  If you can please keep me, or at least our contact
up to date on this bug, it would be most appreciated.

     REPEAT BY:

This bug is tweaked by the zwgc program in the MIT zephyr
distribution.  (You can ask Ralph Swick or Anne Salemme for a demo if
you like.)  (For those of you who are familiar with zephyr, you can
see this lossage if you opaque-move a window diagonally over a zgram.
As the text is redrawn, the color is wrong.  If you've been using
zephyr on a sun and wondering why this is broke, apply the patch at
the end of this message to your X server and try again.)

I can write a simple program which breaks, but I've appended a patch
which fixes the problem instead.

     SAMPLE FIX:

This patch is relative to (I believe) r6 fix-11, but I'm told by
someone who did it that it applies cleanly to 6.1.

*** sunGX.c	1994/08/12 22:39:04
--- 1.3	1994/08/15 19:23:45
***************
*** 1,6 ****
--- 1,7 ----
  #ifndef lint
  static char *rid="$XConsortium: sunGX.c,v 1.26 94/04/17 20:29:38 kaleb Exp $";
  #endif /* lint */
+ static char *localrid="$Id: sunGX.c,v 1.3 1994/08/15 19:23:45 marc Exp $"
  /*
  Copyright (c) 1991  X Consortium
  
***************
*** 1532,1537 ****
--- 1533,1546 ----
      GXResetClip (gx, pDrawable->pScreen);
  }
  
+ /* stolen from cfb/cfbglblt8.c */
+ 
+ #define BOX_OVERLAP(box1, box2) \
+  	((box1)->x1 <= ((box2)->x2) && \
+  	 ((box2)->x1) <= (box1)->x2 && \
+ 	 (box1)->y1 <= ((box2)->y2) && \
+  	 ((box2)->y1) <= (box1)->y2)
+ 
  static void
  sunGXPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
      DrawablePtr	    pDrawable;
***************
*** 1550,1565 ****
      RegionPtr	    clip;
      BoxPtr	    extents;
      BoxRec	    box;
  
      clip = ((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip;
-     extents = &clip->extents;
  
!     if (REGION_NUM_RECTS(clip) == 1)
!     {
! 	GXSetClip (gx, extents);
!     }
!     else
!     {
      	/* compute an approximate (but covering) bounding box */
      	box.x1 = 0;
      	if ((ppci[0]->metrics.leftSideBearing < 0))
--- 1559,1576 ----
      RegionPtr	    clip;
      BoxPtr	    extents;
      BoxRec	    box;
+     BoxPtr	    clipbox;
+     int		    nrects;
+     int		    once = 0;
+     int		    rectx;
+     int		    i;
  
      clip = ((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip;
  
!     x += pDrawable->x;
!     y += pDrawable->y;
! 
!     for (nrects = REGION_NUM_RECTS(clip)-1; nrects >= 0; nrects--) {
      	/* compute an approximate (but covering) bounding box */
      	box.x1 = 0;
      	if ((ppci[0]->metrics.leftSideBearing < 0))
***************
*** 1572,1616 ****
      	box.y1 = -FONTMAXBOUNDS(pGC->font,ascent);
      	box.y2 = FONTMAXBOUNDS(pGC->font,descent);
      
!     	box.x1 += pDrawable->x + x;
!     	box.x2 += pDrawable->x + x;
!     	box.y1 += pDrawable->y + y;
!     	box.y2 += pDrawable->y + y;
      
!     	switch (RECT_IN_REGION(pGC->pScreen, clip, &box))
! 	{
! 	case rgnPART:
! 	    cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
! 	case rgnOUT:
! 	    return;
! 	}
!     }
! 
!     GXDrawInit (gx, pGC->fgPixel, 
! 		gx_stipple_rop_table[pGC->alu]|GX_PATTERN_ONES|POLY_N,
!  		pGC->planemask);
!     gx->mode = GX_BLIT_NOSRC | GX_MODE_COLOR1;
!     x += pDrawable->x;
!     y += pDrawable->y;
! 
!     while (nglyph--)
!     {
! 	pci = *ppci++;
! 	gx->incx = 0;
! 	gx->incy = 1;
! 	gx->x0 = x + pci->metrics.leftSideBearing;
! 	gx->x1 = (x + pci->metrics.rightSideBearing) - 1;
! 	gx->y0 = y - pci->metrics.ascent;
! 	h = pci->metrics.ascent + pci->metrics.descent;
! 	bits = (unsigned long *) pci->bits;
! 	while (h--) {
! 	    gx->font = *bits++;
! 	}
! 	x += pci->metrics.characterWidth;
      }
-     GXWait (gx, r);
-     gx->mode = GX_BLIT_SRC | GX_MODE_COLOR8;
-     GXResetClip (gx, pDrawable->pScreen);
  }
  
  static void
--- 1583,1626 ----
      	box.y1 = -FONTMAXBOUNDS(pGC->font,ascent);
      	box.y2 = FONTMAXBOUNDS(pGC->font,descent);
      
!     	box.x1 += x;
!     	box.x2 += x;
!     	box.y1 += y;
!     	box.y2 += y;
      
! 	if (BOX_OVERLAP(clipbox=(REGION_RECTS(clip)+nrects), &box)) {
! 	   if (!(once++)) {
! 	      GXDrawInit (gx, pGC->fgPixel, 
! 			  gx_stipple_rop_table[pGC->alu]|GX_PATTERN_ONES|POLY_N,
! 			  pGC->planemask);
! 	      gx->mode = GX_BLIT_NOSRC | GX_MODE_COLOR1;
! 	   }
! 
! 	   GXSetClip (gx, clipbox);
! 
! 	   for (i=0, rectx = x; i < nglyph; i++)
! 	      {
! 		 pci = ppci[i];
! 		 gx->incx = 0;
! 		 gx->incy = 1;
! 		 gx->x0 = rectx + pci->metrics.leftSideBearing;
! 		 gx->x1 = (rectx + pci->metrics.rightSideBearing) - 1;
! 		 gx->y0 = y - pci->metrics.ascent;
! 		 h = pci->metrics.ascent + pci->metrics.descent;
! 		 bits = (unsigned long *) pci->bits;
! 		 while (h--) {
! 		    gx->font = *bits++;
! 		 }
! 		 rectx += pci->metrics.characterWidth;
! 	      }
! 	}
!      }
! 
!     if (once) {
!        GXWait (gx, r);
!        gx->mode = GX_BLIT_SRC | GX_MODE_COLOR8;
!        GXResetClip (gx, pDrawable->pScreen);
      }
  }
  
  static void


home help back first fref pref prev next nref lref last post