972 lines
20 KiB
C
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
|