189 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright © 1998 Keith Packard
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is hereby granted without fee, provided that
 | 
						|
 * the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name of Keith Packard not be used in
 | 
						|
 * advertising or publicity pertaining to distribution of the software without
 | 
						|
 * specific, written prior permission.  Keith Packard makes no
 | 
						|
 * representations about the suitability of this software for any purpose.  It
 | 
						|
 * is provided "as is" without express or implied warranty.
 | 
						|
 *
 | 
						|
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
						|
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
						|
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
						|
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
						|
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
						|
 * PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 */
 | 
						|
 | 
						|
#ifdef HAVE_DIX_CONFIG_H
 | 
						|
#include <dix-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include "fb.h"
 | 
						|
 | 
						|
static void
 | 
						|
fbPushPattern(DrawablePtr pDrawable,
 | 
						|
              GCPtr pGC,
 | 
						|
              FbStip * src,
 | 
						|
              FbStride srcStride, int srcX, int x, int y, int width, int height)
 | 
						|
{
 | 
						|
    FbStip *s, bitsMask, bitsMask0, bits;
 | 
						|
    int xspan;
 | 
						|
    int w;
 | 
						|
    int lenspan;
 | 
						|
 | 
						|
    src += srcX >> FB_STIP_SHIFT;
 | 
						|
    srcX &= FB_STIP_MASK;
 | 
						|
 | 
						|
    bitsMask0 = FbStipMask(srcX, 1);
 | 
						|
 | 
						|
    while (height--) {
 | 
						|
        bitsMask = bitsMask0;
 | 
						|
        w = width;
 | 
						|
        s = src;
 | 
						|
        src += srcStride;
 | 
						|
        bits = READ(s++);
 | 
						|
        xspan = x;
 | 
						|
        while (w) {
 | 
						|
            if (bits & bitsMask) {
 | 
						|
                lenspan = 0;
 | 
						|
                do {
 | 
						|
                    lenspan++;
 | 
						|
                    if (lenspan == w)
 | 
						|
                        break;
 | 
						|
                    bitsMask = FbStipRight(bitsMask, 1);
 | 
						|
                    if (!bitsMask) {
 | 
						|
                        bits = READ(s++);
 | 
						|
                        bitsMask = FbBitsMask(0, 1);
 | 
						|
                    }
 | 
						|
                } while (bits & bitsMask);
 | 
						|
                fbFill(pDrawable, pGC, xspan, y, lenspan, 1);
 | 
						|
                xspan += lenspan;
 | 
						|
                w -= lenspan;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                do {
 | 
						|
                    w--;
 | 
						|
                    xspan++;
 | 
						|
                    if (!w)
 | 
						|
                        break;
 | 
						|
                    bitsMask = FbStipRight(bitsMask, 1);
 | 
						|
                    if (!bitsMask) {
 | 
						|
                        bits = READ(s++);
 | 
						|
                        bitsMask = FbBitsMask(0, 1);
 | 
						|
                    }
 | 
						|
                } while (!(bits & bitsMask));
 | 
						|
            }
 | 
						|
        }
 | 
						|
        y++;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
fbPushFill(DrawablePtr pDrawable,
 | 
						|
           GCPtr pGC,
 | 
						|
           FbStip * src,
 | 
						|
           FbStride srcStride, int srcX, int x, int y, int width, int height)
 | 
						|
{
 | 
						|
    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
 | 
						|
 | 
						|
    if (pGC->fillStyle == FillSolid) {
 | 
						|
        FbBits *dst;
 | 
						|
        FbStride dstStride;
 | 
						|
        int dstBpp;
 | 
						|
        int dstXoff, dstYoff;
 | 
						|
        int dstX;
 | 
						|
        int dstWidth;
 | 
						|
 | 
						|
        fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 | 
						|
        dst = dst + (y + dstYoff) * dstStride;
 | 
						|
        dstX = (x + dstXoff) * dstBpp;
 | 
						|
        dstWidth = width * dstBpp;
 | 
						|
        if (dstBpp == 1) {
 | 
						|
            fbBltStip(src,
 | 
						|
                      srcStride,
 | 
						|
                      srcX,
 | 
						|
                      (FbStip *) dst,
 | 
						|
                      FbBitsStrideToStipStride(dstStride),
 | 
						|
                      dstX,
 | 
						|
                      dstWidth,
 | 
						|
                      height,
 | 
						|
                      FbStipple1Rop(pGC->alu, pGC->fgPixel), pPriv->pm, dstBpp);
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            fbBltOne(src,
 | 
						|
                     srcStride,
 | 
						|
                     srcX,
 | 
						|
                     dst,
 | 
						|
                     dstStride,
 | 
						|
                     dstX,
 | 
						|
                     dstBpp,
 | 
						|
                     dstWidth,
 | 
						|
                     height,
 | 
						|
                     pPriv->and, pPriv->xor,
 | 
						|
                     fbAnd(GXnoop, (FbBits) 0, FB_ALLONES),
 | 
						|
                     fbXor(GXnoop, (FbBits) 0, FB_ALLONES));
 | 
						|
        }
 | 
						|
        fbFinishAccess(pDrawable);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        fbPushPattern(pDrawable, pGC, src, srcStride, srcX,
 | 
						|
                      x, y, width, height);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
fbPushImage(DrawablePtr pDrawable,
 | 
						|
            GCPtr pGC,
 | 
						|
            FbStip * src,
 | 
						|
            FbStride srcStride, int srcX, int x, int y, int width, int height)
 | 
						|
{
 | 
						|
    RegionPtr pClip = fbGetCompositeClip(pGC);
 | 
						|
    int nbox;
 | 
						|
    BoxPtr pbox;
 | 
						|
    int x1, y1, x2, y2;
 | 
						|
 | 
						|
    for (nbox = RegionNumRects(pClip),
 | 
						|
         pbox = RegionRects(pClip); nbox--; pbox++) {
 | 
						|
        x1 = x;
 | 
						|
        y1 = y;
 | 
						|
        x2 = x + width;
 | 
						|
        y2 = y + height;
 | 
						|
        if (x1 < pbox->x1)
 | 
						|
            x1 = pbox->x1;
 | 
						|
        if (y1 < pbox->y1)
 | 
						|
            y1 = pbox->y1;
 | 
						|
        if (x2 > pbox->x2)
 | 
						|
            x2 = pbox->x2;
 | 
						|
        if (y2 > pbox->y2)
 | 
						|
            y2 = pbox->y2;
 | 
						|
        if (x1 >= x2 || y1 >= y2)
 | 
						|
            continue;
 | 
						|
        fbPushFill(pDrawable,
 | 
						|
                   pGC,
 | 
						|
                   src + (y1 - y) * srcStride,
 | 
						|
                   srcStride, srcX + (x1 - x), x1, y1, x2 - x1, y2 - y1);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
fbPushPixels(GCPtr pGC,
 | 
						|
             PixmapPtr pBitmap,
 | 
						|
             DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg)
 | 
						|
{
 | 
						|
    FbStip *stip;
 | 
						|
    FbStride stipStride;
 | 
						|
    int stipBpp;
 | 
						|
    _X_UNUSED int stipXoff, stipYoff;
 | 
						|
 | 
						|
    fbGetStipDrawable(&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff,
 | 
						|
                      stipYoff);
 | 
						|
 | 
						|
    fbPushImage(pDrawable, pGC, stip, stipStride, 0, xOrg, yOrg, dx, dy);
 | 
						|
}
 |