xenocara/xserver/fb/fbpoint.c

147 lines
4.4 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"
typedef void (*FbDots) (FbBits * dst,
FbStride dstStride,
int dstBpp,
BoxPtr pBox,
xPoint * pts,
int npt,
int xorg,
int yorg, int xoff, int yoff, FbBits and, FbBits xor);
static void
fbDots(FbBits * dstOrig,
FbStride dstStride,
int dstBpp,
BoxPtr pBox,
xPoint * pts,
int npt,
int xorg, int yorg, int xoff, int yoff, FbBits andOrig, FbBits xorOrig)
{
FbStip *dst = (FbStip *) dstOrig;
int x1, y1, x2, y2;
int x, y;
FbStip *d;
FbStip and = andOrig;
FbStip xor = xorOrig;
dstStride = FbBitsStrideToStipStride(dstStride);
x1 = pBox->x1;
y1 = pBox->y1;
x2 = pBox->x2;
y2 = pBox->y2;
while (npt--) {
x = pts->x + xorg;
y = pts->y + yorg;
pts++;
if (x1 <= x && x < x2 && y1 <= y && y < y2) {
x = (x + xoff) * dstBpp;
d = dst + ((y + yoff) * dstStride) + (x >> FB_STIP_SHIFT);
x &= FB_STIP_MASK;
if (dstBpp == 24) {
FbStip leftMask, rightMask;
int n, rot;
FbStip andT, xorT;
rot = FbFirst24Rot(x);
andT = FbRot24Stip(and, rot);
xorT = FbRot24Stip(xor, rot);
FbMaskStip(x, 24, leftMask, n, rightMask);
if (leftMask) {
WRITE(d, FbDoMaskRRop(READ(d), andT, xorT, leftMask));
andT = FbNext24Stip(andT);
xorT = FbNext24Stip(xorT);
d++;
}
if (rightMask)
WRITE(d, FbDoMaskRRop(READ(d), andT, xorT, rightMask));
}
else {
FbStip mask;
mask = FbStipMask(x, dstBpp);
WRITE(d, FbDoMaskRRop(READ(d), and, xor, mask));
}
}
}
}
void
fbPolyPoint(DrawablePtr pDrawable,
GCPtr pGC, int mode, int nptInit, xPoint * pptInit)
{
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
RegionPtr pClip = fbGetCompositeClip(pGC);
FbBits *dst;
FbStride dstStride;
int dstBpp;
int dstXoff, dstYoff;
FbDots dots;
FbBits and, xor;
xPoint *ppt;
int npt;
BoxPtr pBox;
int nBox;
/* make pointlist origin relative */
ppt = pptInit;
npt = nptInit;
if (mode == CoordModePrevious) {
npt--;
while (npt--) {
ppt++;
ppt->x += (ppt - 1)->x;
ppt->y += (ppt - 1)->y;
}
}
fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
and = pPriv->and;
xor = pPriv->xor;
dots = fbDots;
switch (dstBpp) {
case 8:
dots = fbDots8;
break;
case 16:
dots = fbDots16;
break;
case 24:
dots = fbDots24;
break;
case 32:
dots = fbDots32;
break;
}
for (nBox = RegionNumRects(pClip), pBox = RegionRects(pClip);
nBox--; pBox++)
(*dots) (dst, dstStride, dstBpp, pBox, pptInit, nptInit,
pDrawable->x, pDrawable->y, dstXoff, dstYoff, and, xor);
fbFinishAccess(pDrawable);
}