|
|
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: ! 25: #include "X.h" ! 26: #include "Xmd.h" ! 27: #include "servermd.h" ! 28: ! 29: #include "misc.h" ! 30: #include "regionstr.h" ! 31: #include "gcstruct.h" ! 32: #include "windowstr.h" ! 33: #include "pixmapstr.h" ! 34: #include "scrnintstr.h" ! 35: ! 36: #include "cfb.h" ! 37: #include "cfbmskbits.h" ! 38: ! 39: ! 40: /* cfbSetScanline -- copies the bits from psrc to the drawable starting at ! 41: * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc ! 42: * starts on the scanline. (I.e., if this scanline passes through multiple ! 43: * boxes, we may not want to start grabbing bits at psrc but at some offset ! 44: * further on.) ! 45: */ ! 46: cfbSetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst, planemask) ! 47: int y; ! 48: int xOrigin; /* where this scanline starts */ ! 49: int xStart; /* first bit to use from scanline */ ! 50: int xEnd; /* last bit to use from scanline + 1 */ ! 51: register int *psrc; ! 52: register int alu; /* raster op */ ! 53: int *pdstBase; /* start of the drawable */ ! 54: int widthDst; /* width of drawable in words */ ! 55: long planemask; ! 56: { ! 57: int w; /* width of scanline in bits */ ! 58: register int *pdst; /* where to put the bits */ ! 59: register int tmpSrc; /* scratch buffer to collect bits in */ ! 60: int dstBit; /* offset in bits from beginning of ! 61: * word */ ! 62: register int nstart; /* number of bits from first partial */ ! 63: register int nend; /* " " last partial word */ ! 64: int offSrc; ! 65: int startmask, endmask, nlMiddle, nl; ! 66: ! 67: pdst = pdstBase + (y * widthDst) + (xStart >> PWSH); ! 68: psrc += (xStart - xOrigin) >> PWSH; ! 69: offSrc = (xStart - xOrigin) & PIM; ! 70: w = xEnd - xStart; ! 71: dstBit = xStart & PIM; ! 72: ! 73: if (dstBit + w <= PPW) ! 74: { ! 75: getbits(psrc, offSrc, w, tmpSrc); ! 76: putbitsrop(tmpSrc, dstBit, w, pdst, planemask, alu); ! 77: } ! 78: else ! 79: { ! 80: ! 81: maskbits(xStart, w, startmask, endmask, nlMiddle); ! 82: if (startmask) ! 83: nstart = PPW - dstBit; ! 84: else ! 85: nstart = 0; ! 86: if (endmask) ! 87: nend = xEnd & PIM; ! 88: else ! 89: nend = 0; ! 90: if (startmask) ! 91: { ! 92: getbits(psrc, offSrc, nstart, tmpSrc); ! 93: putbitsrop(tmpSrc, dstBit, nstart, pdst, planemask, alu); ! 94: pdst++; ! 95: offSrc += nstart; ! 96: if (offSrc > PLST) ! 97: { ! 98: psrc++; ! 99: offSrc -= PPW; ! 100: } ! 101: } ! 102: nl = nlMiddle; ! 103: while (nl--) ! 104: { ! 105: getbits(psrc, offSrc, PPW, tmpSrc); ! 106: putbitsrop(tmpSrc, 0, PPW, pdst, planemask, alu ); ! 107: pdst++; ! 108: psrc++; ! 109: } ! 110: if (endmask) ! 111: { ! 112: getbits(psrc, offSrc, nend, tmpSrc); ! 113: putbitsrop(tmpSrc, 0, nend, pdst, planemask, alu); ! 114: } ! 115: ! 116: } ! 117: } ! 118: ! 119: ! 120: ! 121: /* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at ! 122: * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines ! 123: * are in increasing Y order. ! 124: * Source bit lines are server scanline padded so that they always begin ! 125: * on a word boundary. ! 126: */ ! 127: void ! 128: cfbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted) ! 129: DrawablePtr pDrawable; ! 130: GCPtr pGC; ! 131: int *psrc; ! 132: register DDXPointPtr ppt; ! 133: int *pwidth; ! 134: int nspans; ! 135: int fSorted; ! 136: { ! 137: int *pdstBase; /* start of dst bitmap */ ! 138: int widthDst; /* width of bitmap in words */ ! 139: register BoxPtr pbox, pboxLast, pboxTest; ! 140: register DDXPointPtr pptLast; ! 141: int alu; ! 142: RegionPtr prgnDst; ! 143: int xStart, xEnd; ! 144: int yMax; ! 145: ! 146: switch (pDrawable->depth) { ! 147: case 1: ! 148: mfbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); ! 149: return; ! 150: case 8: ! 151: break; ! 152: default: ! 153: FatalError("cfbSetSpans: invalid depth\n"); ! 154: } ! 155: ! 156: alu = pGC->alu; ! 157: prgnDst = ((cfbPrivGC *)(pGC->devPriv))->pCompositeClip; ! 158: ! 159: pptLast = ppt + nspans; ! 160: ! 161: if (pDrawable->type == DRAWABLE_WINDOW) ! 162: { ! 163: pdstBase = (int *) ! 164: (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate); ! 165: widthDst = (int) ! 166: ((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind ! 167: >> 2; ! 168: yMax = (int)((WindowPtr)pDrawable)->clientWinSize.height + ! 169: ((WindowPtr)pDrawable)->absCorner.y; ! 170: ! 171: /* translation should be done by caller of this routine ! 172: pptT = ppt; ! 173: while(pptT < pptLast) ! 174: { ! 175: pptT->x += ((WindowPtr)pDrawable)->absCorner.x; ! 176: pptT->y += ((WindowPtr)pDrawable)->absCorner.y; ! 177: pptT++; ! 178: } ! 179: */ ! 180: } ! 181: else ! 182: { ! 183: pdstBase = (int *)(((PixmapPtr)pDrawable)->devPrivate); ! 184: widthDst = (int)(((PixmapPtr)pDrawable)->devKind) >> 2; ! 185: yMax = ((PixmapPtr)pDrawable)->height; ! 186: } ! 187: ! 188: pbox = prgnDst->rects; ! 189: pboxLast = pbox + prgnDst->numRects; ! 190: ! 191: if(fSorted) ! 192: { ! 193: /* scan lines sorted in ascending order. Because they are sorted, we ! 194: * don't have to check each scanline against each clip box. We can be ! 195: * sure that this scanline only has to be clipped to boxes at or after the ! 196: * beginning of this y-band ! 197: */ ! 198: pboxTest = pbox; ! 199: while(ppt < pptLast) ! 200: { ! 201: pbox = pboxTest; ! 202: if(ppt->y >= yMax) ! 203: break; ! 204: while(pbox < pboxLast) ! 205: { ! 206: if(pbox->y1 > ppt->y) ! 207: { ! 208: /* scanline is before clip box */ ! 209: break; ! 210: } ! 211: else if(pbox->y2 <= ppt->y) ! 212: { ! 213: /* clip box is before scanline */ ! 214: pboxTest = ++pbox; ! 215: continue; ! 216: } ! 217: else if(pbox->x1 > ppt->x + *pwidth) ! 218: { ! 219: /* clip box is to right of scanline */ ! 220: break; ! 221: } ! 222: else if(pbox->x2 <= ppt->x) ! 223: { ! 224: /* scanline is to right of clip box */ ! 225: pbox++; ! 226: continue; ! 227: } ! 228: ! 229: /* at least some of the scanline is in the current clip box */ ! 230: xStart = max(pbox->x1, ppt->x); ! 231: xEnd = min(ppt->x + *pwidth, pbox->x2); ! 232: cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu, ! 233: pdstBase, widthDst, pGC->planemask); ! 234: if(ppt->x + *pwidth <= pbox->x2) ! 235: { ! 236: /* End of the line, as it were */ ! 237: break; ! 238: } ! 239: else ! 240: pbox++; ! 241: } ! 242: /* We've tried this line against every box; it must be outside them ! 243: * all. move on to the next point */ ! 244: ppt++; ! 245: psrc += PixmapWidthInPadUnits(*pwidth, PSZ); ! 246: pwidth++; ! 247: } ! 248: } ! 249: else ! 250: { ! 251: /* scan lines not sorted. We must clip each line against all the boxes */ ! 252: while(ppt < pptLast) ! 253: { ! 254: if(ppt->y >= 0 && ppt->y < yMax) ! 255: { ! 256: ! 257: for(pbox = prgnDst->rects; pbox< pboxLast; pbox++) ! 258: { ! 259: if(pbox->y1 > ppt->y) ! 260: { ! 261: /* rest of clip region is above this scanline, ! 262: * skip it */ ! 263: break; ! 264: } ! 265: if(pbox->y2 <= ppt->y) ! 266: { ! 267: /* clip box is below scanline */ ! 268: pbox++; ! 269: break; ! 270: } ! 271: if(pbox->x1 <= ppt->x + *pwidth && ! 272: pbox->x2 > ppt->x) ! 273: { ! 274: xStart = max(pbox->x1, ppt->x); ! 275: xEnd = min(pbox->x2, ppt->x + *pwidth); ! 276: cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu, ! 277: pdstBase, widthDst, pGC->planemask); ! 278: } ! 279: ! 280: } ! 281: } ! 282: psrc += PixmapWidthInPadUnits(*pwidth, PSZ); ! 283: ppt++; ! 284: pwidth++; ! 285: } ! 286: } ! 287: } ! 288:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.