diff options
Diffstat (limited to 'cfb/cfb8line.c')
-rw-r--r-- | cfb/cfb8line.c | 915 |
1 files changed, 915 insertions, 0 deletions
diff --git a/cfb/cfb8line.c b/cfb/cfb8line.c new file mode 100644 index 000000000..7a5f1ac5d --- /dev/null +++ b/cfb/cfb8line.c @@ -0,0 +1,915 @@ +/* + * $Xorg: cfb8line.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ + * +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 + */ + +#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 + +#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; + 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 */ + addr = addr + WIDTH_MUL(pDrawable->y,nwidth) + pDrawable->x; +#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; + } + addrp = addr + WIDTH_MUL(_y1, nwidth) + _x1; + _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 + addrp = addr + WIDTH_MUL(Y2, nwidth) + X2; + } +#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 */ + addrp = addr + WIDTH_MUL(y1_or_e1, nwidth) + x1_or_len; +#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; + + if (_x2 < extents_x1 || _x2 >= extents_x2 || + _y2 < extents_y1 || _y2 >= extents_y2) + { + 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); + +#define body {\ + RROP_SOLID(addrp); \ + addrp += stepmajor; \ + e += y1_or_e1; \ + if (e >= 0) \ + { \ + addrp += stepminor; \ + e += e3; \ + } \ + } + +#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 + RROP_SOLID(addrp); +#endif + } +#undef body +#ifdef POLYSEGMENT + } + else + { +# ifdef REARRANGE + register int e3; + RROP_DECLARE + RROP_FETCH_GCPRIV(devPriv); +# endif /* REARRANGE */ + if (stepmajor < 0) + { + addrp -= x1_or_len; + if (capStyle) + x1_or_len++; + else + addrp++; + } + else + { + if (capStyle) + x1_or_len++; + } + y1_or_e1 = ((int) addrp) & PIM; + addrp = (PixelType *) (((unsigned char *) addrp) - y1_or_e1); +#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 */ + 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; + } + RROP_SPAN(addrp, x1_or_len) + if (e3) + RROP_SOLID_MASK((unsigned long *) addrp, e3); + } + } +#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 + RROP_SOLID (addrp); + } +#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; + 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); + + addrp = addr + (y1 * nwidth) + x1; + +#ifndef REARRANGE + if (!ady) + { +#define body { RROP_SOLID(addrp); addrp += stepx; } + 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 */ + { +#define body {\ + RROP_SOLID(addrp); \ + addrp += stepx; \ + e += e1; \ + if (e >= 0) \ + { \ + addrp += stepy; \ + e += e3; \ + } \ + } + +#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 */ + } + RROP_SOLID(addrp); +#undef body + } +} + +#endif /* !POLYSEGMENT && !PREVIOUS */ +#endif /* PIXEL_ADDR */ |