Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!cmcl2!rutgers!sri-spam!ames!ucbcad!ucbvax!ZERMATT.LCS.MIT.EDU!RWS From: RWS@ZERMATT.LCS.MIT.EDU (Robert Scheifler) Newsgroups: comp.windows.x Subject: V11 miClipSpans quits early when fSorted is FALSE Message-ID: <871009183246.3.RWS@KILLINGTON.LCS.MIT.EDU> Date: Fri, 9-Oct-87 18:32:00 EDT Article-I.D.: KILLINGT.871009183246.3.RWS Posted: Fri Oct 9 18:32:00 1987 Date-Received: Mon, 12-Oct-87 01:25:33 EDT References: <8710071126.AA09210@ATHENA.MIT.EDU> Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet Lines: 101 Date: Tue, 6 Oct 87 15:35:08 PDT From: Geoff Kuenning 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); }