xenocara/xserver/fb/fbbits.h
2007-11-24 17:55:21 +00:00

972 lines
20 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.
*/
/*
* This file defines functions for drawing some primitives using
* underlying datatypes instead of masks
*/
#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & 0x80008000)
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#ifdef BITSMUL
#define MUL BITSMUL
#else
#define MUL 1
#endif
#ifdef BITSSTORE
#define STORE(b,x) BITSSTORE(b,x)
#else
#define STORE(b,x) WRITE((b), (x))
#endif
#ifdef BITSRROP
#define RROP(b,a,x) BITSRROP(b,a,x)
#else
#define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x)))
#endif
#ifdef BITSUNIT
#define UNIT BITSUNIT
#define USE_SOLID
#else
#define UNIT BITS
#endif
/*
* Define the following before including this file:
*
* BRESSOLID name of function for drawing a solid segment
* BRESDASH name of function for drawing a dashed segment
* DOTS name of function for drawing dots
* ARC name of function for drawing a solid arc
* BITS type of underlying unit
*/
#ifdef BRESSOLID
void
BRESSOLID (DrawablePtr pDrawable,
GCPtr pGC,
int dashOffset,
int signdx,
int signdy,
int axis,
int x1,
int y1,
int e,
int e1,
int e3,
int len)
{
FbBits *dst;
FbStride dstStride;
int dstBpp;
int dstXoff, dstYoff;
FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
UNIT *bits;
FbStride bitsStride;
FbStride majorStep, minorStep;
BITS xor = (BITS) pPriv->xor;
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
if (signdy < 0)
bitsStride = -bitsStride;
if (axis == X_AXIS)
{
majorStep = signdx * MUL;
minorStep = bitsStride;
}
else
{
majorStep = bitsStride;
minorStep = signdx * MUL;
}
while (len--)
{
STORE(bits,xor);
bits += majorStep;
e += e1;
if (e >= 0)
{
bits += minorStep;
e += e3;
}
}
fbFinishAccess (pDrawable);
}
#endif
#ifdef BRESDASH
void
BRESDASH (DrawablePtr pDrawable,
GCPtr pGC,
int dashOffset,
int signdx,
int signdy,
int axis,
int x1,
int y1,
int e,
int e1,
int e3,
int len)
{
FbBits *dst;
FbStride dstStride;
int dstBpp;
int dstXoff, dstYoff;
FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
UNIT *bits;
FbStride bitsStride;
FbStride majorStep, minorStep;
BITS xorfg, xorbg;
FbDashDeclare;
int dashlen;
Bool even;
Bool doOdd;
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
doOdd = pGC->lineStyle == LineDoubleDash;
xorfg = (BITS) pPriv->xor;
xorbg = (BITS) pPriv->bgxor;
FbDashInit (pGC, pPriv, dashOffset, dashlen, even);
bits = ((UNIT *) (dst + ((y1 + dstYoff) * dstStride))) + (x1 + dstXoff) * MUL;
bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
if (signdy < 0)
bitsStride = -bitsStride;
if (axis == X_AXIS)
{
majorStep = signdx * MUL;
minorStep = bitsStride;
}
else
{
majorStep = bitsStride;
minorStep = signdx * MUL;
}
if (dashlen >= len)
dashlen = len;
if (doOdd)
{
if (!even)
goto doubleOdd;
for (;;)
{
len -= dashlen;
while (dashlen--)
{
STORE(bits,xorfg);
bits += majorStep;
if ((e += e1) >= 0)
{
e += e3;
bits += minorStep;
}
}
if (!len)
break;
FbDashNextEven(dashlen);
if (dashlen >= len)
dashlen = len;
doubleOdd:
len -= dashlen;
while (dashlen--)
{
STORE(bits,xorbg);
bits += majorStep;
if ((e += e1) >= 0)
{
e += e3;
bits += minorStep;
}
}
if (!len)
break;
FbDashNextOdd(dashlen);
if (dashlen >= len)
dashlen = len;
}
}
else
{
if (!even)
goto onOffOdd;
for (;;)
{
len -= dashlen;
while (dashlen--)
{
STORE(bits,xorfg);
bits += majorStep;
if ((e += e1) >= 0)
{
e += e3;
bits += minorStep;
}
}
if (!len)
break;
FbDashNextEven (dashlen);
if (dashlen >= len)
dashlen = len;
onOffOdd:
len -= dashlen;
while (dashlen--)
{
bits += majorStep;
if ((e += e1) >= 0)
{
e += e3;
bits += minorStep;
}
}
if (!len)
break;
FbDashNextOdd (dashlen);
if (dashlen >= len)
dashlen = len;
}
}
fbFinishAccess (pDrawable);
}
#endif
#ifdef DOTS
void
DOTS (FbBits *dst,
FbStride dstStride,
int dstBpp,
BoxPtr pBox,
xPoint *ptsOrig,
int npt,
int xorg,
int yorg,
int xoff,
int yoff,
FbBits and,
FbBits xor)
{
INT32 *pts = (INT32 *) ptsOrig;
UNIT *bits = (UNIT *) dst;
UNIT *point;
BITS bxor = (BITS) xor;
BITS band = (BITS) and;
FbStride bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
INT32 ul, lr;
INT32 pt;
ul = coordToInt(pBox->x1 - xorg, pBox->y1 - yorg);
lr = coordToInt(pBox->x2 - xorg - 1, pBox->y2 - yorg - 1);
bits += bitsStride * (yorg + yoff) + (xorg + xoff) * MUL;
if (and == 0)
{
while (npt--)
{
pt = *pts++;
if (!isClipped(pt,ul,lr))
{
point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
STORE(point,bxor);
}
}
}
else
{
while (npt--)
{
pt = *pts++;
if (!isClipped(pt,ul,lr))
{
point = bits + intToY(pt) * bitsStride + intToX(pt) * MUL;
RROP(point,band,bxor);
}
}
}
}
#endif
#ifdef ARC
#define ARCCOPY(d) STORE(d,xorBits)
#define ARCRROP(d) RROP(d,andBits,xorBits)
void
ARC (FbBits *dst,
FbStride dstStride,
int dstBpp,
xArc *arc,
int drawX,
int drawY,
FbBits and,
FbBits xor)
{
UNIT *bits;
FbStride bitsStride;
miZeroArcRec info;
Bool do360;
int x;
UNIT *yorgp, *yorgop;
BITS andBits, xorBits;
int yoffset, dyoffset;
int y, a, b, d, mask;
int k1, k3, dx, dy;
bits = (UNIT *) dst;
bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
andBits = (BITS) and;
xorBits = (BITS) xor;
do360 = miZeroArcSetup(arc, &info, TRUE);
yorgp = bits + ((info.yorg + drawY) * bitsStride);
yorgop = bits + ((info.yorgo + drawY) * bitsStride);
info.xorg = (info.xorg + drawX) * MUL;
info.xorgo = (info.xorgo + drawX) * MUL;
MIARCSETUP();
yoffset = y ? bitsStride : 0;
dyoffset = 0;
mask = info.initialMask;
if (!(arc->width & 1))
{
if (andBits == 0)
{
if (mask & 2)
ARCCOPY(yorgp + info.xorgo);
if (mask & 8)
ARCCOPY(yorgop + info.xorgo);
}
else
{
if (mask & 2)
ARCRROP(yorgp + info.xorgo);
if (mask & 8)
ARCRROP(yorgop + info.xorgo);
}
}
if (!info.end.x || !info.end.y)
{
mask = info.end.mask;
info.end = info.altend;
}
if (do360 && (arc->width == arc->height) && !(arc->width & 1))
{
int xoffset = bitsStride;
UNIT *yorghb = yorgp + (info.h * bitsStride) + info.xorg;
UNIT *yorgohb = yorghb - info.h * MUL;
yorgp += info.xorg;
yorgop += info.xorg;
yorghb += info.h * MUL;
while (1)
{
if (andBits == 0)
{
ARCCOPY(yorgp + yoffset + x * MUL);
ARCCOPY(yorgp + yoffset - x * MUL);
ARCCOPY(yorgop - yoffset - x * MUL);
ARCCOPY(yorgop - yoffset + x * MUL);
}
else
{
ARCRROP(yorgp + yoffset + x * MUL);
ARCRROP(yorgp + yoffset - x * MUL);
ARCRROP(yorgop - yoffset - x * MUL);
ARCRROP(yorgop - yoffset + x * MUL);
}
if (a < 0)
break;
if (andBits == 0)
{
ARCCOPY(yorghb - xoffset - y * MUL);
ARCCOPY(yorgohb - xoffset + y * MUL);
ARCCOPY(yorgohb + xoffset + y * MUL);
ARCCOPY(yorghb + xoffset - y * MUL);
}
else
{
ARCRROP(yorghb - xoffset - y * MUL);
ARCRROP(yorgohb - xoffset + y * MUL);
ARCRROP(yorgohb + xoffset + y * MUL);
ARCRROP(yorghb + xoffset - y * MUL);
}
xoffset += bitsStride;
MIARCCIRCLESTEP(yoffset += bitsStride;);
}
yorgp -= info.xorg;
yorgop -= info.xorg;
x = info.w;
yoffset = info.h * bitsStride;
}
else if (do360)
{
while (y < info.h || x < info.w)
{
MIARCOCTANTSHIFT(dyoffset = bitsStride;);
if (andBits == 0)
{
ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
}
else
{
ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
}
MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
}
}
else
{
while (y < info.h || x < info.w)
{
MIARCOCTANTSHIFT(dyoffset = bitsStride;);
if ((x == info.start.x) || (y == info.start.y))
{
mask = info.start.mask;
info.start = info.altstart;
}
if (andBits == 0)
{
if (mask & 1)
ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
if (mask & 2)
ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
if (mask & 4)
ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
if (mask & 8)
ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
}
else
{
if (mask & 1)
ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
if (mask & 2)
ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
if (mask & 4)
ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
if (mask & 8)
ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
}
if ((x == info.end.x) || (y == info.end.y))
{
mask = info.end.mask;
info.end = info.altend;
}
MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
}
}
if ((x == info.start.x) || (y == info.start.y))
mask = info.start.mask;
if (andBits == 0)
{
if (mask & 1)
ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
if (mask & 4)
ARCCOPY(yorgop - yoffset + info.xorgo - x * MUL);
if (arc->height & 1)
{
if (mask & 2)
ARCCOPY(yorgp + yoffset + info.xorgo - x * MUL);
if (mask & 8)
ARCCOPY(yorgop - yoffset + info.xorg + x * MUL);
}
}
else
{
if (mask & 1)
ARCRROP(yorgp + yoffset + info.xorg + x * MUL);
if (mask & 4)
ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
if (arc->height & 1)
{
if (mask & 2)
ARCRROP(yorgp + yoffset + info.xorgo - x * MUL);
if (mask & 8)
ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
}
}
}
#undef ARCCOPY
#undef ARCRROP
#endif
#ifdef GLYPH
#if BITMAP_BIT_ORDER == LSBFirst
# define WRITE_ADDR1(n) (n)
# define WRITE_ADDR2(n) (n)
# define WRITE_ADDR4(n) (n)
#else
# define WRITE_ADDR1(n) ((n) ^ 3)
# define WRITE_ADDR2(n) ((n) ^ 2)
# define WRITE_ADDR4(n) ((n))
#endif
#define WRITE1(d,n,fg) WRITE(d + WRITE_ADDR1(n), (BITS) (fg))
#ifdef BITS2
# define WRITE2(d,n,fg) WRITE((BITS2 *) &((d)[WRITE_ADDR2(n)]), (BITS2) (fg))
#else
# define WRITE2(d,n,fg) (WRITE1(d,n,fg), WRITE1(d,(n)+1,fg))
#endif
#ifdef BITS4
# define WRITE4(d,n,fg) WRITE((BITS4 *) &((d)[WRITE_ADDR4(n)]), (BITS4) (fg))
#else
# define WRITE4(d,n,fg) (WRITE2(d,n,fg), WRITE2(d,(n)+2,fg))
#endif
void
GLYPH (FbBits *dstBits,
FbStride dstStride,
int dstBpp,
FbStip *stipple,
FbBits fg,
int x,
int height)
{
int lshift;
FbStip bits;
BITS *dstLine;
BITS *dst;
int n;
int shift;
dstLine = (BITS *) dstBits;
dstLine += x & ~3;
dstStride *= (sizeof (FbBits) / sizeof (BITS));
shift = x & 3;
lshift = 4 - shift;
while (height--)
{
bits = *stipple++;
dst = (BITS *) dstLine;
n = lshift;
while (bits)
{
switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) {
case 0:
break;
case 1:
WRITE1(dst,0,fg);
break;
case 2:
WRITE1(dst,1,fg);
break;
case 3:
WRITE2(dst,0,fg);
break;
case 4:
WRITE1(dst,2,fg);
break;
case 5:
WRITE1(dst,0,fg);
WRITE1(dst,2,fg);
break;
case 6:
WRITE1(dst,1,fg);
WRITE1(dst,2,fg);
break;
case 7:
WRITE2(dst,0,fg);
WRITE1(dst,2,fg);
break;
case 8:
WRITE1(dst,3,fg);
break;
case 9:
WRITE1(dst,0,fg);
WRITE1(dst,3,fg);
break;
case 10:
WRITE1(dst,1,fg);
WRITE1(dst,3,fg);
break;
case 11:
WRITE2(dst,0,fg);
WRITE1(dst,3,fg);
break;
case 12:
WRITE2(dst,2,fg);
break;
case 13:
WRITE1(dst,0,fg);
WRITE2(dst,2,fg);
break;
case 14:
WRITE1(dst,1,fg);
WRITE2(dst,2,fg);
break;
case 15:
WRITE4(dst,0,fg);
break;
}
bits = FbStipLeft (bits, n);
n = 4;
dst += 4;
}
dstLine += dstStride;
}
}
#undef WRITE_ADDR1
#undef WRITE_ADDR2
#undef WRITE_ADDR4
#undef WRITE1
#undef WRITE2
#undef WRITE4
#endif
#ifdef POLYLINE
void
POLYLINE (DrawablePtr pDrawable,
GCPtr pGC,
int mode,
int npt,
DDXPointPtr ptsOrig)
{
INT32 *pts = (INT32 *) ptsOrig;
int xoff = pDrawable->x;
int yoff = pDrawable->y;
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
BoxPtr pBox = REGION_EXTENTS (pDrawable->pScreen, fbGetCompositeClip (pGC));
FbBits *dst;
int dstStride;
int dstBpp;
int dstXoff, dstYoff;
UNIT *bits, *bitsBase;
FbStride bitsStride;
BITS xor = fbGetGCPrivate(pGC)->xor;
BITS and = fbGetGCPrivate(pGC)->and;
int dashoffset = 0;
INT32 ul, lr;
INT32 pt1, pt2;
int e, e1, e3, len;
int stepmajor, stepminor;
int octant;
if (mode == CoordModePrevious)
fbFixCoordModePrevious (npt, ptsOrig);
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
pt1 = *pts++;
npt--;
pt2 = *pts++;
npt--;
for (;;)
{
if (isClipped (pt1, ul, lr) | isClipped (pt2, ul, lr))
{
fbSegment (pDrawable, pGC,
intToX(pt1) + xoff, intToY(pt1) + yoff,
intToX(pt2) + xoff, intToY(pt2) + yoff,
npt == 0 && pGC->capStyle != CapNotLast,
&dashoffset);
if (!npt) {
fbFinishAccess (pDrawable);
return;
}
pt1 = pt2;
pt2 = *pts++;
npt--;
}
else
{
bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
for (;;)
{
CalcLineDeltas (intToX(pt1), intToY(pt1),
intToX(pt2), intToY(pt2),
len, e1, stepmajor, stepminor, 1, bitsStride,
octant);
stepmajor *= MUL;
if (len < e1)
{
e3 = len;
len = e1;
e1 = e3;
e3 = stepminor;
stepminor = stepmajor;
stepmajor = e3;
SetYMajorOctant(octant);
}
e = -len;
e1 <<= 1;
e3 = e << 1;
FIXUP_ERROR (e, octant, bias);
if (and == 0)
{
while (len--)
{
STORE(bits,xor);
bits += stepmajor;
e += e1;
if (e >= 0)
{
bits += stepminor;
e += e3;
}
}
}
else
{
while (len--)
{
RROP(bits,and,xor);
bits += stepmajor;
e += e1;
if (e >= 0)
{
bits += stepminor;
e += e3;
}
}
}
if (!npt)
{
if (pGC->capStyle != CapNotLast &&
pt2 != *((INT32 *) ptsOrig))
{
RROP(bits,and,xor);
}
fbFinishAccess (pDrawable);
return;
}
pt1 = pt2;
pt2 = *pts++;
--npt;
if (isClipped (pt2, ul, lr))
break;
}
}
}
fbFinishAccess (pDrawable);
}
#endif
#ifdef POLYSEGMENT
void
POLYSEGMENT (DrawablePtr pDrawable,
GCPtr pGC,
int nseg,
xSegment *pseg)
{
INT32 *pts = (INT32 *) pseg;
int xoff = pDrawable->x;
int yoff = pDrawable->y;
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
BoxPtr pBox = REGION_EXTENTS (pDrawable->pScreen, fbGetCompositeClip (pGC));
FbBits *dst;
int dstStride;
int dstBpp;
int dstXoff, dstYoff;
UNIT *bits, *bitsBase;
FbStride bitsStride;
FbBits xorBits = fbGetGCPrivate(pGC)->xor;
FbBits andBits = fbGetGCPrivate(pGC)->and;
BITS xor = xorBits;
BITS and = andBits;
int dashoffset = 0;
INT32 ul, lr;
INT32 pt1, pt2;
int e, e1, e3, len;
int stepmajor, stepminor;
int octant;
Bool capNotLast;
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
bitsBase = ((UNIT *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff) * MUL;
ul = coordToInt(pBox->x1 - xoff, pBox->y1 - yoff);
lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
capNotLast = pGC->capStyle == CapNotLast;
while (nseg--)
{
pt1 = *pts++;
pt2 = *pts++;
if (isClipped (pt1, ul, lr) | isClipped (pt2, ul, lr))
{
fbSegment (pDrawable, pGC,
intToX(pt1) + xoff, intToY(pt1) + yoff,
intToX(pt2) + xoff, intToY(pt2) + yoff,
!capNotLast, &dashoffset);
}
else
{
CalcLineDeltas (intToX(pt1), intToY(pt1),
intToX(pt2), intToY(pt2),
len, e1, stepmajor, stepminor, 1, bitsStride,
octant);
if (e1 == 0 && len > 3
#if MUL != 1
&& FbCheck24Pix(and) && FbCheck24Pix(xor)
#endif
)
{
int x1, x2;
FbBits *dstLine;
int dstX, width;
FbBits startmask, endmask;
int nmiddle;
if (stepmajor < 0)
{
x1 = intToX(pt2);
x2 = intToX(pt1) + 1;
if (capNotLast)
x1++;
}
else
{
x1 = intToX(pt1);
x2 = intToX(pt2);
if (!capNotLast)
x2++;
}
dstX = (x1 + xoff + dstXoff) * (sizeof (UNIT) * 8 * MUL);
width = (x2 - x1) * (sizeof (UNIT) * 8 * MUL);
dstLine = dst + (intToY(pt1) + yoff + dstYoff) * dstStride;
dstLine += dstX >> FB_SHIFT;
dstX &= FB_MASK;
FbMaskBits (dstX, width, startmask, nmiddle, endmask);
if (startmask)
{
WRITE(dstLine, FbDoMaskRRop (READ(dstLine), andBits, xorBits, startmask));
dstLine++;
}
if (!andBits)
while (nmiddle--)
WRITE(dstLine++, xorBits);
else
while (nmiddle--)
{
WRITE(dstLine, FbDoRRop (READ(dstLine), andBits, xorBits));
dstLine++;
}
if (endmask)
WRITE(dstLine, FbDoMaskRRop (READ(dstLine), andBits, xorBits, endmask));
}
else
{
stepmajor *= MUL;
bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1) * MUL;
if (len < e1)
{
e3 = len;
len = e1;
e1 = e3;
e3 = stepminor;
stepminor = stepmajor;
stepmajor = e3;
SetYMajorOctant(octant);
}
e = -len;
e1 <<= 1;
e3 = e << 1;
FIXUP_ERROR (e, octant, bias);
if (!capNotLast)
len++;
if (and == 0)
{
while (len--)
{
STORE(bits,xor);
bits += stepmajor;
e += e1;
if (e >= 0)
{
bits += stepminor;
e += e3;
}
}
}
else
{
while (len--)
{
RROP(bits,and,xor);
bits += stepmajor;
e += e1;
if (e >= 0)
{
bits += stepminor;
e += e3;
}
}
}
}
}
}
fbFinishAccess (pDrawable);
}
#endif
#undef MUL
#undef STORE
#undef RROP
#undef UNIT
#undef USE_SOLID
#undef isClipped