]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mfb/mfbply1rct.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / mfb / mfbply1rct.c
1 /*
2  * $XConsortium: mfbply1rct.c /main/10 1996/08/23 10:35:13 dpw $
3  *
4 Copyright (c) 1990  X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
26  *
27  * Author:  Keith Packard, MIT X Consortium
28  */
29
30 #include "X.h"
31
32 #include "gcstruct.h"
33 #include "windowstr.h"
34 #include "pixmapstr.h"
35 #include "regionstr.h"
36 #include "scrnintstr.h"
37 #include "mistruct.h"
38
39 #include "mfb.h"
40 #include "maskbits.h"
41
42 #if defined(mips) || defined(sparc)
43 #define GetHighWord(x) (((int) (x)) >> 16)
44 #else
45 #define GetHighWord(x) (((int) (x)) / 65536)
46 #endif
47
48 #if IMAGE_BYTE_ORDER == MSBFirst
49 #define intToCoord(i,x,y)   (((x) = GetHighWord(i)), ((y) = (int) ((short) (i))))
50 #define coordToInt(x,y) (((x) << 16) | (y))
51 #define intToX(i)       (GetHighWord(i))
52 #define intToY(i)       ((int) ((short) i))
53 #else
54 #define intToCoord(i,x,y)   (((x) = (int) ((short) (i))), ((y) = GetHighWord(i)))
55 #define coordToInt(x,y) (((y) << 16) | (x))
56 #define intToX(i)       ((int) ((short) (i)))
57 #define intToY(i)       (GetHighWord(i))
58 #endif
59
60 void
61 MFBFILLPOLY1RECT (pDrawable, pGC, shape, mode, count, ptsIn)
62     DrawablePtr pDrawable;
63     GCPtr       pGC;
64     int         count;
65     DDXPointPtr ptsIn;
66 {
67     mfbPrivGCPtr    devPriv;
68     int             nlwidth;
69     PixelType       *addrl, *addr;
70     int             maxy;
71     int             origin;
72     register int    vertex1, vertex2;
73     int             c;
74     BoxPtr          extents;
75     int             clip;
76     int             y;
77     int             *vertex1p, *vertex2p;
78     int             *endp;
79     int             x1, x2;
80     int             dx1, dx2;
81     int             dy1, dy2;
82     int             e1, e2;
83     int             step1, step2;
84     int             sign1, sign2;
85     int             h;
86     int             l, r;
87     PixelType       mask, bits = ~((PixelType)0);
88     int             nmiddle;
89
90     devPriv = (mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr);
91     if (mode == CoordModePrevious || shape != Convex ||
92         REGION_NUM_RECTS(devPriv->pCompositeClip) != 1)
93     {
94         miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
95         return;
96     }
97     origin = *((int *) &pDrawable->x);
98     vertex2 = origin - ((origin & 0x8000) << 1);
99     extents = &devPriv->pCompositeClip->extents;
100     vertex1 = *((int *) &extents->x1) - vertex2;
101     vertex2 = *((int *) &extents->x2) - vertex2 - 0x00010001;
102     clip = 0;
103     y = 32767;
104     maxy = 0;
105     vertex2p = (int *) ptsIn;
106     endp = vertex2p + count;
107     while (count--)
108     {
109         c = *vertex2p;
110         clip |= (c - vertex1) | (vertex2 - c);
111         c = intToY(c);
112         if (c < y) 
113         {
114             y = c;
115             vertex1p = vertex2p;
116         }
117         vertex2p++;
118         if (c > maxy)
119             maxy = c;
120     }
121     if (y == maxy)
122         return;
123
124     if (clip & 0x80008000)
125     {
126         miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn);
127         return;
128     }
129
130     mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrl);
131     addrl = mfbScanlineDelta(addrl, y + pDrawable->y, nlwidth);
132     origin = intToX(origin);
133     vertex2p = vertex1p;
134     vertex2 = vertex1 = *vertex2p++;
135     if (vertex2p == endp)
136         vertex2p = (int *) ptsIn;
137 #define Setup(c,x,vertex,dx,dy,e,sign,step) {\
138     x = intToX(vertex); \
139     if (dy = intToY(c) - y) { \
140         dx = intToX(c) - x; \
141         step = 0; \
142         if (dx >= 0) \
143         { \
144             e = 0; \
145             sign = 1; \
146             if (dx >= dy) {\
147                 step = dx / dy; \
148                 dx = dx % dy; \
149             } \
150         } \
151         else \
152         { \
153             e = 1 - dy; \
154             sign = -1; \
155             dx = -dx; \
156             if (dx >= dy) { \
157                 step = - (dx / dy); \
158                 dx = dx % dy; \
159             } \
160         } \
161     } \
162     x += origin; \
163     vertex = c; \
164 }
165
166 #define Step(x,dx,dy,e,sign,step) {\
167     x += step; \
168     if ((e += dx) > 0) \
169     { \
170         x += sign; \
171         e -= dy; \
172     } \
173 }
174     for (;;)
175     {
176         if (y == intToY(vertex1))
177         {
178             do
179             {
180                 if (vertex1p == (int *) ptsIn)
181                     vertex1p = endp;
182                 c = *--vertex1p;
183                 Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1)
184             } while (y >= intToY(vertex1));
185             h = dy1;
186         }
187         else
188         {
189             Step(x1,dx1,dy1,e1,sign1,step1)
190             h = intToY(vertex1) - y;
191         }
192         if (y == intToY(vertex2))
193         {
194             do
195             {
196                 c = *vertex2p++;
197                 if (vertex2p == endp)
198                     vertex2p = (int *) ptsIn;
199                 Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
200             } while (y >= intToY(vertex2));
201             if (dy2 < h)
202                 h = dy2;
203         }
204         else
205         {
206             Step(x2,dx2,dy2,e2,sign2,step2)
207             if ((c = (intToY(vertex2) - y)) < h)
208                 h = c;
209         }
210         /* fill spans for this segment */
211         y += h;
212         for (;;)
213         {
214             l = x1;
215             r = x2;
216             nmiddle = x2 - x1;
217             if (nmiddle < 0)
218             {
219                 nmiddle = -nmiddle;
220                 l = x2;
221                 r = x1;
222             }
223             c = l & PIM;
224             l -= c;
225             l = l >> PWSH;
226             addr = addrl + l;
227             if (c + nmiddle < PPW)
228             {
229                 mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle);
230                 *addr OPEQ mask;
231             }
232             else
233             {
234                 if (c)
235                 {
236                     mask = SCRRIGHT(bits, c);
237                     *addr OPEQ mask;
238                     nmiddle += c - PPW;
239                     addr++;
240                 }
241                 nmiddle >>= PWSH;
242                 Duff (nmiddle, *addr++ EQWHOLEWORD)
243                 if (mask = ~SCRRIGHT(bits, r & PIM))
244                     *addr OPEQ mask;
245             }
246             if (!--h)
247                 break;
248             mfbScanlineInc(addrl, nlwidth);
249             Step(x1,dx1,dy1,e1,sign1,step1)
250             Step(x2,dx2,dy2,e2,sign2,step2)
251         }
252         if (y == maxy)
253             break;
254         mfbScanlineInc(addrl, nlwidth);
255     }
256 }