[208] in Zephyr Mailing List
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