RWS@ZERMATT.LCS.MIT.EDU (Robert Scheifler) (10/10/87)
Date: Tue, 6 Oct 87 15:35:08 PDT From: Geoff Kuenning <bilbo.geoff@CS.UCLA.EDU> VERSION: X11 release 1 SYNOPSIS: miClipSpans doesn't check all boxes if !fSorted DESCRIPTION: The code for fSorted == FALSE in miClipSpans appears to have been erroneously copied from the fSorted == TRUE code, and breaks out of the loop before checking all boxes. This can cause clipping errors. REPEAT-BY: Build a server that uses miClipSpans, and run ico in a window that has lots of partial overlaps, so that it has lots of clip boxes. Note that the icosahedron often disappears. FIX: in server/ddx/mi/miregion.c, replace the RCS header with /* $Header: miregion.c,v 1.28 87/10/08 13:48:14 rws Exp $ */ and replace miClipSpans with the following (sending entire thing is smaller than the diffs) (for an RT server with a broken hc, you may have to play with ++s): int miClipSpans(prgnDst, ppt, pwidth, nspans, pptNew, pwidthNew, fSorted) RegionPtr prgnDst; register DDXPointPtr ppt; register int *pwidth; int nspans; register DDXPointPtr pptNew; int *pwidthNew; int fSorted; { register BoxPtr pbox, pboxLast; BoxPtr pboxTest; register DDXPointPtr pptLast; int yMax; int *pwidthNewThatWeWerePassed; /* the vengeance of Xerox! */ pptLast = ppt + nspans; pboxTest = prgnDst->rects; pboxLast = pboxTest + prgnDst->numRects; yMax = prgnDst->extents.y2; pwidthNewThatWeWerePassed = pwidthNew; for (; ppt < pptLast; ppt++, pwidth++) { if(fSorted) { if(ppt->y >= yMax) break; pbox = pboxTest; } else { if(ppt->y >= yMax) continue; pbox = prgnDst->rects; } if(*pwidth == 0) continue; while(pbox < pboxLast) { if(pbox->y1 > ppt->y) { /* scanline is before clip box */ break; } if(pbox->y2 <= ppt->y) { /* clip box is before scanline */ pboxTest = ++pbox; continue; } if(pbox->x1 >= ppt->x + *pwidth) { /* clip box is to right of scanline */ break; } if(pbox->x2 <= ppt->x) { /* scanline is to right of clip box */ pbox++; continue; } /* at least some of the scanline is in the current clip box */ pptNew->x = max(pbox->x1, ppt->x); pptNew->y = ppt->y; *pwidthNew++ = min(ppt->x + *pwidth, pbox->x2) - pptNew->x; pptNew++; pbox++; } } return (pwidthNew - pwidthNewThatWeWerePassed); }