X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=blobdiff_plain;f=Xserver%2Fprograms%2FXserver%2Fcfb%2Fcfb8line.c;fp=Xserver%2Fprograms%2FXserver%2Fcfb%2Fcfb8line.c;h=34bb6000b3650d480b4d9e1c1544cb82842c1f29;hp=0000000000000000000000000000000000000000;hb=b6e6afccf37f4ad0515ef2a698f714fdf1bf23b3;hpb=e3340a110a3b01756b8e67531395a33b40a17d37 diff --git a/Xserver/programs/Xserver/cfb/cfb8line.c b/Xserver/programs/Xserver/cfb/cfb8line.c new file mode 100644 index 0000000..34bb600 --- /dev/null +++ b/Xserver/programs/Xserver/cfb/cfb8line.c @@ -0,0 +1,1458 @@ +/* + * $TOG: cfb8line.c /main/33 1997/07/17 19:33:47 kaleb $ + * +Copyright (c) 1990 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +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 +X CONSORTIUM 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 X Consortium 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 X Consortium. + * + * Author: Keith Packard, MIT X Consortium + * + * $XFree86: xc/programs/Xserver/cfb/cfb8line.c,v 3.2.2.3 1997/07/19 04:59:19 dawes Exp $ + * Jeff Anton'x fixes: cfb8line.c 97/02/07 + */ + +#include "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 + +# ifdef sun +# 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 /* POLYSEGEMENT */ +{ + 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 +#ifndef ORIGIN + register int _x1, _y1, _x2, _y2; /* only used for CoordModePrevious */ + 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 */ + int xOffset_t; /* x of t */ + PixelType *addrLineEnd; + char *addrb; + int stepmajor3, stepminor3, majordx, minordx; +#endif +#ifdef BUGFIX_clip + int ex_x1, ex_y1, ex_x2, ex_y2; +#endif + int octant; + unsigned int bias = miGetZeroLineBias(pDrawable->pScreen); + + devPriv = cfbGetGCPrivate(pGC); + cfbGetPixelWidthAndPointer (pDrawable, nwidth, addr); +#ifndef REARRANGE + RROP_FETCH_GCPRIV(devPriv); +#endif + extents = &devPriv->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 */ +#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 +#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 (long); + majordx = stepmajor; minordx = 0; + } else { + stepmajor3 = stepmajor * sizeof (long); + 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 + { +# 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 + /* Round addrp down to the next PixelGroup boundary, and + * set y1_or_e1 to the excess (in pixels) + * (assumes PGSZB is a power of 2). */ + y1_or_e1 = (((unsigned long) addrp) & (PGSZB - 1)) / (PSZ / 8); + addrp -= y1_or_e1; +# 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++ = piQxelXor[1]; + *addrp = piQxelXor[2]; + break; + case 2: + *addrp++ =((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000); + *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++ = piQxelXor[1]; + *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF); + break; + case 2: + *addrp++ =((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000); + *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF); + break; + } + break; + case 2: + switch(leftIndex){ +/* + case 2: + *addrp++ = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000); + *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF); + break; +*/ + case 1: + *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000); + *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) & 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++ = piQxelXor[1]; + *addrp++ = piQxelXor[2]; + break; + case 2: + *addrp++ = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000); + *addrp++ = piQxelXor[2]; + break; + case 3: + *addrp++ = ((*addrp) & 0xFF) | (piQxelXor[2] & 0xFFFFFF00); + 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) & (0xFFFF0000|~(e3 >> 8))) + | (piQxelXor[1] & 0xFFFF & (e3 >> 8)); + break; + case 2: + *addrp++ = ((*addrp) & (0xFFFF|~(e3 << 16))) + | (piQxelXor[1] & 0xFFFF0000 & (e3 << 16)); + *addrp = ((*addrp) & (0xFFFFFF00|~(e3>>16))) + | (piQxelXor[2] & 0xFF & (e3 >> 16)); + break; + case 3: + *addrp++ = ((*addrp) & (0xFF|~(e3<<8))) + | (piQxelXor[2] & 0xFFFFFF00 & (e3<<8)); + 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((unsigned long *) addrp, e); + } + } + else + { + maskbits(y1_or_e1, x1_or_len, e, e3, x1_or_len) + if (e) + { + RROP_SOLID_MASK((unsigned long *) addrp, e); + addrp += PPW; + } +#if 0 + RROP_SPAN_lu(addrp, x1_or_len) +#else + RROP_SPAN(addrp, x1_or_len) +#endif + if (e3) +#if 0 + RROP_SOLID_MASK_lu((unsigned long *) addrp, e3); +#else + RROP_SOLID_MASK((unsigned long *) addrp, e3); +#endif + } +#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; + } +#endif /* POLYSEGMENT */ + +#ifndef POLYSEGMENT +# 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 */ + 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)(); + void (*clip)(); + int drawn; + cfbPrivGCPtr devPriv; + + devPriv = cfbGetGCPrivate(pGC); +#ifdef NO_ONE_RECT + if (REGION_NUM_RECTS(devPriv->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, + &devPriv->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)(); + void (*clip)(); + int drawn; + cfbPrivGCPtr devPriv; + int x1, y1, x2, y2; + DDXPointPtr pptInitOrig = pptInit; + + devPriv = cfbGetGCPrivate(pGC); +#ifdef NO_ONE_RECT + if (REGION_NUM_RECTS(devPriv->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, + &devPriv->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, + &devPriv->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 + int xOffset; + 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 + xOffset = x1; + addrLineEnd = addr + (y1 * nwidth); + addrb = (char *)addrLineEnd + x1 * 3; + if (stepx == 1 || stepx == -1){ + stepx3 = stepx * 3; + stepy3 = stepy * sizeof (long); + } else { + stepx3 = stepx * sizeof (long); + 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 + } +} + +#endif /* !POLYSEGMENT && !PREVIOUS */ +#endif /* PIXEL_ADDR */