home *** CD-ROM | disk | FTP | other *** search
- /* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
- /***********************************************************
- Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
- and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the names of Digital or MIT not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
-
- ******************************************************************/
- /* $XConsortium: mfbfillrct.c,v 5.8 91/05/25 19:00:50 rws Exp $ */
- #include "X.h"
- #include "Xprotostr.h"
- #include "pixmapstr.h"
- #include "gcstruct.h"
- #include "windowstr.h"
- #include "miscstruct.h"
- #include "regionstr.h"
- #include "scrnintstr.h"
-
- #include "mfb.h"
- #include "maskbits.h"
-
- #define MODEQ(a, b) ((a) %= (b))
- void mfbPaintOddSize();
-
- /*
- filled rectangles.
- translate the rectangles, clip them, and call the
- helper function in the GC.
- */
-
- #define NUM_STACK_RECTS 1024
-
- void
- mfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
- DrawablePtr pDrawable;
- GCPtr pGC;
- int nrectFill; /* number of rectangles to fill */
- xRectangle *prectInit; /* Pointer to first rectangle to fill */
- {
- xRectangle *prect;
- RegionPtr prgnClip;
- register BoxPtr pbox;
- register BoxPtr pboxClipped;
- BoxPtr pboxClippedBase;
- BoxPtr pextent;
- BoxRec stackRects[NUM_STACK_RECTS];
- int numRects;
- int n;
- int xorg, yorg;
- mfbPrivGC *priv;
- int alu;
- void (* pfn) ();
- PixmapPtr ppix;
-
- if (!(pGC->planemask & 1))
- return;
-
- priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
- alu = priv->ropFillArea;
- pfn = priv->FillArea;
- ppix = priv->pRotatedPixmap;
- prgnClip = priv->pCompositeClip;
-
- prect = prectInit;
- xorg = pDrawable->x;
- yorg = pDrawable->y;
- if (xorg || yorg)
- {
- prect = prectInit;
- n = nrectFill;
- Duff (n, prect->x += xorg; prect->y += yorg; prect++);
- }
-
-
- prect = prectInit;
-
- numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
- if (numRects > NUM_STACK_RECTS)
- {
- pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
- if (!pboxClippedBase)
- return;
- }
- else
- pboxClippedBase = stackRects;
-
- pboxClipped = pboxClippedBase;
-
- if (REGION_NUM_RECTS(prgnClip) == 1)
- {
- int x1, y1, x2, y2, bx2, by2;
-
- pextent = REGION_RECTS(prgnClip);
- x1 = pextent->x1;
- y1 = pextent->y1;
- x2 = pextent->x2;
- y2 = pextent->y2;
- while (nrectFill--)
- {
- if ((pboxClipped->x1 = prect->x) < x1)
- pboxClipped->x1 = x1;
-
- if ((pboxClipped->y1 = prect->y) < y1)
- pboxClipped->y1 = y1;
-
- bx2 = (int) prect->x + (int) prect->width;
- if (bx2 > x2)
- bx2 = x2;
- pboxClipped->x2 = bx2;
-
- by2 = (int) prect->y + (int) prect->height;
- if (by2 > y2)
- by2 = y2;
- pboxClipped->y2 = by2;
-
- prect++;
- if ((pboxClipped->x1 < pboxClipped->x2) &&
- (pboxClipped->y1 < pboxClipped->y2))
- {
- pboxClipped++;
- }
- }
- }
- else
- {
- int x1, y1, x2, y2, bx2, by2;
-
- pextent = (*pGC->pScreen->RegionExtents)(prgnClip);
- x1 = pextent->x1;
- y1 = pextent->y1;
- x2 = pextent->x2;
- y2 = pextent->y2;
- while (nrectFill--)
- {
- BoxRec box;
-
- if ((box.x1 = prect->x) < x1)
- box.x1 = x1;
-
- if ((box.y1 = prect->y) < y1)
- box.y1 = y1;
-
- bx2 = (int) prect->x + (int) prect->width;
- if (bx2 > x2)
- bx2 = x2;
- box.x2 = bx2;
-
- by2 = (int) prect->y + (int) prect->height;
- if (by2 > y2)
- by2 = y2;
- box.y2 = by2;
-
- prect++;
-
- if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
- continue;
-
- n = REGION_NUM_RECTS (prgnClip);
- pbox = REGION_RECTS(prgnClip);
-
- /* clip the rectangle to each box in the clip region
- this is logically equivalent to calling Intersect()
- */
- while(n--)
- {
- pboxClipped->x1 = max(box.x1, pbox->x1);
- pboxClipped->y1 = max(box.y1, pbox->y1);
- pboxClipped->x2 = min(box.x2, pbox->x2);
- pboxClipped->y2 = min(box.y2, pbox->y2);
- pbox++;
-
- /* see if clipping left anything */
- if(pboxClipped->x1 < pboxClipped->x2 &&
- pboxClipped->y1 < pboxClipped->y2)
- {
- pboxClipped++;
- }
- }
- }
- }
- if (pboxClipped != pboxClippedBase)
- (*pfn) (pDrawable,pboxClipped-pboxClippedBase, pboxClippedBase, alu, ppix);
- if (pboxClippedBase != stackRects)
- DEALLOCATE_LOCAL(pboxClippedBase);
- }
-