|
|
1.1 ! root 1: /* $Header: sunBW2zoid.c,v 4.1 87/09/10 18:25:11 sun Exp $ */ ! 2: /*- ! 3: * sunBW2zoids.c -- ! 4: * Functions for handling the sun BWTWO board for the zoids extension. ! 5: * ! 6: */ ! 7: ! 8: /************************************************************ ! 9: Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. ! 10: ! 11: All Rights Reserved ! 12: ! 13: Permission to use, copy, modify, and distribute this ! 14: software and its documentation for any purpose and without ! 15: fee is hereby granted, provided that the above copyright no- ! 16: tice appear in all copies and that both that copyright no- ! 17: tice and this permission notice appear in supporting docu- ! 18: mentation, and that the names of Sun or MIT not be used in ! 19: advertising or publicity pertaining to distribution of the ! 20: software without specific prior written permission. Sun and ! 21: M.I.T. make no representations about the suitability of this ! 22: software for any purpose. It is provided "as is" without any ! 23: express or implied warranty. ! 24: ! 25: SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ! 26: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- ! 27: NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- ! 28: ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 29: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ! 30: PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR ! 31: OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH ! 32: THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 33: ! 34: ********************************************************/ ! 35: ! 36: #ifndef lint ! 37: static char sccsid[] = "%W %G Copyright 1987 Sun Micro"; ! 38: #endif ! 39: ! 40: #include "sun.h" ! 41: #include "resource.h" ! 42: ! 43: ! 44: /* ! 45: * ZOIDS should only ever be defined if SUN_WINDOWS is also defined. ! 46: */ ! 47: #ifdef ZOIDS ! 48: /* ! 49: * For tiled & stippled trapezoids, ! 50: * make a mem_point(), pointing at the tile or stipple ! 51: * image. Tile the scratch_pr with the mpr, the size of pDraw. ! 52: * Use the scratch_pr as the source ! 53: * in calls to pr_polygon_2(). Tiles use PIX_SRC; stipples use ! 54: * PIX_SRC|PIX_DST. ! 55: */ ! 56: ! 57: #define X_ALIGN 0 ! 58: #define Y_ALIGN 1 ! 59: ! 60: static Pixrect * ! 61: getMpr(pPixmap) ! 62: PixmapPtr pPixmap; ! 63: { ! 64: register Pixrect *pMpr; ! 65: ! 66: pMpr = mem_point(pPixmap->width, pPixmap->height, ! 67: 1, pPixmap->devPrivate); ! 68: return pMpr; ! 69: } ! 70: ! 71: static Pixrect * ! 72: getSubregion(pDraw, pScratch) ! 73: DrawablePtr pDraw; ! 74: Pixrect *pScratch; ! 75: { ! 76: register Pixrect *pSubpr; ! 77: register int w, h; ! 78: ! 79: if (pDraw->type == DRAWABLE_WINDOW) { ! 80: w = ((WindowPtr) pDraw)->clientWinSize.width; ! 81: h = ((WindowPtr) pDraw)->clientWinSize.height; ! 82: } else { ! 83: w = ((PixmapPtr) pDraw)->width; ! 84: h = ((PixmapPtr) pDraw)->height; ! 85: } ! 86: pSubpr = pr_region(pScratch, 0, 0, w, h); ! 87: return (pSubpr); ! 88: } ! 89: ! 90: static void ! 91: tileRegion(pScratch, pTile) ! 92: Pixrect *pScratch, *pTile; ! 93: { ! 94: pr_replrop(pScratch, 0, 0, pScratch->pr_size.x, pScratch->pr_size.y, ! 95: PIX_SRC, pTile, 0, 0); ! 96: } ! 97: ! 98: static int ! 99: orderXzoid(pZoid, pPtList) ! 100: xXTraps *pZoid; ! 101: struct pr_pos *pPtList; ! 102: { ! 103: int npts = 2; ! 104: ! 105: if (pZoid->x2 == pZoid->x1) ! 106: return (0); ! 107: pPtList[0].x = pZoid->x1; ! 108: pPtList[0].y = pZoid->y1; ! 109: pPtList[1].x = pZoid->x2; ! 110: pPtList[1].y = pZoid->y3; ! 111: if (pZoid->y4 != pPtList[1].y) { ! 112: pPtList[2].x = pZoid->x2; ! 113: pPtList[2].y = pZoid->y4; ! 114: npts++; ! 115: } ! 116: if (pZoid->y2 != pPtList[0].y) { ! 117: pPtList[npts].x = pZoid->x1; ! 118: pPtList[npts].y = pZoid->y2; ! 119: npts++; ! 120: } ! 121: if (npts == 2) ! 122: npts = 0; ! 123: ! 124: return (npts); ! 125: } ! 126: ! 127: static int ! 128: orderYzoid(pZoid, pPtList) ! 129: xYTraps *pZoid; ! 130: struct pr_pos *pPtList; ! 131: { ! 132: int npts = 2; ! 133: ! 134: if (pZoid->y2 == pZoid->y1) ! 135: return (0); ! 136: pPtList[0].x = pZoid->x1; ! 137: pPtList[0].y = pZoid->y1; ! 138: pPtList[1].x = pZoid->x3; ! 139: pPtList[1].y = pZoid->y2; ! 140: if (pZoid->x4 != pPtList[1].x) { ! 141: pPtList[2].x = pZoid->x4; ! 142: pPtList[2].y = pZoid->y2; ! 143: npts++; ! 144: } ! 145: if (pZoid->x2 != pPtList[0].x) { ! 146: pPtList[npts].x = pZoid->x2; ! 147: pPtList[npts].y = pZoid->y1; ! 148: npts++; ! 149: } ! 150: if (npts == 2) ! 151: npts = 0; ! 152: ! 153: return (npts); ! 154: } ! 155: ! 156: static void ! 157: solidXzoid(pPixscreen, pZoid, pPixsrc, sx, sy) ! 158: Pixrect *pPixscreen, ! 159: *pPixsrc; /* unused */ ! 160: xXTraps *pZoid; ! 161: int sx, sy; /* unused */ ! 162: { ! 163: int npts; ! 164: struct pr_pos ptlist[4]; ! 165: ! 166: if ((npts = orderXzoid(pZoid, ptlist)) > 0) ! 167: pr_polygon_2(pPixscreen, 0, 0, 1, &npts, ptlist, ! 168: PIX_SET, NULL, 0, 0); ! 169: } ! 170: ! 171: static void ! 172: solidYzoid(pPixscreen, pZoid, pPixsrc, sx, sy) ! 173: Pixrect *pPixscreen, ! 174: *pPixsrc; /* unused */ ! 175: xYTraps *pZoid; ! 176: int sx, sy; /* unused */ ! 177: { ! 178: int npts; ! 179: struct pr_pos ptlist[4]; ! 180: ! 181: if ((npts = orderYzoid(pZoid, ptlist)) > 0) ! 182: pr_polygon_2(pPixscreen, 0, 0, 1, &npts, ptlist, ! 183: PIX_SET, NULL, 0, 0); ! 184: } ! 185: ! 186: static void ! 187: tiledXzoid(pPixscreen, pZoid, pPixsrc, sx, sy) ! 188: Pixrect *pPixscreen, ! 189: *pPixsrc; ! 190: xXTraps *pZoid; ! 191: int sx, sy; ! 192: { ! 193: int npts; ! 194: struct pr_pos ptlist[4]; ! 195: ! 196: if ((npts = orderXzoid(pZoid, ptlist)) > 0) ! 197: pr_polygon_2(pPixscreen, 0, 0, 1, &npts, ptlist, ! 198: PIX_SRC, pPixsrc, sx, sy); ! 199: } ! 200: ! 201: static void ! 202: tiledYzoid(pPixscreen, pZoid, pPixsrc, sx, sy) ! 203: Pixrect *pPixscreen, ! 204: *pPixsrc; ! 205: xYTraps *pZoid; ! 206: int sx, sy; ! 207: { ! 208: int npts; ! 209: struct pr_pos ptlist[4]; ! 210: ! 211: if ((npts = orderYzoid(pZoid, ptlist)) > 0) ! 212: pr_polygon_2(pPixscreen, 0, 0, 1, &npts, ptlist, ! 213: PIX_SRC, pPixsrc, sx, sy); ! 214: } ! 215: ! 216: static void ! 217: stippledXzoid(pPixscreen, pZoid, pPixsrc, sx, sy) ! 218: Pixrect *pPixscreen, ! 219: *pPixsrc; ! 220: xXTraps *pZoid; ! 221: int sx, sy; ! 222: { ! 223: int npts; ! 224: struct pr_pos ptlist[4]; ! 225: ! 226: if ((npts = orderXzoid(pZoid, ptlist)) > 0) ! 227: pr_polygon_2(pPixscreen, 0, 0, 1, &npts, ptlist, ! 228: PIX_SRC|PIX_DST, pPixsrc, sx, sy); ! 229: } ! 230: ! 231: static void ! 232: stippledYzoid(pPixscreen, pZoid, pPixsrc, sx, sy) ! 233: Pixrect *pPixscreen, ! 234: *pPixsrc; ! 235: xYTraps *pZoid; ! 236: int sx, sy; ! 237: { ! 238: int npts; ! 239: struct pr_pos ptlist[4]; ! 240: ! 241: if ((npts = orderYzoid(pZoid, ptlist)) > 0) ! 242: pr_polygon_2(pPixscreen, 0, 0, 1, &npts, ptlist, ! 243: PIX_SRC|PIX_DST, pPixsrc, sx, sy); ! 244: } ! 245: ! 246: static void ! 247: XzoidBbox(pzoid, pbox) ! 248: xXTraps *pzoid; ! 249: BoxRec *pbox; ! 250: { ! 251: pbox->x1 = min (pzoid->x1, pzoid->x2); ! 252: pbox->y1 = min (min (pzoid->y1, pzoid->y2), min (pzoid->y3, pzoid->y4)); ! 253: pbox->x2 = max (pzoid->x1, pzoid->x2); ! 254: pbox->y2 = max (max (pzoid->y1, pzoid->y2), max (pzoid->y3, pzoid->y4)); ! 255: } ! 256: ! 257: static void ! 258: YzoidBbox(pzoid, pbox) ! 259: xYTraps *pzoid; ! 260: BoxRec *pbox; ! 261: { ! 262: pbox->x1 = min (min (pzoid->x1, pzoid->x2), min (pzoid->x3, pzoid->x4)); ! 263: pbox->y1 = min (pzoid->y1, pzoid->y2); ! 264: pbox->x2 = max (max (pzoid->x1, pzoid->x2), max (pzoid->x3, pzoid->x4)); ! 265: pbox->y2 = max (pzoid->y1, pzoid->y2); ! 266: } ! 267: ! 268: /* ! 269: * X aligned ! 270: * ! 271: * [x2,y3] ! 272: * + ! 273: * A /| ! 274: * [x1,y1] / | ! 275: * + | ! 276: * | | ! 277: * + | ! 278: * [x1,y2] \ | ! 279: * B \| ! 280: * + ! 281: * [x2,y4] ! 282: * ! 283: * A: y1-y3 y1-y3 ! 284: * y = ----- x + (y1 - ----- x1) ! 285: * x1-x2 x1-x2 ! 286: * ! 287: * B: y2-y4 y2-y4 ! 288: * y = ----- x + (y2 - ----- x1) ! 289: * x1-x2 x1-x2 ! 290: */ ! 291: #define Ax2y(_x) (int) (((((long)pz->y1 - (long)pz->y3) * (long)(_x))/ \ ! 292: ((long)pz->x1 - (long)pz->x2)) + (long)pz->y1 - \ ! 293: ((((long)pz->y1 - (long)pz->y3)*(long)pz->x1)/ \ ! 294: ((long)pz->x1 - (long)pz->x2))) ! 295: #define Bx2y(_x) (int) (((((long)pz->y2 - (long)pz->y4) * (long)(_x))/ \ ! 296: ((long)pz->x1 - (long)pz->x2)) + (long)pz->y2 - \ ! 297: ((((long)pz->y2 - (long)pz->y4)*(long)pz->x1)/ \ ! 298: ((long)pz->x1 - (long)pz->x2))) ! 299: #define Ay2x(_y) (int) (((((long)pz->x1 - (long)pz->x2) * (long)(_y))/ \ ! 300: ((long)pz->y1 - (long)pz->y3)) + (long)pz->x1 - \ ! 301: ((((long)pz->x1 - (long)pz->x2)*(long)pz->y1)/ \ ! 302: ((long)pz->y1 - (long)pz->y3))) ! 303: #define By2x(_y) (int) (((((long)pz->x1 - (long)pz->x2) * (long)(_y))/ \ ! 304: ((long)pz->y2 - (long)pz->y4)) + (long)pz->x1 - \ ! 305: ((((long)pz->x1 - (long)pz->x2)*(long)pz->y2)/ \ ! 306: ((long)pz->y2 - (long)pz->y4))) ! 307: static int ! 308: intersectXzoid(pbox, pzoid, subzoid) ! 309: BoxRec *pbox; ! 310: xXTraps *pzoid; ! 311: xXTraps *subzoid; ! 312: { ! 313: int nzoids = 1; ! 314: register int tx, ty, i; ! 315: xXTraps *pz; ! 316: ! 317: pz = subzoid; ! 318: *pz = *pzoid; ! 319: if (pzoid->x1 < pbox->x1) { ! 320: pz->y1 = Ax2y (pbox->x1); ! 321: pz->y2 = Bx2y (pbox->x1); ! 322: pz->x1 = pbox->x1; ! 323: } ! 324: if (pzoid->x2 > pbox->x2) { ! 325: pz->y3 = Ax2y (pbox->x2); ! 326: pz->y4 = Bx2y (pbox->x2); ! 327: pz->x2 = pbox->x2; ! 328: } ! 329: /* did we just clip out the zoid? */ ! 330: if (pz->y1 > pbox->y2 && pz->y3 > pbox->y2) ! 331: return (0); ! 332: if (pz->y2 < pbox->y1 && pz->y4 < pbox->y1) ! 333: return (0); ! 334: /* does zoid side A cross box side A? */ ! 335: if ((pz->y1 < pbox->y1 && pz->y3 > pbox->y1) ! 336: || (pz->y1 > pbox->y1 && pz->y3 < pbox->y1)) { ! 337: tx = Ay2x(pbox->y1); /* side A crosses at [tx,pbox->y1] */ ! 338: ty = Bx2y(tx); ! 339: *(pz+1) = *pz; ! 340: nzoids++; ! 341: /* does either subside of side B cross the box? */ ! 342: if ((pz->y2 < pbox->y2 && ty > pbox->y2) ! 343: || (pz->y2 > pbox->y2 && ty < pbox->y2)) { ! 344: /* left subside crosses; keep right side in pz */ ! 345: pz->x1 = tx; ! 346: pz->y1 = pbox->y1; ! 347: pz->y2 = ty; ! 348: pz++; ! 349: pz->x2 = tx; ! 350: pz->y3 = pbox->y1; ! 351: pz->y4 = ty; ! 352: } else { ! 353: /* keep left side in pz */ ! 354: pz->x2 = tx; ! 355: pz->y3 = pbox->y1; ! 356: pz->y4 = ty; ! 357: pz++; ! 358: pz->x1 = tx; ! 359: pz->y1 = pbox->y1; ! 360: pz->y2 = ty; ! 361: } ! 362: } else ! 363: /* does zoid side A cross box side B? */ ! 364: if ((pz->y1 < pbox->y2 && pz->y3 > pbox->y2) ! 365: || (pz->y1 > pbox->y2 && pz->y3 < pbox->y2)) { ! 366: tx = Ay2x(pbox->y2); /* side A crosses at [tx,pbox->y2] */ ! 367: ty = Bx2y(tx); ! 368: /* pbox contains only a triangle. */ ! 369: if (pz->y1 < pbox->y2) { /* left part of side A is inside */ ! 370: pz->x2 = tx; ! 371: pz->y3 = pbox->y2; ! 372: pz->y4 = ty; ! 373: } else { /* right part of side A is inside */ ! 374: pz->x1 = tx; ! 375: pz->y1 = pbox->y2; ! 376: pz->y2 = ty; ! 377: } ! 378: } ! 379: /* does zoid side B cross box side B? */ ! 380: if ((pz->y2 < pbox->y2 && pz->y4 > pbox->y2) ! 381: || (pz->y2 > pbox->y2 && pz->y4 < pbox->y2)) { ! 382: tx = By2x(pbox->y2); /* side B crosses at [tx,pbox->y2] */ ! 383: ty = Ax2y(tx); ! 384: *(pz+1) = *pz; ! 385: nzoids++; ! 386: /* side A doesn't cross; keep left side in pz */ ! 387: pz->x2 = tx; ! 388: pz->y3 = ty; ! 389: pz->y4 = pbox->y2; ! 390: pz++; ! 391: pz->x1 = tx; ! 392: pz->y1 = ty; ! 393: pz->y2 = pbox->y2; ! 394: } else ! 395: /* does zoid side B cross box side A? */ ! 396: if ((pz->y2 < pbox->y1 && pz->y4 > pbox->y1) ! 397: || (pz->y2 > pbox->y1 && pz->y4 < pbox->y1)) { ! 398: tx = By2x(pbox->y1); /* side B crosses at [tx,pbox->y1] */ ! 399: ty = Ax2y(tx); ! 400: /* pbox contains only a triangle. */ ! 401: if (pz->y2 > pbox->y1) { /* left part of side B is inside */ ! 402: pz->x2 = tx; ! 403: pz->y3 = ty; ! 404: pz->y4 = pbox->y1; ! 405: } else { /* right part of side B is inside */ ! 406: pz->x1 = tx; ! 407: pz->y1 = ty; ! 408: pz->y2 = pbox->y1; ! 409: } ! 410: } ! 411: /* finish the clipping, now that nothing crosses */ ! 412: for (i = 0, pz = subzoid; i < nzoids; i++, pz++) { ! 413: if (pz->y1 < pbox->y1 || pz->y3 < pbox->y1) { ! 414: pz->y1 = pz->y3 = pbox->y1; ! 415: } ! 416: if (pz->y2 > pbox->y2 || pz->y4 > pbox->y2) { ! 417: pz->y2 = pz->y4 = pbox->y2; ! 418: } ! 419: } ! 420: ! 421: return (nzoids); ! 422: } ! 423: ! 424: /* ! 425: * Y aligned ! 426: * ! 427: * [x1,y1] [x2,y1] ! 428: * +-----------+ ! 429: * A / \ B ! 430: * +---------------+ ! 431: * [x3,y2] [x4,y2] ! 432: * ! 433: * A: y1-y2 y1-y2 ! 434: * y = ----- x + (y1 - ----- x1) ! 435: * x1-x3 x1-x3 ! 436: * ! 437: * B: y1-y2 y1-y2 ! 438: * y = ----- x + (y1 - ----- x2) ! 439: * x2-x4 x2-x4 ! 440: */ ! 441: #undef Ax2y ! 442: #undef Bx2y ! 443: #undef Ay2x ! 444: #undef By2x ! 445: #define Ax2y(_x) (int) (((((long)pz->y1 - (long)pz->y2) * (long)(_x))/ \ ! 446: ((long)pz->x1 - (long)pz->x3)) + (long)pz->y1 - \ ! 447: ((((long)pz->y1 - (long)pz->y2)*(long)pz->x1)/ \ ! 448: ((long)pz->x1 - (long)pz->x3))) ! 449: #define Bx2y(_x) (int) (((((long)pz->y1 - (long)pz->y2) * (long)(_x))/ \ ! 450: ((long)pz->x2 - (long)pz->x4)) + (long)pz->y1 - \ ! 451: ((((long)pz->y1 - (long)pz->y2)*(long)pz->x2)/ \ ! 452: ((long)pz->x2 - (long)pz->x4))) ! 453: #define Ay2x(_y) (int) (((((long)pz->x1 - (long)pz->x3) * (long)(_y))/ \ ! 454: ((long)pz->y1 - (long)pz->y2)) + (long)pz->x1 - \ ! 455: ((((long)pz->x1 - (long)pz->x3)*(long)pz->y1)/ \ ! 456: ((long)pz->y1 - (long)pz->y2))) ! 457: #define By2x(_y) (int) (((((long)pz->x2 - (long)pz->x4) * (long)(_y))/ \ ! 458: ((long)pz->y1 - (long)pz->y2)) + (long)pz->x2 - \ ! 459: ((((long)pz->x2 - (long)pz->x4)*(long)pz->y1)/ \ ! 460: ((long)pz->y1 - (long)pz->y2))) ! 461: static int ! 462: intersectYzoid(pbox, pzoid, subzoid) ! 463: BoxRec *pbox; ! 464: xYTraps *pzoid; ! 465: xYTraps *subzoid; ! 466: { ! 467: int nzoids = 1; ! 468: register int tx, ty, i; ! 469: xYTraps *pz; ! 470: ! 471: pz = subzoid; ! 472: *pz = *pzoid; ! 473: if (pzoid->y1 < pbox->y1) { ! 474: pz->x1 = Ay2x (pbox->y1); ! 475: pz->x2 = By2x (pbox->y1); ! 476: pz->y1 = pbox->y1; ! 477: } ! 478: if (pzoid->y2 > pbox->y2) { ! 479: pz->x3 = Ay2x (pbox->y2); ! 480: pz->x4 = By2x (pbox->y2); ! 481: pz->y2 = pbox->y2; ! 482: } ! 483: /* did we just clip out the zoid? */ ! 484: if (pz->x1 > pbox->x2 && pz->x3 > pbox->x2) ! 485: return (0); ! 486: if (pz->x2 < pbox->x1 && pz->x4 < pbox->x1) ! 487: return (0); ! 488: /* does zoid side A cross box side A? */ ! 489: if ((pz->x1 < pbox->x1 && pz->x3 > pbox->x1) ! 490: || (pz->x1 > pbox->x1 && pz->x3 < pbox->x1)) { ! 491: ty = Ax2y(pbox->x1); /* side A crosses at [pbox->x1,ty] */ ! 492: tx = By2x(ty); ! 493: *(pz+1) = *pz; ! 494: nzoids++; ! 495: /* does either subside of side B cross the box? */ ! 496: if ((pz->x2 < pbox->x2 && tx > pbox->x2) ! 497: || (pz->x2 > pbox->x2 && tx < pbox->x2)) { ! 498: /* top subside crosses; keep bottom side in pz */ ! 499: pz->y1 = ty; ! 500: pz->x1 = pbox->x1; ! 501: pz->x2 = tx; ! 502: pz++; ! 503: pz->y2 = ty; ! 504: pz->x3 = pbox->x1; ! 505: pz->x4 = tx; ! 506: } else { ! 507: /* keep top side in pz */ ! 508: pz->y2 = ty; ! 509: pz->x3 = pbox->x1; ! 510: pz->x4 = tx; ! 511: pz++; ! 512: pz->y1 = ty; ! 513: pz->x1 = pbox->x1; ! 514: pz->x2 = tx; ! 515: } ! 516: } else ! 517: /* does zoid side A cross box side B? */ ! 518: if ((pz->x1 < pbox->x2 && pz->x3 > pbox->x2) ! 519: || (pz->x1 > pbox->x2 && pz->x3 < pbox->x2)) { ! 520: ty = Ax2y(pbox->x2); /* side A crosses at [pbox->x2,ty] */ ! 521: tx = By2x(ty); ! 522: /* pbox contains only a triangle. */ ! 523: if (pz->x1 < pbox->x2) { /* top part of side A is inside */ ! 524: pz->y2 = ty; ! 525: pz->x3 = pbox->x2; ! 526: pz->x4 = tx; ! 527: } else { /* bottom part of side A is inside */ ! 528: pz->y1 = ty; ! 529: pz->x1 = pbox->x2; ! 530: pz->x2 = tx; ! 531: } ! 532: } ! 533: /* does zoid side B cross box side B? */ ! 534: if ((pz->x2 < pbox->x2 && pz->x4 > pbox->x2) ! 535: || (pz->x2 > pbox->x2 && pz->x4 < pbox->x2)) { ! 536: ty = Bx2y(pbox->x2); /* side B crosses at [pbox->x2,ty] */ ! 537: tx = Ay2x(ty); ! 538: *(pz+1) = *pz; ! 539: nzoids++; ! 540: /* side A doesn't cross; keep top side in pz */ ! 541: pz->y2 = ty; ! 542: pz->x3 = tx; ! 543: pz->x4 = pbox->x2; ! 544: pz++; ! 545: pz->y1 = ty; ! 546: pz->x1 = tx; ! 547: pz->x2 = pbox->x2; ! 548: } else ! 549: /* does zoid side B cross box side A? */ ! 550: if ((pz->x2 < pbox->x1 && pz->x4 > pbox->x1) ! 551: || (pz->x2 > pbox->x1 && pz->x4 < pbox->x1)) { ! 552: ty = Bx2y(pbox->x1); /* side B crosses at [pbox->x1,ty] */ ! 553: tx = Ay2x(ty); ! 554: /* pbox contains only a triangle. */ ! 555: if (pz->x2 > pbox->x1) { /* top part of side B is inside */ ! 556: pz->y2 = ty; ! 557: pz->x3 = tx; ! 558: pz->x4 = pbox->x1; ! 559: } else { /* bottom part of side B is inside */ ! 560: pz->y1 = ty; ! 561: pz->x1 = tx; ! 562: pz->x2 = pbox->x1; ! 563: } ! 564: } ! 565: /* finish the clipping, now that nothing crosses */ ! 566: for (i = 0, pz = subzoid; i < nzoids; i++, pz++) { ! 567: if (pz->x1 < pbox->x1 || pz->x3 < pbox->x1) { ! 568: pz->x1 = pz->x3 = pbox->x1; ! 569: } ! 570: if (pz->x2 > pbox->x2 || pz->x4 > pbox->x2) { ! 571: pz->x2 = pz->x4 = pbox->x2; ! 572: } ! 573: } ! 574: ! 575: return (nzoids); ! 576: } ! 577: ! 578: static void ! 579: fillZoids(pDrawable, pGC, ntraps, traplist, alignment, pPaint) ! 580: DrawablePtr pDrawable; ! 581: GCPtr pGC; ! 582: int ntraps; ! 583: xXYTraps *traplist; ! 584: int alignment; ! 585: void (* pPaint) (); ! 586: { ! 587: /* rip off from mfbPolyFillRect() */ ! 588: register BoxPtr pbox; /* pointer to current box in clip region */ ! 589: int i; /* loop index */ ! 590: ! 591: register xXYTraps *pzoid; /* pointer to current zoid to be filled */ ! 592: int xorg, yorg; /* origin of window */ ! 593: int nrectClip; /* number of rectangles in clip region */ ! 594: short alu; /* gc filling function */ ! 595: Pixrect *pTile; /* temporary for replropping scratch_pr */ ! 596: Pixrect *pScratch; /* temporary for replropping scratch_pr */ ! 597: mfbPrivGC *privGC; /* for reducing pointer dereferencing */ ! 598: ! 599: ! 600: if (!(pGC->planemask & 1)) ! 601: return; ! 602: ! 603: privGC = (mfbPrivGC *)((GCPtr)pGC->devPriv)->devPriv; ! 604: nrectClip = privGC->pCompositeClip->numRects; ! 605: ! 606: if (pDrawable->type == DRAWABLE_WINDOW) ! 607: { ! 608: xorg = ((WindowPtr)pDrawable)->absCorner.x; ! 609: yorg = ((WindowPtr)pDrawable)->absCorner.y; ! 610: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate); ! 611: /* translate the rectangle list */ ! 612: for (i = 0, pzoid = traplist; i < ntraps; i++, pzoid++) ! 613: { ! 614: if (alignment == X_ALIGN) { ! 615: pzoid->Xt.x1 += xorg; ! 616: pzoid->Xt.x2 += xorg; ! 617: pzoid->Xt.y1 += yorg; ! 618: pzoid->Xt.y2 += yorg; ! 619: pzoid->Xt.y3 += yorg; ! 620: pzoid->Xt.y4 += yorg; ! 621: } else { ! 622: pzoid->Yt.y1 += yorg; ! 623: pzoid->Yt.y2 += yorg; ! 624: pzoid->Yt.x1 += xorg; ! 625: pzoid->Yt.x2 += xorg; ! 626: pzoid->Yt.x3 += xorg; ! 627: pzoid->Yt.x4 += xorg; ! 628: } ! 629: } ! 630: } ! 631: else ! 632: { ! 633: xorg = 0; ! 634: yorg = 0; ! 635: } ! 636: ! 637: ! 638: if((alu = pGC->alu) == GXnoop) ! 639: return; /* hey, this is easy! */ ! 640: ! 641: switch (pGC->fillStyle) ! 642: { ! 643: case FillSolid: ! 644: alu = privGC->rop; /* used reduced ROP */ ! 645: pScratch = (Pixrect *)NULL; ! 646: break; ! 647: ! 648: case FillStippled: ! 649: alu = privGC->rop; /* used reduced ROP */ ! 650: pTile = getMpr(privGC->pRotatedStipple); ! 651: pScratch = getSubregion(pDrawable, ! 652: sunFbData[pDrawable->pScreen->myNum].scratch_pr); ! 653: tileRegion(pScratch, pTile); ! 654: pr_destroy(pTile); ! 655: break; ! 656: ! 657: case FillTiled: ! 658: pTile = getMpr(privGC->pRotatedTile); ! 659: pScratch = getSubregion(pDrawable, ! 660: sunFbData[pDrawable->pScreen->myNum].scratch_pr); ! 661: tileRegion(pScratch, pTile); ! 662: pr_destroy(pTile); ! 663: break; ! 664: } ! 665: ! 666: for (pzoid = traplist, --ntraps; ntraps >= 0; ++pzoid, --ntraps) { ! 667: BoxRec boxS, boxD; ! 668: ! 669: if (alignment == X_ALIGN) ! 670: XzoidBbox(pzoid, &boxS); ! 671: else ! 672: YzoidBbox(pzoid, &boxS); ! 673: ! 674: /* if lower right is out, the whole box is */ ! 675: if ((boxS.x2 <= 0) || (boxS.y2 <= 0)) ! 676: continue; ! 677: ! 678: /* clip left and top to drawable's origin */ ! 679: if (boxS.x1 < 0) ! 680: boxS.x1 = 0; ! 681: ! 682: if (boxS.y1 < 0) ! 683: boxS.y1 = 0; ! 684: ! 685: /* If the box is completely out of this clip rectangle, ignore it. ! 686: * if it is completely within, draw it, ! 687: * otherwise, draw the part that is within this region ! 688: */ ! 689: switch ((*pGC->pScreen->RectIn) ! 690: (privGC->pCompositeClip, &boxS)) ! 691: { ! 692: case rgnOUT: ! 693: break; ! 694: case rgnIN: ! 695: { ! 696: /* Draw entire zoid */ ! 697: (*pPaint)(sunFbData[pDrawable->pScreen->myNum].pr, ! 698: pzoid, pScratch, -xorg, -yorg); ! 699: break; ! 700: } ! 701: case rgnPART: ! 702: { ! 703: pbox = privGC->pCompositeClip->rects; ! 704: for (i = nrectClip; i > 0; --i, ++pbox) { ! 705: /* Clip box to each rect in turn ! 706: and draw the clipped box */ ! 707: ! 708: boxD.x1 = max(boxS.x1, pbox->x1); ! 709: boxD.y1 = max(boxS.y1, pbox->y1); ! 710: boxD.x2 = min(boxS.x2, pbox->x2); ! 711: boxD.y2 = min(boxS.y2, pbox->y2); ! 712: ! 713: if(boxD.x1 < boxD.x2 && boxD.y1 < boxD.y2) { ! 714: /* Construct subzoid and draw it. ! 715: * Note: sometimes 3 subzoids are needed. ! 716: */ ! 717: xXYTraps subzoid[3], *pz; ! 718: int nzoids; ! 719: ! 720: if (alignment == X_ALIGN) { ! 721: nzoids = intersectXzoid(&boxD, pzoid, subzoid); ! 722: } else { ! 723: nzoids = intersectYzoid(&boxD, pzoid, subzoid); ! 724: } ! 725: for (pz=subzoid; nzoids > 0; pz++, --nzoids) { ! 726: (*pPaint)( ! 727: sunFbData[pDrawable->pScreen->myNum].pr, ! 728: pz, pScratch, -xorg, -yorg); ! 729: } ! 730: } ! 731: } ! 732: break; ! 733: } ! 734: } /* switch RectIn */ ! 735: } /* for each pzoid */ ! 736: if (pScratch) ! 737: pr_destroy(pScratch); ! 738: } ! 739: ! 740: void ! 741: sunBW2SolidXZoids(pDraw, pGC, ntraps, traplist) ! 742: DrawablePtr pDraw; ! 743: GCPtr pGC; ! 744: int ntraps; ! 745: xXYTraps *traplist; ! 746: { ! 747: fillZoids(pDraw, pGC, ntraps, traplist, X_ALIGN, solidXzoid); ! 748: } ! 749: ! 750: void ! 751: sunBW2SolidYZoids(pDraw, pGC, ntraps, traplist) ! 752: DrawablePtr pDraw; ! 753: GCPtr pGC; ! 754: int ntraps; ! 755: xXYTraps *traplist; ! 756: { ! 757: fillZoids(pDraw, pGC, ntraps, traplist, Y_ALIGN, solidYzoid); ! 758: } ! 759: ! 760: void ! 761: sunBW2TiledXZoids(pDraw, pGC, ntraps, traplist) ! 762: DrawablePtr pDraw; ! 763: GCPtr pGC; ! 764: int ntraps; ! 765: xXYTraps *traplist; ! 766: { ! 767: fillZoids(pDraw, pGC, ntraps, traplist, X_ALIGN, tiledXzoid); ! 768: } ! 769: ! 770: void ! 771: sunBW2TiledYZoids(pDraw, pGC, ntraps, traplist) ! 772: DrawablePtr pDraw; ! 773: GCPtr pGC; ! 774: int ntraps; ! 775: xXYTraps *traplist; ! 776: { ! 777: fillZoids(pDraw, pGC, ntraps, traplist, Y_ALIGN, tiledYzoid); ! 778: } ! 779: ! 780: void ! 781: sunBW2StipXZoids(pDraw, pGC, ntraps, traplist) ! 782: DrawablePtr pDraw; ! 783: GCPtr pGC; ! 784: int ntraps; ! 785: xXYTraps *traplist; ! 786: { ! 787: fillZoids(pDraw, pGC, ntraps, traplist, X_ALIGN, stippledXzoid); ! 788: } ! 789: ! 790: void ! 791: sunBW2StipYZoids(pDraw, pGC, ntraps, traplist) ! 792: DrawablePtr pDraw; ! 793: GCPtr pGC; ! 794: int ntraps; ! 795: xXYTraps *traplist; ! 796: { ! 797: fillZoids(pDraw, pGC, ntraps, traplist, Y_ALIGN, stippledYzoid); ! 798: } ! 799: #endif ZOIDS
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.