|
|
1.1 ! root 1: /************************************************************ ! 2: Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. ! 3: ! 4: All Rights Reserved ! 5: ! 6: Permission to use, copy, modify, and distribute this ! 7: software and its documentation for any purpose and without ! 8: fee is hereby granted, provided that the above copyright no- ! 9: tice appear in all copies and that both that copyright no- ! 10: tice and this permission notice appear in supporting docu- ! 11: mentation, and that the names of Sun or MIT not be used in ! 12: advertising or publicity pertaining to distribution of the ! 13: software without specific prior written permission. Sun and ! 14: M.I.T. make no representations about the suitability of this ! 15: software for any purpose. It is provided "as is" without any ! 16: express or implied warranty. ! 17: ! 18: SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ! 19: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- ! 20: NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- ! 21: ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 22: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ! 23: PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR ! 24: OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH ! 25: THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 26: ! 27: ********************************************************/ ! 28: ! 29: /*********************************************************** ! 30: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 31: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 32: ! 33: All Rights Reserved ! 34: ! 35: Permission to use, copy, modify, and distribute this software and its ! 36: documentation for any purpose and without fee is hereby granted, ! 37: provided that the above copyright notice appear in all copies and that ! 38: both that copyright notice and this permission notice appear in ! 39: supporting documentation, and that the names of Digital or MIT not be ! 40: used in advertising or publicity pertaining to distribution of the ! 41: software without specific, written prior permission. ! 42: ! 43: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 44: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 45: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 46: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 47: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 48: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 49: SOFTWARE. ! 50: ! 51: ******************************************************************/ ! 52: #include "X.h" ! 53: #include "Xmd.h" ! 54: #include "servermd.h" ! 55: #include "gcstruct.h" ! 56: #include "window.h" ! 57: #include "pixmapstr.h" ! 58: #include "scrnintstr.h" ! 59: ! 60: #include "cfb.h" ! 61: #include "cfbmskbits.h" ! 62: ! 63: /* scanline filling for color frame buffer ! 64: written by drewry, oct 1986 modified by smarks ! 65: changes for compatibility with Little-endian systems Jul 1987; MIT:yba. ! 66: ! 67: these routines all clip. they assume that anything that has called ! 68: them has already translated the points (i.e. pGC->miTranslate is ! 69: non-zero, which is howit gets set in cfbCreateGC().) ! 70: ! 71: the number of new scnalines created by clipping == ! 72: MaxRectsPerBand * nSpans. ! 73: ! 74: FillSolid is overloaded to be used for OpaqueStipple as well, ! 75: if fgPixel == bgPixel. ! 76: Note that for solids, PrivGC.rop == PrivGC.ropOpStip ! 77: ! 78: ! 79: FillTiled is overloaded to be used for OpaqueStipple, if ! 80: fgPixel != bgPixel. based on the fill style, it uses ! 81: {RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip} ! 82: */ ! 83: ! 84: #ifdef notdef ! 85: #include <stdio.h> ! 86: static ! 87: dumpspans(n, ppt, pwidth) ! 88: int n; ! 89: DDXPointPtr ppt; ! 90: int *pwidth; ! 91: { ! 92: fprintf(stderr,"%d spans\n", n); ! 93: while (n--) { ! 94: fprintf(stderr, "[%d,%d] %d\n", ppt->x, ppt->y, *pwidth); ! 95: ppt++; ! 96: pwidth++; ! 97: } ! 98: fprintf(stderr, "\n"); ! 99: } ! 100: #endif ! 101: ! 102: void ! 103: cfbSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) ! 104: DrawablePtr pDrawable; ! 105: GCPtr pGC; ! 106: int nInit; /* number of spans to fill */ ! 107: DDXPointPtr pptInit; /* pointer to list of start points */ ! 108: int *pwidthInit; /* pointer to list of n widths */ ! 109: int fSorted; ! 110: { ! 111: /* next three parameters are post-clip */ ! 112: int n; /* number of spans to fill */ ! 113: register DDXPointPtr ppt; /* pointer to list of start points */ ! 114: register int *pwidth; /* pointer to list of n widths */ ! 115: int *addrlBase; /* pointer to start of bitmap */ ! 116: int nlwidth; /* width in longwords of bitmap */ ! 117: register int *addrl; /* pointer to current longword in bitmap */ ! 118: register int startmask; ! 119: register int endmask; ! 120: register int nlmiddle; ! 121: int rop; /* reduced rasterop */ ! 122: int *pwidthFree; /* copies of the pointers to free */ ! 123: DDXPointPtr pptFree; ! 124: int fill, rrop; ! 125: ! 126: switch (pDrawable->depth) { ! 127: case 1: ! 128: rrop = ReduceRop( pGC->alu, pGC->fgPixel ); ! 129: switch ( rrop ) { ! 130: case RROP_BLACK: ! 131: mfbBlackSolidFS(pDrawable, pGC, nInit, pptInit, ! 132: pwidthInit, fSorted); ! 133: break; ! 134: case RROP_WHITE: ! 135: mfbWhiteSolidFS(pDrawable, pGC, nInit, pptInit, ! 136: pwidthInit, fSorted); ! 137: break; ! 138: case RROP_NOP: ! 139: return; ! 140: case RROP_INVERT: ! 141: mfbInvertSolidFS(pDrawable, pGC, nInit, pptInit, ! 142: pwidthInit, fSorted); ! 143: break; ! 144: } ! 145: return; ! 146: case 8: ! 147: break; ! 148: default: ! 149: FatalError("cfbSolidFS: invalid depth\n"); ! 150: } ! 151: ! 152: if (!(pGC->planemask)) ! 153: return; ! 154: ! 155: n = nInit * miFindMaxBand(((cfbPrivGC *)(pGC->devPriv))->pCompositeClip); ! 156: pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int)); ! 157: ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); ! 158: if(!ppt || !pwidth) ! 159: { ! 160: DEALLOCATE_LOCAL(ppt); ! 161: DEALLOCATE_LOCAL(pwidth); ! 162: return; ! 163: } ! 164: #ifdef notdef ! 165: dumpspans(n, pptInit, pwidthInit); ! 166: #endif ! 167: pwidthFree = pwidth; ! 168: pptFree = ppt; ! 169: n = miClipSpans(((cfbPrivGC *)(pGC->devPriv))->pCompositeClip, ! 170: pptInit, pwidthInit, nInit, ! 171: ppt, pwidth, fSorted); ! 172: ! 173: #ifdef notdef ! 174: dumpspans(n, ppt, pwidth); ! 175: #endif ! 176: if (pDrawable->type == DRAWABLE_WINDOW) ! 177: { ! 178: addrlBase = (int *) ! 179: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate); ! 180: nlwidth = (int) ! 181: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2; ! 182: } ! 183: else ! 184: { ! 185: addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate); ! 186: nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2; ! 187: } ! 188: ! 189: rop = pGC->alu; ! 190: fill = PFILL(pGC->fgPixel); ! 191: ! 192: while (n--) ! 193: { ! 194: addrl = addrlBase + (ppt->y * nlwidth) + (ppt->x >> PWSH); ! 195: ! 196: if (*pwidth) ! 197: { ! 198: if ( ((ppt->x & PIM) + *pwidth) <= PPW) ! 199: { ! 200: /* all bits inside same longword */ ! 201: putbitsrop( fill, ppt->x & PIM, *pwidth, ! 202: addrl, pGC->planemask, rop ); ! 203: } ! 204: else ! 205: { ! 206: maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); ! 207: if ( startmask ) { ! 208: putbitsrop( fill, ppt->x & PIM, ! 209: PPW-(ppt->x&PIM), addrl, pGC->planemask, rop); ! 210: ++addrl; ! 211: } ! 212: while ( nlmiddle-- ) { ! 213: putbitsrop( fill, 0, PPW, ! 214: addrl, pGC->planemask, rop ); ! 215: ++addrl; ! 216: } ! 217: if ( endmask ) { ! 218: putbitsrop( fill, 0, ! 219: ((ppt->x + *pwidth)&PIM), addrl, pGC->planemask, rop ); ! 220: } ! 221: } ! 222: } ! 223: pwidth++; ! 224: ppt++; ! 225: } ! 226: DEALLOCATE_LOCAL(pptFree); ! 227: DEALLOCATE_LOCAL(pwidthFree); ! 228: } ! 229: ! 230: ! 231: /* Fill spans with tiles that aren't 32 bits wide */ ! 232: void ! 233: cfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) ! 234: DrawablePtr pDrawable; ! 235: GC *pGC; ! 236: int nInit; /* number of spans to fill */ ! 237: DDXPointPtr pptInit; /* pointer to list of start points */ ! 238: int *pwidthInit; /* pointer to list of n widths */ ! 239: int fSorted; ! 240: { ! 241: int iline; /* first line of tile to use */ ! 242: /* next three parameters are post-clip */ ! 243: int n; /* number of spans to fill */ ! 244: register DDXPointPtr ppt; /* pointer to list of start points */ ! 245: register int *pwidth; /* pointer to list of n widths */ ! 246: int *addrlBase; /* pointer to start of bitmap */ ! 247: int nlwidth; /* width in longwords of bitmap */ ! 248: register int *pdst; /* pointer to current word in bitmap */ ! 249: register int *psrc; /* pointer to current word in tile */ ! 250: register int startmask; ! 251: register int nlMiddle; ! 252: PixmapPtr pTile; /* pointer to tile we want to fill with */ ! 253: int w, width, x, tmpSrc, srcStartOver, nstart, nend; ! 254: int endmask, tlwidth, rem, tileWidth, *psrcT, rop; ! 255: int *pwidthFree; /* copies of the pointers to free */ ! 256: DDXPointPtr pptFree; ! 257: ! 258: switch (pDrawable->depth) { ! 259: case 1: ! 260: mfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); ! 261: return; ! 262: case 8: ! 263: break; ! 264: default: ! 265: FatalError("cfbUnnaturalTileFS: invalid depth\n"); ! 266: } ! 267: ! 268: if (!(pGC->planemask)) ! 269: return; ! 270: ! 271: n = nInit * miFindMaxBand(((cfbPrivGC *)(pGC->devPriv))->pCompositeClip); ! 272: pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int)); ! 273: ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); ! 274: if(!ppt || !pwidth) ! 275: { ! 276: DEALLOCATE_LOCAL(ppt); ! 277: DEALLOCATE_LOCAL(pwidth); ! 278: return; ! 279: } ! 280: pwidthFree = pwidth; ! 281: pptFree = ppt; ! 282: n = miClipSpans(((cfbPrivGC *)(pGC->devPriv))->pCompositeClip, ! 283: pptInit, pwidthInit, nInit, ! 284: ppt, pwidth, fSorted); ! 285: ! 286: if (pGC->fillStyle == FillTiled) ! 287: { ! 288: pTile = ((cfbPrivGC *)(pGC->devPriv))->pRotatedTile; ! 289: tlwidth = pTile->devKind >> 2; ! 290: rop = pGC->alu; ! 291: } ! 292: else ! 293: { ! 294: pTile = ((cfbPrivGC *)(pGC->devPriv))->pRotatedStipple; ! 295: tlwidth = pTile->devKind >> 2; ! 296: rop = pGC->alu; ! 297: } ! 298: ! 299: if (pDrawable->type == DRAWABLE_WINDOW) ! 300: { ! 301: addrlBase = (int *) ! 302: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate); ! 303: nlwidth = (int) ! 304: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2; ! 305: } ! 306: else ! 307: { ! 308: addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate); ! 309: nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2; ! 310: } ! 311: ! 312: tileWidth = pTile->width; ! 313: while (n--) ! 314: { ! 315: iline = ppt->y % pTile->height; ! 316: pdst = addrlBase + (ppt->y * nlwidth) + (ppt->x >> PWSH); ! 317: psrcT = (int *) pTile->devPrivate + (iline * tlwidth); ! 318: x = ppt->x; ! 319: ! 320: if (*pwidth) ! 321: { ! 322: width = *pwidth; ! 323: while(width > 0) ! 324: { ! 325: rem = x % tileWidth; ! 326: psrc = psrcT + rem / PPW; ! 327: w = min(tileWidth, width); ! 328: w = min(w,tileWidth-rem); ! 329: #ifdef notdef ! 330: if((rem = x % tileWidth) != 0) ! 331: { ! 332: w = min(min(tileWidth - rem, width), PPW); ! 333: /* we want to grab from the end of the tile. Figure ! 334: * out where that is. In general, the start of the last ! 335: * word of data on this scanline is tlwidth -1 words ! 336: * away. But if we want to grab more bits than we'll ! 337: * find on that line, we have to back up 1 word further. ! 338: * On the other hand, if the whole tile fits in 1 word, ! 339: * let's skip the work */ ! 340: endinc = tlwidth - 1 - (tileWidth-rem) / PPW; ! 341: ! 342: if(endinc) ! 343: { ! 344: if((rem & PIM) + w > tileWidth % PPW) ! 345: endinc--; ! 346: } ! 347: ! 348: getbits(psrc + endinc, rem & PIM, w, tmpSrc); ! 349: putbitsrop(tmpSrc, (x & PIM), w, pdst, ! 350: pGC->planemask, rop); ! 351: if((x & PIM) + w >= PPW) ! 352: pdst++; ! 353: } ! 354: else ! 355: #endif notdef ! 356: if(((rem & PIM) + w) <= PPW) ! 357: { ! 358: getbits(psrc, (rem & PIM), w, tmpSrc); ! 359: putbitsrop(tmpSrc, x & PIM, w, pdst, ! 360: pGC->planemask, rop); ! 361: ++pdst; ! 362: } ! 363: else ! 364: { ! 365: maskbits(x, w, startmask, endmask, nlMiddle); ! 366: ! 367: if (startmask) ! 368: nstart = PPW - (x & PIM); ! 369: else ! 370: nstart = 0; ! 371: if (endmask) ! 372: nend = (x + w) & PIM; ! 373: else ! 374: nend = 0; ! 375: ! 376: srcStartOver = nstart > PLST; ! 377: ! 378: if(startmask) ! 379: { ! 380: getbits(psrc, rem & PIM, nstart, tmpSrc); ! 381: putbitsrop(tmpSrc, x & PIM, nstart, pdst, ! 382: pGC->planemask, rop); ! 383: pdst++; ! 384: psrc++; ! 385: } ! 386: ! 387: while(nlMiddle--) ! 388: { ! 389: getbits(psrc, 0, PPW, tmpSrc); ! 390: putbitsrop( tmpSrc, 0, PPW, ! 391: pdst, pGC->planemask, rop ); ! 392: pdst++; ! 393: psrc++; ! 394: } ! 395: if(endmask) ! 396: { ! 397: getbits(psrc, 0, nend, tmpSrc); ! 398: putbitsrop(tmpSrc, 0, nend, pdst, ! 399: pGC->planemask, rop); ! 400: } ! 401: } ! 402: x += w; ! 403: width -= w; ! 404: } ! 405: } ! 406: ppt++; ! 407: pwidth++; ! 408: } ! 409: DEALLOCATE_LOCAL(pptFree); ! 410: DEALLOCATE_LOCAL(pwidthFree); ! 411: } ! 412: ! 413: ! 414: /* ! 415: * QuartetBitsTable contains four masks whose binary values are masks in the ! 416: * low order quartet that contain the number of bits specified in the ! 417: * index. This table is used by getstipplepixels. ! 418: */ ! 419: static unsigned int QuartetBitsTable[5] = { ! 420: #if (BITMAP_BIT_ORDER == MSBFirst) ! 421: 0x00000000, /* 0 - 0000 */ ! 422: 0x00000008, /* 1 - 1000 */ ! 423: 0x0000000C, /* 2 - 1100 */ ! 424: 0x0000000E, /* 3 - 1110 */ ! 425: 0x0000000F /* 4 - 1111 */ ! 426: #else /* (BITMAP_BIT_ORDER == LSBFirst */ ! 427: 0x00000000, /* 0 - 0000 */ ! 428: 0x00000001, /* 1 - 0001 */ ! 429: 0x00000003, /* 2 - 0011 */ ! 430: 0x00000007, /* 3 - 0111 */ ! 431: 0x0000000F /* 4 - 1111 */ ! 432: #endif (BITMAP_BIT_ORDER == MSBFirst) ! 433: }; ! 434: ! 435: /* ! 436: * QuartetPixelMaskTable is used by getstipplepixels to get a pixel mask ! 437: * corresponding to a quartet of bits. ! 438: */ ! 439: static unsigned int QuartetPixelMaskTable[16] = { ! 440: 0x00000000, ! 441: 0x000000FF, ! 442: 0x0000FF00, ! 443: 0x0000FFFF, ! 444: 0x00FF0000, ! 445: 0x00FF00FF, ! 446: 0x00FFFF00, ! 447: 0x00FFFFFF, ! 448: 0xFF000000, ! 449: 0xFF0000FF, ! 450: 0xFF00FF00, ! 451: 0xFF00FFFF, ! 452: 0xFFFF0000, ! 453: 0xFFFF00FF, ! 454: 0xFFFFFF00, ! 455: 0xFFFFFFFF ! 456: }; ! 457: ! 458: ! 459: /* ! 460: * getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix ) ! 461: * ! 462: * Converts bits to pixels in a reasonable way. Takes w (1 <= w <= 4) ! 463: * bits from *psrcstip, starting at bit x; call this a quartet of bits. ! 464: * Then, takes the pixels from *psrcpix corresponding to the one-bits (if ! 465: * ones is TRUE) or the zero-bits (if ones is FALSE) of the quartet ! 466: * and puts these pixels into destpix. ! 467: * ! 468: * Example: ! 469: * ! 470: * getstipplepixels( &(0x08192A3B), 17, 4, 1, &(0x4C5D6E7F), dest ) ! 471: * ! 472: * 0x08192A3B = 0000 1000 0001 1001 0010 1010 0011 1011 ! 473: * ! 474: * This will take 4 bits starting at bit 17, so the quartet is 0x5 = 0101. ! 475: * It will take pixels from 0x4C5D6E7F corresponding to the one-bits in this ! 476: * quartet, so dest = 0x005D007F. ! 477: * ! 478: * XXX This should be turned into a macro after it is debugged. ! 479: * XXX Has byte order dependencies. ! 480: * XXX This works for all values of x and w within a doubleword, depending ! 481: * on the compiler to generate proper code for negative shifts. ! 482: */ ! 483: ! 484: void getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix ) ! 485: unsigned int *psrcstip, *psrcpix, *destpix; ! 486: int x, w, ones; ! 487: { ! 488: unsigned int q; ! 489: ! 490: #if (BITMAP_BIT_ORDER == MSBFirst) ! 491: q = ((*psrcstip) >> (28-x)) & 0x0F; ! 492: if ( x+w > 32 ) ! 493: q |= *(psrcstip+1) >> (64-x-w); /* & 0xF ? ****XXX*/ ! 494: #else ! 495: q = (*psrcstip) >> x; ! 496: if ( x+w > 32 ) ! 497: q |= *(psrcstip+1) << (32-x); ! 498: q &= 0xf; ! 499: #endif ! 500: q = QuartetBitsTable[w] & (ones ? q : ~q); ! 501: *destpix = (*(psrcpix)) & QuartetPixelMaskTable[q]; ! 502: } ! 503: ! 504: ! 505: /* Fill spans with stipples that aren't 32 bits wide */ ! 506: void ! 507: cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) ! 508: DrawablePtr pDrawable; ! 509: GC *pGC; ! 510: int nInit; /* number of spans to fill */ ! 511: DDXPointPtr pptInit; /* pointer to list of start points */ ! 512: int *pwidthInit; /* pointer to list of n widths */ ! 513: int fSorted; ! 514: { ! 515: /* next three parameters are post-clip */ ! 516: int n; /* number of spans to fill */ ! 517: int xrem; ! 518: register DDXPointPtr ppt; /* pointer to list of start points */ ! 519: register int *pwidth; /* pointer to list of n widths */ ! 520: int iline; /* first line of tile to use */ ! 521: int *addrlBase; /* pointer to start of bitmap */ ! 522: int nlwidth; /* width in longwords of bitmap */ ! 523: register int *pdst; /* pointer to current word in bitmap */ ! 524: PixmapPtr pStipple; /* pointer to stipple we want to fill with */ ! 525: int w, width, x; ! 526: unsigned int tmpSrc, tmpDst1, tmpDst2; ! 527: int stwidth, stippleWidth, *psrcS, rop; ! 528: int *pwidthFree; /* copies of the pointers to free */ ! 529: DDXPointPtr pptFree; ! 530: unsigned int fgfill, bgfill; ! 531: ! 532: switch (pDrawable->depth) { ! 533: case 1: ! 534: mfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, ! 535: pwidthInit, fSorted); ! 536: return; ! 537: case 8: ! 538: break; ! 539: default: ! 540: FatalError("cfbUnnaturalStippleFS: invalid depth\n"); ! 541: } ! 542: ! 543: if (!(pGC->planemask)) ! 544: return; ! 545: ! 546: n = nInit * miFindMaxBand(((cfbPrivGC *)(pGC->devPriv))->pCompositeClip); ! 547: pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int)); ! 548: ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec)); ! 549: if(!ppt || !pwidth) ! 550: { ! 551: DEALLOCATE_LOCAL(ppt); ! 552: DEALLOCATE_LOCAL(pwidth); ! 553: return; ! 554: } ! 555: pwidthFree = pwidth; ! 556: pptFree = ppt; ! 557: n = miClipSpans(((cfbPrivGC *)(pGC->devPriv))->pCompositeClip, ! 558: pptInit, pwidthInit, nInit, ! 559: ppt, pwidth, fSorted); ! 560: rop = ((cfbPrivGC *)(pGC->devPriv))->rop; ! 561: fgfill = PFILL(pGC->fgPixel); ! 562: bgfill = PFILL(pGC->bgPixel); ! 563: ! 564: /* ! 565: * OK, so what's going on here? We have two Drawables: ! 566: * ! 567: * The Stipple: ! 568: * Depth = 1 ! 569: * Width = stippleWidth ! 570: * Words per scanline = stwidth ! 571: * Pointer to pixels = pStipple->devPrivate ! 572: */ ! 573: pStipple = ((cfbPrivGC *)(pGC->devPriv))->pRotatedStipple; ! 574: ! 575: if (pStipple->drawable.depth != 1) { ! 576: FatalError( "Stipple depth not equal to 1!\n" ); ! 577: } ! 578: ! 579: stwidth = pStipple->devKind >> 2; ! 580: stippleWidth = pStipple->width; ! 581: ! 582: /* ! 583: * The Target: ! 584: * Depth = PSZ ! 585: * Width = determined from *pwidth ! 586: * Words per scanline = nlwidth ! 587: * Pointer to pixels = addrlBase ! 588: */ ! 589: if (pDrawable->type == DRAWABLE_WINDOW) ! 590: { ! 591: addrlBase = (int *) ! 592: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate); ! 593: nlwidth = (int) ! 594: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2; ! 595: } ! 596: else ! 597: { ! 598: addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate); ! 599: nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2; ! 600: } ! 601: ! 602: while (n--) ! 603: { ! 604: iline = ppt->y % pStipple->height; ! 605: x = ppt->x; ! 606: pdst = addrlBase + (ppt->y * nlwidth); ! 607: psrcS = (int *) pStipple->devPrivate + (iline * stwidth); ! 608: ! 609: if (*pwidth) ! 610: { ! 611: width = *pwidth; ! 612: while(width > 0) ! 613: { ! 614: /* ! 615: * Do a stripe through the stipple & destination w pixels ! 616: * wide. w is not more than: ! 617: * - the width of the destination ! 618: * - the width of the stipple ! 619: * - the distance between x and the next word ! 620: * boundary in the destination ! 621: * - the distance between x and the next word ! 622: * boundary in the stipple ! 623: */ ! 624: ! 625: /* width of dest/stipple */ ! 626: xrem = x % stippleWidth; ! 627: w = min((stippleWidth - (x % stippleWidth)), width); ! 628: /* dist to word bound in dest */ ! 629: w = min(w, PPW - (x & PIM)); ! 630: /* dist to word bound in stip */ ! 631: w = min(w, 32 - (x & 0x1f)); ! 632: ! 633: /* Fill tmpSrc with the source pixels */ ! 634: tmpSrc = *(pdst + (x >> PWSH)); ! 635: switch ( pGC->fillStyle ) { ! 636: case FillOpaqueStippled: ! 637: getstipplepixels(psrcS + (xrem>>5), (x&0x1f), w, 0, ! 638: &bgfill, &tmpDst1); ! 639: getstipplepixels(psrcS + (xrem>>5), (x&0x1f), w, 1, ! 640: &fgfill, &tmpDst2); ! 641: break; ! 642: case FillStippled: ! 643: getstipplepixels(psrcS + (xrem>>5), (x&0x1f), w, 0, ! 644: &tmpSrc, &tmpDst1); ! 645: getstipplepixels(psrcS + (xrem>>5), (x&0x1f), w, 1, ! 646: &fgfill, &tmpDst2); ! 647: break; ! 648: } ! 649: #ifdef notdef ! 650: putbitsrop(tmpDst1 | tmpDst2, x & PIM, w, pdst + (x>>PWSH), ! 651: pGC->planemask, rop); ! 652: #else ! 653: { ! 654: /* ! 655: * Ultrix cc hasn't enough expression stack to compile ! 656: * these values in the putbitsrop call. (MIT:yba) ! 657: */ ! 658: int tmpDst = tmpDst1 | tmpDst2, tmpx = x & PIM; ! 659: int * pdsttmp = pdst + (x>>PWSH); ! 660: putbitsrop(tmpDst, tmpx, w, pdsttmp, pGC->planemask, rop); ! 661: } ! 662: #endif notdef ! 663: x += w; ! 664: width -= w; ! 665: } ! 666: } ! 667: #ifdef notdef ! 668: if (*pwidth) ! 669: { ! 670: width = *pwidth; ! 671: while(width > 0) ! 672: { ! 673: psrc = psrcS; ! 674: w = min(min(stippleWidth, width), PPW); ! 675: if((rem = x % stippleWidth) != 0) ! 676: { ! 677: w = min(min(stippleWidth - rem, width), PPW); ! 678: /* we want to grab from the end of the tile. Figure ! 679: * out where that is. In general, the start of the last ! 680: * word of data on this scanline is stwidth -1 words ! 681: * away. But if we want to grab more bits than we'll ! 682: * find on that line, we have to back up 1 word further. ! 683: * On the other hand, if the whole tile fits in 1 word, ! 684: * let's skip the work */ ! 685: endinc = stwidth - 1 - w / PPW; ! 686: ! 687: if(endinc) ! 688: { ! 689: if((rem & 0x1f) + w > stippleWidth % PPW) ! 690: endinc--; ! 691: } ! 692: ! 693: getbits(psrc + endinc, rem & PIM, w, tmpSrc); ! 694: putbitsrop(tmpSrc, (x & PIM), w, pdst, ! 695: pGC->planemask, rop); ! 696: if((x & PIM) + w >= PPW) ! 697: pdst++; ! 698: } ! 699: ! 700: else if(((x & PIM) + w) < PPW) ! 701: { ! 702: getbits(psrc, 0, w, tmpSrc); ! 703: putbitsrop(tmpSrc, x & PIM, w, pdst, ! 704: pGC->planemask, rop); ! 705: } ! 706: else ! 707: { ! 708: maskbits(x, w, startmask, endmask, nlMiddle); ! 709: ! 710: if (startmask) ! 711: nstart = PPW - (x & PIM); ! 712: else ! 713: nstart = 0; ! 714: if (endmask) ! 715: nend = (x + w) & PIM; ! 716: else ! 717: nend = 0; ! 718: ! 719: srcStartOver = nstart > PLST; ! 720: ! 721: if(startmask) ! 722: { ! 723: getbits(psrc, 0, nstart, tmpSrc); ! 724: putbitsrop(tmpSrc, (x & PIM), nstart, pdst, ! 725: pGC->planemask, rop); ! 726: pdst++; ! 727: if(srcStartOver) ! 728: psrc++; ! 729: } ! 730: ! 731: while(nlMiddle--) ! 732: { ! 733: /* ! 734: getbits(psrc, nstart, PPW, tmpSrc); ! 735: putbitsrop( tmpSrc, 0, PPW, ! 736: pdst, pGC->planemask, rop ); ! 737: */ ! 738: switch ( pGC->fillStyle ) { ! 739: case FillStippled: ! 740: getstipplepixels( psrc, j, 4, 1, pdst, tmp1 ); ! 741: break; ! 742: case FillOpaqueStippled: ! 743: getstipplepixels( psrc, j, 4, 1, pdst, tmp1 ); ! 744: break; ! 745: } ! 746: pdst++; ! 747: psrc++; ! 748: } ! 749: if(endmask) ! 750: { ! 751: getbits(psrc, nstart, nend, tmpSrc); ! 752: putbitsrop(tmpSrc, 0, nend, pdst, ! 753: pGC->planemask, rop); ! 754: } ! 755: } ! 756: x += w; ! 757: width -= w; ! 758: } ! 759: } ! 760: #endif ! 761: ppt++; ! 762: pwidth++; ! 763: } ! 764: DEALLOCATE_LOCAL(pptFree); ! 765: DEALLOCATE_LOCAL(pwidthFree); ! 766: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.