xserver-multidpi/fb/fbpush.c
2007-06-29 14:06:52 -04:00

246 lines
5.0 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"
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++;
}
}
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 = REGION_NUM_RECTS (pClip),
pbox = REGION_RECTS(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;
int stipXoff, stipYoff; /* Assumed to be zero */
fbGetStipDrawable (&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
fbPushImage (pDrawable, pGC,
stip, stipStride, 0,
xOrg, yOrg, dx, dy);
}