First import
[xorg_rtime.git] / xorg-server-1.4 / cfb / cfbply1rct.c
blobce0bcb203115e38d5b48f5f9f014dc943a7fcbfb
1 /*
3 Copyright 1990, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
25 * Author: Keith Packard, MIT X Consortium
28 #ifdef HAVE_DIX_CONFIG_H
29 #include <dix-config.h>
30 #endif
32 #include <stdlib.h>
34 #include <X11/X.h>
36 #include "gcstruct.h"
37 #include "windowstr.h"
38 #include "pixmapstr.h"
39 #include "regionstr.h"
40 #include "scrnintstr.h"
41 #include "mistruct.h"
43 #include "cfb.h"
44 #include "cfbmskbits.h"
45 #include "cfbrrop.h"
47 void
48 RROP_NAME(cfbFillPoly1Rect) (pDrawable, pGC, shape, mode, count, ptsIn)
49 DrawablePtr pDrawable;
50 GCPtr pGC;
51 int shape;
52 int mode;
53 int count;
54 DDXPointPtr ptsIn;
56 cfbPrivGCPtr devPriv;
57 int nwidth;
58 CfbBits *addrl, *addr;
59 #if PSZ == 24
60 CfbBits startmask, endmask;
61 register int pidx;
62 #else
63 #if PPW > 1
64 CfbBits mask, bits = ~((CfbBits)0);
65 #endif
66 #endif
67 int maxy;
68 int origin;
69 register int vertex1, vertex2;
70 int c = 0;
71 BoxPtr extents;
72 int clip;
73 int y;
74 int *vertex1p = NULL, *vertex2p;
75 int *endp;
76 int x1 = 0, x2 = 0;
77 int dx1 = 0, dx2 = 0;
78 int dy1 = 0, dy2 = 0;
79 int e1 = 0, e2 = 0;
80 int step1 = 0, step2 = 0;
81 int sign1 = 0, sign2 = 0;
82 int h;
83 int l;
84 #if PSZ != 24 && PPW > 1
85 int r;
86 #endif
87 int nmiddle;
88 RROP_DECLARE
90 if (mode == CoordModePrevious)
92 miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
93 return;
96 devPriv = cfbGetGCPrivate(pGC);
97 #ifdef NO_ONE_RECT
98 if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1)
100 miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
101 return;
103 #endif
104 origin = *((int *) &pDrawable->x);
105 vertex2 = origin - ((origin & 0x8000) << 1);
106 extents = &pGC->pCompositeClip->extents;
107 RROP_FETCH_GCPRIV(devPriv);
108 vertex1 = *((int *) &extents->x1) - vertex2;
109 vertex2 = *((int *) &extents->x2) - vertex2 - 0x00010001;
110 clip = 0;
111 y = 32767;
112 maxy = 0;
113 vertex2p = (int *) ptsIn;
114 endp = vertex2p + count;
115 if (shape == Convex)
117 while (count--)
119 c = *vertex2p;
120 clip |= (c - vertex1) | (vertex2 - c);
121 c = intToY(c);
122 if (c < y)
124 y = c;
125 vertex1p = vertex2p;
127 vertex2p++;
128 if (c > maxy)
129 maxy = c;
132 else
134 int yFlip = 0;
135 dx1 = 1;
136 x2 = -1;
137 x1 = -1;
138 while (count--)
140 c = *vertex2p;
141 clip |= (c - vertex1) | (vertex2 - c);
142 c = intToY(c);
143 if (c < y)
145 y = c;
146 vertex1p = vertex2p;
148 vertex2p++;
149 if (c > maxy)
150 maxy = c;
151 if (c == x1)
152 continue;
153 if (dx1 > 0)
155 if (x2 < 0)
156 x2 = c;
157 else
158 dx2 = dx1 = (c - x1) >> 31;
160 else
161 if ((c - x1) >> 31 != dx1)
163 dx1 = ~dx1;
164 yFlip++;
166 x1 = c;
168 x1 = (x2 - c) >> 31;
169 if (x1 != dx1)
170 yFlip++;
171 if (x1 != dx2)
172 yFlip++;
173 if (yFlip != 2)
174 clip = 0x8000;
176 if (y == maxy)
177 return;
179 if (clip & 0x80008000)
181 miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn);
182 return;
185 #define AddrYPlus(a,y) (CfbBits *) (((unsigned char *) (a)) + (y) * nwidth)
187 cfbGetTypedWidthAndPointer(pDrawable, nwidth, addrl, unsigned char, CfbBits);
188 addrl = AddrYPlus(addrl,y + pDrawable->y);
189 origin = intToX(origin);
190 vertex2p = vertex1p;
191 vertex2 = vertex1 = *vertex2p++;
192 if (vertex2p == endp)
193 vertex2p = (int *) ptsIn;
194 #define Setup(c,x,vertex,dx,dy,e,sign,step) {\
195 x = intToX(vertex); \
196 if ((dy = intToY(c) - y)) { \
197 dx = intToX(c) - x; \
198 step = 0; \
199 if (dx >= 0) \
201 e = 0; \
202 sign = 1; \
203 if (dx >= dy) {\
204 step = dx / dy; \
205 dx = dx % dy; \
208 else \
210 e = 1 - dy; \
211 sign = -1; \
212 dx = -dx; \
213 if (dx >= dy) { \
214 step = - (dx / dy); \
215 dx = dx % dy; \
219 x += origin; \
220 vertex = c; \
223 #define Step(x,dx,dy,e,sign,step) {\
224 x += step; \
225 if ((e += dx) > 0) \
227 x += sign; \
228 e -= dy; \
231 for (;;)
233 if (y == intToY(vertex1))
237 if (vertex1p == (int *) ptsIn)
238 vertex1p = endp;
239 c = *--vertex1p;
240 Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1)
241 } while (y >= intToY(vertex1));
242 h = dy1;
244 else
246 Step(x1,dx1,dy1,e1,sign1,step1)
247 h = intToY(vertex1) - y;
249 if (y == intToY(vertex2))
253 c = *vertex2p++;
254 if (vertex2p == endp)
255 vertex2p = (int *) ptsIn;
256 Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
257 } while (y >= intToY(vertex2));
258 if (dy2 < h)
259 h = dy2;
261 else
263 Step(x2,dx2,dy2,e2,sign2,step2)
264 if ((c = (intToY(vertex2) - y)) < h)
265 h = c;
267 /* fill spans for this segment */
268 y += h;
269 for (;;)
271 l = x1;
272 #if PSZ != 24 && PPW > 1
273 r = x2;
274 #endif
275 nmiddle = x2 - x1;
276 if (nmiddle < 0)
278 nmiddle = -nmiddle;
279 l = x2;
280 #if PSZ != 24 && PPW > 1
281 r = x1;
282 #endif
284 #if PPW > 1
285 c = l & PIM;
286 l -= c;
287 #endif
289 #if PGSZ == 32
290 #define LWRD_SHIFT 2
291 #else /* PGSZ == 64 */
292 #define LWRD_SHIFT 3
293 #endif /* PGSZ */
295 #if PSZ == 24
296 addr = (CfbBits *)((char *)addrl + ((l * 3) & ~0x03));
297 if (nmiddle <= 1){
298 if (nmiddle)
299 RROP_SOLID24(addr, l);
300 } else {
301 maskbits(l, nmiddle, startmask, endmask, nmiddle);
302 pidx = l & 3;
303 if (startmask){
304 RROP_SOLID_MASK(addr, startmask, pidx-1);
305 addr++;
306 if (pidx == 3)
307 pidx = 0;
309 while (--nmiddle >= 0){
310 RROP_SOLID(addr, pidx);
311 addr++;
312 if (++pidx == 3)
313 pidx = 0;
315 if (endmask)
316 RROP_SOLID_MASK(addr, endmask, pidx);
318 #else /* PSZ == 24 */
319 #if PWSH > LWRD_SHIFT
320 l = l >> (PWSH - LWRD_SHIFT);
321 #endif
322 #if PWSH < LWRD_SHIFT
323 l = l << (LWRD_SHIFT - PWSH);
324 #endif
325 addr = (CfbBits *) (((char *) addrl) + l);
326 #if PPW > 1
327 if (c + nmiddle < PPW)
329 mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle);
330 RROP_SOLID_MASK(addr,mask);
332 else
334 if (c)
336 mask = SCRRIGHT(bits, c);
337 RROP_SOLID_MASK(addr,mask);
338 nmiddle += c - PPW;
339 addr++;
341 #endif
342 nmiddle >>= PWSH;
343 while (--nmiddle >= 0) {
344 RROP_SOLID(addr); addr++;
346 #if PPW > 1
347 if ((mask = ~SCRRIGHT(bits, r & PIM)))
348 RROP_SOLID_MASK(addr,mask);
350 #endif
351 #endif /* PSZ == 24 */
352 if (!--h)
353 break;
354 addrl = AddrYPlus (addrl, 1);
355 Step(x1,dx1,dy1,e1,sign1,step1)
356 Step(x2,dx2,dy2,e2,sign2,step2)
358 if (y == maxy)
359 break;
360 addrl = AddrYPlus (addrl, 1);
362 RROP_UNDECLARE