diff options
Diffstat (limited to 'xorg-server/fb/fbbits.h')
-rw-r--r-- | xorg-server/fb/fbbits.h | 1846 |
1 files changed, 875 insertions, 971 deletions
diff --git a/xorg-server/fb/fbbits.h b/xorg-server/fb/fbbits.h index 80a61ddeb..be32d8cf0 100644 --- a/xorg-server/fb/fbbits.h +++ b/xorg-server/fb/fbbits.h @@ -1,971 +1,875 @@ -/*
- * 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) | ((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 = RegionExtents(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 = RegionExtents(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
+/* + * 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) | ((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 = RegionExtents(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 = RegionExtents(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 |