863 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			863 lines
		
	
	
		
			24 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) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
 | |
| 
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #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);
 | |
|     bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
 | |
|     if (signdy < 0)
 | |
|         bitsStride = -bitsStride;
 | |
|     if (axis == X_AXIS) {
 | |
|         majorStep = signdx;
 | |
|         minorStep = bitsStride;
 | |
|     }
 | |
|     else {
 | |
|         majorStep = bitsStride;
 | |
|         minorStep = signdx;
 | |
|     }
 | |
|     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);
 | |
|     bitsStride = dstStride * (sizeof(FbBits) / sizeof(UNIT));
 | |
|     if (signdy < 0)
 | |
|         bitsStride = -bitsStride;
 | |
|     if (axis == X_AXIS) {
 | |
|         majorStep = signdx;
 | |
|         minorStep = bitsStride;
 | |
|     }
 | |
|     else {
 | |
|         majorStep = bitsStride;
 | |
|         minorStep = signdx;
 | |
|     }
 | |
|     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);
 | |
| 
 | |
|     if (and == 0) {
 | |
|         while (npt--) {
 | |
|             pt = *pts++;
 | |
|             if (!isClipped(pt, ul, lr)) {
 | |
|                 point = bits + intToY(pt) * bitsStride + intToX(pt);
 | |
|                 STORE(point, bxor);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     else {
 | |
|         while (npt--) {
 | |
|             pt = *pts++;
 | |
|             if (!isClipped(pt, ul, lr)) {
 | |
|                 point = bits + intToY(pt) * bitsStride + intToX(pt);
 | |
|                 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);
 | |
|     info.xorgo = (info.xorgo + drawX);
 | |
|     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;
 | |
| 
 | |
|         yorgp += info.xorg;
 | |
|         yorgop += info.xorg;
 | |
|         yorghb += info.h;
 | |
|         while (1) {
 | |
|             if (andBits == 0) {
 | |
|                 ARCCOPY(yorgp + yoffset + x);
 | |
|                 ARCCOPY(yorgp + yoffset - x);
 | |
|                 ARCCOPY(yorgop - yoffset - x);
 | |
|                 ARCCOPY(yorgop - yoffset + x);
 | |
|             }
 | |
|             else {
 | |
|                 ARCRROP(yorgp + yoffset + x);
 | |
|                 ARCRROP(yorgp + yoffset - x);
 | |
|                 ARCRROP(yorgop - yoffset - x);
 | |
|                 ARCRROP(yorgop - yoffset + x);
 | |
|             }
 | |
|             if (a < 0)
 | |
|                 break;
 | |
|             if (andBits == 0) {
 | |
|                 ARCCOPY(yorghb - xoffset - y);
 | |
|                 ARCCOPY(yorgohb - xoffset + y);
 | |
|                 ARCCOPY(yorgohb + xoffset + y);
 | |
|                 ARCCOPY(yorghb + xoffset - y);
 | |
|             }
 | |
|             else {
 | |
|                 ARCRROP(yorghb - xoffset - y);
 | |
|                 ARCRROP(yorgohb - xoffset + y);
 | |
|                 ARCRROP(yorgohb + xoffset + y);
 | |
|                 ARCRROP(yorghb + xoffset - y);
 | |
|             }
 | |
|             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);
 | |
|                 ARCCOPY(yorgp + yoffset + info.xorgo - x);
 | |
|                 ARCCOPY(yorgop - yoffset + info.xorgo - x);
 | |
|                 ARCCOPY(yorgop - yoffset + info.xorg + x);
 | |
|             }
 | |
|             else {
 | |
|                 ARCRROP(yorgp + yoffset + info.xorg + x);
 | |
|                 ARCRROP(yorgp + yoffset + info.xorgo - x);
 | |
|                 ARCRROP(yorgop - yoffset + info.xorgo - x);
 | |
|                 ARCRROP(yorgop - yoffset + info.xorg + x);
 | |
|             }
 | |
|             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);
 | |
|                 if (mask & 2)
 | |
|                     ARCCOPY(yorgp + yoffset + info.xorgo - x);
 | |
|                 if (mask & 4)
 | |
|                     ARCCOPY(yorgop - yoffset + info.xorgo - x);
 | |
|                 if (mask & 8)
 | |
|                     ARCCOPY(yorgop - yoffset + info.xorg + x);
 | |
|             }
 | |
|             else {
 | |
|                 if (mask & 1)
 | |
|                     ARCRROP(yorgp + yoffset + info.xorg + x);
 | |
|                 if (mask & 2)
 | |
|                     ARCRROP(yorgp + yoffset + info.xorgo - x);
 | |
|                 if (mask & 4)
 | |
|                     ARCRROP(yorgop - yoffset + info.xorgo - x);
 | |
|                 if (mask & 8)
 | |
|                     ARCRROP(yorgop - yoffset + info.xorg + x);
 | |
|             }
 | |
|             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);
 | |
|         if (mask & 4)
 | |
|             ARCCOPY(yorgop - yoffset + info.xorgo - x);
 | |
|         if (arc->height & 1) {
 | |
|             if (mask & 2)
 | |
|                 ARCCOPY(yorgp + yoffset + info.xorgo - x);
 | |
|             if (mask & 8)
 | |
|                 ARCCOPY(yorgop - yoffset + info.xorg + x);
 | |
|         }
 | |
|     }
 | |
|     else {
 | |
|         if (mask & 1)
 | |
|             ARCRROP(yorgp + yoffset + info.xorg + x);
 | |
|         if (mask & 4)
 | |
|             ARCRROP(yorgop - yoffset + info.xorgo - x);
 | |
|         if (arc->height & 1) {
 | |
|             if (mask & 2)
 | |
|                 ARCRROP(yorgp + yoffset + info.xorgo - x);
 | |
|             if (mask & 8)
 | |
|                 ARCRROP(yorgop - yoffset + info.xorg + x);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| #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);
 | |
|     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);
 | |
|             for (;;) {
 | |
|                 CalcLineDeltas(intToX(pt1), intToY(pt1),
 | |
|                                intToX(pt2), intToY(pt2),
 | |
|                                len, e1, stepmajor, stepminor, 1, bitsStride,
 | |
|                                octant);
 | |
|                 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);
 | |
|     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) {
 | |
|                 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);
 | |
|                 width = (x2 - x1) * (sizeof(UNIT) * 8);
 | |
| 
 | |
|                 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 {
 | |
|                 bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1);
 | |
|                 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 STORE
 | |
| #undef RROP
 | |
| #undef UNIT
 | |
| #undef USE_SOLID
 | |
| 
 | |
| #undef isClipped
 |