]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbply1rct.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbply1rct.c
1 /*
2  * $XConsortium: cfbply1rct.c /main/16 1996/08/12 22:07:31 dpw $
3  * $XFree86: xc/programs/Xserver/cfb/cfbply1rct.c,v 3.3 1996/12/23 06:29:21 dawes Exp $
4  *
5 Copyright (c) 1990  X Consortium
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
27  *
28  * Author:  Keith Packard, MIT X Consortium
29  */
30
31 #include "X.h"
32
33 #include "gcstruct.h"
34 #include "windowstr.h"
35 #include "pixmapstr.h"
36 #include "regionstr.h"
37 #include "scrnintstr.h"
38 #include "mistruct.h"
39
40 #include "cfb.h"
41 #include "cfbmskbits.h"
42 #include "cfbrrop.h"
43
44 void
45 RROP_NAME(cfbFillPoly1Rect) (pDrawable, pGC, shape, mode, count, ptsIn)
46     DrawablePtr pDrawable;
47     GCPtr       pGC;
48     int         shape;
49     int         mode;
50     int         count;
51     DDXPointPtr ptsIn;
52 {
53     cfbPrivGCPtr    devPriv;
54     int             nwidth;
55     unsigned long   *addrl, *addr;
56 #if PSZ == 24
57     unsigned long startmask, endmask;
58     register int pidx;
59 #endif
60     int             maxy;
61     int             origin;
62     register int    vertex1, vertex2;
63     int             c;
64     BoxPtr          extents;
65     int             clip;
66     int             y;
67     int             *vertex1p, *vertex2p;
68     int             *endp;
69     int             x1, x2;
70     int             dx1, dx2;
71     int             dy1, dy2;
72     int             e1, e2;
73     int             step1, step2;
74     int             sign1, sign2;
75     int             h;
76     int             l, r;
77     unsigned long   mask, bits = ~((unsigned long)0);
78     int             nmiddle;
79     RROP_DECLARE
80
81     if (mode == CoordModePrevious)
82     {
83         miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
84         return;
85     }
86     
87     devPriv = cfbGetGCPrivate(pGC);
88 #ifdef NO_ONE_RECT
89     if (REGION_NUM_RECTS(devPriv->pCompositeClip) != 1)
90     {
91         miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
92         return;
93     }
94 #endif
95     origin = *((int *) &pDrawable->x);
96     vertex2 = origin - ((origin & 0x8000) << 1);
97     extents = &devPriv->pCompositeClip->extents;
98     RROP_FETCH_GCPRIV(devPriv);
99     vertex1 = *((int *) &extents->x1) - vertex2;
100     vertex2 = *((int *) &extents->x2) - vertex2 - 0x00010001;
101     clip = 0;
102     y = 32767;
103     maxy = 0;
104     vertex2p = (int *) ptsIn;
105     endp = vertex2p + count;
106     if (shape == Convex)
107     {
108         while (count--)
109         {
110             c = *vertex2p;
111             clip |= (c - vertex1) | (vertex2 - c);
112             c = intToY(c);
113             if (c < y) 
114             {
115                 y = c;
116                 vertex1p = vertex2p;
117             }
118             vertex2p++;
119             if (c > maxy)
120                 maxy = c;
121         }
122     }
123     else
124     {
125         int yFlip = 0;
126         dx1 = 1;
127         x2 = -1;
128         x1 = -1;
129         while (count--)
130         {
131             c = *vertex2p;
132             clip |= (c - vertex1) | (vertex2 - c);
133             c = intToY(c);
134             if (c < y) 
135             {
136                 y = c;
137                 vertex1p = vertex2p;
138             }
139             vertex2p++;
140             if (c > maxy)
141                 maxy = c;
142             if (c == x1)
143                 continue;
144             if (dx1 > 0)
145             {
146                 if (x2 < 0)
147                     x2 = c;
148                 else
149                     dx2 = dx1 = (c - x1) >> 31;
150             }
151             else
152                 if ((c - x1) >> 31 != dx1) 
153                 {
154                     dx1 = ~dx1;
155                     yFlip++;
156                 }
157             x1 = c;
158         }
159         x1 = (x2 - c) >> 31;
160         if (x1 != dx1)
161             yFlip++;
162         if (x1 != dx2)
163             yFlip++;
164         if (yFlip != 2) 
165             clip = 0x8000;
166     }
167     if (y == maxy)
168         return;
169
170     if (clip & 0x80008000)
171     {
172         miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn);
173         return;
174     }
175
176 #define AddrYPlus(a,y)  (unsigned long *) (((unsigned char *) (a)) + (y) * nwidth)
177
178     cfbGetTypedWidthAndPointer(pDrawable, nwidth, addrl, unsigned char, unsigned long);
179     addrl = AddrYPlus(addrl,y + pDrawable->y);
180     origin = intToX(origin);
181     vertex2p = vertex1p;
182     vertex2 = vertex1 = *vertex2p++;
183     if (vertex2p == endp)
184         vertex2p = (int *) ptsIn;
185 #define Setup(c,x,vertex,dx,dy,e,sign,step) {\
186     x = intToX(vertex); \
187     if (dy = intToY(c) - y) { \
188         dx = intToX(c) - x; \
189         step = 0; \
190         if (dx >= 0) \
191         { \
192             e = 0; \
193             sign = 1; \
194             if (dx >= dy) {\
195                 step = dx / dy; \
196                 dx = dx % dy; \
197             } \
198         } \
199         else \
200         { \
201             e = 1 - dy; \
202             sign = -1; \
203             dx = -dx; \
204             if (dx >= dy) { \
205                 step = - (dx / dy); \
206                 dx = dx % dy; \
207             } \
208         } \
209     } \
210     x += origin; \
211     vertex = c; \
212 }
213
214 #define Step(x,dx,dy,e,sign,step) {\
215     x += step; \
216     if ((e += dx) > 0) \
217     { \
218         x += sign; \
219         e -= dy; \
220     } \
221 }
222     for (;;)
223     {
224         if (y == intToY(vertex1))
225         {
226             do
227             {
228                 if (vertex1p == (int *) ptsIn)
229                     vertex1p = endp;
230                 c = *--vertex1p;
231                 Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1)
232             } while (y >= intToY(vertex1));
233             h = dy1;
234         }
235         else
236         {
237             Step(x1,dx1,dy1,e1,sign1,step1)
238             h = intToY(vertex1) - y;
239         }
240         if (y == intToY(vertex2))
241         {
242             do
243             {
244                 c = *vertex2p++;
245                 if (vertex2p == endp)
246                     vertex2p = (int *) ptsIn;
247                 Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
248             } while (y >= intToY(vertex2));
249             if (dy2 < h)
250                 h = dy2;
251         }
252         else
253         {
254             Step(x2,dx2,dy2,e2,sign2,step2)
255             if ((c = (intToY(vertex2) - y)) < h)
256                 h = c;
257         }
258         /* fill spans for this segment */
259         y += h;
260         for (;;)
261         {
262             l = x1;
263             r = x2;
264             nmiddle = x2 - x1;
265             if (nmiddle < 0)
266             {
267                 nmiddle = -nmiddle;
268                 l = x2;
269                 r = x1;
270             }
271 #if PPW > 1
272             c = l & PIM;
273             l -= c;
274 #endif
275
276 #if PGSZ == 32
277 #define LWRD_SHIFT 2
278 #else /* PGSZ == 64 */
279 #define LWRD_SHIFT 3
280 #endif /* PGSZ */
281
282 #if PSZ == 24
283             addr = (unsigned long *)((char *)addrl + ((l * 3) & ~0x03));
284 #else /* PSZ == 24 */
285 #if PWSH > LWRD_SHIFT
286             l = l >> (PWSH - LWRD_SHIFT);
287 #endif
288 #if PWSH < LWRD_SHIFT
289             l = l << (LWRD_SHIFT - PWSH);
290 #endif
291             addr = (unsigned long *) (((char *) addrl) + l);
292 #endif /* PSZ == 24 */
293 #if PSZ == 24
294             if (nmiddle <= 1){
295               if (nmiddle)
296                 RROP_SOLID24(addr, l);
297             } else {
298               maskbits(l, nmiddle, startmask, endmask, nmiddle);
299               pidx = l & 3;
300               if (startmask){
301                 RROP_SOLID_MASK(addr, startmask, pidx-1);
302                 addr++;
303                 if (pidx == 3)
304                   pidx = 0;
305               }
306               while (--nmiddle >= 0){
307                 RROP_SOLID(addr, pidx);
308                 addr++;
309                 if (++pidx == 3)
310                   pidx = 0;
311               }
312               if (endmask)
313                 RROP_SOLID_MASK(addr, endmask, pidx);
314             }
315 #else /* PSZ == 24 */
316 #if PPW > 1
317             if (c + nmiddle < PPW)
318             {
319                 mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle);
320                 RROP_SOLID_MASK(addr,mask);
321             }
322             else
323             {
324                 if (c)
325                 {
326                     mask = SCRRIGHT(bits, c);
327                     RROP_SOLID_MASK(addr,mask);
328                     nmiddle += c - PPW;
329                     addr++;
330                 }
331 #endif
332                 nmiddle >>= PWSH;
333                 while (--nmiddle >= 0) {
334                     RROP_SOLID(addr); addr++;
335                 }
336 #if PPW > 1
337                 if (mask = ~SCRRIGHT(bits, r & PIM))
338                     RROP_SOLID_MASK(addr,mask);
339             }
340 #endif
341 #endif /* PSZ == 24 */
342             if (!--h)
343                 break;
344             addrl = AddrYPlus (addrl, 1);
345             Step(x1,dx1,dy1,e1,sign1,step1)
346             Step(x2,dx2,dy2,e2,sign2,step2)
347         }
348         if (y == maxy)
349             break;
350         addrl = AddrYPlus (addrl, 1);
351     }
352 }