]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfb8line.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfb8line.c
1 /*
2  * $TOG: cfb8line.c /main/33 1997/07/17 19:33:47 kaleb $
3  *
4 Copyright (c) 1990  X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
26  *
27  * Author:  Keith Packard, MIT X Consortium
28  *
29  * $XFree86: xc/programs/Xserver/cfb/cfb8line.c,v 3.2.2.3 1997/07/19 04:59:19 dawes Exp $
30  * Jeff Anton'x fixes: cfb8line.c   97/02/07
31  */
32
33 #include "X.h"
34
35 #include "gcstruct.h"
36 #include "windowstr.h"
37 #include "pixmapstr.h"
38 #include "regionstr.h"
39 #include "scrnintstr.h"
40 #include "mistruct.h"
41
42 #include "cfb.h"
43 #include "cfbmskbits.h"
44 #include "cfbrrop.h"
45 #include "miline.h"
46
47 #ifdef PIXEL_ADDR
48
49 #if defined(__GNUC__) && defined(mc68020)
50 #define STUPID volatile
51 #define REARRANGE
52 #else
53 #define STUPID
54 #endif
55
56 #ifdef __GNUC__
57 /* lame compiler doesn't even look at 'register' attributes */
58 #define I_H do{
59 #define I_T }while(0);
60 #define IMPORTANT_START I_H I_H I_H I_H I_H I_H I_H I_H I_H I_H
61 #define IMPORTANT_END   I_T I_T I_T I_T I_T I_T I_T I_T I_T I_T
62 #else
63 #define IMPORTANT_START
64 #define IMPORTANT_END
65 #endif
66
67 #define isClipped(c,ul,lr)  ((((c) - (ul)) | ((lr) - (c))) & ClipMask)
68
69 #ifdef POLYSEGMENT
70
71 # ifdef sun
72 #  define WIDTH_FAST  1152
73 # endif
74
75 # ifdef ultrix
76 #  define WIDTH_FAST  1024
77 # endif
78
79 # ifdef Mips
80 #  define WIDTH_FAST 4096
81 # endif
82 # ifdef WIDTH_FAST
83 #  if WIDTH_FAST == 1024
84 #   define FAST_MUL(y)  ((y) << 10)
85 #  endif
86
87 #  if WIDTH_FAST == 1152
88 #   define FAST_MUL(y)  (((y) << 10) + ((y) << 7))
89 #  endif
90
91 #  if WIDTH_FAST == 1280
92 #   define FAST_MUL(y)  (((y) << 10) + ((y) << 8))
93 #  endif
94
95 #  if WIDTH_FAST == 2048
96 #   define FAST_MUL(y)  ((y) << 11)
97 #  endif
98
99 #  if WIDTH_FAST == 4096
100 #   define FAST_MUL(y)  ((y) << 12)
101 #  endif
102 # endif
103
104 # if defined(WIDTH_SHIFT)
105 #  ifdef FAST_MUL
106 #   define FUNC_NAME(e)     RROP_NAME(RROP_NAME_CAT(e,Shift))
107 #   if RROP == GXcopy
108 #    define INCLUDE_OTHERS
109 #    define SERIOUS_UNROLLING
110 #   endif
111 #   define INCLUDE_DRAW
112 #   define NWIDTH(nwidth)   WIDTH_FAST
113 #   define WIDTH_MUL(y,w)   FAST_MUL(y)
114 #  endif
115 # else
116 #  define FUNC_NAME(e)      RROP_NAME(e)
117 #  define WIDTH_MUL(y,w)    ((y) * (w))
118 #  define NWIDTH(nwidth)    (nwidth)
119 #  define INCLUDE_DRAW
120 #  if !defined (FAST_MUL) && RROP == GXcopy
121 #   define INCLUDE_OTHERS
122 #   define SERIOUS_UNROLLING
123 #  endif
124 # endif
125 #else
126
127 # define INCLUDE_DRAW
128 # define WIDTH_MUL(y,w) ((y) * (w))
129 # define NWIDTH(nwidth) nwidth
130 # ifdef PREVIOUS
131 #  define FUNC_NAME(e)  RROP_NAME(RROP_NAME_CAT(e,Previous))
132 # else
133 #  define FUNC_NAME(e)  RROP_NAME(e)
134 #  if RROP == GXcopy
135 #   define INCLUDE_OTHERS
136 #   ifdef PLENTIFUL_REGISTERS
137 #    define SAVE_X2Y2
138 #   endif
139 #   define ORIGIN
140 #   define SERIOUS_UNROLLING
141 #  else
142 #   define EITHER_MODE
143 #  endif
144 # endif
145 #endif
146
147 #if PSZ == 24
148 #define PXL2ADR(x)  ((x)*3 >> 2)
149
150 #if RROP == GXcopy
151 #define body_rop \
152             addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
153             switch((unsigned long)addrb & 3){ \
154             case 0: \
155               *addrp = (*addrp & 0xFF000000)|(piQxelXor[0] & 0xFFFFFF); \
156               break; \
157             case 1: \
158               *addrp = (*addrp & 0xFF)|(piQxelXor[2] & 0xFFFFFF00); \
159               break; \
160             case 3: \
161               *addrp = (*addrp & 0xFFFFFF)|(piQxelXor[0] & 0xFF000000); \
162               *(addrp+1)=(*(addrp+1) & 0xFFFF0000)|(piQxelXor[1] & 0xFFFF); \
163               break; \
164             case 2: \
165               *addrp = (*addrp & 0xFFFF)|(piQxelXor[1] & 0xFFFF0000); \
166               *(addrp+1)=(*(addrp+1) & 0xFFFFFF00)|(piQxelXor[2] & 0xFF); \
167               break; \
168             }
169 #endif
170 #if RROP == GXxor
171 #define body_rop \
172             addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
173             switch((unsigned long)addrb & 3){ \
174             case 0: \
175               *addrp ^= piQxelXor[0] & 0xFFFFFF; \
176               break; \
177             case 1: \
178               *addrp ^= piQxelXor[2] & 0xFFFFFF00; \
179               break; \
180             case 3: \
181               *addrp ^= piQxelXor[0] & 0xFF000000; \
182               *(addrp+1) ^= piQxelXor[1] & 0xFFFF; \
183               break; \
184             case 2: \
185               *addrp ^= piQxelXor[1] & 0xFFFF0000; \
186               *(addrp+1) ^= piQxelXor[2] & 0xFF; \
187               break; \
188             }
189 #endif
190 #if RROP == GXand
191 #define body_rop \
192             addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
193             switch((unsigned long)addrb & 3){ \
194             case 0: \
195               *addrp &= piQxelAnd[0] | 0xFF000000; \
196               break; \
197             case 1: \
198               *addrp &= piQxelAnd[2] | 0xFF; \
199               break; \
200             case 3: \
201               *addrp &= 0xFFFFFF | piQxelAnd[0]; \
202               *(addrp+1) &= 0xFFFF0000 | piQxelAnd[1]; \
203               break; \
204             case 2: \
205               *addrp &= 0xFFFF | piQxelAnd[1]; \
206               *(addrp+1) &= 0xFFFFFF00 | piQxelAnd[2]; \
207               break; \
208             }
209 #endif
210 #if RROP == GXor
211 #define body_rop \
212             addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
213             switch((unsigned long)addrb & 3){ \
214             case 0: \
215               *addrp |= piQxelOr[0] & 0xFFFFFF; \
216               break; \
217             case 1: \
218               *addrp |= piQxelOr[2] & 0xFFFFFF00; \
219               break; \
220             case 3: \
221               *addrp |= piQxelOr[0] & 0xFF000000; \
222               *(addrp+1) |= piQxelOr[1] & 0xFFFF; \
223               break; \
224             case 2: \
225               *addrp |= piQxelOr[1] & 0xFFFF0000; \
226               *(addrp+1) |= piQxelOr[2] & 0xFF; \
227               break; \
228             }
229 #endif
230 #if RROP == GXset
231 #define body_rop \
232             addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
233             switch((unsigned long)addrb & 3){ \
234             case 0: \
235               *addrp = (*addrp & (piQxelAnd[0]|0xFF000000)) \
236                         ^ (piQxelXor[0] & 0xFFFFFF); \
237               break; \
238             case 1: \
239               *addrp = (*addrp & (piQxelAnd[2]|0xFF)) \
240                         ^ (piQxelXor[2] & 0xFFFFFF00); \
241               break; \
242             case 3: \
243               *addrp = (*addrp & (piQxelAnd[0]|0xFFFFFF)) \
244                         ^ (piQxelXor[0] & 0xFF000000); \
245               *(addrp+1) = (*(addrp+1) & (piQxelAnd[1]|0xFFFF0000)) \
246                         ^ (piQxelXor[1] & 0xFFFF); \
247               break; \
248             case 2: \
249               *addrp = (*addrp & (piQxelAnd[1]|0xFFFF)) \
250                         ^ (piQxelXor[1] & 0xFFFF0000); \
251               *(addrp+1) = (*(addrp+1) & (piQxelAnd[2]|0xFFFFFF00)) \
252                         ^ (piQxelXor[2] & 0xFF); \
253               break; \
254             }
255 #endif
256 #endif /* PSZ == 24 */
257
258 #define BUGFIX_clip
259
260 #ifdef INCLUDE_DRAW
261
262 int
263 #ifdef POLYSEGMENT
264 FUNC_NAME(cfb8SegmentSS1Rect) (pDrawable, pGC, nseg, pSegInit)
265     DrawablePtr pDrawable;
266     GCPtr       pGC;
267     int         nseg;
268     xSegment    *pSegInit;
269 #else
270 FUNC_NAME(cfb8LineSS1Rect) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig,
271                             x1p,y1p,x2p,y2p)
272     DrawablePtr pDrawable;
273     GCPtr       pGC;
274     int mode;           /* Origin or Previous */
275     int npt;            /* number of points */
276     DDXPointPtr pptInit, pptInitOrig;
277     int *x1p, *y1p, *x2p, *y2p;
278 #endif /* POLYSEGEMENT */
279 {
280     register long   e;
281     register int    y1_or_e1;
282     register PixelType   *addrp;
283     register int    stepmajor;
284     register int    stepminor;
285 #ifndef REARRANGE
286     register long   e3;
287 #endif
288 #ifdef mc68000
289     register short  x1_or_len;
290 #else
291     register int    x1_or_len;
292 #endif
293     RROP_DECLARE
294
295 #ifdef SAVE_X2Y2
296 # define c2 y2
297 #else
298     register int    c2;
299 #endif
300 #ifndef ORIGIN
301     register int _x1, _y1, _x2, _y2;    /* only used for CoordModePrevious */
302     int extents_x1, extents_y1, extents_x2, extents_y2;
303 #endif /* !ORIGIN */
304 #ifndef PREVIOUS
305     register int upperleft, lowerright;
306     CARD32       ClipMask = 0x80008000;
307 #endif /* !PREVIOUS */
308 #ifdef POLYSEGMENT
309     register int    capStyle;
310 #endif /* POLYSEGMENT */
311 #ifdef SAVE_X2Y2
312     register int    x2, y2;
313 # define X1  x1_or_len
314 # define Y1  y1_or_e1
315 # define X2  x2
316 # define Y2  y2
317 #else
318 # ifdef POLYSEGMENT
319 #  define X1  x1_or_len
320 #  define Y1  y1_or_e1
321 # else
322 #  define X1  intToX(y1_or_e1)
323 #  define Y1  intToY(y1_or_e1)
324 # endif /* POLYSEGMENT */
325 # define X2  intToX(c2)
326 # define Y2  intToY(c2)
327 #endif /* SAVE_X2Y2 */
328     PixelType   *addr;
329     int             nwidth;
330     cfbPrivGCPtr    devPriv;
331     BoxPtr          extents;
332     int             *ppt;
333 #if PSZ == 24
334     int xBase;     /* x of addr */
335     int xOffset;   /* x of addrp */
336     int xOffset_t; /* x of t */
337     PixelType   *addrLineEnd;
338     char *addrb;
339     int stepmajor3, stepminor3, majordx, minordx;
340 #endif
341 #ifdef BUGFIX_clip
342     int ex_x1, ex_y1, ex_x2, ex_y2;
343 #endif
344     int             octant;
345     unsigned int    bias = miGetZeroLineBias(pDrawable->pScreen);
346
347     devPriv = cfbGetGCPrivate(pGC);
348     cfbGetPixelWidthAndPointer (pDrawable, nwidth, addr);
349 #ifndef REARRANGE
350     RROP_FETCH_GCPRIV(devPriv);
351 #endif
352     extents = &devPriv->pCompositeClip->extents;
353 #ifndef PREVIOUS
354     c2 = *((int *) &pDrawable->x);
355     c2 -= (c2 & 0x8000) << 1;
356     upperleft = *((int *) &extents->x1) - c2;
357     lowerright = *((int *) &extents->x2) - c2 - 0x00010001;
358 #endif /* !PREVIOUS */
359 #ifdef BUGFIX_clip
360     ex_x1 = extents->x1 - pDrawable->x;
361     ex_y1 = extents->y1 - pDrawable->y;
362     ex_x2 = extents->x2 - pDrawable->x;
363     ex_y2 = extents->y2 - pDrawable->y;
364 #endif
365 #if PSZ == 24
366     xBase = pDrawable->x;
367     addr += WIDTH_MUL(pDrawable->y,nwidth);
368 #else
369     addr = addr + WIDTH_MUL(pDrawable->y,nwidth) + pDrawable->x;
370 #endif
371 #ifdef POLYSEGMENT
372     capStyle = pGC->capStyle - CapNotLast;
373     ppt = (int *) pSegInit;
374     while (nseg--)
375 #else /* POLYSEGMENT */
376 #ifdef EITHER_MODE
377     mode -= CoordModePrevious;
378     if (!mode)
379 #endif /* EITHER_MODE */        
380 #ifndef ORIGIN
381     {   /* CoordModePrevious */
382         ppt = (int *)pptInit + 1;
383         _x1 = *x1p;
384         _y1 = *y1p;
385         extents_x1 = extents->x1 - pDrawable->x;
386         extents_x2 = extents->x2 - pDrawable->x;
387         extents_y1 = extents->y1 - pDrawable->y;
388         extents_y2 = extents->y2 - pDrawable->y;
389         if (_x1 < extents_x1 || _x1 >= extents_x2 ||
390             _y1 < extents_y1 || _y1 >= extents_y2)
391         {
392             c2 = *ppt++;
393             intToCoord(c2, _x2, _y2);
394             *x2p = _x1 + _x2;
395             *y2p = _y1 + _y2;
396             return 1;
397         }
398 #if PSZ == 24
399         addrLineEnd = addr + WIDTH_MUL(_y1, nwidth);
400         xOffset = xBase + _x1;
401         addrb = (char *)addrLineEnd + xOffset * 3;
402         addrp = (PixelType *)((unsigned long)addrb & ~0x03);
403 #else
404         addrp = addr + WIDTH_MUL(_y1, nwidth) + _x1;
405 #endif
406         _x2 = _x1;
407         _y2 = _y1;      
408     }
409 #endif /* !ORIGIN */
410 #ifdef EITHER_MODE
411     else
412 #endif /* EITHER_MODE */
413 #ifndef PREVIOUS
414     {
415         ppt = (int *) pptInit;
416         c2 = *ppt++;
417         if (isClipped (c2, upperleft, lowerright))
418         {
419             return 1;
420         }
421 #ifdef SAVE_X2Y2
422         intToCoord(c2,x2,y2);
423 #endif
424 #if PSZ == 24
425         addrLineEnd = addr + WIDTH_MUL(Y2, nwidth);
426         xOffset = xBase + X2;
427         addrb = (char *)addrLineEnd + xOffset * 3;
428         addrp = (PixelType *)((unsigned long)addrb & ~0x03);
429 #else
430         addrp = addr + WIDTH_MUL(Y2, nwidth) + X2;
431 #endif
432     }
433 #endif /* !PREVIOUS */    
434     while (--npt)
435 #endif /* POLYSEGMENT */
436     {
437 #ifdef POLYSEGMENT
438         y1_or_e1 = ppt[0];
439         c2 = ppt[1];
440         ppt += 2;
441         if (isClipped(y1_or_e1,upperleft,lowerright)|isClipped(c2,upperleft,lowerright))
442             break;
443         intToCoord(y1_or_e1,x1_or_len,y1_or_e1);
444         /* compute now to avoid needing x1, y1 later */
445 #if PSZ == 24
446         addrLineEnd = addr + WIDTH_MUL(y1_or_e1, nwidth);
447         xOffset = xBase + x1_or_len;
448         addrb = (char *)addrLineEnd + xOffset * 3;
449         addrp = (PixelType *)((unsigned long)addrb & ~0x03);
450 #else
451         addrp = addr + WIDTH_MUL(y1_or_e1, nwidth) + x1_or_len;
452 #endif
453 #else /* !POLYSEGMENT */
454 #ifdef EITHER_MODE
455         if (!mode)
456 #endif /* EITHER_MODE */        
457 #ifndef ORIGIN
458         {       
459             /* CoordModePrevious */
460             _x1 = _x2;
461             _y1 = _y2;
462             c2 = *ppt++;
463             intToCoord(c2, _x2, _y2);
464             _x2 = _x1 + _x2;
465             _y2 = _y1 + _y2;
466
467 #ifdef BUGFIX_clip
468             if (_x2 < ex_x1 || _x2 >= ex_x2 ||
469                 _y2 < ex_y1 || _y2 >= ex_y2)
470 #else
471             if (_x2 < extents_x1 || _x2 >= extents_x2 ||
472                 _y2 < extents_y1 || _y2 >= extents_y2)
473 #endif
474             {
475                 break;
476             }
477             CalcLineDeltas(_x1, _y1, _x2, _y2, x1_or_len, y1_or_e1,
478                            stepmajor, stepminor, 1, NWIDTH(nwidth), octant);
479         }
480 #endif /* !ORIGIN */
481 #ifdef EITHER_MODE
482         else
483 #endif /* EITHER_MODE */
484 #ifndef PREVIOUS
485         {
486 #ifndef SAVE_X2Y2
487             y1_or_e1 = c2;
488 #else
489             y1_or_e1 = y2;
490             x1_or_len = x2;
491 #endif /* SAVE_X2Y2 */
492             c2 = *ppt++;
493
494             if (isClipped (c2, upperleft, lowerright))
495                 break;
496 #ifdef SAVE_X2Y2
497             intToCoord(c2,x2,y2);
498 #endif
499             CalcLineDeltas(X1, Y1, X2, Y2, x1_or_len, y1_or_e1,
500                            stepmajor, stepminor, 1, NWIDTH(nwidth), octant);
501         }
502 #endif /* !PREVIOUS */
503 #endif /* POLYSEGMENT */
504
505 #ifdef POLYSEGMENT
506         CalcLineDeltas(X1, Y1, X2, Y2, x1_or_len, y1_or_e1,
507                        stepmajor, stepminor, 1, NWIDTH(nwidth), octant);
508         /*
509          * although the horizontal code works for polyline, it
510          * slows down 10 pixel lines by 15%.  Thus, this
511          * code is optimized for horizontal segments and
512          * random orientation lines, which seems like a reasonable
513          * assumption
514          */
515         if (y1_or_e1 != 0)
516         {
517 #endif /* POLYSEGMENT */
518         if (x1_or_len < y1_or_e1)
519         {
520 #ifdef REARRANGE
521             register int        e3;
522 #endif
523
524             e3 = x1_or_len;
525             x1_or_len = y1_or_e1;
526             y1_or_e1 = e3;
527
528             e3 = stepminor;
529             stepminor = stepmajor;
530             stepmajor = e3;
531             SetYMajorOctant(octant);
532         }
533
534         e = -x1_or_len;
535 #ifdef POLYSEGMENT
536         if (!capStyle)
537             x1_or_len--;
538 #endif
539
540         {
541 #ifdef REARRANGE
542         register int e3;
543         RROP_DECLARE
544         RROP_FETCH_GCPRIV(devPriv);
545 #endif
546
547         y1_or_e1 = y1_or_e1 << 1;
548         e3 = e << 1;
549
550         FIXUP_ERROR(e, octant, bias);
551
552 #if PSZ == 24
553         if (stepmajor == 1  ||  stepmajor == -1){
554             stepmajor3 = stepmajor * 3;
555             stepminor3 = stepminor * sizeof (long);
556             majordx = stepmajor; minordx = 0;
557          } else {
558             stepmajor3 = stepmajor * sizeof (long);
559             stepminor3 = stepminor * 3;
560             majordx = 0; minordx = stepminor;
561          }
562 #endif
563  
564 #if PSZ == 24
565 #define body {\
566             body_rop \
567             addrb += stepmajor3; \
568              xOffset += majordx; \
569             e += y1_or_e1; \
570             if (e >= 0){ \
571                 addrb += stepminor3; \
572                  xOffset += minordx; \
573                 e += e3; \
574             } \
575         }
576 #else /* PSZ == 24 */
577
578 #define body {\
579             RROP_SOLID(addrp); \
580             addrp += stepmajor; \
581             e += y1_or_e1; \
582             if (e >= 0) \
583             { \
584                 addrp += stepminor; \
585                 e += e3; \
586              } \
587         }
588 #endif /* PSZ == 24 */
589
590 #ifdef LARGE_INSTRUCTION_CACHE
591
592 # ifdef SERIOUS_UNROLLING
593 #  define UNROLL        16
594 # else
595 #  define UNROLL        4
596 # endif
597 #define CASE(n) case -n: body
598
599         while ((x1_or_len -= UNROLL) >= 0)
600         {
601             body body body body
602 # if UNROLL >= 8
603             body body body body
604 # endif
605 # if UNROLL >= 12
606             body body body body
607 # endif
608 # if UNROLL >= 16
609             body body body body
610 # endif
611         }
612         switch (x1_or_len)
613         {
614         CASE(1) CASE(2) CASE(3)
615 # if UNROLL >= 8
616         CASE(4) CASE(5) CASE(6) CASE(7)
617 # endif
618 # if UNROLL >= 12
619         CASE(8) CASE(9) CASE(10) CASE(11)
620 # endif
621 # if UNROLL >= 16
622         CASE(12) CASE(13) CASE(14) CASE(15)
623 # endif
624         }
625 #else /* !LARGE_INSTRUCTION_CACHE */
626
627         IMPORTANT_START
628         IMPORTANT_START
629
630         if (x1_or_len & 1)
631             body
632         x1_or_len >>= 1;
633         while (x1_or_len--) {
634             body body
635         }
636
637         IMPORTANT_END
638         IMPORTANT_END
639 #endif /* LARGE_INSTRUCTION_CACHE */
640
641 #ifdef POLYSEGMENT
642 #if PSZ == 24
643         body_rop
644 #else
645         RROP_SOLID(addrp);
646 #endif
647 #endif
648 #if PSZ == 24
649         addrp = (PixelType *)((unsigned long)addrb & ~0x03);
650 #endif
651         }
652 #undef body
653 #ifdef POLYSEGMENT
654         }
655         else
656         {
657 # ifdef REARRANGE
658             register int    e3;
659             RROP_DECLARE
660             RROP_FETCH_GCPRIV(devPriv);
661 # endif /* REARRANGE */
662             if (stepmajor < 0)
663             {
664 #if PSZ == 24
665                 xOffset -= x1_or_len;
666                 addrp = addrLineEnd + PXL2ADR(xOffset);
667 #else
668                 addrp -= x1_or_len;
669 #endif
670                 if (capStyle)
671                     x1_or_len++;
672                 else
673 #if PSZ == 24
674                   xOffset++;
675                 addrp = addrLineEnd + PXL2ADR(xOffset);
676 #else
677                     addrp++;
678 #endif
679             }
680             else
681             {
682 #if PSZ == 24
683                 addrp = addrLineEnd + PXL2ADR(xOffset);
684 #endif
685                 if (capStyle)
686                     x1_or_len++;
687             }
688 # if PSZ == 24
689             y1_or_e1 = xOffset & 3;
690 # else
691             /* Round addrp down to the next PixelGroup boundary, and
692              * set y1_or_e1 to the excess (in pixels)
693              * (assumes PGSZB is a power of 2). */
694             y1_or_e1 = (((unsigned long) addrp) & (PGSZB - 1)) / (PSZ / 8);
695             addrp -= y1_or_e1;
696 # endif /* PSZ == 24 */
697 #if PSZ == 24
698             {
699 #if RROP == GXcopy
700               register int nlmiddle;
701               int leftIndex = xOffset & 3;
702               int rightIndex = (xOffset + x1_or_len) & 3;
703 #else
704               register int pidx;
705 #endif
706
707 #if RROP == GXcopy
708               nlmiddle = x1_or_len;
709               if(leftIndex){
710                 nlmiddle -= (4 - leftIndex);
711               }
712               if(rightIndex){
713                 nlmiddle -= rightIndex;
714               }
715               
716               nlmiddle >>= 2;
717               switch(leftIndex+x1_or_len){
718               case 4:
719                 switch(leftIndex){
720                 case 0:
721                   *addrp++ = piQxelXor[0];
722                   *addrp++ = piQxelXor[1];
723                   *addrp   = piQxelXor[2];
724                   break;
725                 case 1:
726                   *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
727                   *addrp++ = piQxelXor[1];
728                   *addrp   = piQxelXor[2];
729                   break;
730                 case 2:
731                   *addrp++ =((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
732                   *addrp = piQxelXor[2];
733                   break;
734                 case 3:
735                   *addrp =((*addrp) & 0xFF) | (piQxelXor[2] & 0xFFFFFF00);
736                   break;
737                 }
738                 break;
739               case 3:
740                 switch(leftIndex){
741                 case 0:
742                   *addrp++ = piQxelXor[0];
743                   *addrp++ = piQxelXor[1];
744                   *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
745                   break;
746                 case 1:
747                   *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
748                   *addrp++ = piQxelXor[1];
749                   *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
750                   break;
751                 case 2:
752                   *addrp++ =((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
753                   *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
754                   break;
755                 }
756                 break;
757               case 2:
758                 switch(leftIndex){
759 /*
760                 case 2:
761                   *addrp++ = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
762                   *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
763                   break;
764 */
765                 case 1:
766                   *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
767                   *addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
768                   break;
769                 case 0:
770                   *addrp++ =  piQxelXor[0];
771                   *addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
772                   break;
773                 }
774                 break;
775               case 1: /*only if leftIndex = 0 and w = 1*/
776                 if(x1_or_len){
777                 *addrp =  ((*addrp) & 0xFF000000) | (piQxelXor[0] & 0xFFFFFF);
778                 }
779 /*
780                 else{
781                 *addrp++ =  ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
782                 *addrp =  ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
783                 }
784 */
785                 break;
786               case 0: /*never*/
787                 break;
788               default:
789                 {
790 /*
791                   maskbits(y1_or_e1, x1_or_len, e, e3, x1_or_len)
792 */
793                   switch(leftIndex){
794                   case 0:
795                     break;
796                   case 1:
797                     *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
798                     *addrp++ = piQxelXor[1];
799                     *addrp++ = piQxelXor[2];
800                     break;
801                   case 2:
802                     *addrp++ = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
803                     *addrp++ = piQxelXor[2];
804                     break;
805                   case 3:
806                     *addrp++ = ((*addrp) & 0xFF) | (piQxelXor[2] & 0xFFFFFF00);
807                     break;
808                   }
809                   while(nlmiddle--){
810                     *addrp++ = piQxelXor[0];
811                     *addrp++ = piQxelXor[1];
812                     *addrp++ = piQxelXor[2];
813                   }
814                   switch(rightIndex++){
815                   case 0:
816                     break;
817                   case 1:
818                     *addrp = ((*addrp) & 0xFF000000) | (piQxelXor[0] & 0xFFFFFF);
819                     break;
820                   case 2:
821                     *addrp++ = piQxelXor[0];
822                     *addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
823                     break;
824                   case 3:
825                     *addrp++ = piQxelXor[0];
826                     *addrp++ = piQxelXor[1];
827                     *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
828                     break;
829                   }
830 /*
831                   if (e3){
832                     e3 &= 0xFFFFFF;
833                     switch(rightIndex&3){
834                     case 0:
835                       *addrp = ((*addrp) & (0xFF000000 | ~e3))
836                         | (piQxelXor[0] & 0xFFFFFF & e3);
837                       break;
838                     case 1:
839                       *addrp++ = ((*addrp) & (0xFFFFFF | ~(e3<<24)))
840                                   | (piQxelXor[0] & 0xFF000000 & (e3<<24));
841                       *addrp = ((*addrp) & (0xFFFF0000|~(e3 >> 8)))
842                                   | (piQxelXor[1] & 0xFFFF & (e3 >> 8));
843                       break;
844                     case 2:
845                       *addrp++ = ((*addrp) & (0xFFFF|~(e3 << 16)))
846                                   | (piQxelXor[1] & 0xFFFF0000 & (e3 << 16));
847                       *addrp = ((*addrp) & (0xFFFFFF00|~(e3>>16)))
848                                   | (piQxelXor[2] & 0xFF & (e3 >> 16));
849                       break;
850                     case 3:
851                       *addrp++ = ((*addrp) & (0xFF|~(e3<<8)))
852                                   | (piQxelXor[2] & 0xFFFFFF00 & (e3<<8));
853                       break;
854                     }
855                   }
856 */
857                 }
858               }
859 #else /* GXcopy */
860               addrp = (PixelType *)((char *)addrLineEnd + ((xOffset * 3) & ~0x03));
861               if (x1_or_len <= 1){
862                 if (x1_or_len)
863                   RROP_SOLID24(addrp, xOffset);
864               } else {
865                 maskbits(xOffset, x1_or_len, e, e3, x1_or_len);
866                 pidx = xOffset & 3;
867                 if (e){
868                   RROP_SOLID_MASK(addrp, e, pidx-1);
869                   addrp++;
870                   if (pidx == 3)
871                     pidx = 0;
872                 }
873                 while (--x1_or_len >= 0){
874                   RROP_SOLID(addrp, pidx);
875                   addrp++;
876                   if (++pidx == 3)
877                     pidx = 0;
878                 }
879                 if (e3)
880                   RROP_SOLID_MASK(addrp, e3, pidx);
881               }
882 #endif /* GXcopy */
883             }
884 #else /* PSZ == 24 */
885             if (y1_or_e1 + x1_or_len <= PPW)
886               {
887                 if (x1_or_len)
888                   {
889                     maskpartialbits(y1_or_e1, x1_or_len, e)
890                       RROP_SOLID_MASK((unsigned long *) addrp, e);
891                   }
892               }
893             else
894             {
895                 maskbits(y1_or_e1, x1_or_len, e, e3, x1_or_len)
896                 if (e)
897                 {
898                     RROP_SOLID_MASK((unsigned long *) addrp, e);
899                     addrp += PPW;
900                 }
901 #if 0
902                 RROP_SPAN_lu(addrp, x1_or_len)
903 #else
904                 RROP_SPAN(addrp, x1_or_len)
905 #endif
906                 if (e3)
907 #if 0
908                     RROP_SOLID_MASK_lu((unsigned long *) addrp, e3);
909 #else
910                     RROP_SOLID_MASK((unsigned long *) addrp, e3);
911 #endif
912             }
913 #endif /* PSZ == 24 */
914         }
915 #endif /* POLYSEGMENT */
916     }
917 #ifdef POLYSEGMENT
918     if (nseg >= 0)
919         return (xSegment *) ppt - pSegInit;
920 #else
921     if (npt)
922     {
923 #ifdef EITHER_MODE
924         if (!mode)
925 #endif /* EITHER_MODE */
926 #ifndef ORIGIN
927         {
928             *x1p = _x1;
929             *y1p = _y1;         
930             *x2p = _x2;
931             *y2p = _y2;
932         }
933 #endif /* !ORIGIN */        
934         return ((DDXPointPtr) ppt - pptInit) - 1;
935     }
936 #endif /* POLYSEGMENT */
937
938 #ifndef POLYSEGMENT
939 # ifndef ORIGIN
940 #  define C2  c2
941 # else
942 #  define C2  ppt[-1]
943 # endif
944 #ifdef EITHER_MODE
945     if (pGC->capStyle != CapNotLast &&
946         ((mode ? (C2 != *((int *) pptInitOrig))
947                : ((_x2 != pptInitOrig->x) ||
948                   (_y2 != pptInitOrig->y)))
949          || (ppt == ((int *)pptInitOrig) + 2)))
950 #endif /* EITHER_MODE */
951 #ifdef PREVIOUS
952     if (pGC->capStyle != CapNotLast &&
953         ((_x2 != pptInitOrig->x) ||
954          (_y2 != pptInitOrig->y) ||
955          (ppt == ((int *)pptInitOrig) + 2)))
956 #endif /* PREVIOUS */
957 #ifdef ORIGIN
958     if (pGC->capStyle != CapNotLast &&
959         ((C2 != *((int *) pptInitOrig)) ||
960          (ppt == ((int *)pptInitOrig) + 2)))
961 #endif /* !PREVIOUS */
962     {
963 # ifdef REARRANGE
964         RROP_DECLARE
965
966         RROP_FETCH_GCPRIV(devPriv);
967 # endif
968 #if PSZ == 24
969 #if RROP == GXcopy
970             switch(xOffset & 3){
971             case 0:
972               *addrp = ((*addrp)&0xFF000000)|(piQxelXor[0] & 0xFFFFFF);
973               break;
974             case 3:
975               *addrp = ((*addrp)&0xFF)|(piQxelXor[2] & 0xFFFFFF00);
976               break;
977             case 1:
978               *addrp = ((*addrp)&0xFFFFFF)|(piQxelXor[0] & 0xFF000000);
979               *(addrp+1) = ((*(addrp+1))&0xFFFF0000)|(piQxelXor[1] & 0xFFFF);
980               break;
981             case 2:
982               *addrp = ((*addrp)&0xFFFF)|(piQxelXor[1] & 0xFFFF0000);
983               *(addrp+1) = ((*(addrp+1))&0xFFFFFF00)|(piQxelXor[2] & 0xFF);
984               break;
985             }
986 #endif
987 #if RROP == GXxor
988             switch(xOffset & 3){
989             case 0:
990               *addrp ^= (piQxelXor[0] & 0xFFFFFF);
991               break;
992             case 3:
993               *addrp ^= (piQxelXor[2] & 0xFFFFFF00);
994               break;
995             case 1:
996               *addrp ^= (piQxelXor[0] & 0xFF000000);
997               *(addrp+1) ^= (piQxelXor[1] & 0xFFFF);
998               break;
999             case 2:
1000               *addrp ^= (piQxelXor[1] & 0xFFFF0000);
1001               *(addrp+1) ^= (piQxelXor[2] & 0xFF);
1002               break;
1003             }
1004 #endif
1005 #if RROP == GXand
1006             switch(xOffset & 3){
1007             case 0:
1008               *addrp &= (piQxelAnd[0] | 0xFF000000);
1009               break;
1010             case 3:
1011               *addrp &= (piQxelAnd[2] | 0xFF);
1012               break;
1013             case 1:
1014               *addrp &= (0xFFFFFF|piQxelAnd[0]);
1015               *(addrp+1) &= (0xFFFF0000|piQxelAnd[1]);
1016               break;
1017             case 2:
1018               *addrp &= (0xFFFF|piQxelAnd[1]);
1019               *(addrp+1) &= (0xFFFFFF00|piQxelAnd[2]);
1020               break;
1021             }
1022 #endif
1023 #if RROP == GXor
1024             switch(xOffset & 3){
1025             case 0:
1026               *addrp |= (piQxelOr[0] & 0xFFFFFF);
1027               break;
1028             case 3:
1029               *addrp |= (piQxelOr[2] & 0xFFFFFF00);
1030               break;
1031             case 1:
1032               *addrp |= (piQxelOr[0] & 0xFF000000);
1033               *(addrp+1) |= (piQxelOr[1] & 0xFFFF);
1034               break;
1035             case 2:
1036               *addrp |= (piQxelOr[1] & 0xFFFF0000);
1037               *(addrp+1) |= (piQxelOr[2] & 0xFF);
1038               break;
1039             }
1040 #endif
1041 #if RROP == GXset
1042             switch(xOffset & 3){
1043             case 0:
1044               *addrp = (((*addrp)&(piQxelAnd[0] |0xFF000000))^(piQxelXor[0] & 0xFFFFFF));
1045               break;
1046             case 3:
1047               *addrp = (((*addrp)&(piQxelAnd[2]|0xFF))^(piQxelXor[2] & 0xFFFFFF00));
1048               break;
1049             case 1:
1050               *addrp = (((*addrp)&(piQxelAnd[0]|0xFFFFFF))^(piQxelXor[0] & 0xFF000000));
1051               *(addrp+1) = (((*(addrp+1))&(piQxelAnd[1]|0xFFFF0000))^(piQxelXor[1] & 0xFFFF));
1052               break;
1053             case 2:
1054               *addrp = (((*addrp)&(piQxelAnd[1]|0xFFFF))^(piQxelXor[1] & 0xFFFF0000));
1055               *(addrp+1) = (((*(addrp+1))&(piQxelAnd[2]|0xFFFFFF00))^(piQxelXor[2] & 0xFF));
1056               break;
1057             } 
1058 #endif
1059 #else
1060         RROP_SOLID (addrp);
1061 # endif
1062     }
1063 #endif /* !POLYSEGMENT */
1064     return -1;
1065 }
1066
1067 #endif /* INCLUDE_DRAW */
1068
1069
1070 #ifdef INCLUDE_OTHERS
1071
1072 #ifdef POLYSEGMENT
1073
1074 void
1075 cfb8SegmentSS1Rect (pDrawable, pGC, nseg, pSegInit)
1076     DrawablePtr     pDrawable;
1077     GCPtr           pGC;
1078     int             nseg;
1079     xSegment        *pSegInit;
1080 {
1081     int     (*func)();
1082     void    (*clip)();
1083     int     drawn;
1084     cfbPrivGCPtr    devPriv;
1085
1086     devPriv = cfbGetGCPrivate(pGC);
1087 #ifdef NO_ONE_RECT
1088     if (REGION_NUM_RECTS(devPriv->pCompositeClip) != 1)
1089     {
1090        cfbSegmentSS(pDrawable, pGC, nseg, pSegInit);
1091        return;
1092     }
1093 #endif
1094     switch (devPriv->rop)
1095     {
1096     case GXcopy:
1097         func = cfb8SegmentSS1RectCopy;
1098         clip = cfb8ClippedLineCopy;
1099 #ifdef FAST_MUL
1100         if (cfbGetPixelWidth (pDrawable) == WIDTH_FAST)
1101             func = cfb8SegmentSS1RectShiftCopy;
1102 #endif
1103         break;
1104     case GXxor:
1105         func = cfb8SegmentSS1RectXor;
1106         clip = cfb8ClippedLineXor;
1107         break;
1108     default:
1109         func = cfb8SegmentSS1RectGeneral;
1110         clip = cfb8ClippedLineGeneral;
1111         break;
1112     }
1113     while (nseg)
1114     {
1115         drawn = (*func) (pDrawable, pGC, nseg, pSegInit);
1116         if (drawn == -1)
1117             break;
1118         (*clip) (pDrawable, pGC,
1119                          pSegInit[drawn-1].x1, pSegInit[drawn-1].y1,
1120                          pSegInit[drawn-1].x2, pSegInit[drawn-1].y2,
1121                          &devPriv->pCompositeClip->extents,
1122                          pGC->capStyle == CapNotLast);
1123         pSegInit += drawn;
1124         nseg -= drawn;
1125     }
1126 }
1127
1128 #else /* POLYSEGMENT */
1129
1130 void
1131 cfb8LineSS1Rect (pDrawable, pGC, mode, npt, pptInit)
1132     DrawablePtr pDrawable;
1133     GCPtr       pGC;
1134     int         mode;
1135     int         npt;
1136     DDXPointPtr pptInit;
1137 {
1138     int     (*func)();
1139     void    (*clip)();
1140     int     drawn;
1141     cfbPrivGCPtr    devPriv;
1142     int x1, y1, x2, y2;
1143     DDXPointPtr pptInitOrig = pptInit;
1144
1145     devPriv = cfbGetGCPrivate(pGC);
1146 #ifdef NO_ONE_RECT
1147     if (REGION_NUM_RECTS(devPriv->pCompositeClip) != 1)
1148     {
1149        cfbLineSS(pDrawable, pGC, mode, npt, pptInit);
1150        return;
1151     }
1152 #endif
1153     switch (devPriv->rop)
1154     {
1155     case GXcopy:
1156         func = cfb8LineSS1RectCopy;
1157         clip = cfb8ClippedLineCopy;
1158         if (mode == CoordModePrevious)
1159             func = cfb8LineSS1RectPreviousCopy;
1160         break;
1161     case GXxor:
1162         func = cfb8LineSS1RectXor;
1163         clip = cfb8ClippedLineXor;
1164         break;
1165     default:
1166         func = cfb8LineSS1RectGeneral;
1167         clip = cfb8ClippedLineGeneral;
1168         break;
1169     }
1170     if (mode == CoordModePrevious)
1171     {
1172         x1 = pptInit->x;
1173         y1 = pptInit->y;
1174         while (npt > 1)
1175         {
1176             drawn = (*func) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig,
1177                              &x1, &y1, &x2, &y2);
1178             if (drawn == -1)
1179                 break;
1180             (*clip) (pDrawable, pGC, x1, y1, x2, y2,
1181                      &devPriv->pCompositeClip->extents,
1182                      drawn != npt - 1 || pGC->capStyle == CapNotLast);
1183             pptInit += drawn;
1184             npt -= drawn;
1185             x1 = x2;
1186             y1 = y2;
1187         }
1188     }
1189     else
1190     {
1191         while (npt > 1)
1192         {
1193             drawn = (*func) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig,
1194                              &x1, &y1, &x2, &y2);
1195             if (drawn == -1)
1196                 break;
1197             (*clip) (pDrawable, pGC,
1198                      pptInit[drawn-1].x, pptInit[drawn-1].y,
1199                      pptInit[drawn].x, pptInit[drawn].y,
1200                      &devPriv->pCompositeClip->extents,
1201                      drawn != npt - 1 || pGC->capStyle == CapNotLast);
1202             pptInit += drawn;
1203             npt -= drawn;
1204         }
1205     }
1206 }
1207
1208 #endif /* else POLYSEGMENT */
1209 #endif /* INCLUDE_OTHERS */
1210
1211 #if !defined(POLYSEGMENT) && !defined (PREVIOUS)
1212
1213 void
1214 RROP_NAME (cfb8ClippedLine) (pDrawable, pGC, x1, y1, x2, y2, boxp, shorten)
1215     DrawablePtr pDrawable;
1216     GCPtr       pGC;
1217     int         x1, y1, x2, y2;
1218     BoxPtr      boxp;
1219     Bool        shorten;
1220 {
1221     int             oc1, oc2;
1222     int             e, e1, e3, len;
1223     int             adx, ady;
1224
1225     PixelType       *addr;
1226     int             nwidth;
1227     int             stepx, stepy;
1228     int             xorg, yorg;
1229     int             new_x1, new_y1, new_x2, new_y2;
1230     Bool            pt1_clipped, pt2_clipped;
1231     int             changex, changey, result;
1232 #if PSZ == 24
1233     int xOffset;
1234     PixelType   *addrLineEnd;
1235     char *addrb;
1236     int stepx3, stepy3;
1237 #endif
1238     int             octant;
1239     unsigned int    bias = miGetZeroLineBias(pDrawable->pScreen);
1240
1241     cfbGetPixelWidthAndPointer(pDrawable, nwidth, addr);
1242
1243     xorg = pDrawable->x;
1244     yorg = pDrawable->y;
1245     x1 += xorg;
1246     y1 += yorg;
1247     x2 += xorg;
1248     y2 += yorg;
1249     oc1 = 0;
1250     oc2 = 0;
1251     OUTCODES (oc1, x1, y1, boxp);
1252     OUTCODES (oc2, x2, y2, boxp);
1253
1254     if (oc1 & oc2)
1255         return;
1256
1257     CalcLineDeltas(x1, y1, x2, y2, adx, ady, stepx, stepy, 1, nwidth, octant);
1258
1259     if (adx <= ady)
1260     {
1261         int     t;
1262
1263         t = adx;
1264         adx = ady;
1265         ady = t;
1266
1267         t = stepx;
1268         stepx = stepy;
1269         stepy = t;
1270         
1271         SetYMajorOctant(octant);
1272     }
1273     e = - adx;
1274     e1 = ady << 1;
1275     e3 = - (adx << 1);
1276
1277     FIXUP_ERROR(e, octant, bias);
1278
1279     new_x1 = x1;
1280     new_y1 = y1;
1281     new_x2 = x2;
1282     new_y2 = y2;
1283     pt1_clipped = 0;
1284     pt2_clipped = 0;
1285
1286     if (IsXMajorOctant(octant))
1287     {
1288         result = miZeroClipLine(boxp->x1, boxp->y1, boxp->x2 - 1, boxp->y2 - 1,
1289                                 &new_x1, &new_y1, &new_x2, &new_y2,
1290                                 adx, ady,
1291                                 &pt1_clipped, &pt2_clipped,
1292                                 octant, bias, oc1, oc2);
1293         if (result == -1)
1294             return;
1295         
1296         len = abs(new_x2 - new_x1) - 1; /* this routine needs the "-1" */
1297         
1298         /* if we've clipped the endpoint, always draw the full length
1299          * of the segment, because then the capstyle doesn't matter 
1300          * if x2,y2 isn't clipped, use the capstyle
1301          * (shorten == TRUE <--> CapNotLast)
1302          */
1303         if (pt2_clipped || !shorten)
1304             len++;
1305         
1306         if (pt1_clipped)
1307         {
1308             /* must calculate new error terms */
1309             changex = abs(new_x1 - x1);
1310             changey = abs(new_y1 - y1);
1311             e = e + changey * e3 + changex * e1;            
1312         }
1313     }
1314     else /* Y_AXIS */
1315     {
1316         result = miZeroClipLine(boxp->x1, boxp->y1, boxp->x2 - 1, boxp->y2 - 1,
1317                                 &new_x1, &new_y1, &new_x2, &new_y2,
1318                                 ady, adx,
1319                                 &pt1_clipped, &pt2_clipped,
1320                                 octant, bias, oc1, oc2);
1321         if (result == -1)
1322             return;
1323         
1324         len = abs(new_y2 - new_y1) - 1; /* this routine needs the "-1" */
1325         
1326         /* if we've clipped the endpoint, always draw the full length
1327          * of the segment, because then the capstyle doesn't matter 
1328          * if x2,y2 isn't clipped, use the capstyle
1329          * (shorten == TRUE <--> CapNotLast)
1330          */
1331         if (pt2_clipped || !shorten)
1332             len++;
1333         
1334         if (pt1_clipped)
1335         {
1336             /* must calculate new error terms */
1337             changex = abs(new_x1 - x1);
1338             changey = abs(new_y1 - y1);
1339             e = e + changex * e3 + changey * e1;
1340         }
1341     }
1342     x1 = new_x1;
1343     y1 = new_y1;
1344     {
1345     register PixelType  *addrp;
1346     RROP_DECLARE
1347
1348     RROP_FETCH_GC(pGC);
1349
1350 #if PSZ == 24
1351     xOffset = x1;
1352     addrLineEnd = addr + (y1 * nwidth);
1353     addrb = (char *)addrLineEnd + x1 * 3;
1354     if (stepx == 1  ||  stepx == -1){
1355       stepx3 = stepx * 3;
1356       stepy3 = stepy * sizeof (long);
1357     } else {
1358       stepx3 = stepx * sizeof (long);
1359       stepy3 = stepy * 3;
1360     }
1361 #else
1362     addrp = addr + (y1 * nwidth) + x1;
1363 #endif
1364
1365 #ifndef REARRANGE
1366     if (!ady)
1367     {
1368 #if PSZ == 24
1369 #define body {\
1370             body_rop \
1371             addrb += stepx3; \
1372         }
1373 #else
1374 #define body    { RROP_SOLID(addrp); addrp += stepx; }
1375 #endif
1376         while (len >= PGSZB)
1377         {
1378             body body body body
1379 #if PGSZ == 64
1380             body body body body
1381 #endif
1382             len -= PGSZB;
1383         }
1384         switch (len)
1385         {
1386 #if PGSZ == 64
1387         case  7: body case 6: body case 5: body case 4: body
1388 #endif
1389         case  3: body case 2: body case 1: body
1390         }
1391 #undef body
1392     }
1393     else
1394 #endif /* !REARRANGE */
1395     {
1396 #if PSZ == 24
1397 #define body {\
1398             body_rop \
1399             addrb += stepx3; \
1400             e += e1; \
1401             if (e >= 0) \
1402             { \
1403                 addrb += stepy3; \
1404                 e += e3; \
1405             } \
1406         }
1407 #else
1408 #define body {\
1409             RROP_SOLID(addrp); \
1410             addrp += stepx; \
1411             e += e1; \
1412             if (e >= 0) \
1413             { \
1414                 addrp += stepy; \
1415                 e += e3; \
1416              } \
1417         }
1418 #endif
1419
1420 #ifdef LARGE_INSTRUCTION_CACHE
1421         while ((len -= PGSZB) >= 0)
1422         {
1423             body body body body
1424 #if PGSZ == 64
1425             body body body body
1426 #endif
1427         }
1428         switch (len)
1429         {
1430         case  -1: body case -2: body case -3: body
1431 #if PGSZ == 64
1432         case  -4: body case -5: body case -6: body case -7: body
1433 #endif
1434         }
1435 #else /* !LARGE_INSTRUCTION_CACHE */
1436         IMPORTANT_START;
1437
1438         while ((len -= 2) >= 0)
1439         {
1440             body body;
1441         }
1442         if (len & 1)
1443             body;
1444
1445         IMPORTANT_END;
1446 #endif /* LARGE_INSTRUCTION_CACHE */
1447     }
1448 #if PSZ == 24
1449     body_rop
1450 #else
1451     RROP_SOLID(addrp);
1452 #endif
1453 #undef body
1454     }
1455 }
1456
1457 #endif /* !POLYSEGMENT && !PREVIOUS */
1458 #endif /* PIXEL_ADDR */