1 dawes 1.1 /*
2 * Fill rectangles.
3 */
|
4 dawes 3.5 /* $XFree86: xc/programs/Xserver/cfb/cfbfillrct.c,v 3.4tsi Exp $ */
|
5 dawes 1.1
6 /*
7
|
8 dawes 3.4 Copyright 1989, 1998 The Open Group
|
9 dawes 1.1
|
10 dawes 3.4 All Rights Reserved.
|
11 dawes 1.1
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 dawes 3.4 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
19 dawes 1.1 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
|
22 dawes 3.4 Except as contained in this notice, the name of The Open Group shall not be
|
23 dawes 1.1 used in advertising or otherwise to promote the sale, use or other dealings
|
24 dawes 3.4 in this Software without prior written authorization from The Open Group.
|
25 dawes 1.1 */
26
|
27 dawes 3.4 /* $TOG: cfbfillrct.c /main/20 1998/02/09 14:05:17 kaleb $ */
|
28 dawes 1.1
29 #include "X.h"
30 #include "Xmd.h"
31 #include "servermd.h"
32 #include "gcstruct.h"
33 #include "window.h"
34 #include "pixmapstr.h"
35 #include "scrnintstr.h"
36 #include "windowstr.h"
|
37 dawes 3.5 #include "mi.h"
|
38 dawes 1.1 #include "cfb.h"
39 #include "cfbmskbits.h"
40 #include "mergerop.h"
41
42
43 void
44 cfbFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
45 DrawablePtr pDrawable;
46 int n;
47 BoxPtr rects;
48 PixmapPtr tile;
49 int xrot, yrot;
50 {
|
51 dawes 3.1 #if PSZ == 24
52 if (tile->drawable.width & 3)
53 #else
|
54 dawes 1.1 if (tile->drawable.width & PIM)
|
55 dawes 3.1 #endif
|
56 dawes 1.1 cfbFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
57 else
58 cfbFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
59 }
60
61 void
62 cfbFillRectTileOdd (pDrawable, pGC, nBox, pBox)
63 DrawablePtr pDrawable;
64 GCPtr pGC;
65 int nBox;
66 BoxPtr pBox;
67 {
68 int xrot, yrot;
69 void (*fill)();
70
71 xrot = pDrawable->x + pGC->patOrg.x;
72 yrot = pDrawable->y + pGC->patOrg.y;
|
73 hohndel 3.2 #if PSZ == 24
74 if (pGC->tile.pixmap->drawable.width & 3)
75 #else
|
76 dawes 1.1 if (pGC->tile.pixmap->drawable.width & PIM)
|
77 hohndel 3.2 #endif
|
78 dawes 1.1 {
79 fill = cfbFillBoxTileOddGeneral;
80 if ((pGC->planemask & PMSK) == PMSK)
81 {
82 if (pGC->alu == GXcopy)
83 fill = cfbFillBoxTileOddCopy;
84 }
85 }
86 else
87 {
88 fill = cfbFillBoxTile32sGeneral;
89 if ((pGC->planemask & PMSK) == PMSK)
90 {
91 if (pGC->alu == GXcopy)
92 fill = cfbFillBoxTile32sCopy;
93 }
94 }
95 (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
96 }
97
98 #define NUM_STACK_RECTS 1024
99 dawes 1.1
100 void
101 cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
102 DrawablePtr pDrawable;
103 register GCPtr pGC;
104 int nrectFill; /* number of rectangles to fill */
105 xRectangle *prectInit; /* Pointer to first rectangle to fill */
106 {
107 xRectangle *prect;
108 RegionPtr prgnClip;
109 register BoxPtr pbox;
110 register BoxPtr pboxClipped;
111 BoxPtr pboxClippedBase;
112 BoxPtr pextent;
113 BoxRec stackRects[NUM_STACK_RECTS];
114 cfbPrivGC *priv;
115 int numRects;
116 void (*BoxFill)();
117 int n;
118 int xorg, yorg;
|
119 dawes 3.0
120 #if PSZ != 8
121 if ((pGC->fillStyle == FillStippled) ||
122 (pGC->fillStyle == FillOpaqueStippled)) {
123 miPolyFillRect(pDrawable, pGC, nrectFill, prectInit);
124 return;
125 }
126 #endif
|
127 dawes 1.1
128 priv = cfbGetGCPrivate(pGC);
|
129 hohndel 3.3 prgnClip = pGC->pCompositeClip;
|
130 dawes 1.1
131 BoxFill = 0;
132 switch (pGC->fillStyle)
133 {
134 case FillSolid:
135 switch (priv->rop) {
136 case GXcopy:
137 BoxFill = cfbFillRectSolidCopy;
138 break;
139 case GXxor:
140 BoxFill = cfbFillRectSolidXor;
141 break;
142 default:
143 BoxFill = cfbFillRectSolidGeneral;
144 break;
145 }
146 break;
147 case FillTiled:
|
148 hohndel 3.3 if (!pGC->pRotatedPixmap)
|
149 dawes 1.1 BoxFill = cfbFillRectTileOdd;
150 else
151 {
152 if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
153 BoxFill = cfbFillRectTile32Copy;
154 else
155 BoxFill = cfbFillRectTile32General;
156 }
157 break;
158 #if PSZ == 8
159 case FillStippled:
|
160 hohndel 3.3 if (!pGC->pRotatedPixmap)
|
161 dawes 1.1 BoxFill = cfb8FillRectStippledUnnatural;
162 else
163 BoxFill = cfb8FillRectTransparentStippled32;
164 break;
165 case FillOpaqueStippled:
|
166 hohndel 3.3 if (!pGC->pRotatedPixmap)
|
167 dawes 1.1 BoxFill = cfb8FillRectStippledUnnatural;
168 else
169 BoxFill = cfb8FillRectOpaqueStippled32;
170 break;
171 #endif
172 }
173 prect = prectInit;
174 xorg = pDrawable->x;
175 yorg = pDrawable->y;
176 if (xorg || yorg)
177 {
178 prect = prectInit;
179 n = nrectFill;
180 while(n--)
181 {
182 prect->x += xorg;
183 prect->y += yorg;
184 prect++;
185 }
186 }
187
188 dawes 1.1 prect = prectInit;
189
190 numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
191 if (numRects > NUM_STACK_RECTS)
192 {
193 pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
194 if (!pboxClippedBase)
195 return;
196 }
197 else
198 pboxClippedBase = stackRects;
199
200 pboxClipped = pboxClippedBase;
201
202 if (REGION_NUM_RECTS(prgnClip) == 1)
203 {
204 int x1, y1, x2, y2, bx2, by2;
205
206 pextent = REGION_RECTS(prgnClip);
207 x1 = pextent->x1;
208 y1 = pextent->y1;
209 dawes 1.1 x2 = pextent->x2;
210 y2 = pextent->y2;
211 while (nrectFill--)
212 {
213 if ((pboxClipped->x1 = prect->x) < x1)
214 pboxClipped->x1 = x1;
215
216 if ((pboxClipped->y1 = prect->y) < y1)
217 pboxClipped->y1 = y1;
218
219 bx2 = (int) prect->x + (int) prect->width;
220 if (bx2 > x2)
221 bx2 = x2;
222 pboxClipped->x2 = bx2;
223
224 by2 = (int) prect->y + (int) prect->height;
225 if (by2 > y2)
226 by2 = y2;
227 pboxClipped->y2 = by2;
228
229 prect++;
230 dawes 1.1 if ((pboxClipped->x1 < pboxClipped->x2) &&
231 (pboxClipped->y1 < pboxClipped->y2))
232 {
233 pboxClipped++;
234 }
235 }
236 }
237 else
238 {
239 int x1, y1, x2, y2, bx2, by2;
240
241 pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
242 x1 = pextent->x1;
243 y1 = pextent->y1;
244 x2 = pextent->x2;
245 y2 = pextent->y2;
246 while (nrectFill--)
247 {
248 BoxRec box;
249
250 if ((box.x1 = prect->x) < x1)
251 dawes 1.1 box.x1 = x1;
252
253 if ((box.y1 = prect->y) < y1)
254 box.y1 = y1;
255
256 bx2 = (int) prect->x + (int) prect->width;
257 if (bx2 > x2)
258 bx2 = x2;
259 box.x2 = bx2;
260
261 by2 = (int) prect->y + (int) prect->height;
262 if (by2 > y2)
263 by2 = y2;
264 box.y2 = by2;
265
266 prect++;
267
268 if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
269 continue;
270
271 n = REGION_NUM_RECTS (prgnClip);
272 dawes 1.1 pbox = REGION_RECTS(prgnClip);
273
274 /* clip the rectangle to each box in the clip region
275 this is logically equivalent to calling Intersect()
276 */
277 while(n--)
278 {
279 pboxClipped->x1 = max(box.x1, pbox->x1);
280 pboxClipped->y1 = max(box.y1, pbox->y1);
281 pboxClipped->x2 = min(box.x2, pbox->x2);
282 pboxClipped->y2 = min(box.y2, pbox->y2);
283 pbox++;
284
285 /* see if clipping left anything */
286 if(pboxClipped->x1 < pboxClipped->x2 &&
287 pboxClipped->y1 < pboxClipped->y2)
288 {
289 pboxClipped++;
290 }
291 }
292 }
293 dawes 1.1 }
294 if (pboxClipped != pboxClippedBase)
295 (*BoxFill) (pDrawable, pGC,
296 pboxClipped-pboxClippedBase, pboxClippedBase);
297 if (pboxClippedBase != stackRects)
298 DEALLOCATE_LOCAL(pboxClippedBase);
299 }
|