First import
[xorg_rtime.git] / xorg-server-1.4 / afb / afbply1rct.c
blob86ec174f43071e8911f14d5d912f7901f9f9261a
1 /*
3 Copyright (c) 1990 X Consortium
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 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.
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
26 * Author: Keith Packard, MIT X Consortium
29 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
31 #endif
33 #include <stdlib.h>
35 #include <X11/X.h>
37 #include "gcstruct.h"
38 #include "windowstr.h"
39 #include "pixmapstr.h"
40 #include "regionstr.h"
41 #include "scrnintstr.h"
42 #include "mistruct.h"
44 #include "afb.h"
45 #include "maskbits.h"
47 #if defined(mips) || defined(sparc)
48 #define GetHighWord(x) (((int)(x)) >> 16)
49 #else
50 #define GetHighWord(x) (((int)(x)) / 65536)
51 #endif
53 #if IMAGE_BYTE_ORDER == MSBFirst
54 #define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int)((short) (i))))
55 #define coordToInt(x,y) (((x) << 16) | (y))
56 #define intToX(i) (GetHighWord(i))
57 #define intToY(i) ((int)((short) i))
58 #else
59 #define intToCoord(i,x,y) (((x) = (int)((short) (i))), ((y) = GetHighWord(i)))
60 #define coordToInt(x,y) (((y) << 16) | (x))
61 #define intToX(i) ((int)((short) (i)))
62 #define intToY(i) (GetHighWord(i))
63 #endif
65 void
66 afbFillPolygonSolid (pDrawable, pGC, shape, mode, count, ptsIn)
67 DrawablePtr pDrawable;
68 GCPtr pGC;
69 int shape;
70 int mode;
71 int count;
72 DDXPointPtr ptsIn;
74 afbPrivGCPtr devPriv;
75 int nlwidth;
76 PixelType *addrl, *addr;
77 int maxy;
78 int origin;
79 register int vertex1, vertex2;
80 int c;
81 BoxPtr extents;
82 int clip;
83 int y;
84 int *vertex1p = NULL, *vertex2p;
85 int *endp;
86 int x1 = 0, x2 = 0;
87 int dx1 = 0, dx2 = 0;
88 int dy1 = 0, dy2 = 0;
89 int e1 = 0, e2 = 0;
90 int step1 = 0, step2 = 0;
91 int sign1 = 0, sign2 = 0;
92 int h;
93 int l, r;
94 PixelType mask, bits = ~((PixelType)0);
95 int nmiddle;
96 register unsigned char *rrops;
97 register int n;
98 register int d;
99 int sizeDst;
100 int depthDst;
101 register PixelType *pdst;
103 devPriv = (afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr);
105 if (mode == CoordModePrevious || shape != Convex ||
106 REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
107 miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
108 return;
110 origin = *((int *) &pDrawable->x);
111 origin -= (origin & 0x8000) << 1;
112 extents = &pGC->pCompositeClip->extents;
113 vertex1 = *((int *) &extents->x1) - origin;
114 vertex2 = *((int *) &extents->x2) - origin - 0x00010001;
115 clip = 0;
116 y = 32767;
117 maxy = 0;
118 vertex2p = (int *) ptsIn;
119 endp = vertex2p + count;
120 while (count--) {
121 c = *vertex2p;
122 clip |= (c - vertex1) | (vertex2 - c);
123 c = intToY(c);
124 if (c < y) {
125 y = c;
126 vertex1p = vertex2p;
128 vertex2p++;
129 if (c > maxy)
130 maxy = c;
132 if (y == maxy)
133 return;
135 if (clip & 0x80008000) {
136 miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn);
137 return;
140 afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst,
141 addrl);
142 rrops = devPriv->rrops;
143 addrl = afbScanlineDelta(addrl, y + pDrawable->y, nlwidth);
144 origin = intToX(origin);
145 vertex2p = vertex1p;
146 vertex2 = vertex1 = *vertex2p++;
147 if (vertex2p == endp)
148 vertex2p = (int *) ptsIn;
149 #define Setup(c,x,vertex,dx,dy,e,sign,step) {\
150 x = intToX(vertex); \
151 if ((dy = intToY(c) - y)) { \
152 dx = intToX(c) - x; \
153 step = 0; \
154 if (dx >= 0) { \
155 e = 0; \
156 sign = 1; \
157 if (dx >= dy) {\
158 step = dx / dy; \
159 dx = dx % dy; \
161 } else { \
162 e = 1 - dy; \
163 sign = -1; \
164 dx = -dx; \
165 if (dx >= dy) { \
166 step = - (dx / dy); \
167 dx = dx % dy; \
171 x += origin; \
172 vertex = c; \
175 #define Step(x,dx,dy,e,sign,step) {\
176 x += step; \
177 if ((e += dx) > 0) { \
178 x += sign; \
179 e -= dy; \
182 for (;;) {
183 if (y == intToY(vertex1)) {
184 do {
185 if (vertex1p == (int *) ptsIn)
186 vertex1p = endp;
187 c = *--vertex1p;
188 Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1)
189 } while (y >= intToY(vertex1));
190 h = dy1;
191 } else {
192 Step(x1,dx1,dy1,e1,sign1,step1)
193 h = intToY(vertex1) - y;
195 if (y == intToY(vertex2)) {
196 do {
197 c = *vertex2p++;
198 if (vertex2p == endp)
199 vertex2p = (int *) ptsIn;
200 Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
201 } while (y >= intToY(vertex2));
202 if (dy2 < h)
203 h = dy2;
204 } else {
205 Step(x2,dx2,dy2,e2,sign2,step2)
206 if ((c = (intToY(vertex2) - y)) < h)
207 h = c;
209 /* fill spans for this segment */
210 y += h;
211 for (;;) {
212 l = x1;
213 r = x2;
214 nmiddle = x2 - x1;
215 if (nmiddle < 0) {
216 nmiddle = -nmiddle;
217 l = x2;
218 r = x1;
220 c = l & PIM;
221 l -= c;
222 l = l >> PWSH;
223 addr = addrl + l;
224 if (c + nmiddle < PPW) {
225 mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle);
226 for (pdst = addr, d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */
227 switch (rrops[d]) {
228 case RROP_BLACK:
229 *pdst &= ~mask;
230 break;
231 case RROP_WHITE:
232 *pdst |= mask;
233 break;
234 case RROP_INVERT:
235 *pdst ^= mask;
236 break;
237 case RROP_NOP:
238 break;
241 } else {
242 if (c) {
243 mask = SCRRIGHT(bits, c);
244 for (pdst = addr, d = 0; d < depthDst; d++, pdst += sizeDst) { /* @@@ NEXT PLANE @@@ */
245 switch (rrops[d]) {
246 case RROP_BLACK:
247 *pdst &= ~mask;
248 break;
249 case RROP_WHITE:
250 *pdst |= mask;
251 break;
252 case RROP_INVERT:
253 *pdst ^= mask;
254 break;
255 case RROP_NOP:
256 break;
259 nmiddle += c - PPW;
260 addr++;
262 nmiddle >>= PWSH;
263 mask = ~SCRRIGHT(bits, r & PIM);
265 for (d = 0; d < depthDst; d++, addr += sizeDst) { /* @@@ NEXT PLANE @@@ */
266 n = nmiddle;
267 pdst = addr;
269 switch (rrops[d]) {
270 case RROP_BLACK:
271 Duff (n, *pdst++ = 0;)
272 if (mask)
273 *pdst &= ~mask;
274 break;
275 case RROP_WHITE:
276 Duff (n, *pdst++ = ~0;);
277 if (mask)
278 *pdst |= mask;
279 break;
280 case RROP_INVERT:
281 Duff (n, *pdst++ ^= ~0;);
282 if (mask)
283 *pdst ^= mask;
284 break;
285 case RROP_NOP:
286 break;
290 if (!--h)
291 break;
292 afbScanlineInc(addrl, nlwidth);
293 Step(x1,dx1,dy1,e1,sign1,step1)
294 Step(x2,dx2,dy2,e2,sign2,step2)
296 if (y == maxy)
297 break;
298 afbScanlineInc(addrl, nlwidth);