7 Copyright (c) 1989 X Consortium
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 Except as contained in this notice, the name of the X Consortium shall not be
27 used in advertising or otherwise to promote the sale, use or other dealings
28 in this Software without prior written authorization from the X Consortium.
31 /* $XConsortium: cfbfillrct.c,v 5.18 94/04/17 20:28:47 dpw Exp $ */
32 /* $XFree86: xc/programs/Xserver/cfb/cfbfillrct.c,v 3.1.4.1 1997/05/10 07:02:48 hohndel Exp $ */
39 #include "pixmapstr.h"
40 #include "scrnintstr.h"
41 #include "windowstr.h"
44 #include "cfbmskbits.h"
49 cfbFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
50 DrawablePtr pDrawable;
57 if (tile->drawable.width & 3)
59 if (tile->drawable.width & PIM)
61 cfbFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
63 cfbFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
67 cfbFillRectTileOdd (pDrawable, pGC, nBox, pBox)
68 DrawablePtr pDrawable;
76 xrot = pDrawable->x + pGC->patOrg.x;
77 yrot = pDrawable->y + pGC->patOrg.y;
79 if (pGC->tile.pixmap->drawable.width & 3)
81 if (pGC->tile.pixmap->drawable.width & PIM)
84 fill = cfbFillBoxTileOddGeneral;
85 if ((pGC->planemask & PMSK) == PMSK)
87 if (pGC->alu == GXcopy)
88 fill = cfbFillBoxTileOddCopy;
93 fill = cfbFillBoxTile32sGeneral;
94 if ((pGC->planemask & PMSK) == PMSK)
96 if (pGC->alu == GXcopy)
97 fill = cfbFillBoxTile32sCopy;
100 (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
103 #define NUM_STACK_RECTS 1024
106 cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
107 DrawablePtr pDrawable;
109 int nrectFill; /* number of rectangles to fill */
110 xRectangle *prectInit; /* Pointer to first rectangle to fill */
114 register BoxPtr pbox;
115 register BoxPtr pboxClipped;
116 BoxPtr pboxClippedBase;
118 BoxRec stackRects[NUM_STACK_RECTS];
126 if ((pGC->fillStyle == FillStippled) ||
127 (pGC->fillStyle == FillOpaqueStippled)) {
128 miPolyFillRect(pDrawable, pGC, nrectFill, prectInit);
133 priv = cfbGetGCPrivate(pGC);
134 prgnClip = priv->pCompositeClip;
137 switch (pGC->fillStyle)
142 BoxFill = cfbFillRectSolidCopy;
145 BoxFill = cfbFillRectSolidXor;
148 BoxFill = cfbFillRectSolidGeneral;
153 if (!cfbGetGCPrivate(pGC)->pRotatedPixmap)
154 BoxFill = cfbFillRectTileOdd;
157 if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
158 BoxFill = cfbFillRectTile32Copy;
160 BoxFill = cfbFillRectTile32General;
165 if (!cfbGetGCPrivate(pGC)->pRotatedPixmap)
166 BoxFill = cfb8FillRectStippledUnnatural;
168 BoxFill = cfb8FillRectTransparentStippled32;
170 case FillOpaqueStippled:
171 if (!cfbGetGCPrivate(pGC)->pRotatedPixmap)
172 BoxFill = cfb8FillRectStippledUnnatural;
174 BoxFill = cfb8FillRectOpaqueStippled32;
195 numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
196 if (numRects > NUM_STACK_RECTS)
198 pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
199 if (!pboxClippedBase)
203 pboxClippedBase = stackRects;
205 pboxClipped = pboxClippedBase;
207 if (REGION_NUM_RECTS(prgnClip) == 1)
209 int x1, y1, x2, y2, bx2, by2;
211 pextent = REGION_RECTS(prgnClip);
218 if ((pboxClipped->x1 = prect->x) < x1)
219 pboxClipped->x1 = x1;
221 if ((pboxClipped->y1 = prect->y) < y1)
222 pboxClipped->y1 = y1;
224 bx2 = (int) prect->x + (int) prect->width;
227 pboxClipped->x2 = bx2;
229 by2 = (int) prect->y + (int) prect->height;
232 pboxClipped->y2 = by2;
235 if ((pboxClipped->x1 < pboxClipped->x2) &&
236 (pboxClipped->y1 < pboxClipped->y2))
244 int x1, y1, x2, y2, bx2, by2;
246 pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
255 if ((box.x1 = prect->x) < x1)
258 if ((box.y1 = prect->y) < y1)
261 bx2 = (int) prect->x + (int) prect->width;
266 by2 = (int) prect->y + (int) prect->height;
273 if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
276 n = REGION_NUM_RECTS (prgnClip);
277 pbox = REGION_RECTS(prgnClip);
279 /* clip the rectangle to each box in the clip region
280 this is logically equivalent to calling Intersect()
284 pboxClipped->x1 = max(box.x1, pbox->x1);
285 pboxClipped->y1 = max(box.y1, pbox->y1);
286 pboxClipped->x2 = min(box.x2, pbox->x2);
287 pboxClipped->y2 = min(box.y2, pbox->y2);
290 /* see if clipping left anything */
291 if(pboxClipped->x1 < pboxClipped->x2 &&
292 pboxClipped->y1 < pboxClipped->y2)
299 if (pboxClipped != pboxClippedBase)
300 (*BoxFill) (pDrawable, pGC,
301 pboxClipped-pboxClippedBase, pboxClippedBase);
302 if (pboxClippedBase != stackRects)
303 DEALLOCATE_LOCAL(pboxClippedBase);