diff options
Diffstat (limited to 'xorg-server/fb/fbseg.c')
-rw-r--r-- | xorg-server/fb/fbseg.c | 1470 |
1 files changed, 736 insertions, 734 deletions
diff --git a/xorg-server/fb/fbseg.c b/xorg-server/fb/fbseg.c index 80ce7404e..0236721ab 100644 --- a/xorg-server/fb/fbseg.c +++ b/xorg-server/fb/fbseg.c @@ -1,734 +1,736 @@ -/* - * Copyright © 1998 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <stdlib.h> - -#include "fb.h" -#include "miline.h" - -#define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \ - ((dir < 0) ? FbStipLeft(mask,bpp) : \ - FbStipRight(mask,bpp))) - -void -fbBresSolid (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x1, - int y1, - int e, - int e1, - int e3, - int len) -{ - FbStip *dst; - FbStride dstStride; - int dstBpp; - int dstXoff, dstYoff; - FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); - FbStip and = (FbStip) pPriv->and; - FbStip xor = (FbStip) pPriv->xor; - FbStip mask, mask0; - FbStip bits; - - fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); - dst += ((y1 + dstYoff) * dstStride); - x1 = (x1 + dstXoff) * dstBpp; - dst += x1 >> FB_STIP_SHIFT; - x1 &= FB_STIP_MASK; - mask0 = FbStipMask(0, dstBpp); - mask = FbStipRight (mask0, x1); - if (signdx < 0) - mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp); - if (signdy < 0) - dstStride = -dstStride; - if (axis == X_AXIS) - { - bits = 0; - while (len--) - { - bits |= mask; - mask = fbBresShiftMask(mask,signdx,dstBpp); - if (!mask) - { - WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits)); - bits = 0; - dst += signdx; - mask = mask0; - } - e += e1; - if (e >= 0) - { - WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits)); - bits = 0; - dst += dstStride; - e += e3; - } - } - if (bits) - WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits)); - } - else - { - while (len--) - { - WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, mask)); - dst += dstStride; - e += e1; - if (e >= 0) - { - e += e3; - mask = fbBresShiftMask(mask,signdx,dstBpp); - if (!mask) - { - dst += signdx; - mask = mask0; - } - } - } - } - - fbFinishAccess (pDrawable); -} - -void -fbBresDash (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x1, - int y1, - int e, - int e1, - int e3, - int len) -{ - FbStip *dst; - FbStride dstStride; - int dstBpp; - int dstXoff, dstYoff; - FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); - FbStip and = (FbStip) pPriv->and; - FbStip xor = (FbStip) pPriv->xor; - FbStip bgand = (FbStip) pPriv->bgand; - FbStip bgxor = (FbStip) pPriv->bgxor; - FbStip mask, mask0; - FbDashDeclare; - int dashlen; - Bool even; - Bool doOdd; - - fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); - doOdd = pGC->lineStyle == LineDoubleDash; - - FbDashInit (pGC, pPriv, dashOffset, dashlen, even); - - dst += ((y1 + dstYoff) * dstStride); - x1 = (x1 + dstXoff) * dstBpp; - dst += x1 >> FB_STIP_SHIFT; - x1 &= FB_STIP_MASK; - mask0 = FbStipMask(0, dstBpp); - mask = FbStipRight (mask0, x1); - if (signdx < 0) - mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp); - if (signdy < 0) - dstStride = -dstStride; - while (len--) - { - if (even) - WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, mask)); - else if (doOdd) - WRITE(dst, FbDoMaskRRop (READ(dst), bgand, bgxor, mask)); - if (axis == X_AXIS) - { - mask = fbBresShiftMask(mask,signdx,dstBpp); - if (!mask) - { - dst += signdx; - mask = mask0; - } - e += e1; - if (e >= 0) - { - dst += dstStride; - e += e3; - } - } - else - { - dst += dstStride; - e += e1; - if (e >= 0) - { - e += e3; - mask = fbBresShiftMask(mask,signdx,dstBpp); - if (!mask) - { - dst += signdx; - mask = mask0; - } - } - } - FbDashStep (dashlen, even); - } - - fbFinishAccess (pDrawable); -} - -void -fbBresFill (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x1, - int y1, - int e, - int e1, - int e3, - int len) -{ - while (len--) - { - fbFill (pDrawable, pGC, x1, y1, 1, 1); - if (axis == X_AXIS) - { - x1 += signdx; - e += e1; - if (e >= 0) - { - e += e3; - y1 += signdy; - } - } - else - { - y1 += signdy; - e += e1; - if (e >= 0) - { - e += e3; - x1 += signdx; - } - } - } -} - -static void -fbSetFg (DrawablePtr pDrawable, - GCPtr pGC, - Pixel fg) -{ - if (fg != pGC->fgPixel) - { - DoChangeGC (pGC, GCForeground, (XID *) &fg, FALSE); - ValidateGC (pDrawable, pGC); - } -} - -void -fbBresFillDash (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x1, - int y1, - int e, - int e1, - int e3, - int len) -{ - FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); - FbDashDeclare; - int dashlen; - Bool even; - Bool doOdd; - Bool doBg; - Pixel fg, bg; - - fg = pGC->fgPixel; - bg = pGC->bgPixel; - - /* whether to fill the odd dashes */ - doOdd = pGC->lineStyle == LineDoubleDash; - /* whether to switch fg to bg when filling odd dashes */ - doBg = doOdd && (pGC->fillStyle == FillSolid || - pGC->fillStyle == FillStippled); - - /* compute current dash position */ - FbDashInit (pGC, pPriv, dashOffset, dashlen, even); - - while (len--) - { - if (even || doOdd) - { - if (doBg) - { - if (even) - fbSetFg (pDrawable, pGC, fg); - else - fbSetFg (pDrawable, pGC, bg); - } - fbFill (pDrawable, pGC, x1, y1, 1, 1); - } - if (axis == X_AXIS) - { - x1 += signdx; - e += e1; - if (e >= 0) - { - e += e3; - y1 += signdy; - } - } - else - { - y1 += signdy; - e += e1; - if (e >= 0) - { - e += e3; - x1 += signdx; - } - } - FbDashStep (dashlen, even); - } - if (doBg) - fbSetFg (pDrawable, pGC, fg); -} - -#ifdef FB_24BIT -static void -fbBresSolid24RRop (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x1, - int y1, - int e, - int e1, - int e3, - int len) -{ - FbStip *dst; - FbStride dstStride; - int dstBpp; - int dstXoff, dstYoff; - FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); - FbStip and = pPriv->and; - FbStip xor = pPriv->xor; - FbStip leftMask, rightMask; - int nl; - FbStip *d; - int x; - int rot; - FbStip andT, xorT; - - fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); - dst += ((y1 + dstYoff) * dstStride); - x1 = (x1 + dstXoff) * 24; - if (signdy < 0) - dstStride = -dstStride; - signdx *= 24; - while (len--) - { - d = dst + (x1 >> FB_STIP_SHIFT); - x = x1 & FB_STIP_MASK; - rot = FbFirst24Rot (x); - andT = FbRot24Stip(and,rot); - xorT = FbRot24Stip(xor,rot); - FbMaskStip (x, 24, leftMask, nl, rightMask); - if (leftMask) - { - WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, leftMask)); - d++; - andT = FbNext24Stip (andT); - xorT = FbNext24Stip (xorT); - } - if (rightMask) - WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, rightMask)); - if (axis == X_AXIS) - { - x1 += signdx; - e += e1; - if (e >= 0) - { - e += e3; - dst += dstStride; - } - } - else - { - dst += dstStride; - e += e1; - if (e >= 0) - { - e += e3; - x1 += signdx; - } - } - } - - fbFinishAccess (pDrawable); -} - -static void -fbBresDash24RRop (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x1, - int y1, - int e, - int e1, - int e3, - int len) -{ - FbStip *dst; - FbStride dstStride; - int dstBpp; - int dstXoff, dstYoff; - FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); - FbStip andT, xorT; - FbStip fgand = pPriv->and; - FbStip fgxor = pPriv->xor; - FbStip bgand = pPriv->bgand; - FbStip bgxor = pPriv->bgxor; - FbStip leftMask, rightMask; - int nl; - FbStip *d; - int x; - int rot; - FbDashDeclare; - int dashlen; - Bool even; - Bool doOdd; - - fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); - doOdd = pGC->lineStyle == LineDoubleDash; - - /* compute current dash position */ - FbDashInit(pGC, pPriv, dashOffset, dashlen, even); - - dst += ((y1 + dstYoff) * dstStride); - x1 = (x1 + dstXoff) * 24; - if (signdy < 0) - dstStride = -dstStride; - signdx *= 24; - while (len--) - { - if (even || doOdd) - { - if (even) - { - andT = fgand; - xorT = fgxor; - } - else - { - andT = bgand; - xorT = bgxor; - } - d = dst + (x1 >> FB_STIP_SHIFT); - x = x1 & FB_STIP_MASK; - rot = FbFirst24Rot (x); - andT = FbRot24Stip (andT, rot); - xorT = FbRot24Stip (xorT, rot); - FbMaskStip (x, 24, leftMask, nl, rightMask); - if (leftMask) - { - WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, leftMask)); - d++; - andT = FbNext24Stip (andT); - xorT = FbNext24Stip (xorT); - } - if (rightMask) - WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, rightMask)); - } - if (axis == X_AXIS) - { - x1 += signdx; - e += e1; - if (e >= 0) - { - e += e3; - dst += dstStride; - } - } - else - { - dst += dstStride; - e += e1; - if (e >= 0) - { - e += e3; - x1 += signdx; - } - } - FbDashStep (dashlen, even); - } - - fbFinishAccess (pDrawable); -} -#endif - -/* - * For drivers that want to bail drawing some lines, this - * function takes care of selecting the appropriate rasterizer - * based on the contents of the specified GC. - */ - -FbBres * -fbSelectBres (DrawablePtr pDrawable, - GCPtr pGC) -{ - FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); - int dstBpp = pDrawable->bitsPerPixel; - FbBres * bres; - - if (pGC->lineStyle == LineSolid) - { - bres = fbBresFill; - if (pGC->fillStyle == FillSolid) - { - bres = fbBresSolid; -#ifdef FB_24BIT - if (dstBpp == 24) - bres = fbBresSolid24RRop; -#endif -#ifndef FBNOPIXADDR - if (pPriv->and == 0) - { - switch (dstBpp) { - case 8: bres = fbBresSolid8; break; - case 16: bres = fbBresSolid16; break; -#ifdef FB_24BIT - case 24: bres = fbBresSolid24; break; -#endif - case 32: bres = fbBresSolid32; break; - } - } -#endif - } - } - else - { - bres = fbBresFillDash; - if (pGC->fillStyle == FillSolid) - { - bres = fbBresDash; -#ifdef FB_24BIT - if (dstBpp == 24) - bres = fbBresDash24RRop; -#endif -#ifndef FBNOPIXADDR - if (pPriv->and == 0 && - (pGC->lineStyle == LineOnOffDash || pPriv->bgand == 0)) - { - switch (dstBpp) { - case 8: bres = fbBresDash8; break; - case 16: bres = fbBresDash16; break; -#ifdef FB_24BIT - case 24: bres = fbBresDash24; break; -#endif - case 32: bres = fbBresDash32; break; - } - } -#endif - } - } - return bres; -} - -void -fbBres (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x1, - int y1, - int e, - int e1, - int e3, - int len) -{ - (*fbSelectBres (pDrawable, pGC)) (pDrawable, pGC, dashOffset, - signdx, signdy, axis, x1, y1, - e, e1, e3, len); -} - -void -fbSegment (DrawablePtr pDrawable, - GCPtr pGC, - int x1, - int y1, - int x2, - int y2, - Bool drawLast, - int *dashOffset) -{ - FbBres * bres; - RegionPtr pClip = fbGetCompositeClip(pGC); - BoxPtr pBox; - int nBox; - int adx; /* abs values of dx and dy */ - int ady; - int signdx; /* sign of dx and dy */ - int signdy; - int e, e1, e2, e3; /* bresenham error and increments */ - int len; /* length of segment */ - int axis; /* major axis */ - int octant; - int dashoff; - int doff; - unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); - unsigned int oc1; /* outcode of point 1 */ - unsigned int oc2; /* outcode of point 2 */ - - nBox = REGION_NUM_RECTS (pClip); - pBox = REGION_RECTS (pClip); - - bres = fbSelectBres (pDrawable, pGC); - - CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, - 1, 1, octant); - - if (adx > ady) - { - axis = X_AXIS; - e1 = ady << 1; - e2 = e1 - (adx << 1); - e = e1 - adx; - len = adx; - } - else - { - axis = Y_AXIS; - e1 = adx << 1; - e2 = e1 - (ady << 1); - e = e1 - ady; - SetYMajorOctant(octant); - len = ady; - } - - FIXUP_ERROR (e, octant, bias); - - /* - * Adjust error terms to compare against zero - */ - e3 = e2 - e1; - e = e - e1; - - /* we have bresenham parameters and two points. - all we have to do now is clip and draw. - */ - - if (drawLast) - len++; - dashoff = *dashOffset; - *dashOffset = dashoff + len; - while(nBox--) - { - oc1 = 0; - oc2 = 0; - OUTCODES(oc1, x1, y1, pBox); - OUTCODES(oc2, x2, y2, pBox); - if ((oc1 | oc2) == 0) - { - (*bres) (pDrawable, pGC, dashoff, - signdx, signdy, axis, x1, y1, - e, e1, e3, len); - break; - } - else if (oc1 & oc2) - { - pBox++; - } - else - { - int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2; - int clip1 = 0, clip2 = 0; - int clipdx, clipdy; - int err; - - if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1, - pBox->y2-1, - &new_x1, &new_y1, &new_x2, &new_y2, - adx, ady, &clip1, &clip2, - octant, bias, oc1, oc2) == -1) - { - pBox++; - continue; - } - - if (axis == X_AXIS) - len = abs(new_x2 - new_x1); - else - len = abs(new_y2 - new_y1); - if (clip2 != 0 || drawLast) - len++; - if (len) - { - /* unwind bresenham error term to first point */ - doff = dashoff; - err = e; - if (clip1) - { - clipdx = abs(new_x1 - x1); - clipdy = abs(new_y1 - y1); - if (axis == X_AXIS) - { - doff += clipdx; - err += e3 * clipdy + e1 * clipdx; - } - else - { - doff += clipdy; - err += e3 * clipdx + e1 * clipdy; - } - } - (*bres) (pDrawable, pGC, doff, - signdx, signdy, axis, new_x1, new_y1, - err, e1, e3, len); - } - pBox++; - } - } /* while (nBox--) */ -} +/*
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "fb.h"
+#include "miline.h"
+
+#define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \
+ ((dir < 0) ? FbStipLeft(mask,bpp) : \
+ FbStipRight(mask,bpp)))
+
+void
+fbBresSolid (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbStip and = (FbStip) pPriv->and;
+ FbStip xor = (FbStip) pPriv->xor;
+ FbStip mask, mask0;
+ FbStip bits;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ dst += ((y1 + dstYoff) * dstStride);
+ x1 = (x1 + dstXoff) * dstBpp;
+ dst += x1 >> FB_STIP_SHIFT;
+ x1 &= FB_STIP_MASK;
+ mask0 = FbStipMask(0, dstBpp);
+ mask = FbStipRight (mask0, x1);
+ if (signdx < 0)
+ mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp);
+ if (signdy < 0)
+ dstStride = -dstStride;
+ if (axis == X_AXIS)
+ {
+ bits = 0;
+ while (len--)
+ {
+ bits |= mask;
+ mask = fbBresShiftMask(mask,signdx,dstBpp);
+ if (!mask)
+ {
+ WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits));
+ bits = 0;
+ dst += signdx;
+ mask = mask0;
+ }
+ e += e1;
+ if (e >= 0)
+ {
+ WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits));
+ bits = 0;
+ dst += dstStride;
+ e += e3;
+ }
+ }
+ if (bits)
+ WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, bits));
+ }
+ else
+ {
+ while (len--)
+ {
+ WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, mask));
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ mask = fbBresShiftMask(mask,signdx,dstBpp);
+ if (!mask)
+ {
+ dst += signdx;
+ mask = mask0;
+ }
+ }
+ }
+ }
+
+ fbFinishAccess (pDrawable);
+}
+
+void
+fbBresDash (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbStip and = (FbStip) pPriv->and;
+ FbStip xor = (FbStip) pPriv->xor;
+ FbStip bgand = (FbStip) pPriv->bgand;
+ FbStip bgxor = (FbStip) pPriv->bgxor;
+ FbStip mask, mask0;
+ FbDashDeclare;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ doOdd = pGC->lineStyle == LineDoubleDash;
+
+ FbDashInit (pGC, pPriv, dashOffset, dashlen, even);
+
+ dst += ((y1 + dstYoff) * dstStride);
+ x1 = (x1 + dstXoff) * dstBpp;
+ dst += x1 >> FB_STIP_SHIFT;
+ x1 &= FB_STIP_MASK;
+ mask0 = FbStipMask(0, dstBpp);
+ mask = FbStipRight (mask0, x1);
+ if (signdx < 0)
+ mask0 = FbStipRight (mask0, FB_STIP_UNIT - dstBpp);
+ if (signdy < 0)
+ dstStride = -dstStride;
+ while (len--)
+ {
+ if (even)
+ WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, mask));
+ else if (doOdd)
+ WRITE(dst, FbDoMaskRRop (READ(dst), bgand, bgxor, mask));
+ if (axis == X_AXIS)
+ {
+ mask = fbBresShiftMask(mask,signdx,dstBpp);
+ if (!mask)
+ {
+ dst += signdx;
+ mask = mask0;
+ }
+ e += e1;
+ if (e >= 0)
+ {
+ dst += dstStride;
+ e += e3;
+ }
+ }
+ else
+ {
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ mask = fbBresShiftMask(mask,signdx,dstBpp);
+ if (!mask)
+ {
+ dst += signdx;
+ mask = mask0;
+ }
+ }
+ }
+ FbDashStep (dashlen, even);
+ }
+
+ fbFinishAccess (pDrawable);
+}
+
+void
+fbBresFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ while (len--)
+ {
+ fbFill (pDrawable, pGC, x1, y1, 1, 1);
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ y1 += signdy;
+ }
+ }
+ else
+ {
+ y1 += signdy;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ }
+}
+
+static void
+fbSetFg (DrawablePtr pDrawable,
+ GCPtr pGC,
+ Pixel fg)
+{
+ if (fg != pGC->fgPixel)
+ {
+ ChangeGCVal val;
+ val.val = fg;
+ ChangeGC (NullClient, pGC, GCForeground, &val);
+ ValidateGC (pDrawable, pGC);
+ }
+}
+
+void
+fbBresFillDash (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbDashDeclare;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+ Bool doBg;
+ Pixel fg, bg;
+
+ fg = pGC->fgPixel;
+ bg = pGC->bgPixel;
+
+ /* whether to fill the odd dashes */
+ doOdd = pGC->lineStyle == LineDoubleDash;
+ /* whether to switch fg to bg when filling odd dashes */
+ doBg = doOdd && (pGC->fillStyle == FillSolid ||
+ pGC->fillStyle == FillStippled);
+
+ /* compute current dash position */
+ FbDashInit (pGC, pPriv, dashOffset, dashlen, even);
+
+ while (len--)
+ {
+ if (even || doOdd)
+ {
+ if (doBg)
+ {
+ if (even)
+ fbSetFg (pDrawable, pGC, fg);
+ else
+ fbSetFg (pDrawable, pGC, bg);
+ }
+ fbFill (pDrawable, pGC, x1, y1, 1, 1);
+ }
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ y1 += signdy;
+ }
+ }
+ else
+ {
+ y1 += signdy;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ FbDashStep (dashlen, even);
+ }
+ if (doBg)
+ fbSetFg (pDrawable, pGC, fg);
+}
+
+#ifdef FB_24BIT
+static void
+fbBresSolid24RRop (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbStip and = pPriv->and;
+ FbStip xor = pPriv->xor;
+ FbStip leftMask, rightMask;
+ int nl;
+ FbStip *d;
+ int x;
+ int rot;
+ FbStip andT, xorT;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ dst += ((y1 + dstYoff) * dstStride);
+ x1 = (x1 + dstXoff) * 24;
+ if (signdy < 0)
+ dstStride = -dstStride;
+ signdx *= 24;
+ while (len--)
+ {
+ d = dst + (x1 >> FB_STIP_SHIFT);
+ x = x1 & FB_STIP_MASK;
+ rot = FbFirst24Rot (x);
+ andT = FbRot24Stip(and,rot);
+ xorT = FbRot24Stip(xor,rot);
+ FbMaskStip (x, 24, leftMask, nl, rightMask);
+ if (leftMask)
+ {
+ WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, leftMask));
+ d++;
+ andT = FbNext24Stip (andT);
+ xorT = FbNext24Stip (xorT);
+ }
+ if (rightMask)
+ WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, rightMask));
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ dst += dstStride;
+ }
+ }
+ else
+ {
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ }
+
+ fbFinishAccess (pDrawable);
+}
+
+static void
+fbBresDash24RRop (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pPriv = fbGetGCPrivate (pGC);
+ FbStip andT, xorT;
+ FbStip fgand = pPriv->and;
+ FbStip fgxor = pPriv->xor;
+ FbStip bgand = pPriv->bgand;
+ FbStip bgxor = pPriv->bgxor;
+ FbStip leftMask, rightMask;
+ int nl;
+ FbStip *d;
+ int x;
+ int rot;
+ FbDashDeclare;
+ int dashlen;
+ Bool even;
+ Bool doOdd;
+
+ fbGetStipDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ doOdd = pGC->lineStyle == LineDoubleDash;
+
+ /* compute current dash position */
+ FbDashInit(pGC, pPriv, dashOffset, dashlen, even);
+
+ dst += ((y1 + dstYoff) * dstStride);
+ x1 = (x1 + dstXoff) * 24;
+ if (signdy < 0)
+ dstStride = -dstStride;
+ signdx *= 24;
+ while (len--)
+ {
+ if (even || doOdd)
+ {
+ if (even)
+ {
+ andT = fgand;
+ xorT = fgxor;
+ }
+ else
+ {
+ andT = bgand;
+ xorT = bgxor;
+ }
+ d = dst + (x1 >> FB_STIP_SHIFT);
+ x = x1 & FB_STIP_MASK;
+ rot = FbFirst24Rot (x);
+ andT = FbRot24Stip (andT, rot);
+ xorT = FbRot24Stip (xorT, rot);
+ FbMaskStip (x, 24, leftMask, nl, rightMask);
+ if (leftMask)
+ {
+ WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, leftMask));
+ d++;
+ andT = FbNext24Stip (andT);
+ xorT = FbNext24Stip (xorT);
+ }
+ if (rightMask)
+ WRITE(d, FbDoMaskRRop (READ(d), andT, xorT, rightMask));
+ }
+ if (axis == X_AXIS)
+ {
+ x1 += signdx;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ dst += dstStride;
+ }
+ }
+ else
+ {
+ dst += dstStride;
+ e += e1;
+ if (e >= 0)
+ {
+ e += e3;
+ x1 += signdx;
+ }
+ }
+ FbDashStep (dashlen, even);
+ }
+
+ fbFinishAccess (pDrawable);
+}
+#endif
+
+/*
+ * For drivers that want to bail drawing some lines, this
+ * function takes care of selecting the appropriate rasterizer
+ * based on the contents of the specified GC.
+ */
+
+FbBres *
+fbSelectBres (DrawablePtr pDrawable,
+ GCPtr pGC)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ int dstBpp = pDrawable->bitsPerPixel;
+ FbBres * bres;
+
+ if (pGC->lineStyle == LineSolid)
+ {
+ bres = fbBresFill;
+ if (pGC->fillStyle == FillSolid)
+ {
+ bres = fbBresSolid;
+#ifdef FB_24BIT
+ if (dstBpp == 24)
+ bres = fbBresSolid24RRop;
+#endif
+#ifndef FBNOPIXADDR
+ if (pPriv->and == 0)
+ {
+ switch (dstBpp) {
+ case 8: bres = fbBresSolid8; break;
+ case 16: bres = fbBresSolid16; break;
+#ifdef FB_24BIT
+ case 24: bres = fbBresSolid24; break;
+#endif
+ case 32: bres = fbBresSolid32; break;
+ }
+ }
+#endif
+ }
+ }
+ else
+ {
+ bres = fbBresFillDash;
+ if (pGC->fillStyle == FillSolid)
+ {
+ bres = fbBresDash;
+#ifdef FB_24BIT
+ if (dstBpp == 24)
+ bres = fbBresDash24RRop;
+#endif
+#ifndef FBNOPIXADDR
+ if (pPriv->and == 0 &&
+ (pGC->lineStyle == LineOnOffDash || pPriv->bgand == 0))
+ {
+ switch (dstBpp) {
+ case 8: bres = fbBresDash8; break;
+ case 16: bres = fbBresDash16; break;
+#ifdef FB_24BIT
+ case 24: bres = fbBresDash24; break;
+#endif
+ case 32: bres = fbBresDash32; break;
+ }
+ }
+#endif
+ }
+ }
+ return bres;
+}
+
+void
+fbBres (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int dashOffset,
+ int signdx,
+ int signdy,
+ int axis,
+ int x1,
+ int y1,
+ int e,
+ int e1,
+ int e3,
+ int len)
+{
+ (*fbSelectBres (pDrawable, pGC)) (pDrawable, pGC, dashOffset,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e3, len);
+}
+
+void
+fbSegment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ Bool drawLast,
+ int *dashOffset)
+{
+ FbBres * bres;
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pBox;
+ int nBox;
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2, e3; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ int dashoff;
+ int doff;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ unsigned int oc1; /* outcode of point 1 */
+ unsigned int oc2; /* outcode of point 2 */
+
+ nBox = REGION_NUM_RECTS (pClip);
+ pBox = REGION_RECTS (pClip);
+
+ bres = fbSelectBres (pDrawable, pGC);
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
+ 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ len = adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ len = ady;
+ }
+
+ FIXUP_ERROR (e, octant, bias);
+
+ /*
+ * Adjust error terms to compare against zero
+ */
+ e3 = e2 - e1;
+ e = e - e1;
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ if (drawLast)
+ len++;
+ dashoff = *dashOffset;
+ *dashOffset = dashoff + len;
+ while(nBox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pBox);
+ OUTCODES(oc2, x2, y2, pBox);
+ if ((oc1 | oc2) == 0)
+ {
+ (*bres) (pDrawable, pGC, dashoff,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e3, len);
+ break;
+ }
+ else if (oc1 & oc2)
+ {
+ pBox++;
+ }
+ else
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1,
+ pBox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pBox++;
+ continue;
+ }
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+ if (clip2 != 0 || drawLast)
+ len++;
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ doff = dashoff;
+ err = e;
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ {
+ doff += clipdx;
+ err += e3 * clipdy + e1 * clipdx;
+ }
+ else
+ {
+ doff += clipdy;
+ err += e3 * clipdx + e1 * clipdy;
+ }
+ }
+ (*bres) (pDrawable, pGC, doff,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e3, len);
+ }
+ pBox++;
+ }
+ } /* while (nBox--) */
+}
|