First import
[xorg_rtime.git] / xorg-server-1.4 / cfb / cfbfillrct.c
blob4c78c24b391a8f472396b65052f08011756f877f
1 /*
2 * Fill rectangles.
3 */
5 /*
7 Copyright 1989, 1998 The Open Group
9 Permission to use, copy, modify, distribute, and sell this software and its
10 documentation for any purpose is hereby granted without fee, provided that
11 the above copyright notice appear in all copies and that both that
12 copyright notice and this permission notice appear in supporting
13 documentation.
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 Except as contained in this notice, the name of The Open Group shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings
27 in this Software without prior written authorization from The Open Group.
31 #ifdef HAVE_DIX_CONFIG_H
32 #include <dix-config.h>
33 #endif
35 #include <X11/X.h>
36 #include <X11/Xmd.h>
37 #include "servermd.h"
38 #include "gcstruct.h"
39 #include "window.h"
40 #include "pixmapstr.h"
41 #include "scrnintstr.h"
42 #include "windowstr.h"
43 #include "mi.h"
44 #include "cfb.h"
45 #include "cfbmskbits.h"
46 #include "mergerop.h"
49 void
50 cfbFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
51 DrawablePtr pDrawable;
52 int n;
53 BoxPtr rects;
54 PixmapPtr tile;
55 int xrot, yrot;
57 #if PSZ == 24
58 if (tile->drawable.width & 3)
59 #else
60 if (tile->drawable.width & PIM)
61 #endif
62 cfbFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
63 else
64 cfbFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
67 void
68 cfbFillRectTileOdd (pDrawable, pGC, nBox, pBox)
69 DrawablePtr pDrawable;
70 GCPtr pGC;
71 int nBox;
72 BoxPtr pBox;
74 int xrot, yrot;
75 void (*fill)(DrawablePtr, int, BoxPtr, PixmapPtr, int, int, int, unsigned long);
77 xrot = pDrawable->x + pGC->patOrg.x;
78 yrot = pDrawable->y + pGC->patOrg.y;
79 #if PSZ == 24
80 if (pGC->tile.pixmap->drawable.width & 3)
81 #else
82 if (pGC->tile.pixmap->drawable.width & PIM)
83 #endif
85 fill = cfbFillBoxTileOddGeneral;
86 if ((pGC->planemask & PMSK) == PMSK)
88 if (pGC->alu == GXcopy)
89 fill = cfbFillBoxTileOddCopy;
92 else
94 fill = cfbFillBoxTile32sGeneral;
95 if ((pGC->planemask & PMSK) == PMSK)
97 if (pGC->alu == GXcopy)
98 fill = cfbFillBoxTile32sCopy;
101 (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
104 #define NUM_STACK_RECTS 1024
106 void
107 cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
108 DrawablePtr pDrawable;
109 register GCPtr pGC;
110 int nrectFill; /* number of rectangles to fill */
111 xRectangle *prectInit; /* Pointer to first rectangle to fill */
113 xRectangle *prect;
114 RegionPtr prgnClip;
115 register BoxPtr pbox;
116 register BoxPtr pboxClipped;
117 BoxPtr pboxClippedBase;
118 BoxPtr pextent;
119 BoxRec stackRects[NUM_STACK_RECTS];
120 cfbPrivGC *priv;
121 int numRects;
122 void (*BoxFill)(DrawablePtr, GCPtr, int, BoxPtr);
123 int n;
124 int xorg, yorg;
126 #if PSZ != 8
127 if ((pGC->fillStyle == FillStippled) ||
128 (pGC->fillStyle == FillOpaqueStippled)) {
129 miPolyFillRect(pDrawable, pGC, nrectFill, prectInit);
130 return;
132 #endif
134 priv = cfbGetGCPrivate(pGC);
135 prgnClip = pGC->pCompositeClip;
137 BoxFill = 0;
138 switch (pGC->fillStyle)
140 case FillSolid:
141 switch (priv->rop) {
142 case GXcopy:
143 BoxFill = cfbFillRectSolidCopy;
144 break;
145 case GXxor:
146 BoxFill = cfbFillRectSolidXor;
147 break;
148 default:
149 BoxFill = cfbFillRectSolidGeneral;
150 break;
152 break;
153 case FillTiled:
154 if (!pGC->pRotatedPixmap)
155 BoxFill = cfbFillRectTileOdd;
156 else
158 if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
159 BoxFill = cfbFillRectTile32Copy;
160 else
161 BoxFill = cfbFillRectTile32General;
163 break;
164 #if PSZ == 8
165 case FillStippled:
166 if (!pGC->pRotatedPixmap)
167 BoxFill = cfb8FillRectStippledUnnatural;
168 else
169 BoxFill = cfb8FillRectTransparentStippled32;
170 break;
171 case FillOpaqueStippled:
172 if (!pGC->pRotatedPixmap)
173 BoxFill = cfb8FillRectStippledUnnatural;
174 else
175 BoxFill = cfb8FillRectOpaqueStippled32;
176 break;
177 #endif
179 prect = prectInit;
180 xorg = pDrawable->x;
181 yorg = pDrawable->y;
182 if (xorg || yorg)
184 prect = prectInit;
185 n = nrectFill;
186 while(n--)
188 prect->x += xorg;
189 prect->y += yorg;
190 prect++;
194 prect = prectInit;
196 numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
197 if (numRects > NUM_STACK_RECTS)
199 pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
200 if (!pboxClippedBase)
201 return;
203 else
204 pboxClippedBase = stackRects;
206 pboxClipped = pboxClippedBase;
208 if (REGION_NUM_RECTS(prgnClip) == 1)
210 int x1, y1, x2, y2, bx2, by2;
212 pextent = REGION_RECTS(prgnClip);
213 x1 = pextent->x1;
214 y1 = pextent->y1;
215 x2 = pextent->x2;
216 y2 = pextent->y2;
217 while (nrectFill--)
219 if ((pboxClipped->x1 = prect->x) < x1)
220 pboxClipped->x1 = x1;
222 if ((pboxClipped->y1 = prect->y) < y1)
223 pboxClipped->y1 = y1;
225 bx2 = (int) prect->x + (int) prect->width;
226 if (bx2 > x2)
227 bx2 = x2;
228 pboxClipped->x2 = bx2;
230 by2 = (int) prect->y + (int) prect->height;
231 if (by2 > y2)
232 by2 = y2;
233 pboxClipped->y2 = by2;
235 prect++;
236 if ((pboxClipped->x1 < pboxClipped->x2) &&
237 (pboxClipped->y1 < pboxClipped->y2))
239 pboxClipped++;
243 else
245 int x1, y1, x2, y2, bx2, by2;
247 pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
248 x1 = pextent->x1;
249 y1 = pextent->y1;
250 x2 = pextent->x2;
251 y2 = pextent->y2;
252 while (nrectFill--)
254 BoxRec box;
256 if ((box.x1 = prect->x) < x1)
257 box.x1 = x1;
259 if ((box.y1 = prect->y) < y1)
260 box.y1 = y1;
262 bx2 = (int) prect->x + (int) prect->width;
263 if (bx2 > x2)
264 bx2 = x2;
265 box.x2 = bx2;
267 by2 = (int) prect->y + (int) prect->height;
268 if (by2 > y2)
269 by2 = y2;
270 box.y2 = by2;
272 prect++;
274 if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
275 continue;
277 n = REGION_NUM_RECTS (prgnClip);
278 pbox = REGION_RECTS(prgnClip);
280 /* clip the rectangle to each box in the clip region
281 this is logically equivalent to calling Intersect()
283 while(n--)
285 pboxClipped->x1 = max(box.x1, pbox->x1);
286 pboxClipped->y1 = max(box.y1, pbox->y1);
287 pboxClipped->x2 = min(box.x2, pbox->x2);
288 pboxClipped->y2 = min(box.y2, pbox->y2);
289 pbox++;
291 /* see if clipping left anything */
292 if(pboxClipped->x1 < pboxClipped->x2 &&
293 pboxClipped->y1 < pboxClipped->y2)
295 pboxClipped++;
300 if (pboxClipped != pboxClippedBase)
301 (*BoxFill) (pDrawable, pGC,
302 pboxClipped-pboxClippedBase, pboxClippedBase);
303 if (pboxClippedBase != stackRects)
304 DEALLOCATE_LOCAL(pboxClippedBase);