aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/fb/fbbits.h
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/fb/fbbits.h')
-rw-r--r--xorg-server/fb/fbbits.h971
1 files changed, 971 insertions, 0 deletions
diff --git a/xorg-server/fb/fbbits.h b/xorg-server/fb/fbbits.h
new file mode 100644
index 000000000..44991f106
--- /dev/null
+++ b/xorg-server/fb/fbbits.h
@@ -0,0 +1,971 @@
+/*
+ * 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