/*
*
Copyright 1990, 1998 The Open Group
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.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*
* Author: Keith Packard, MIT X Consortium
*
* Jeff Anton'x fixes: cfb8line.c 97/02/07
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdlib.h>
#include <X11/X.h>
#include "gcstruct.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "regionstr.h"
#include "scrnintstr.h"
#include "mistruct.h"
#include "cfb.h"
#include "cfbmskbits.h"
#include "cfbrrop.h"
#include "miline.h"
#ifdef PIXEL_ADDR
#if defined(__GNUC__) && defined(mc68020)
#define STUPID volatile
#define REARRANGE
#else
#define STUPID
#endif
#ifdef __GNUC__
/* lame compiler doesn't even look at 'register' attributes */
#define I_H do{
#define I_T }while(0);
#define IMPORTANT_START I_H I_H I_H I_H I_H I_H I_H I_H I_H I_H
#define IMPORTANT_END I_T I_T I_T I_T I_T I_T I_T I_T I_T I_T
#else
#define IMPORTANT_START
#define IMPORTANT_END
#endif
#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & ClipMask)
#ifdef POLYSEGMENT
# if (defined(sun) || defined(__bsdi__)) && \
(defined(sparc) || defined(__sparc__))
# define WIDTH_FAST 1152
# endif
# ifdef ultrix
# define WIDTH_FAST 1024
# endif
# ifdef Mips
# define WIDTH_FAST 4096
# endif
# ifdef WIDTH_FAST
# if WIDTH_FAST == 1024
# define FAST_MUL(y) ((y) << 10)
# endif
# if WIDTH_FAST == 1152
# define FAST_MUL(y) (((y) << 10) + ((y) << 7))
# endif
# if WIDTH_FAST == 1280
# define FAST_MUL(y) (((y) << 10) + ((y) << 8))
# endif
# if WIDTH_FAST == 2048
# define FAST_MUL(y) ((y) << 11)
# endif
# if WIDTH_FAST == 4096
# define FAST_MUL(y) ((y) << 12)
# endif
# endif
# if defined(WIDTH_SHIFT)
# ifdef FAST_MUL
# define FUNC_NAME(e) RROP_NAME(RROP_NAME_CAT(e,Shift))
# if RROP == GXcopy
# define INCLUDE_OTHERS
# define SERIOUS_UNROLLING
# endif
# define INCLUDE_DRAW
# define NWIDTH(nwidth) WIDTH_FAST
# define WIDTH_MUL(y,w) FAST_MUL(y)
# endif
# else
# define FUNC_NAME(e) RROP_NAME(e)
# define WIDTH_MUL(y,w) ((y) * (w))
# define NWIDTH(nwidth) (nwidth)
# define INCLUDE_DRAW
# if !defined (FAST_MUL) && RROP == GXcopy
# define INCLUDE_OTHERS
# define SERIOUS_UNROLLING
# endif
# endif
#else
# define INCLUDE_DRAW
# define WIDTH_MUL(y,w) ((y) * (w))
# define NWIDTH(nwidth) nwidth
# ifdef PREVIOUS
# define FUNC_NAME(e) RROP_NAME(RROP_NAME_CAT(e,Previous))
# else
# define FUNC_NAME(e) RROP_NAME(e)
# if RROP == GXcopy
# define INCLUDE_OTHERS
# ifdef PLENTIFUL_REGISTERS
# define SAVE_X2Y2
# endif
# define ORIGIN
# define SERIOUS_UNROLLING
# else
# define EITHER_MODE
# endif
# endif
#endif
#if PSZ == 24
#define PXL2ADR(x) ((x)*3 >> 2)
#if RROP == GXcopy
#define body_rop \
addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
switch((unsigned long)addrb & 3){ \
case 0: \
*addrp = (*addrp & 0xFF000000)|(piQxelXor[0] & 0xFFFFFF); \
break; \
case 1: \
*addrp = (*addrp & 0xFF)|(piQxelXor[2] & 0xFFFFFF00); \
break; \
case 3: \
*addrp = (*addrp & 0xFFFFFF)|(piQxelXor[0] & 0xFF000000); \
*(addrp+1)=(*(addrp+1) & 0xFFFF0000)|(piQxelXor[1] & 0xFFFF); \
break; \
case 2: \
*addrp = (*addrp & 0xFFFF)|(piQxelXor[1] & 0xFFFF0000); \
*(addrp+1)=(*(addrp+1) & 0xFFFFFF00)|(piQxelXor[2] & 0xFF); \
break; \
}
#endif
#if RROP == GXxor
#define body_rop \
addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
switch((unsigned long)addrb & 3){ \
case 0: \
*addrp ^= piQxelXor[0] & 0xFFFFFF; \
break; \
case 1: \
*addrp ^= piQxelXor[2] & 0xFFFFFF00; \
break; \
case 3: \
*addrp ^= piQxelXor[0] & 0xFF000000; \
*(addrp+1) ^= piQxelXor[1] & 0xFFFF; \
break; \
case 2: \
*addrp ^= piQxelXor[1] & 0xFFFF0000; \
*(addrp+1) ^= piQxelXor[2] & 0xFF; \
break; \
}
#endif
#if RROP == GXand
#define body_rop \
addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
switch((unsigned long)addrb & 3){ \
case 0: \
*addrp &= piQxelAnd[0] | 0xFF000000; \
break; \
case 1: \
*addrp &= piQxelAnd[2] | 0xFF; \
break; \
case 3: \
*addrp &= 0xFFFFFF | piQxelAnd[0]; \
*(addrp+1) &= 0xFFFF0000 | piQxelAnd[1]; \
break; \
case 2: \
*addrp &= 0xFFFF | piQxelAnd[1]; \
*(addrp+1) &= 0xFFFFFF00 | piQxelAnd[2]; \
break; \
}
#endif
#if RROP == GXor
#define body_rop \
addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
switch((unsigned long)addrb & 3){ \
case 0: \
*addrp |= piQxelOr[0] & 0xFFFFFF; \
break; \
case 1: \
*addrp |= piQxelOr[2] & 0xFFFFFF00; \
break; \
case 3: \
*addrp |= piQxelOr[0] & 0xFF000000; \
*(addrp+1) |= piQxelOr[1] & 0xFFFF; \
break; \
case 2: \
*addrp |= piQxelOr[1] & 0xFFFF0000; \
*(addrp+1) |= piQxelOr[2] & 0xFF; \
break; \
}
#endif
#if RROP == GXset
#define body_rop \
addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
switch((unsigned long)addrb & 3){ \
case 0: \
*addrp = (*addrp & (piQxelAnd[0]|0xFF000000)) \
^ (piQxelXor[0] & 0xFFFFFF); \
break; \
case 1: \
*addrp = (*addrp & (piQxelAnd[2]|0xFF)) \
^ (piQxelXor[2] & 0xFFFFFF00); \
break; \
case 3: \
*addrp = (*addrp & (piQxelAnd[0]|0xFFFFFF)) \
^ (piQxelXor[0] & 0xFF000000); \
*(addrp+1) = (*(addrp+1) & (piQxelAnd[1]|0xFFFF0000)) \
^ (piQxelXor[1] & 0xFFFF); \
break; \
case 2: \
*addrp = (*addrp & (piQxelAnd[1]|0xFFFF)) \
^ (piQxelXor[1] & 0xFFFF0000); \
*(addrp+1) = (*(addrp+1) & (piQxelAnd[2]|0xFFFFFF00)) \
^ (piQxelXor[2] & 0xFF); \
break; \
}
#endif
#endif /* PSZ == 24 */
#define BUGFIX_clip
#ifdef INCLUDE_DRAW
int
#ifdef POLYSEGMENT
FUNC_NAME(cfb8SegmentSS1Rect) (pDrawable, pGC, nseg, pSegInit)
DrawablePtr pDrawable;
GCPtr pGC;
int nseg;
xSegment *pSegInit;
#else
FUNC_NAME(cfb8LineSS1Rect) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig,
x1p,y1p,x2p,y2p)
DrawablePtr pDrawable;
GCPtr pGC;
int mode; /* Origin or Previous */
int npt; /* number of points */
DDXPointPtr pptInit, pptInitOrig;
int *x1p, *y1p, *x2p, *y2p;
#endif /* POLYSEGMENT */
{
register long e;
register int y1_or_e1;
register PixelType *addrp;
register int stepmajor;
register int stepminor;
#ifndef REARRANGE
register long e3;
#endif
#ifdef mc68000
register short x1_or_len;
#else
register int x1_or_len;
#endif
RROP_DECLARE
#ifdef SAVE_X2Y2
# define c2 y2
#else
register int c2;
#endif
#if !defined(ORIGIN) && !defined(POLYSEGMENT)
register int _x1 = 0, _y1 = 0, _x2 = 0, _y2 = 0;
int extents_x1, extents_y1, extents_x2, extents_y2;
#endif /* !ORIGIN */
#ifndef PREVIOUS
register int upperleft, lowerright;
CARD32 ClipMask = 0x80008000;
#endif /* !PREVIOUS */
#ifdef POLYSEGMENT
register int capStyle;
#endif /* POLYSEGMENT */
#ifdef SAVE_X2Y2
register int x2, y2;
# define X1 x1_or_len
# define Y1 y1_or_e1
# define X2 x2
# define Y2 y2
#else
# ifdef POLYSEGMENT
# define X1 x1_or_len
# define Y1 y1_or_e1
# else
# define X1 intToX(y1_or_e1)
# define Y1 intToY(y1_or_e1)
# endif /* POLYSEGMENT */
# define X2 intToX(c2)
# define Y2 intToY(c2)
#endif /* SAVE_X2Y2 */
PixelType *addr;
int nwidth;
cfbPrivGCPtr devPriv;
BoxPtr extents;
int *ppt;
#if PSZ == 24
int xBase; /* x of addr */
int xOffset; /* x of addrp */
PixelType *addrLineEnd;
char *addrb;
int stepmajor3, stepminor3, majordx, minordx;
#endif
#ifndef POLYSEGMENT
#ifndef ORIGIN
#ifdef BUGFIX_clip
int ex_x1, ex_y1, ex_x2, ex_y2;
#endif
#endif
#endif
int octant;
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
devPriv = cfbGetGCPrivate(pGC);
cfbGetPixelWidthAndPointer (pDrawable, nwidth, addr);
#ifndef REARRANGE
RROP_FETCH_GCPRIV(devPriv);
#endif
extents = &pGC->pCompositeClip->extents;
#ifndef PREVIOUS
c2 = *((int *) &pDrawable->x);
c2 -= (c2 & 0x8000) << 1;
upperleft = *((int *) &extents->x1) - c2;
lowerright = *((int *) &extents->x2) - c2 - 0x00010001;
#endif /* !PREVIOUS */
#ifndef POLYSEGMENT
#ifndef ORIGIN
#ifdef BUGFIX_clip
ex_x1 = extents->x1 - pDrawable->x;
ex_y1 = extents->y1 - pDrawable->y;
ex_x2 = extents->x2 - pDrawable->x;
ex_y2 = extents->y2 - pDrawable->y;
#endif
#endif
#endif
#if PSZ == 24
xBase = pDrawable->x;
addr += WIDTH_MUL(pDrawable->y,nwidth);
#else
addr = addr + WIDTH_MUL(pDrawable->y,nwidth) + pDrawable->x;
#endif
#ifdef POLYSEGMENT
capStyle = pGC->capStyle - CapNotLast;
ppt = (int *) pSegInit;
while (nseg--)
#else /* POLYSEGMENT */
#ifdef EITHER_MODE
mode -= CoordModePrevious;
if (!mode)
#endif /* EITHER_MODE */
#ifndef ORIGIN
{ /* CoordModePrevious */
ppt = (int *)pptInit + 1;
_x1 = *x1p;
_y1 = *y1p;
extents_x1 = extents->x1 - pDrawable->x;
extents_x2 = extents->x2 - pDrawable->x;
extents_y1 = extents->y1 - pDrawable->y;
extents_y2 = extents->y2 - pDrawable->y;
if (_x1 < extents_x1 || _x1 >= extents_x2 ||
_y1 < extents_y1 || _y1 >= extents_y2)
{
c2 = *ppt++;
intToCoord(c2, _x2, _y2);
*x2p = _x1 + _x2;
*y2p = _y1 + _y2;
return 1;
}
#if PSZ == 24
addrLineEnd = addr + WIDTH_MUL(_y1, nwidth);
xOffset = xBase + _x1;
addrb = (char *)addrLineEnd + xOffset * 3;
addrp = (PixelType *)((unsigned long)addrb & ~0x03);
#else
addrp = addr + WIDTH_MUL(_y1, nwidth) + _x1;
#endif
_x2 = _x1;
_y2 = _y1;
}
#endif /* !ORIGIN */
#ifdef EITHER_MODE
else
#endif /* EITHER_MODE */
#ifndef PREVIOUS
{
ppt = (int *) pptInit;
c2 = *ppt++;
if (isClipped (c2, upperleft, lowerright))
{
return 1;
}
#ifdef SAVE_X2Y2
intToCoord(c2,x2,y2);
#endif
#if PSZ == 24
addrLineEnd = addr + WIDTH_MUL(Y2, nwidth);
xOffset = xBase + X2;
addrb = (char *)addrLineEnd + xOffset * 3;
addrp = (PixelType *)((unsigned long)addrb & ~0x03);
#else
addrp = addr + WIDTH_MUL(Y2, nwidth) + X2;
#endif
}
#endif /* !PREVIOUS */
while (--npt)
#endif /* POLYSEGMENT */
{
#ifdef POLYSEGMENT
y1_or_e1 = ppt[0];
c2 = ppt[1];
ppt += 2;
if (isClipped(y1_or_e1,upperleft,lowerright)|isClipped(c2,upperleft,lowerright))
break;
intToCoord(y1_or_e1,x1_or_len,y1_or_e1);
/* compute now to avoid needing x1, y1 later */
#if PSZ == 24
addrLineEnd = addr + WIDTH_MUL(y1_or_e1, nwidth);
xOffset = xBase + x1_or_len;
addrb = (char *)addrLineEnd + xOffset * 3;
addrp = (PixelType *)((unsigned long)addrb & ~0x03);
#else
addrp = addr + WIDTH_MUL(y1_or_e1, nwidth) + x1_or_len;
#endif
#else /* !POLYSEGMENT */
#ifdef EITHER_MODE
if (!mode)
#endif /* EITHER_MODE */
#ifndef ORIGIN
{
/* CoordModePrevious */
_x1 = _x2;
_y1 = _y2;
c2 = *ppt++;
intToCoord(c2, _x2, _y2);
_x2 = _x1 + _x2;
_y2 = _y1 + _y2;
#ifdef BUGFIX_clip
if (_x2 < ex_x1 || _x2 >= ex_x2 ||
_y2 < ex_y1 || _y2 >= ex_y2)
#else
if (_x2 < extents_x1 || _x2 >= extents_x2 ||
_y2 < extents_y1 || _y2 >= extents_y2)
#endif
{
break;
}
CalcLineDeltas(_x1, _y1, _x2, _y2, x1_or_len, y1_or_e1,
stepmajor, stepminor, 1, NWIDTH(nwidth), octant);
}
#endif /* !ORIGIN */
#ifdef EITHER_MODE
else
#endif /* EITHER_MODE */
#ifndef PREVIOUS
{
#ifndef SAVE_X2Y2
y1_or_e1 = c2;
#else
y1_or_e1 = y2;
x1_or_len = x2;
#endif /* SAVE_X2Y2 */
c2 = *ppt++;
if (isClipped (c2, upperleft, lowerright))
break;
#ifdef SAVE_X2Y2
intToCoord(c2,x2,y2);
#endif
CalcLineDeltas(X1, Y1, X2, Y2, x1_or_len, y1_or_e1,
stepmajor, stepminor, 1, NWIDTH(nwidth), octant);
}
#endif /* !PREVIOUS */
#endif /* POLYSEGMENT */
#ifdef POLYSEGMENT
CalcLineDeltas(X1, Y1, X2, Y2, x1_or_len, y1_or_e1,
stepmajor, stepminor, 1, NWIDTH(nwidth), octant);
/*
* although the horizontal code works for polyline, it
* slows down 10 pixel lines by 15%. Thus, this
* code is optimized for horizontal segments and
* random orientation lines, which seems like a reasonable
* assumption
*/
if (y1_or_e1 != 0)
{
#endif /* POLYSEGMENT */
if (x1_or_len < y1_or_e1)
{
#ifdef REARRANGE
register int e3;
#endif
e3 = x1_or_len;
x1_or_len = y1_or_e1;
y1_or_e1 = e3;
e3 = stepminor;
stepminor = stepmajor;
stepmajor = e3;
SetYMajorOctant(octant);
}
e = -x1_or_len;
#ifdef POLYSEGMENT
if (!capStyle)
x1_or_len--;
#endif
{
#ifdef REARRANGE
register int e3;
RROP_DECLARE
RROP_FETCH_GCPRIV(devPriv);
#endif
y1_or_e1 = y1_or_e1 << 1;
e3 = e << 1;
FIXUP_ERROR(e, octant, bias);
#if PSZ == 24
if (stepmajor == 1 || stepmajor == -1){
stepmajor3 = stepmajor * 3;
stepminor3 = stepminor * sizeof (CfbBits);
majordx = stepmajor; minordx = 0;
} else {
stepmajor3 = stepmajor * sizeof (CfbBits);
stepminor3 = stepminor * 3;
majordx = 0; minordx = stepminor;
}
#endif
#if PSZ == 24
#define body {\
body_rop \
addrb += stepmajor3; \
xOffset += majordx; \
e += y1_or_e1; \
if (e >= 0){ \
addrb += stepminor3; \
xOffset += minordx; \
e += e3; \
} \
}
#else /* PSZ == 24 */
#define body {\
RROP_SOLID(addrp); \
addrp += stepmajor; \
e += y1_or_e1; \
if (e >= 0) \
{ \
addrp += stepminor; \
e += e3; \
} \
}
#endif /* PSZ == 24 */
#ifdef LARGE_INSTRUCTION_CACHE
# ifdef SERIOUS_UNROLLING
# define UNROLL 16
# else
# define UNROLL 4
# endif
#define CASE(n) case -n: body
while ((x1_or_len -= UNROLL) >= 0)
{
body body body body
# if UNROLL >= 8
body body body body
# endif
# if UNROLL >= 12
body body body body
# endif
# if UNROLL >= 16
body body body body
# endif
}
switch (x1_or_len)
{
CASE(1) CASE(2) CASE(3)
# if UNROLL >= 8
CASE(4) CASE(5) CASE(6) CASE(7)
# endif
# if UNROLL >= 12
CASE(8) CASE(9) CASE(10) CASE(11)
# endif
# if UNROLL >= 16
CASE(12) CASE(13) CASE(14) CASE(15)
# endif
}
#else /* !LARGE_INSTRUCTION_CACHE */
IMPORTANT_START
IMPORTANT_START
if (x1_or_len & 1)
body
x1_or_len >>= 1;
while (x1_or_len--) {
body body
}
IMPORTANT_END
IMPORTANT_END
#endif /* LARGE_INSTRUCTION_CACHE */
#ifdef POLYSEGMENT
#if PSZ == 24
body_rop
#else
RROP_SOLID(addrp);
#endif
#endif
#if PSZ == 24
addrp = (PixelType *)((unsigned long)addrb & ~0x03);
#endif
}
#undef body
#ifdef POLYSEGMENT
}
else /* Polysegment horizontal line optimization */
{
# ifdef REARRANGE
register int e3;
RROP_DECLARE
RROP_FETCH_GCPRIV(devPriv);
# endif /* REARRANGE */
if (stepmajor < 0)
{
#if PSZ == 24
xOffset -= x1_or_len;
addrp = addrLineEnd + PXL2ADR(xOffset);
#else
addrp -= x1_or_len;
#endif
if (capStyle)
x1_or_len++;
else
#if PSZ == 24
xOffset++;
addrp = addrLineEnd + PXL2ADR(xOffset);
#else
addrp++;
#endif
}
else
{
#if PSZ == 24
addrp = addrLineEnd + PXL2ADR(xOffset);
#endif
if (capStyle)
x1_or_len++;
}
# if PSZ == 24
y1_or_e1 = xOffset & 3;
# else
# if PGSZ == 64 /* PIM value from <cfbmskbits.h> is not it! (for 16/32 PSZ)*/
y1_or_e1 = ((long) addrp) & 0x7;
addrp = (PixelType *) (((unsigned char *) addrp) - y1_or_e1);
# else
y1_or_e1 = ((long) addrp) & PIM;
addrp = (PixelType *) (((unsigned char *) addrp) - y1_or_e1);
# endif
#if PGSZ == 32
# if PWSH != 2
y1_or_e1 >>= (2 - PWSH);
# endif
#else /* PGSZ == 64 */
# if PWSH != 3
y1_or_e1 >>= (3 - PWSH);
# endif
#endif /* PGSZ */
# endif /* PSZ == 24 */
#if PSZ == 24
{
#if RROP == GXcopy
register int nlmiddle;
int leftIndex = xOffset & 3;
int rightIndex = (xOffset + x1_or_len) & 3;
#else
register int pidx;
#endif
#if RROP == GXcopy
nlmiddle = x1_or_len;
if(leftIndex){
nlmiddle -= (4 - leftIndex);
}
if(rightIndex){
nlmiddle -= rightIndex;
}
nlmiddle >>= 2;
switch(leftIndex+x1_or_len){
case 4:
switch(leftIndex){
case 0:
*addrp++ = piQxelXor[0];
*addrp++ = piQxelXor[1];
*addrp = piQxelXor[2];
break;
case 1:
*addrp = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
addrp++;
*addrp = piQxelXor[1];
addrp++;
*addrp = piQxelXor[2];
break;
case 2:
*addrp = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
addrp++;
*addrp = piQxelXor[2];
break;
case 3:
*addrp = ((*addrp) & 0xFF) | (piQxelXor[2] & 0xFFFFFF00);
break;
}
break;
case 3:
switch(leftIndex){
case 0:
*addrp++ = piQxelXor[0];
*addrp++ = piQxelXor[1];
*addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
break;
case 1:
*addrp = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
addrp++;
*addrp = piQxelXor[1];
addrp++;
*addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
break;
case 2:
*addrp = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
addrp++;
*addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
break;
}
break;
case 2:
switch(leftIndex){
/*
case 2:
*addrp = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
addrp++;
*addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
break;
*/
case 1:
*addrp = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
addrp++;
*addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
break;
case 0:
*addrp++ = piQxelXor[0];
*addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
break;
}
break;
case 1: /*only if leftIndex = 0 and w = 1*/
if(x1_or_len){
*addrp = ((*addrp) & 0xFF000000) | (piQxelXor[0] & 0xFFFFFF);
}
/*
else{
*addrp = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
addrp++;
*addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
}
*/
break;
case 0: /*never*/
break;
default:
{
/*
maskbits(y1_or_e1, x1_or_len, e, e3, x1_or_len)
*/
switch(leftIndex){
case 0:
break;
case 1:
*addrp = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
addrp++;
*addrp = piQxelXor[1];
addrp++;
*addrp = piQxelXor[2];
addrp++;
break;
case 2:
*addrp = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
addrp++;
*addrp = piQxelXor[2];
addrp++;
break;
case 3:
*addrp = ((*addrp) & 0xFF) | (piQxelXor[2] & 0xFFFFFF00);
addrp++;
break;
}
while(nlmiddle--){
*addrp++ = piQxelXor[0];
*addrp++ = piQxelXor[1];
*addrp++ = piQxelXor[2];
}
switch(rightIndex++){
case 0:
break;
case 1:
*addrp = ((*addrp) & 0xFF000000) | (piQxelXor[0] & 0xFFFFFF);
break;
case 2:
*addrp++ = piQxelXor[0];
*addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
break;
case 3:
*addrp++ = piQxelXor[0];
*addrp++ = piQxelXor[1];
*addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
break;
}
/*
if (e3){
e3 &= 0xFFFFFF;
switch(rightIndex&3){
case 0:
*addrp = ((*addrp) & (0xFF000000 | ~e3))
| (piQxelXor[0] & 0xFFFFFF & e3);
break;
case 1:
*addrp = ((*addrp) & (0xFFFFFF | ~(e3<<24)))
+ (piQxelXor[0] & 0xFF000000 & (e3<<24));
addrp++;
*addrp = ((*addrp) & (0xFFFF0000|~(e3 >> 8)))
| (piQxelXor[1] & 0xFFFF & (e3 >> 8));
break;
case 2:
*addrp = ((*addrp) & (0xFFFF|~(e3 << 16)))
| (piQxelXor[1] & 0xFFFF0000 & (e3 << 16));
addrp++;
*addrp = ((*addrp) & (0xFFFFFF00|~(e3>>16)))
| (piQxelXor[2] & 0xFF & (e3 >> 16));
break;
case 3:
*addrp = ((*addrp) & (0xFF|~(e3<<8)))
| (piQxelXor[2] & 0xFFFFFF00 & (e3<<8));
addrp++;
break;
}
}
*/
}
}
#else /* GXcopy */
addrp = (PixelType *)((char *)addrLineEnd + ((xOffset * 3) & ~0x03));
if (x1_or_len <= 1){
if (x1_or_len)
RROP_SOLID24(addrp, xOffset);
} else {
maskbits(xOffset, x1_or_len, e, e3, x1_or_len);
pidx = xOffset & 3;
if (e){
RROP_SOLID_MASK(addrp, e, pidx-1);
addrp++;
if (pidx == 3)
pidx = 0;
}
while (--x1_or_len >= 0){
RROP_SOLID(addrp, pidx);
addrp++;
if (++pidx == 3)
pidx = 0;
}
if (e3)
RROP_SOLID_MASK(addrp, e3, pidx);
}
#endif /* GXcopy */
}
#else /* PSZ == 24 */
if (y1_or_e1 + x1_or_len <= PPW)
{
if (x1_or_len)
{
maskpartialbits(y1_or_e1, x1_or_len, e)
RROP_SOLID_MASK((CfbBits *) addrp, e);
}
}
else
{
maskbits(y1_or_e1, x1_or_len, e, e3, x1_or_len)
if (e)
{
RROP_SOLID_MASK((CfbBits *) addrp, e);
addrp += PPW;
}
RROP_SPAN(addrp, x1_or_len)
if (e3)
RROP_SOLID_MASK((CfbBits *) addrp, e3);
}
#endif /* PSZ == 24 */
}
#endif /* POLYSEGMENT */
}
#ifdef POLYSEGMENT
if (nseg >= 0)
return (xSegment *) ppt - pSegInit;
#else
if (npt)
{
#ifdef EITHER_MODE
if (!mode)
#endif /* EITHER_MODE */
#ifndef ORIGIN
{
*x1p = _x1;
*y1p = _y1;
*x2p = _x2;
*y2p = _y2;
}
#endif /* !ORIGIN */
return ((DDXPointPtr) ppt - pptInit) - 1;
}
# ifndef ORIGIN
# define C2 c2
# else
# define C2 ppt[-1]
# endif
#ifdef EITHER_MODE
if (pGC->capStyle != CapNotLast &&
((mode ? (C2 != *((int *) pptInitOrig))
: ((_x2 != pptInitOrig->x) ||
(_y2 != pptInitOrig->y)))
|| (ppt == ((int *)pptInitOrig) + 2)))
#endif /* EITHER_MODE */
#ifdef PREVIOUS
if (pGC->capStyle != CapNotLast &&
((_x2 != pptInitOrig->x) ||
(_y2 != pptInitOrig->y) ||
(ppt == ((int *)pptInitOrig) + 2)))
#endif /* PREVIOUS */
#ifdef ORIGIN
if (pGC->capStyle != CapNotLast &&
((C2 != *((int *) pptInitOrig)) ||
(ppt == ((int *)pptInitOrig) + 2)))
#endif /* !PREVIOUS */
{
# ifdef REARRANGE
RROP_DECLARE
RROP_FETCH_GCPRIV(devPriv);
# endif
#if PSZ == 24
#if RROP == GXcopy
switch(xOffset & 3){
case 0:
*addrp = ((*addrp)&0xFF000000)|(piQxelXor[0] & 0xFFFFFF);
break;
case 3:
*addrp = ((*addrp)&0xFF)|(piQxelXor[2] & 0xFFFFFF00);
break;
case 1:
*addrp = ((*addrp)&0xFFFFFF)|(piQxelXor[0] & 0xFF000000);
*(addrp+1) = ((*(addrp+1))&0xFFFF0000)|(piQxelXor[1] & 0xFFFF);
break;
case 2:
*addrp = ((*addrp)&0xFFFF)|(piQxelXor[1] & 0xFFFF0000);
*(addrp+1) = ((*(addrp+1))&0xFFFFFF00)|(piQxelXor[2] & 0xFF);
break;
}
#endif
#if RROP == GXxor
switch(xOffset & 3){
case 0:
*addrp ^= (piQxelXor[0] & 0xFFFFFF);
break;
case 3:
*addrp ^= (piQxelXor[2] & 0xFFFFFF00);
break;
case 1:
*addrp ^= (piQxelXor[0] & 0xFF000000);
*(addrp+1) ^= (piQxelXor[1] & 0xFFFF);
break;
case 2:
*addrp ^= (piQxelXor[1] & 0xFFFF0000);
*(addrp+1) ^= (piQxelXor[2] & 0xFF);
break;
}
#endif
#if RROP == GXand
switch(xOffset & 3){
case 0:
*addrp &= (piQxelAnd[0] | 0xFF000000);
break;
case 3:
*addrp &= (piQxelAnd[2] | 0xFF);
break;
case 1:
*addrp &= (0xFFFFFF|piQxelAnd[0]);
*(addrp+1) &= (0xFFFF0000|piQxelAnd[1]);
break;
case 2:
*addrp &= (0xFFFF|piQxelAnd[1]);
*(addrp+1) &= (0xFFFFFF00|piQxelAnd[2]);
break;
}
#endif
#if RROP == GXor
switch(xOffset & 3){
case 0:
*addrp |= (piQxelOr[0] & 0xFFFFFF);
break;
case 3:
*addrp |= (piQxelOr[2] & 0xFFFFFF00);
break;
case 1:
*addrp |= (piQxelOr[0] & 0xFF000000);
*(addrp+1) |= (piQxelOr[1] & 0xFFFF);
break;
case 2:
*addrp |= (piQxelOr[1] & 0xFFFF0000);
*(addrp+1) |= (piQxelOr[2] & 0xFF);
break;
}
#endif
#if RROP == GXset
switch(xOffset & 3){
case 0:
*addrp = (((*addrp)&(piQxelAnd[0] |0xFF000000))^(piQxelXor[0] & 0xFFFFFF));
break;
case 3:
*addrp = (((*addrp)&(piQxelAnd[2]|0xFF))^(piQxelXor[2] & 0xFFFFFF00));
break;
case 1:
*addrp = (((*addrp)&(piQxelAnd[0]|0xFFFFFF))^(piQxelXor[0] & 0xFF000000));
*(addrp+1) = (((*(addrp+1))&(piQxelAnd[1]|0xFFFF0000))^(piQxelXor[1] & 0xFFFF));
break;
case 2:
*addrp = (((*addrp)&(piQxelAnd[1]|0xFFFF))^(piQxelXor[1] & 0xFFFF0000));
*(addrp+1) = (((*(addrp+1))&(piQxelAnd[2]|0xFFFFFF00))^(piQxelXor[2] & 0xFF));
break;
}
#endif
#else
RROP_SOLID (addrp);
# endif
}
#endif /* !POLYSEGMENT */
RROP_UNDECLARE;
return -1;
}
#endif /* INCLUDE_DRAW */
#ifdef INCLUDE_OTHERS
#ifdef POLYSEGMENT
void
cfb8SegmentSS1Rect (pDrawable, pGC, nseg, pSegInit)
DrawablePtr pDrawable;
GCPtr pGC;
int nseg;
xSegment *pSegInit;
{
int (*func)(DrawablePtr, GCPtr, int, xSegment *);
void (*clip)(DrawablePtr, GCPtr, int, int, int, int, BoxPtr, Bool);
int drawn;
cfbPrivGCPtr devPriv;
#if defined(__arm32__) && PSZ != 8
/* XXX -JJK */
/* There is a painting bug when PSZ != 8; I need to track it down! */
cfbSegmentSS(pDrawable, pGC, nseg, pSegInit);
return;
#endif
devPriv = cfbGetGCPrivate(pGC);
#ifdef NO_ONE_RECT
if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1)
{
cfbSegmentSS(pDrawable, pGC, nseg, pSegInit);
return;
}
#endif
switch (devPriv->rop)
{
case GXcopy:
func = cfb8SegmentSS1RectCopy;
clip = cfb8ClippedLineCopy;
#ifdef FAST_MUL
if (cfbGetPixelWidth (pDrawable) == WIDTH_FAST)
func = cfb8SegmentSS1RectShiftCopy;
#endif
break;
case GXxor:
func = cfb8SegmentSS1RectXor;
clip = cfb8ClippedLineXor;
break;
default:
func = cfb8SegmentSS1RectGeneral;
clip = cfb8ClippedLineGeneral;
break;
}
while (nseg)
{
drawn = (*func) (pDrawable, pGC, nseg, pSegInit);
if (drawn == -1)
break;
(*clip) (pDrawable, pGC,
pSegInit[drawn-1].x1, pSegInit[drawn-1].y1,
pSegInit[drawn-1].x2, pSegInit[drawn-1].y2,
&pGC->pCompositeClip->extents,
pGC->capStyle == CapNotLast);
pSegInit += drawn;
nseg -= drawn;
}
}
#else /* POLYSEGMENT */
void
cfb8LineSS1Rect (pDrawable, pGC, mode, npt, pptInit)
DrawablePtr pDrawable;
GCPtr pGC;
int mode;
int npt;
DDXPointPtr pptInit;
{
int (*func)(DrawablePtr, GCPtr, int, int,
DDXPointPtr, DDXPointPtr,
int *, int *, int *, int *);
void (*clip)(DrawablePtr, GCPtr, int, int, int, int, BoxPtr, Bool);
int drawn;
cfbPrivGCPtr devPriv;
int x1, y1, x2, y2;
DDXPointPtr pptInitOrig = pptInit;
#if defined(__arm32__) && PSZ != 8
/* XXX -JJK */
/* There is a painting bug when PSZ != 8; I need to track it down! */
cfbLineSS(pDrawable, pGC, mode, npt, pptInit);
return;
#endif
devPriv = cfbGetGCPrivate(pGC);
#ifdef NO_ONE_RECT
if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1)
{
cfbLineSS(pDrawable, pGC, mode, npt, pptInit);
return;
}
#endif
switch (devPriv->rop)
{
case GXcopy:
func = cfb8LineSS1RectCopy;
clip = cfb8ClippedLineCopy;
if (mode == CoordModePrevious)
func = cfb8LineSS1RectPreviousCopy;
break;
case GXxor:
func = cfb8LineSS1RectXor;
clip = cfb8ClippedLineXor;
break;
default:
func = cfb8LineSS1RectGeneral;
clip = cfb8ClippedLineGeneral;
break;
}
if (mode == CoordModePrevious)
{
x1 = pptInit->x;
y1 = pptInit->y;
while (npt > 1)
{
drawn = (*func) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig,
&x1, &y1, &x2, &y2);
if (drawn == -1)
break;
(*clip) (pDrawable, pGC, x1, y1, x2, y2,
&pGC->pCompositeClip->extents,
drawn != npt - 1 || pGC->capStyle == CapNotLast);
pptInit += drawn;
npt -= drawn;
x1 = x2;
y1 = y2;
}
}
else
{
while (npt > 1)
{
drawn = (*func) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig,
&x1, &y1, &x2, &y2);
if (drawn == -1)
break;
(*clip) (pDrawable, pGC,
pptInit[drawn-1].x, pptInit[drawn-1].y,
pptInit[drawn].x, pptInit[drawn].y,
&pGC->pCompositeClip->extents,
drawn != npt - 1 || pGC->capStyle == CapNotLast);
pptInit += drawn;
npt -= drawn;
}
}
}
#endif /* else POLYSEGMENT */
#endif /* INCLUDE_OTHERS */
#if !defined(POLYSEGMENT) && !defined (PREVIOUS)
void
RROP_NAME (cfb8ClippedLine) (pDrawable, pGC, x1, y1, x2, y2, boxp, shorten)
DrawablePtr pDrawable;
GCPtr pGC;
int x1, y1, x2, y2;
BoxPtr boxp;
Bool shorten;
{
int oc1, oc2;
int e, e1, e3, len;
int adx, ady;
PixelType *addr;
int nwidth;
int stepx, stepy;
int xorg, yorg;
int new_x1, new_y1, new_x2, new_y2;
Bool pt1_clipped, pt2_clipped;
int changex, changey, result;
#if PSZ == 24
PixelType *addrLineEnd;
char *addrb;
int stepx3, stepy3;
#endif
int octant;
unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
cfbGetPixelWidthAndPointer(pDrawable, nwidth, addr);
xorg = pDrawable->x;
yorg = pDrawable->y;
x1 += xorg;
y1 += yorg;
x2 += xorg;
y2 += yorg;
oc1 = 0;
oc2 = 0;
OUTCODES (oc1, x1, y1, boxp);
OUTCODES (oc2, x2, y2, boxp);
if (oc1 & oc2)
return;
CalcLineDeltas(x1, y1, x2, y2, adx, ady, stepx, stepy, 1, nwidth, octant);
if (adx <= ady)
{
int t;
t = adx;
adx = ady;
ady = t;
t = stepx;
stepx = stepy;
stepy = t;
SetYMajorOctant(octant);
}
e = - adx;
e1 = ady << 1;
e3 = - (adx << 1);
FIXUP_ERROR(e, octant, bias);
new_x1 = x1;
new_y1 = y1;
new_x2 = x2;
new_y2 = y2;
pt1_clipped = 0;
pt2_clipped = 0;
if (IsXMajorOctant(octant))
{
result = miZeroClipLine(boxp->x1, boxp->y1, boxp->x2 - 1, boxp->y2 - 1,
&new_x1, &new_y1, &new_x2, &new_y2,
adx, ady,
&pt1_clipped, &pt2_clipped,
octant, bias, oc1, oc2);
if (result == -1)
return;
len = abs(new_x2 - new_x1) - 1; /* this routine needs the "-1" */
/* if we've clipped the endpoint, always draw the full length
* of the segment, because then the capstyle doesn't matter
* if x2,y2 isn't clipped, use the capstyle
* (shorten == TRUE <--> CapNotLast)
*/
if (pt2_clipped || !shorten)
len++;
if (pt1_clipped)
{
/* must calculate new error terms */
changex = abs(new_x1 - x1);
changey = abs(new_y1 - y1);
e = e + changey * e3 + changex * e1;
}
}
else /* Y_AXIS */
{
result = miZeroClipLine(boxp->x1, boxp->y1, boxp->x2 - 1, boxp->y2 - 1,
&new_x1, &new_y1, &new_x2, &new_y2,
ady, adx,
&pt1_clipped, &pt2_clipped,
octant, bias, oc1, oc2);
if (result == -1)
return;
len = abs(new_y2 - new_y1) - 1; /* this routine needs the "-1" */
/* if we've clipped the endpoint, always draw the full length
* of the segment, because then the capstyle doesn't matter
* if x2,y2 isn't clipped, use the capstyle
* (shorten == TRUE <--> CapNotLast)
*/
if (pt2_clipped || !shorten)
len++;
if (pt1_clipped)
{
/* must calculate new error terms */
changex = abs(new_x1 - x1);
changey = abs(new_y1 - y1);
e = e + changex * e3 + changey * e1;
}
}
x1 = new_x1;
y1 = new_y1;
{
register PixelType *addrp;
RROP_DECLARE
RROP_FETCH_GC(pGC);
#if PSZ == 24
addrLineEnd = addr + (y1 * nwidth);
addrb = (char *)addrLineEnd + x1 * 3;
if (stepx == 1 || stepx == -1){
stepx3 = stepx * 3;
stepy3 = stepy * sizeof (CfbBits);
} else {
stepx3 = stepx * sizeof (CfbBits);
stepy3 = stepy * 3;
}
#else
addrp = addr + (y1 * nwidth) + x1;
#endif
#ifndef REARRANGE
if (!ady)
{
#if PSZ == 24
#define body {\
body_rop \
addrb += stepx3; \
}
#else
#define body { RROP_SOLID(addrp); addrp += stepx; }
#endif
while (len >= PGSZB)
{
body body body body
#if PGSZ == 64
body body body body
#endif
len -= PGSZB;
}
switch (len)
{
#if PGSZ == 64
case 7: body case 6: body case 5: body case 4: body
#endif
case 3: body case 2: body case 1: body
}
#undef body
}
else
#endif /* !REARRANGE */
{
#if PSZ == 24
#define body {\
body_rop \
addrb += stepx3; \
e += e1; \
if (e >= 0) \
{ \
addrb += stepy3; \
e += e3; \
} \
}
#else
#define body {\
RROP_SOLID(addrp); \
addrp += stepx; \
e += e1; \
if (e >= 0) \
{ \
addrp += stepy; \
e += e3; \
} \
}
#endif
#ifdef LARGE_INSTRUCTION_CACHE
while ((len -= PGSZB) >= 0)
{
body body body body
#if PGSZ == 64
body body body body
#endif
}
switch (len)
{
case -1: body case -2: body case -3: body
#if PGSZ == 64
case -4: body case -5: body case -6: body case -7: body
#endif
}
#else /* !LARGE_INSTRUCTION_CACHE */
IMPORTANT_START;
while ((len -= 2) >= 0)
{
body body;
}
if (len & 1)
body;
IMPORTANT_END;
#endif /* LARGE_INSTRUCTION_CACHE */
}
#if PSZ == 24
body_rop
#else
RROP_SOLID(addrp);
#endif
#undef body
RROP_UNDECLARE
}
}
#endif /* !POLYSEGMENT && !PREVIOUS */
#endif /* PIXEL_ADDR */
|