957 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			957 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * $XFree86: xc/programs/Xserver/fb/fbbits.h,v 1.14 2003/11/03 05:11:00 tsi Exp $
 | |
|  *
 | |
|  * 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 BITSMUL
 | |
| #define MUL BITSMUL
 | |
| #else
 | |
| #define MUL 1
 | |
| #endif
 | |
| 
 | |
| #ifdef BITSSTORE
 | |
| #define STORE(b,x)  BITSSTORE(b,x)
 | |
| #else
 | |
| #define STORE(b,x)  (*(b) = (x))
 | |
| #endif
 | |
| 
 | |
| #ifdef BITSRROP
 | |
| #define RROP(b,a,x)	BITSRROP(b,a,x)
 | |
| #else
 | |
| #define RROP(b,a,x)	(*(b) = FbDoRRop (*(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;
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| #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;
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef DOTS
 | |
| void
 | |
| DOTS (FbBits	    *dst,
 | |
|       FbStride	    dstStride,
 | |
|       int	    dstBpp,
 | |
|       BoxPtr	    pBox,
 | |
|       xPoint	    *ptsOrig,
 | |
|       int	    npt,
 | |
|       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 - xoff,     pBox->y1 - yoff);
 | |
|     lr = coordToInt(pBox->x2 - xoff - 1, pBox->y2 - yoff - 1);
 | |
| 
 | |
|     bits += bitsStride * yoff + 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)	    ((d)[WRITE_ADDR1(n)] = (BITS) (fg))
 | |
| 
 | |
| #ifdef BITS2
 | |
| # define WRITE2(d,n,fg)	    (*((BITS2 *) &((d)[WRITE_ADDR2(n)])) = (BITS2) (fg))
 | |
| #else
 | |
| # define WRITE2(d,n,fg)	    WRITE1(d,(n)+1,WRITE1(d,n,fg))
 | |
| #endif
 | |
| 
 | |
| #ifdef BITS4
 | |
| # define WRITE4(d,n,fg)	    (*((BITS4 *) &((d)[WRITE_ADDR4(n)])) = (BITS4) (fg))
 | |
| #else
 | |
| # define WRITE4(d,n,fg)	    WRITE2(d,(n)+2,WRITE2(d,n,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)
 | |
| 		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);
 | |
| 		    }
 | |
| 		    return;
 | |
| 		}
 | |
| 		pt1 = pt2;
 | |
| 		pt2 = *pts++;
 | |
| 		--npt;
 | |
| 		if (isClipped (pt2, ul, lr))
 | |
| 		    break;
 | |
|     	    }
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| #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)
 | |
| 		{
 | |
| 		    *dstLine = FbDoMaskRRop (*dstLine, andBits, xorBits, startmask);
 | |
| 		    dstLine++;
 | |
| 		}
 | |
| 		if (!andBits)
 | |
| 		    while (nmiddle--)
 | |
| 			*dstLine++ = xorBits;
 | |
| 		else
 | |
| 		    while (nmiddle--)
 | |
| 		    {
 | |
| 			*dstLine = FbDoRRop (*dstLine, andBits, xorBits);
 | |
| 			dstLine++;
 | |
| 		    }
 | |
| 		if (endmask)
 | |
| 		    *dstLine = FbDoMaskRRop (*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;
 | |
| 			}
 | |
| 		    }
 | |
| 		}
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #undef MUL
 | |
| #undef STORE
 | |
| #undef RROP
 | |
| #undef UNIT
 | |
| #undef USE_SOLID
 | |
| 
 | |
| #undef isClipped
 |