예제 #1
0
파일: fbblt.c 프로젝트: narenas/nx-libs
void
fbBlt (FbBits   *srcLine,
       FbStride	srcStride,
       int	srcX,
       
       FbBits   *dstLine,
       FbStride dstStride,
       int	dstX,
       
       int	width, 
       int	height,
       
       int	alu,
       FbBits	pm,
       int	bpp,
       
       Bool	reverse,
       Bool	upsidedown)
{
    FbBits  *src, *dst;
    int	    leftShift, rightShift;
    FbBits  startmask, endmask;
    FbBits  bits, bits1;
    int	    n, nmiddle;
    Bool    destInvarient;
    int	    startbyte, endbyte;
    FbDeclareMergeRop ();

#ifdef FB_24BIT
    if (bpp == 24 && !FbCheck24Pix (pm))
    {
	fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
		 width, height, alu, pm, reverse, upsidedown);
	return;
    }
#endif
    FbInitializeMergeRop(alu, pm);
    destInvarient = FbDestInvarientMergeRop();
    if (upsidedown)
    {
	srcLine += (height - 1) * (srcStride);
	dstLine += (height - 1) * (dstStride);
	srcStride = -srcStride;
	dstStride = -dstStride;
    }
    FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte,
		     nmiddle, endmask, endbyte);
    if (reverse)
    {
	srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
	dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
	srcX = (srcX + width - 1) & FB_MASK;
	dstX = (dstX + width - 1) & FB_MASK;
    }
    else
    {
예제 #2
0
파일: fbbltone.c 프로젝트: Agnesa/xserver
void
fbBltOne(FbStip * src, FbStride srcStride,      /* FbStip units per scanline */
         int srcX,              /* bit position of source */
         FbBits * dst, FbStride dstStride,      /* FbBits units per scanline */
         int dstX,              /* bit position of dest */
         int dstBpp,            /* bits per destination unit */
         int width,             /* width in bits of destination */
         int height,            /* height in scanlines */
         FbBits fgand,          /* rrop values */
         FbBits fgxor, FbBits bgand, FbBits bgxor)
{
    const FbBits *fbBits;
    FbBits *srcEnd;
    int pixelsPerDst;           /* dst pixels per FbBits */
    int unitsPerSrc;            /* src patterns per FbStip */
    int leftShift, rightShift;  /* align source with dest */
    FbBits startmask, endmask;  /* dest scanline masks */
    FbStip bits = 0, bitsLeft, bitsRight;       /* source bits */
    FbStip left;
    FbBits mask;
    int nDst;                   /* dest longwords (w.o. end) */
    int w;
    int n, nmiddle;
    int dstS;                   /* stipple-relative dst X coordinate */
    Bool copy;                  /* accelerate dest-invariant */
    Bool transparent;           /* accelerate 0 nop */
    int srcinc;                 /* source units consumed */
    Bool endNeedsLoad = FALSE;  /* need load for endmask */
    CARD8 *fbLane;
    int startbyte, endbyte;

    if (dstBpp == 24) {
        fbBltOne24(src, srcStride, srcX,
                   dst, dstStride, dstX, dstBpp,
                   width, height, fgand, fgxor, bgand, bgxor);
        return;
    }

    /*
     * Do not read past the end of the buffer!
     */
    srcEnd = src + height * srcStride;

    /*
     * Number of destination units in FbBits == number of stipple pixels
     * used each time
     */
    pixelsPerDst = FB_UNIT / dstBpp;

    /*
     * Number of source stipple patterns in FbStip 
     */
    unitsPerSrc = FB_STIP_UNIT / pixelsPerDst;

    copy = FALSE;
    transparent = FALSE;
    if (bgand == 0 && fgand == 0)
        copy = TRUE;
    else if (bgand == FB_ALLONES && bgxor == 0)
        transparent = TRUE;

    /*
     * Adjust source and dest to nearest FbBits boundary
     */
    src += srcX >> FB_STIP_SHIFT;
    dst += dstX >> FB_SHIFT;
    srcX &= FB_STIP_MASK;
    dstX &= FB_MASK;

    FbMaskBitsBytes(dstX, width, copy,
                    startmask, startbyte, nmiddle, endmask, endbyte);

    /*
     * Compute effective dest alignment requirement for
     * source -- must align source to dest unit boundary
     */
    dstS = dstX / dstBpp;
    /*
     * Compute shift constants for effective alignement
     */
    if (srcX >= dstS) {
        leftShift = srcX - dstS;
        rightShift = FB_STIP_UNIT - leftShift;
    }
    else {
        rightShift = dstS - srcX;
        leftShift = FB_STIP_UNIT - rightShift;
    }
    /*
     * Get pointer to stipple mask array for this depth
     */
    fbBits = 0;                 /* unused */
    if (pixelsPerDst <= 8)
        fbBits = fbStippleTable[pixelsPerDst];
    fbLane = 0;
    if (transparent && fgand == 0 && dstBpp >= 8)
        fbLane = fbLaneTable[dstBpp];

    /*
     * Compute total number of destination words written, but 
     * don't count endmask 
     */
    nDst = nmiddle;
    if (startmask)
        nDst++;

    dstStride -= nDst;

    /*
     * Compute total number of source words consumed
     */

    srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc;

    if (srcX > dstS)
        srcinc++;
    if (endmask) {
        endNeedsLoad = nDst % unitsPerSrc == 0;
        if (endNeedsLoad)
            srcinc++;
    }

    srcStride -= srcinc;

    /*
     * Copy rectangle
     */
    while (height--) {
        w = nDst;               /* total units across scanline */
        n = unitsPerSrc;        /* units avail in single stipple */
        if (n > w)
            n = w;

        bitsLeft = 0;
        if (srcX > dstS)
            bitsLeft = READ(src++);
        if (n) {
            /*
             * Load first set of stipple bits
             */
            LoadBits;

            /*
             * Consume stipple bits for startmask
             */
            if (startmask) {
#if FB_UNIT > 32
                if (pixelsPerDst == 16)
                    mask = FbStipple16Bits(FbLeftStipBits(bits, 16));
                else
#endif
                    mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
                if (fbLane) {
                    fbTransparentSpan(dst, mask & startmask, fgxor, 1);
                }
                else {
                    if (mask || !transparent)
                        FbDoLeftMaskByteStippleRRop(dst, mask,
                                                    fgand, fgxor, bgand, bgxor,
                                                    startbyte, startmask);
                }
                bits = FbStipLeft(bits, pixelsPerDst);
                dst++;
                n--;
                w--;
            }
            /*
             * Consume stipple bits across scanline
             */
            for (;;) {
                w -= n;
                if (copy) {
                    while (n--) {
#if FB_UNIT > 32
                        if (pixelsPerDst == 16)
                            mask = FbStipple16Bits(FbLeftStipBits(bits, 16));
                        else
#endif
                            mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
                        WRITE(dst, FbOpaqueStipple(mask, fgxor, bgxor));
                        dst++;
                        bits = FbStipLeft(bits, pixelsPerDst);
                    }
                }
                else {
                    if (fbLane) {
                        while (bits && n) {
                            switch (fbLane[FbLeftStipBits(bits, pixelsPerDst)]) {
                                LaneCases((CARD8 *) dst);
                            }
                            bits = FbStipLeft(bits, pixelsPerDst);
                            dst++;
                            n--;
                        }
                        dst += n;
                    }
                    else {
                        while (n--) {
                            left = FbLeftStipBits(bits, pixelsPerDst);
                            if (left || !transparent) {
                                mask = fbBits[left];
                                WRITE(dst, FbStippleRRop(READ(dst), mask,
                                                         fgand, fgxor, bgand,
                                                         bgxor));
                            }
                            dst++;
                            bits = FbStipLeft(bits, pixelsPerDst);
                        }
                    }
                }
                if (!w)
                    break;
                /*
                 * Load another set and reset number of available units
                 */
                LoadBits;
                n = unitsPerSrc;
                if (n > w)
                    n = w;
            }
        }
        /*
         * Consume stipple bits for endmask
         */
        if (endmask) {
            if (endNeedsLoad) {
                LoadBits;
            }
#if FB_UNIT > 32
            if (pixelsPerDst == 16)
                mask = FbStipple16Bits(FbLeftStipBits(bits, 16));
            else
#endif
                mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
            if (fbLane) {
                fbTransparentSpan(dst, mask & endmask, fgxor, 1);
            }
            else {
                if (mask || !transparent)
                    FbDoRightMaskByteStippleRRop(dst, mask,
                                                 fgand, fgxor, bgand, bgxor,
                                                 endbyte, endmask);
            }
        }
        dst += dstStride;
        src += srcStride;
    }
}