]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/programs/Xserver/cfb/cfb8line.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfb8line.c
diff --git a/Xserver/programs/Xserver/cfb/cfb8line.c b/Xserver/programs/Xserver/cfb/cfb8line.c
new file mode 100644 (file)
index 0000000..34bb600
--- /dev/null
@@ -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 */