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 } 353