📄 cfbbitblt.c
字号:
int widthDst; /* # of groups of 4 pixels (8 bits/pixel) in dst */ unsigned long *psrcLine, *pdstLine; /* steps a row at a time thru src/dst; * may point into middle of row */ register unsigned long *psrc, *pdst; /* steps within the row */ register unsigned long bits, tmp; /* bits from source */ register int leftShift; register int rightShift; unsigned long startmask; /* left edge pixel mask */ unsigned long endmask; /* right edge pixel mask */ register int nlMiddle; /* number of words in middle of the row to draw */ register int nl; int firstoff; int secondoff; unsigned long src; int nbox; /* number of boxes in region to copy */ BoxPtr pbox; /* steps thru boxes in region */ int pixelsRemainingOnRightEdge; /* # pixels to be drawn on a row after * the main "middle" loop */ cfbGetLongWidthAndPointer (pSrcDrawable, widthSrc, psrcBase) cfbGetLongWidthAndPointer (pDstDrawable, widthDst, pdstBase) nbox = REGION_NUM_RECTS(prgnDst); pbox = REGION_RECTS(prgnDst); while (nbox--) { dstx = pbox->x1; dsty = pbox->y1; srcx = pptSrc->x; srcy = pptSrc->y; width = pbox->x2 - pbox->x1; height = pbox->y2 - pbox->y1; pbox++; pptSrc++; psrcLine = psrcBase + srcy * widthSrc + (srcx >> MFB_PWSH); pdstLine = pdstBase + dsty * widthDst + (dstx >> PWSH); xoffSrc = srcx & MFB_PIM; /* finds starting bit in src */ xoffDst = dstx & PIM; /* finds starting byte in dst */ /* compute startmask, endmask, nlMiddle */ if (xoffDst + width < PPW) /* XXX should this be '<= PPW' ? */ { /* the copy only affects one word per row in destination */ maskpartialbits(dstx, width, startmask); endmask = 0; /* nothing on right edge */ nlMiddle = 0; /* nothing in middle */ } else { /* the copy will affect multiple words per row in destination */ maskbits(dstx, width, startmask, endmask, nlMiddle); } /* * compute constants for the first four bits to be * copied. This avoids troubles with partial first * writes, and difficult shift computation */ if (startmask) { firstoff = xoffSrc - xoffDst; if (firstoff > (MFB_PPW-PPW)) secondoff = MFB_PPW - firstoff; if (xoffDst) { srcx += (PPW-xoffDst); xoffSrc = srcx & MFB_PIM; } } leftShift = xoffSrc; rightShift = MFB_PPW - leftShift; pixelsRemainingOnRightEdge = (nlMiddle & 7) * PPW + ((dstx + width) & PIM); /* setup is done; now let's move some bits */ /* caller must call cfb8CheckOpaqueStipple before this function * to set cfb8StippleRRop! */ if (cfb8StippleRRop == GXcopy) { while (height--) { /* one iteration of this loop copies one row */ psrc = psrcLine; pdst = pdstLine; psrcLine += widthSrc; pdstLine += widthDst; bits = *psrc++; if (startmask) { if (firstoff < 0) tmp = BitRight (bits, -firstoff); else { tmp = BitLeft (bits, firstoff); /* * need a more cautious test for partialmask * case... */ if (firstoff >= (MFB_PPW-PPW)) { bits = *psrc++; if (firstoff != (MFB_PPW-PPW)) tmp |= BitRight (bits, secondoff); } } *pdst = (*pdst & ~startmask) | (GetPixelGroup(tmp) & startmask); pdst++; } nl = nlMiddle; while (nl >= 8) { nl -= 8; tmp = BitLeft(bits, leftShift); bits = *psrc++; if (rightShift != MFB_PPW) tmp |= BitRight(bits, rightShift);#ifdef FAST_CONSTANT_OFFSET_MODE# define StorePixels(pdst,o,pixels) (pdst)[o] = (pixels)# define EndStep(pdst,o) (pdst) += (o)# define StoreRopPixels(pdst,o,and,xor) (pdst)[o] = DoRRop((pdst)[o],and,xor);#else# define StorePixels(pdst,o,pixels) *(pdst)++ = (pixels)# define EndStep(pdst,o)# define StoreRopPixels(pdst,o,and,xor) *(pdst) = DoRRop(*(pdst),and,xor); (pdst)++;#endif#define Step(c) NextBitGroup(c);#define StoreBitsPlain(o,c) StorePixels(pdst,o,GetPixelGroup(c))#define StoreRopBitsPlain(o,c) StoreRopPixels(pdst,o,\ cfb8StippleAnd[GetBitGroup(c)], \ cfb8StippleXor[GetBitGroup(c)])#define StoreBits0(c) StoreBitsPlain(0,c)#define StoreRopBits0(c) StoreRopBitsPlain(0,c)#if (BITMAP_BIT_ORDER == MSBFirst)# define StoreBits(o,c) StoreBitsPlain(o,c)# define StoreRopBits(o,c) StoreRopBitsPlain(o,c)# define FirstStep(c) Step(c)#else /* BITMAP_BIT_ORDER == LSBFirst */#if PGSZ == 64# define StoreBits(o,c) StorePixels(pdst,o, (cfb8Pixels[c & 0xff]))# define StoreRopBits(o,c) StoreRopPixels(pdst,o, \ (cfb8StippleAnd[c & 0xff]), \ (cfb8StippleXor[c & 0xff]))# define FirstStep(c) c = BitLeft (c, 8);#else/* 0x3c is 0xf << 2 (4 bits, long word) */# define StoreBits(o,c) StorePixels(pdst,o,*((unsigned long *)\ (((char *) cfb8Pixels) + (c & 0x3c))))# define StoreRopBits(o,c) StoreRopPixels(pdst,o, \ *((unsigned long *) (((char *) cfb8StippleAnd) + (c & 0x3c))), \ *((unsigned long *) (((char *) cfb8StippleXor) + (c & 0x3c))))# define FirstStep(c) c = BitLeft (c, 2);#endif /* PGSZ */#endif /* BITMAP_BIT_ORDER */ StoreBits0(tmp); FirstStep(tmp); StoreBits(1,tmp); Step(tmp); StoreBits(2,tmp); Step(tmp); StoreBits(3,tmp); Step(tmp); StoreBits(4,tmp); Step(tmp); StoreBits(5,tmp); Step(tmp); StoreBits(6,tmp); Step(tmp); StoreBits(7,tmp); EndStep (pdst,8); } /* do rest of middle and partial word on right edge */ if (pixelsRemainingOnRightEdge) { tmp = BitLeft(bits, leftShift); if (pixelsRemainingOnRightEdge > rightShift) { bits = *psrc++; tmp |= BitRight (bits, rightShift); } EndStep (pdst, nl); switch (nl) { case 7: StoreBitsPlain(-7,tmp); Step(tmp); case 6: StoreBitsPlain(-6,tmp); Step(tmp); case 5: StoreBitsPlain(-5,tmp); Step(tmp); case 4: StoreBitsPlain(-4,tmp); Step(tmp); case 3: StoreBitsPlain(-3,tmp); Step(tmp); case 2: StoreBitsPlain(-2,tmp); Step(tmp); case 1: StoreBitsPlain(-1,tmp); Step(tmp); } if (endmask) *pdst = (*pdst & ~endmask) | (GetPixelGroup(tmp) & endmask); } } } else /* cfb8StippleRRop != GXcopy */ { while (height--) { /* one iteration of this loop copies one row */ psrc = psrcLine; pdst = pdstLine; psrcLine += widthSrc; pdstLine += widthDst; bits = *psrc++; /* do partial word on left edge */ if (startmask) { if (firstoff < 0) tmp = BitRight (bits, -firstoff); else { tmp = BitLeft (bits, firstoff); if (firstoff >= (MFB_PPW-PPW)) { bits = *psrc++; if (firstoff != (MFB_PPW-PPW)) tmp |= BitRight (bits, secondoff); } } src = GetBitGroup(tmp); *pdst = MaskRRopPixels (*pdst, src, startmask); pdst++; } /* do middle of row */ nl = nlMiddle; while (nl >= 8) { nl -= 8; tmp = BitLeft(bits, leftShift); bits = *psrc++; if (rightShift != MFB_PPW) tmp |= BitRight(bits, rightShift); StoreRopBits0(tmp); FirstStep(tmp); StoreRopBits(1,tmp); Step(tmp); StoreRopBits(2,tmp); Step(tmp); StoreRopBits(3,tmp); Step(tmp); StoreRopBits(4,tmp); Step(tmp); StoreRopBits(5,tmp); Step(tmp); StoreRopBits(6,tmp); Step(tmp); StoreRopBits(7,tmp); EndStep(pdst,8); } /* do rest of middle and partial word on right edge */ if (pixelsRemainingOnRightEdge) { tmp = BitLeft(bits, leftShift); if (pixelsRemainingOnRightEdge > rightShift) { bits = *psrc++; /* XXX purify abr here */ tmp |= BitRight (bits, rightShift); } while (nl--) { src = GetBitGroup (tmp); *pdst = RRopPixels (*pdst, src); pdst++; NextBitGroup(tmp); } if (endmask) { src = GetBitGroup (tmp); *pdst = MaskRRopPixels (*pdst, src, endmask); } } } /* end copy one row */ } /* end alu is non-copy-mode case */ } /* end iteration over region boxes */}#endif/* shared among all different cfb depths through linker magic */RegionPtr (*cfbPuntCopyPlane)();RegionPtr cfbCopyPlane(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane) DrawablePtr pSrcDrawable; DrawablePtr pDstDrawable; GCPtr pGC; int srcx, srcy; int width, height; int dstx, dsty; unsigned long bitPlane;{ RegionPtr ret; extern RegionPtr miHandleExposures(); void (*doBitBlt)();#if PSZ == 8 if (pSrcDrawable->bitsPerPixel == 1 && pDstDrawable->bitsPerPixel == 8) { if (bitPlane == 1) { doBitBlt = cfbCopyPlane1to8; cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask); ret = cfbBitBlt (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, bitPlane); } else ret = miHandleExposures (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); } else if (pSrcDrawable->bitsPerPixel == 8 && pDstDrawable->bitsPerPixel == 1) { extern int InverseAlu[16]; int oldalu; oldalu = pGC->alu; if ((pGC->fgPixel & 1) == 0 && (pGC->bgPixel&1) == 1) pGC->alu = InverseAlu[pGC->alu]; else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1)) pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel); ret = cfbBitBlt (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, cfbCopyPlane8to1, bitPlane); pGC->alu = oldalu; } else if (pSrcDrawable->bitsPerPixel == 8 && pDstDrawable->bitsPerPixel == 8) { PixmapPtr pBitmap; ScreenPtr pScreen = pSrcDrawable->pScreen; GCPtr pGC1; pBitmap = (*pScreen->CreatePixmap) (pScreen, width, height, 1); if (!pBitmap) return NULL; pGC1 = GetScratchGC (1, pScreen); if (!pGC1) { (*pScreen->DestroyPixmap) (pBitmap); return NULL; } /* * don't need to set pGC->fgPixel,bgPixel as copyPlane8to1 * ignores pixel values, expecting the rop to "do the * right thing", which GXcopy will. */ ValidateGC ((DrawablePtr) pBitmap, pGC1); /* no exposures here, scratch GC's don't get graphics expose */ (void) cfbBitBlt (pSrcDrawable, (DrawablePtr) pBitmap, pGC1, srcx, srcy, width, height, 0, 0, cfbCopyPlane8to1, bitPlane); cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask); /* no exposures here, copy bits from inside a pixmap */ (void) cfbBitBlt ((DrawablePtr) pBitmap, pDstDrawable, pGC, 0, 0, width, height, dstx, dsty, cfbCopyPlane1to8, 1); FreeScratchGC (pGC1); (*pScreen->DestroyPixmap) (pBitmap); /* compute resultant exposures */ ret = miHandleExposures (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); } else#endif ret = (*cfbPuntCopyPlane) (pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height, dstx, dsty, bitPlane); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -