|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 4: ! 5: All Rights Reserved ! 6: ! 7: Permission to use, copy, modify, and distribute this software and its ! 8: documentation for any purpose and without fee is hereby granted, ! 9: provided that the above copyright notice appear in all copies and that ! 10: both that copyright notice and this permission notice appear in ! 11: supporting documentation, and that the names of Digital or MIT not be ! 12: used in advertising or publicity pertaining to distribution of the ! 13: software without specific, written prior permission. ! 14: ! 15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 21: SOFTWARE. ! 22: ! 23: ******************************************************************/ ! 24: /* $Header: mfbbitblt.c,v 1.42 87/08/09 13:58:52 ham Exp $ */ ! 25: #include "X.h" ! 26: #include "Xprotostr.h" ! 27: ! 28: #include "miscstruct.h" ! 29: #include "regionstr.h" ! 30: #include "gcstruct.h" ! 31: #include "windowstr.h" ! 32: #include "pixmapstr.h" ! 33: #include "scrnintstr.h" ! 34: ! 35: #include "mfb.h" ! 36: #include "maskbits.h" ! 37: ! 38: ! 39: /* CopyArea and CopyPlane for a monchrome frame buffer ! 40: ! 41: ! 42: clip the source rectangle to the source's available bits. (this ! 43: avoids copying unnecessary pieces that will just get exposed anyway.) ! 44: this becomes the new shape of the destination. ! 45: clip the destination region to the composite clip in the ! 46: GC. this requires translating the destination region to (dstx, dsty). ! 47: build a list of source points, one for each rectangle in the ! 48: destination. this is a simple translation. ! 49: go do the multiple rectangle copies ! 50: do graphics exposures ! 51: */ ! 52: ! 53: void ! 54: mfbCopyArea(pSrcDrawable, pDstDrawable, ! 55: pGC, srcx, srcy, width, height, dstx, dsty) ! 56: register DrawablePtr pSrcDrawable; ! 57: register DrawablePtr pDstDrawable; ! 58: GC *pGC; ! 59: int srcx, srcy; ! 60: int width, height; ! 61: int dstx, dsty; ! 62: { ! 63: BoxRec srcBox; ! 64: RegionPtr prgnSrcClip; /* may be a new region, or just a copy */ ! 65: int realSrcClip = 0; /* non-0 if we've created a src clip */ ! 66: ! 67: RegionPtr prgnDst; ! 68: DDXPointPtr pptSrc; ! 69: register DDXPointPtr ppt; ! 70: register BoxPtr pbox; ! 71: int i; ! 72: register int dx; ! 73: register int dy; ! 74: xRectangle origSource; ! 75: DDXPointRec origDest; ! 76: ! 77: if (!(pGC->planemask & 1)) ! 78: return; ! 79: ! 80: origSource.x = srcx; ! 81: origSource.y = srcy; ! 82: origSource.width = width; ! 83: origSource.height = height; ! 84: origDest.x = dstx; ! 85: origDest.y = dsty; ! 86: ! 87: /* ! 88: clip the left and top edges of the source ! 89: */ ! 90: if (srcx < 0) ! 91: { ! 92: width += srcx; ! 93: srcx = 0; ! 94: } ! 95: if (srcy < 0) ! 96: { ! 97: height += srcy; ! 98: srcy = 0; ! 99: } ! 100: ! 101: /* clip the source */ ! 102: ! 103: if (pSrcDrawable->type == DRAWABLE_PIXMAP) ! 104: { ! 105: BoxRec box; ! 106: ! 107: box.x1 = 0; ! 108: box.y1 = 0; ! 109: box.x2 = ((PixmapPtr)pSrcDrawable)->width; ! 110: box.y2 = ((PixmapPtr)pSrcDrawable)->height; ! 111: ! 112: prgnSrcClip = miRegionCreate(&box, 1); ! 113: realSrcClip = 1; ! 114: } ! 115: else ! 116: { ! 117: srcx += ((WindowPtr)pSrcDrawable)->absCorner.x; ! 118: srcy += ((WindowPtr)pSrcDrawable)->absCorner.y; ! 119: prgnSrcClip = ((WindowPtr)pSrcDrawable)->clipList; ! 120: } ! 121: ! 122: srcBox.x1 = srcx; ! 123: srcBox.y1 = srcy; ! 124: srcBox.x2 = srcx + width; ! 125: srcBox.y2 = srcy + height; ! 126: ! 127: prgnDst = miRegionCreate(&srcBox, 1); ! 128: miIntersect(prgnDst, prgnDst, prgnSrcClip); ! 129: ! 130: if (pDstDrawable->type == DRAWABLE_WINDOW) ! 131: { ! 132: if (!((WindowPtr)pDstDrawable)->realized) ! 133: { ! 134: miSendNoExpose(pGC); ! 135: miRegionDestroy(prgnDst); ! 136: if (realSrcClip) ! 137: miRegionDestroy(prgnSrcClip); ! 138: return; ! 139: } ! 140: dstx += ((WindowPtr)pDstDrawable)->absCorner.x; ! 141: dsty += ((WindowPtr)pDstDrawable)->absCorner.y; ! 142: } ! 143: ! 144: dx = srcx - dstx; ! 145: dy = srcy - dsty; ! 146: ! 147: /* clip the shape of the dst to the destination composite clip */ ! 148: miTranslateRegion(prgnDst, -dx, -dy); ! 149: miIntersect(prgnDst, ! 150: prgnDst, ! 151: ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip); ! 152: ! 153: if (!prgnDst->numRects) ! 154: { ! 155: miSendNoExpose(pGC); ! 156: miRegionDestroy(prgnDst); ! 157: if (realSrcClip) ! 158: miRegionDestroy(prgnSrcClip); ! 159: return; ! 160: } ! 161: if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL( prgnDst->numRects * ! 162: sizeof(DDXPointRec)))) ! 163: { ! 164: miRegionDestroy(prgnDst); ! 165: if (realSrcClip) ! 166: miRegionDestroy(prgnSrcClip); ! 167: return; ! 168: } ! 169: pbox = prgnDst->rects; ! 170: ppt = pptSrc; ! 171: for (i=0; i<prgnDst->numRects; i++, pbox++, ppt++) ! 172: { ! 173: ppt->x = pbox->x1 + dx; ! 174: ppt->y = pbox->y1 + dy; ! 175: } ! 176: ! 177: mfbDoBitblt(pSrcDrawable, pDstDrawable, pGC->alu, prgnDst, pptSrc); ! 178: ! 179: if (((mfbPrivGC *)(pGC->devPriv))->fExpose) ! 180: miHandleExposures(pSrcDrawable, pDstDrawable, pGC, ! 181: origSource.x, origSource.y, ! 182: origSource.width, origSource.height, ! 183: origDest.x, origDest.y); ! 184: ! 185: DEALLOCATE_LOCAL(pptSrc); ! 186: miRegionDestroy(prgnDst); ! 187: if (realSrcClip) ! 188: miRegionDestroy(prgnSrcClip); ! 189: } ! 190: ! 191: /* DoBitblt() does multiple rectangle moves into the rectangles ! 192: DISCLAIMER: ! 193: this code can be made much faster; this implementation is ! 194: designed to be independent of byte/bit order, processor ! 195: instruction set, and the like. it could probably be done ! 196: in a similarly device independent way using mask tables instead ! 197: of the getbits/putbits macros. the narrow case (w<32) can be ! 198: subdivided into a case that crosses word boundaries and one that ! 199: doesn't. ! 200: ! 201: we have to cope with the dircetion on a per band basis, ! 202: rather than a per rectangle basis. moving bottom to top ! 203: means we have to invert the order of the bands; moving right ! 204: to left requires reversing the order of the rectangles in ! 205: each band. ! 206: ! 207: if src or dst is a window, the points have already been ! 208: translated. ! 209: */ ! 210: ! 211: mfbDoBitblt(pSrcDrawable, pDstDrawable, alu, prgnDst, pptSrc) ! 212: DrawablePtr pSrcDrawable; ! 213: DrawablePtr pDstDrawable; ! 214: int alu; ! 215: RegionPtr prgnDst; ! 216: DDXPointPtr pptSrc; ! 217: { ! 218: unsigned int *psrcBase, *pdstBase; ! 219: /* start of src and dst bitmaps */ ! 220: int widthSrc, widthDst; /* add to get to same position in next line */ ! 221: ! 222: register BoxPtr pbox; ! 223: int nbox; ! 224: ! 225: BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2; ! 226: /* temporaries for shuffling rectangles */ ! 227: DDXPointPtr pptTmp, pptNew1, pptNew2; ! 228: /* shuffling boxes entails shuffling the ! 229: source points too */ ! 230: int w, h; ! 231: int xdir; /* 1 = left right, -1 = right left/ */ ! 232: int ydir; /* 1 = top down, -1 = bottom up */ ! 233: ! 234: unsigned int *psrcLine, *pdstLine; ! 235: /* pointers to line with current src and dst */ ! 236: register unsigned int *psrc;/* pointer to current src longword */ ! 237: register unsigned int *pdst;/* pointer to current dst longword */ ! 238: ! 239: /* following used for looping through a line */ ! 240: int startmask, endmask; /* masks for writing ends of dst */ ! 241: int nlMiddle; /* whole longwords in dst */ ! 242: register int nl; /* temp copy of nlMiddle */ ! 243: register unsigned int tmpSrc; ! 244: /* place to store full source word */ ! 245: register int xoffSrc; /* offset (>= 0, < 32) from which to ! 246: fetch whole longwords fetched ! 247: in src */ ! 248: int nstart; /* number of ragged bits at start of dst */ ! 249: int nend; /* number of ragged bits at end of dst */ ! 250: int srcStartOver; /* pulling nstart bits from src ! 251: overflows into the next word? */ ! 252: ! 253: ! 254: if (pSrcDrawable->type == DRAWABLE_WINDOW) ! 255: { ! 256: psrcBase = (unsigned int *) ! 257: (((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devPrivate); ! 258: widthSrc = (int) ! 259: ((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devKind ! 260: >> 2; ! 261: } ! 262: else ! 263: { ! 264: psrcBase = (unsigned int *)(((PixmapPtr)pSrcDrawable)->devPrivate); ! 265: widthSrc = (int)(((PixmapPtr)pSrcDrawable)->devKind) >> 2; ! 266: } ! 267: ! 268: if (pDstDrawable->type == DRAWABLE_WINDOW) ! 269: { ! 270: pdstBase = (unsigned int *) ! 271: (((PixmapPtr)(pDstDrawable->pScreen->devPrivate))->devPrivate); ! 272: widthDst = (int) ! 273: ((PixmapPtr)(pDstDrawable->pScreen->devPrivate))->devKind ! 274: >> 2; ! 275: } ! 276: else ! 277: { ! 278: pdstBase = (unsigned int *)(((PixmapPtr)pDstDrawable)->devPrivate); ! 279: widthDst = (int)(((PixmapPtr)pDstDrawable)->devKind) >> 2; ! 280: } ! 281: ! 282: pbox = prgnDst->rects; ! 283: nbox = prgnDst->numRects; ! 284: ! 285: pboxNew1 = 0; ! 286: pptNew1 = 0; ! 287: pboxNew2 = 0; ! 288: pptNew2 = 0; ! 289: if (pptSrc->y < pbox->y1) ! 290: { ! 291: /* walk source botttom to top */ ! 292: ydir = -1; ! 293: widthSrc = -widthSrc; ! 294: widthDst = -widthDst; ! 295: ! 296: if (nbox > 1) ! 297: { ! 298: /* keep ordering in each band, reverse order of bands */ ! 299: pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); ! 300: pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); ! 301: if(!pboxNew1 || !pptNew1) ! 302: { ! 303: DEALLOCATE_LOCAL(pptNew1); ! 304: DEALLOCATE_LOCAL(pboxNew1); ! 305: return; ! 306: } ! 307: pboxBase = pboxNext = pbox+nbox-1; ! 308: while (pboxBase >= pbox) ! 309: { ! 310: while ((pboxNext >= pbox) && ! 311: (pboxBase->y1 == pboxNext->y1)) ! 312: pboxNext--; ! 313: pboxTmp = pboxNext+1; ! 314: pptTmp = pptSrc + (pboxTmp - pbox); ! 315: while (pboxTmp <= pboxBase) ! 316: { ! 317: *pboxNew1++ = *pboxTmp++; ! 318: *pptNew1++ = *pptTmp++; ! 319: } ! 320: pboxBase = pboxNext; ! 321: } ! 322: pboxNew1 -= nbox; ! 323: pbox = pboxNew1; ! 324: pptNew1 -= nbox; ! 325: pptSrc = pptNew1; ! 326: } ! 327: } ! 328: else ! 329: { ! 330: /* walk source top to bottom */ ! 331: ydir = 1; ! 332: } ! 333: ! 334: if (pptSrc->x < pbox->x1) ! 335: { ! 336: /* walk source right to left */ ! 337: xdir = -1; ! 338: ! 339: if (nbox > 1) ! 340: { ! 341: /* reverse order of rects in each band */ ! 342: pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); ! 343: pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); ! 344: pboxBase = pboxNext = pbox; ! 345: if(!pboxNew2 || !pptNew2) ! 346: { ! 347: DEALLOCATE_LOCAL(pptNew2); ! 348: DEALLOCATE_LOCAL(pboxNew2); ! 349: return; ! 350: } ! 351: while (pboxBase < pbox+nbox) ! 352: { ! 353: while ((pboxNext < pbox+nbox) && ! 354: (pboxNext->y1 == pboxBase->y1)) ! 355: pboxNext++; ! 356: pboxTmp = pboxNext; ! 357: pptTmp = pptSrc + (pboxTmp - pbox); ! 358: while (pboxTmp != pboxBase) ! 359: { ! 360: *pboxNew2++ = *--pboxTmp; ! 361: *pptNew2++ = *--pptTmp; ! 362: } ! 363: pboxBase = pboxNext; ! 364: } ! 365: pboxNew2 -= nbox; ! 366: pbox = pboxNew2; ! 367: pptNew2 -= nbox; ! 368: pptSrc = pptNew2; ! 369: } ! 370: } ! 371: else ! 372: { ! 373: /* walk source left to right */ ! 374: xdir = 1; ! 375: } ! 376: ! 377: ! 378: /* special case copy */ ! 379: if (alu == GXcopy) ! 380: { ! 381: while (nbox--) ! 382: { ! 383: w = pbox->x2 - pbox->x1; ! 384: h = pbox->y2 - pbox->y1; ! 385: ! 386: if (ydir == -1) /* start at last scanline of rectangle */ ! 387: { ! 388: psrcLine = psrcBase + ((pptSrc->y+h-1) * -widthSrc); ! 389: pdstLine = pdstBase + ((pbox->y2-1) * -widthDst); ! 390: } ! 391: else /* start at first scanline */ ! 392: { ! 393: psrcLine = psrcBase + (pptSrc->y * widthSrc); ! 394: pdstLine = pdstBase + (pbox->y1 * widthDst); ! 395: } ! 396: ! 397: /* x direction doesn't matter for < 1 longword */ ! 398: if (w <= 32) ! 399: { ! 400: int srcBit, dstBit; /* bit offset of src and dst */ ! 401: ! 402: pdstLine += (pbox->x1 >> 5); ! 403: psrcLine += (pptSrc->x >> 5); ! 404: psrc = psrcLine; ! 405: pdst = pdstLine; ! 406: ! 407: srcBit = pptSrc->x & 0x1f; ! 408: dstBit = pbox->x1 & 0x1f; ! 409: ! 410: while(h--) ! 411: { ! 412: getbits(psrc, srcBit, w, tmpSrc) ! 413: putbits(tmpSrc, dstBit, w, pdst) ! 414: pdst += widthDst; ! 415: psrc += widthSrc; ! 416: } ! 417: } ! 418: else ! 419: { ! 420: maskbits(pbox->x1, w, startmask, endmask, nlMiddle) ! 421: if (startmask) ! 422: nstart = 32 - (pbox->x1 & 0x1f); ! 423: else ! 424: nstart = 0; ! 425: if (endmask) ! 426: nend = pbox->x2 & 0x1f; ! 427: else ! 428: nend = 0; ! 429: ! 430: xoffSrc = ((pptSrc->x & 0x1f) + nstart) & 0x1f; ! 431: srcStartOver = ((pptSrc->x & 0x1f) + nstart) > 31; ! 432: ! 433: if (xdir == 1) /* move left to right */ ! 434: { ! 435: pdstLine += (pbox->x1 >> 5); ! 436: psrcLine += (pptSrc->x >> 5); ! 437: ! 438: while (h--) ! 439: { ! 440: psrc = psrcLine; ! 441: pdst = pdstLine; ! 442: ! 443: if (startmask) ! 444: { ! 445: getbits(psrc, (pptSrc->x & 0x1f), nstart, tmpSrc) ! 446: putbits(tmpSrc, (pbox->x1 & 0x1f), nstart, pdst) ! 447: pdst++; ! 448: if (srcStartOver) ! 449: psrc++; ! 450: } ! 451: ! 452: nl = nlMiddle; ! 453: while (nl--) ! 454: { ! 455: getbits(psrc, xoffSrc, 32, tmpSrc) ! 456: *pdst++ = tmpSrc; ! 457: psrc++; ! 458: } ! 459: ! 460: if (endmask) ! 461: { ! 462: getbits(psrc, xoffSrc, nend, tmpSrc) ! 463: putbits(tmpSrc, 0, nend, pdst) ! 464: } ! 465: ! 466: pdstLine += widthDst; ! 467: psrcLine += widthSrc; ! 468: } ! 469: } ! 470: else /* move right to left */ ! 471: { ! 472: pdstLine += (pbox->x2 >> 5); ! 473: psrcLine += (pptSrc->x+w >> 5); ! 474: /* if fetch of last partial bits from source crosses ! 475: a longword boundary, start at the previous longword ! 476: */ ! 477: if (xoffSrc + nend >= 32) ! 478: --psrcLine; ! 479: ! 480: while (h--) ! 481: { ! 482: psrc = psrcLine; ! 483: pdst = pdstLine; ! 484: ! 485: if (endmask) ! 486: { ! 487: getbits(psrc, xoffSrc, nend, tmpSrc) ! 488: putbits(tmpSrc, 0, nend, pdst) ! 489: } ! 490: ! 491: nl = nlMiddle; ! 492: while (nl--) ! 493: { ! 494: --psrc; ! 495: getbits(psrc, xoffSrc, 32, tmpSrc) ! 496: *--pdst = tmpSrc; ! 497: } ! 498: ! 499: if (startmask) ! 500: { ! 501: if (srcStartOver) ! 502: --psrc; ! 503: --pdst; ! 504: getbits(psrc, (pptSrc->x & 0x1f), nstart, tmpSrc) ! 505: putbits(tmpSrc, (pbox->x1 & 0x1f), nstart, pdst) ! 506: } ! 507: ! 508: pdstLine += widthDst; ! 509: psrcLine += widthSrc; ! 510: } ! 511: } /* move right to left */ ! 512: } ! 513: pbox++; ! 514: pptSrc++; ! 515: } /* while (nbox--) */ ! 516: } ! 517: else /* do some rop */ ! 518: { ! 519: while (nbox--) ! 520: { ! 521: w = pbox->x2 - pbox->x1; ! 522: h = pbox->y2 - pbox->y1; ! 523: ! 524: if (ydir == -1) /* start at last scanline of rectangle */ ! 525: { ! 526: psrcLine = psrcBase + ((pptSrc->y+h-1) * -widthSrc); ! 527: pdstLine = pdstBase + ((pbox->y2-1) * -widthDst); ! 528: } ! 529: else /* start at first scanline */ ! 530: { ! 531: psrcLine = psrcBase + (pptSrc->y * widthSrc); ! 532: pdstLine = pdstBase + (pbox->y1 * widthDst); ! 533: } ! 534: ! 535: /* x direction doesn't matter for < 1 longword */ ! 536: if (w <= 32) ! 537: { ! 538: int srcBit, dstBit; /* bit offset of src and dst */ ! 539: ! 540: pdstLine += (pbox->x1 >> 5); ! 541: psrcLine += (pptSrc->x >> 5); ! 542: psrc = psrcLine; ! 543: pdst = pdstLine; ! 544: ! 545: srcBit = pptSrc->x & 0x1f; ! 546: dstBit = pbox->x1 & 0x1f; ! 547: ! 548: while(h--) ! 549: { ! 550: getbits(psrc, srcBit, w, tmpSrc) ! 551: putbitsrop(tmpSrc, dstBit, w, pdst, alu) ! 552: pdst += widthDst; ! 553: psrc += widthSrc; ! 554: } ! 555: } ! 556: else ! 557: { ! 558: maskbits(pbox->x1, w, startmask, endmask, nlMiddle) ! 559: if (startmask) ! 560: nstart = 32 - (pbox->x1 & 0x1f); ! 561: else ! 562: nstart = 0; ! 563: if (endmask) ! 564: nend = pbox->x2 & 0x1f; ! 565: else ! 566: nend = 0; ! 567: ! 568: xoffSrc = ((pptSrc->x & 0x1f) + nstart) & 0x1f; ! 569: srcStartOver = ((pptSrc->x & 0x1f) + nstart) > 31; ! 570: ! 571: if (xdir == 1) /* move left to right */ ! 572: { ! 573: pdstLine += (pbox->x1 >> 5); ! 574: psrcLine += (pptSrc->x >> 5); ! 575: ! 576: while (h--) ! 577: { ! 578: psrc = psrcLine; ! 579: pdst = pdstLine; ! 580: ! 581: if (startmask) ! 582: { ! 583: getbits(psrc, (pptSrc->x & 0x1f), nstart, tmpSrc) ! 584: putbitsrop(tmpSrc, (pbox->x1 & 0x1f), nstart, pdst, ! 585: alu) ! 586: pdst++; ! 587: if (srcStartOver) ! 588: psrc++; ! 589: } ! 590: ! 591: nl = nlMiddle; ! 592: while (nl--) ! 593: { ! 594: getbits(psrc, xoffSrc, 32, tmpSrc) ! 595: *pdst = DoRop(alu, tmpSrc, *pdst); ! 596: pdst++; ! 597: psrc++; ! 598: } ! 599: ! 600: if (endmask) ! 601: { ! 602: getbits(psrc, xoffSrc, nend, tmpSrc) ! 603: putbitsrop(tmpSrc, 0, nend, pdst, alu) ! 604: } ! 605: ! 606: pdstLine += widthDst; ! 607: psrcLine += widthSrc; ! 608: } ! 609: } ! 610: else /* move right to left */ ! 611: { ! 612: pdstLine += (pbox->x2 >> 5); ! 613: psrcLine += (pptSrc->x+w >> 5); ! 614: /* if fetch of last partial bits from source crosses ! 615: a longword boundary, start at the previous longword ! 616: */ ! 617: if (xoffSrc + nend >= 32) ! 618: --psrcLine; ! 619: ! 620: while (h--) ! 621: { ! 622: psrc = psrcLine; ! 623: pdst = pdstLine; ! 624: ! 625: if (endmask) ! 626: { ! 627: getbits(psrc, xoffSrc, nend, tmpSrc) ! 628: putbitsrop(tmpSrc, 0, nend, pdst, alu) ! 629: } ! 630: ! 631: nl = nlMiddle; ! 632: while (nl--) ! 633: { ! 634: --psrc; ! 635: --pdst; ! 636: getbits(psrc, xoffSrc, 32, tmpSrc) ! 637: *pdst = DoRop(alu, tmpSrc, *pdst); ! 638: } ! 639: ! 640: if (startmask) ! 641: { ! 642: if (srcStartOver) ! 643: --psrc; ! 644: --pdst; ! 645: getbits(psrc, (pptSrc->x & 0x1f), nstart, tmpSrc) ! 646: putbitsrop(tmpSrc, (pbox->x1 & 0x1f), nstart, pdst, ! 647: alu) ! 648: } ! 649: ! 650: pdstLine += widthDst; ! 651: psrcLine += widthSrc; ! 652: } ! 653: } /* move right to left */ ! 654: } ! 655: pbox++; ! 656: pptSrc++; ! 657: } /* while (nbox--) */ ! 658: } ! 659: ! 660: /* free up stuff */ ! 661: if (pptNew1) ! 662: { ! 663: DEALLOCATE_LOCAL(pptNew1); ! 664: } ! 665: if (pboxNew1) ! 666: { ! 667: DEALLOCATE_LOCAL(pboxNew1); ! 668: } ! 669: if (pptNew2) ! 670: { ! 671: DEALLOCATE_LOCAL(pptNew2); ! 672: } ! 673: if (pboxNew2) ! 674: { ! 675: DEALLOCATE_LOCAL(pboxNew2); ! 676: } ! 677: } ! 678: ! 679: ! 680: /* ! 681: if fg == 1 and bg ==0, we can do an ordinary CopyArea. ! 682: if fg == bg, we can do a CopyArea with alu = ReduceRop(alu, fg) ! 683: if fg == 0 and bg == 1, we use the same rasterop, with ! 684: source operand inverted. ! 685: ! 686: CopyArea deals with all of the graphics exposure events. ! 687: This code depends on knowing that we can change the ! 688: alu in the GC without having to call ValidateGC() before calling ! 689: CopyArea(). ! 690: ! 691: */ ! 692: ! 693: void ! 694: mfbCopyPlane(pSrcDrawable, pDstDrawable, ! 695: pGC, srcx, srcy, width, height, dstx, dsty, plane) ! 696: DrawablePtr pSrcDrawable, pDstDrawable; ! 697: register GC *pGC; ! 698: int srcx, srcy; ! 699: int width, height; ! 700: int dstx, dsty; ! 701: unsigned int plane; ! 702: { ! 703: int alu; ! 704: ! 705: if (!(pGC->planemask & 1)) ! 706: return; ! 707: ! 708: if (plane != 1) ! 709: return; ! 710: ! 711: if ((pGC->fgPixel == 1) && (pGC->bgPixel == 0)) ! 712: { ! 713: (*pGC->CopyArea)(pSrcDrawable, pDstDrawable, ! 714: pGC, srcx, srcy, width, height, dstx, dsty); ! 715: } ! 716: else if (pGC->fgPixel == pGC->bgPixel) ! 717: { ! 718: alu = pGC->alu; ! 719: pGC->alu = ReduceRop(pGC->alu, pGC->fgPixel); ! 720: (*pGC->CopyArea)(pSrcDrawable, pDstDrawable, ! 721: pGC, srcx, srcy, width, height, dstx, dsty); ! 722: pGC->alu = alu; ! 723: } ! 724: else /* need to invert the src */ ! 725: { ! 726: alu = pGC->alu; ! 727: pGC->alu = InverseAlu[alu]; ! 728: (*pGC->CopyArea)(pSrcDrawable, pDstDrawable, ! 729: pGC, srcx, srcy, width, height, dstx, dsty); ! 730: pGC->alu = alu; ! 731: } ! 732: } ! 733:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.