2 * $TOG: cfb8line.c /main/33 1997/07/17 19:33:47 kaleb $
4 Copyright (c) 1990 X Consortium
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:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
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.
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.
27 * Author: Keith Packard, MIT X Consortium
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
36 #include "windowstr.h"
37 #include "pixmapstr.h"
38 #include "regionstr.h"
39 #include "scrnintstr.h"
43 #include "cfbmskbits.h"
49 #if defined(__GNUC__) && defined(mc68020)
50 #define STUPID volatile
57 /* lame compiler doesn't even look at 'register' attributes */
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
63 #define IMPORTANT_START
67 #define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & ClipMask)
72 # define WIDTH_FAST 1152
76 # define WIDTH_FAST 1024
80 # define WIDTH_FAST 4096
83 # if WIDTH_FAST == 1024
84 # define FAST_MUL(y) ((y) << 10)
87 # if WIDTH_FAST == 1152
88 # define FAST_MUL(y) (((y) << 10) + ((y) << 7))
91 # if WIDTH_FAST == 1280
92 # define FAST_MUL(y) (((y) << 10) + ((y) << 8))
95 # if WIDTH_FAST == 2048
96 # define FAST_MUL(y) ((y) << 11)
99 # if WIDTH_FAST == 4096
100 # define FAST_MUL(y) ((y) << 12)
104 # if defined(WIDTH_SHIFT)
106 # define FUNC_NAME(e) RROP_NAME(RROP_NAME_CAT(e,Shift))
108 # define INCLUDE_OTHERS
109 # define SERIOUS_UNROLLING
111 # define INCLUDE_DRAW
112 # define NWIDTH(nwidth) WIDTH_FAST
113 # define WIDTH_MUL(y,w) FAST_MUL(y)
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
127 # define INCLUDE_DRAW
128 # define WIDTH_MUL(y,w) ((y) * (w))
129 # define NWIDTH(nwidth) nwidth
131 # define FUNC_NAME(e) RROP_NAME(RROP_NAME_CAT(e,Previous))
133 # define FUNC_NAME(e) RROP_NAME(e)
135 # define INCLUDE_OTHERS
136 # ifdef PLENTIFUL_REGISTERS
140 # define SERIOUS_UNROLLING
148 #define PXL2ADR(x) ((x)*3 >> 2)
152 addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
153 switch((unsigned long)addrb & 3){ \
155 *addrp = (*addrp & 0xFF000000)|(piQxelXor[0] & 0xFFFFFF); \
158 *addrp = (*addrp & 0xFF)|(piQxelXor[2] & 0xFFFFFF00); \
161 *addrp = (*addrp & 0xFFFFFF)|(piQxelXor[0] & 0xFF000000); \
162 *(addrp+1)=(*(addrp+1) & 0xFFFF0000)|(piQxelXor[1] & 0xFFFF); \
165 *addrp = (*addrp & 0xFFFF)|(piQxelXor[1] & 0xFFFF0000); \
166 *(addrp+1)=(*(addrp+1) & 0xFFFFFF00)|(piQxelXor[2] & 0xFF); \
172 addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
173 switch((unsigned long)addrb & 3){ \
175 *addrp ^= piQxelXor[0] & 0xFFFFFF; \
178 *addrp ^= piQxelXor[2] & 0xFFFFFF00; \
181 *addrp ^= piQxelXor[0] & 0xFF000000; \
182 *(addrp+1) ^= piQxelXor[1] & 0xFFFF; \
185 *addrp ^= piQxelXor[1] & 0xFFFF0000; \
186 *(addrp+1) ^= piQxelXor[2] & 0xFF; \
192 addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
193 switch((unsigned long)addrb & 3){ \
195 *addrp &= piQxelAnd[0] | 0xFF000000; \
198 *addrp &= piQxelAnd[2] | 0xFF; \
201 *addrp &= 0xFFFFFF | piQxelAnd[0]; \
202 *(addrp+1) &= 0xFFFF0000 | piQxelAnd[1]; \
205 *addrp &= 0xFFFF | piQxelAnd[1]; \
206 *(addrp+1) &= 0xFFFFFF00 | piQxelAnd[2]; \
212 addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
213 switch((unsigned long)addrb & 3){ \
215 *addrp |= piQxelOr[0] & 0xFFFFFF; \
218 *addrp |= piQxelOr[2] & 0xFFFFFF00; \
221 *addrp |= piQxelOr[0] & 0xFF000000; \
222 *(addrp+1) |= piQxelOr[1] & 0xFFFF; \
225 *addrp |= piQxelOr[1] & 0xFFFF0000; \
226 *(addrp+1) |= piQxelOr[2] & 0xFF; \
232 addrp = (PixelType *)((unsigned long)addrb & ~0x03); \
233 switch((unsigned long)addrb & 3){ \
235 *addrp = (*addrp & (piQxelAnd[0]|0xFF000000)) \
236 ^ (piQxelXor[0] & 0xFFFFFF); \
239 *addrp = (*addrp & (piQxelAnd[2]|0xFF)) \
240 ^ (piQxelXor[2] & 0xFFFFFF00); \
243 *addrp = (*addrp & (piQxelAnd[0]|0xFFFFFF)) \
244 ^ (piQxelXor[0] & 0xFF000000); \
245 *(addrp+1) = (*(addrp+1) & (piQxelAnd[1]|0xFFFF0000)) \
246 ^ (piQxelXor[1] & 0xFFFF); \
249 *addrp = (*addrp & (piQxelAnd[1]|0xFFFF)) \
250 ^ (piQxelXor[1] & 0xFFFF0000); \
251 *(addrp+1) = (*(addrp+1) & (piQxelAnd[2]|0xFFFFFF00)) \
252 ^ (piQxelXor[2] & 0xFF); \
256 #endif /* PSZ == 24 */
264 FUNC_NAME(cfb8SegmentSS1Rect) (pDrawable, pGC, nseg, pSegInit)
265 DrawablePtr pDrawable;
270 FUNC_NAME(cfb8LineSS1Rect) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig,
272 DrawablePtr pDrawable;
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 */
281 register int y1_or_e1;
282 register PixelType *addrp;
283 register int stepmajor;
284 register int stepminor;
289 register short x1_or_len;
291 register int x1_or_len;
301 register int _x1, _y1, _x2, _y2; /* only used for CoordModePrevious */
302 int extents_x1, extents_y1, extents_x2, extents_y2;
305 register int upperleft, lowerright;
306 CARD32 ClipMask = 0x80008000;
307 #endif /* !PREVIOUS */
309 register int capStyle;
310 #endif /* POLYSEGMENT */
313 # define X1 x1_or_len
319 # define X1 x1_or_len
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 */
330 cfbPrivGCPtr devPriv;
334 int xBase; /* x of addr */
335 int xOffset; /* x of addrp */
336 int xOffset_t; /* x of t */
337 PixelType *addrLineEnd;
339 int stepmajor3, stepminor3, majordx, minordx;
342 int ex_x1, ex_y1, ex_x2, ex_y2;
345 unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
347 devPriv = cfbGetGCPrivate(pGC);
348 cfbGetPixelWidthAndPointer (pDrawable, nwidth, addr);
350 RROP_FETCH_GCPRIV(devPriv);
352 extents = &devPriv->pCompositeClip->extents;
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 */
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;
366 xBase = pDrawable->x;
367 addr += WIDTH_MUL(pDrawable->y,nwidth);
369 addr = addr + WIDTH_MUL(pDrawable->y,nwidth) + pDrawable->x;
372 capStyle = pGC->capStyle - CapNotLast;
373 ppt = (int *) pSegInit;
375 #else /* POLYSEGMENT */
377 mode -= CoordModePrevious;
379 #endif /* EITHER_MODE */
381 { /* CoordModePrevious */
382 ppt = (int *)pptInit + 1;
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)
393 intToCoord(c2, _x2, _y2);
399 addrLineEnd = addr + WIDTH_MUL(_y1, nwidth);
400 xOffset = xBase + _x1;
401 addrb = (char *)addrLineEnd + xOffset * 3;
402 addrp = (PixelType *)((unsigned long)addrb & ~0x03);
404 addrp = addr + WIDTH_MUL(_y1, nwidth) + _x1;
412 #endif /* EITHER_MODE */
415 ppt = (int *) pptInit;
417 if (isClipped (c2, upperleft, lowerright))
422 intToCoord(c2,x2,y2);
425 addrLineEnd = addr + WIDTH_MUL(Y2, nwidth);
426 xOffset = xBase + X2;
427 addrb = (char *)addrLineEnd + xOffset * 3;
428 addrp = (PixelType *)((unsigned long)addrb & ~0x03);
430 addrp = addr + WIDTH_MUL(Y2, nwidth) + X2;
433 #endif /* !PREVIOUS */
435 #endif /* POLYSEGMENT */
441 if (isClipped(y1_or_e1,upperleft,lowerright)|isClipped(c2,upperleft,lowerright))
443 intToCoord(y1_or_e1,x1_or_len,y1_or_e1);
444 /* compute now to avoid needing x1, y1 later */
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);
451 addrp = addr + WIDTH_MUL(y1_or_e1, nwidth) + x1_or_len;
453 #else /* !POLYSEGMENT */
456 #endif /* EITHER_MODE */
459 /* CoordModePrevious */
463 intToCoord(c2, _x2, _y2);
468 if (_x2 < ex_x1 || _x2 >= ex_x2 ||
469 _y2 < ex_y1 || _y2 >= ex_y2)
471 if (_x2 < extents_x1 || _x2 >= extents_x2 ||
472 _y2 < extents_y1 || _y2 >= extents_y2)
477 CalcLineDeltas(_x1, _y1, _x2, _y2, x1_or_len, y1_or_e1,
478 stepmajor, stepminor, 1, NWIDTH(nwidth), octant);
483 #endif /* EITHER_MODE */
491 #endif /* SAVE_X2Y2 */
494 if (isClipped (c2, upperleft, lowerright))
497 intToCoord(c2,x2,y2);
499 CalcLineDeltas(X1, Y1, X2, Y2, x1_or_len, y1_or_e1,
500 stepmajor, stepminor, 1, NWIDTH(nwidth), octant);
502 #endif /* !PREVIOUS */
503 #endif /* POLYSEGMENT */
506 CalcLineDeltas(X1, Y1, X2, Y2, x1_or_len, y1_or_e1,
507 stepmajor, stepminor, 1, NWIDTH(nwidth), octant);
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
517 #endif /* POLYSEGMENT */
518 if (x1_or_len < y1_or_e1)
525 x1_or_len = y1_or_e1;
529 stepminor = stepmajor;
531 SetYMajorOctant(octant);
544 RROP_FETCH_GCPRIV(devPriv);
547 y1_or_e1 = y1_or_e1 << 1;
550 FIXUP_ERROR(e, octant, bias);
553 if (stepmajor == 1 || stepmajor == -1){
554 stepmajor3 = stepmajor * 3;
555 stepminor3 = stepminor * sizeof (long);
556 majordx = stepmajor; minordx = 0;
558 stepmajor3 = stepmajor * sizeof (long);
559 stepminor3 = stepminor * 3;
560 majordx = 0; minordx = stepminor;
567 addrb += stepmajor3; \
568 xOffset += majordx; \
571 addrb += stepminor3; \
572 xOffset += minordx; \
576 #else /* PSZ == 24 */
580 addrp += stepmajor; \
584 addrp += stepminor; \
588 #endif /* PSZ == 24 */
590 #ifdef LARGE_INSTRUCTION_CACHE
592 # ifdef SERIOUS_UNROLLING
597 #define CASE(n) case -n: body
599 while ((x1_or_len -= UNROLL) >= 0)
614 CASE(1) CASE(2) CASE(3)
616 CASE(4) CASE(5) CASE(6) CASE(7)
619 CASE(8) CASE(9) CASE(10) CASE(11)
622 CASE(12) CASE(13) CASE(14) CASE(15)
625 #else /* !LARGE_INSTRUCTION_CACHE */
633 while (x1_or_len--) {
639 #endif /* LARGE_INSTRUCTION_CACHE */
649 addrp = (PixelType *)((unsigned long)addrb & ~0x03);
660 RROP_FETCH_GCPRIV(devPriv);
661 # endif /* REARRANGE */
665 xOffset -= x1_or_len;
666 addrp = addrLineEnd + PXL2ADR(xOffset);
675 addrp = addrLineEnd + PXL2ADR(xOffset);
683 addrp = addrLineEnd + PXL2ADR(xOffset);
689 y1_or_e1 = xOffset & 3;
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);
696 # endif /* PSZ == 24 */
700 register int nlmiddle;
701 int leftIndex = xOffset & 3;
702 int rightIndex = (xOffset + x1_or_len) & 3;
708 nlmiddle = x1_or_len;
710 nlmiddle -= (4 - leftIndex);
713 nlmiddle -= rightIndex;
717 switch(leftIndex+x1_or_len){
721 *addrp++ = piQxelXor[0];
722 *addrp++ = piQxelXor[1];
723 *addrp = piQxelXor[2];
726 *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
727 *addrp++ = piQxelXor[1];
728 *addrp = piQxelXor[2];
731 *addrp++ =((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
732 *addrp = piQxelXor[2];
735 *addrp =((*addrp) & 0xFF) | (piQxelXor[2] & 0xFFFFFF00);
742 *addrp++ = piQxelXor[0];
743 *addrp++ = piQxelXor[1];
744 *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
747 *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
748 *addrp++ = piQxelXor[1];
749 *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
752 *addrp++ =((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
753 *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
761 *addrp++ = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
762 *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
766 *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
767 *addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
770 *addrp++ = piQxelXor[0];
771 *addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
775 case 1: /*only if leftIndex = 0 and w = 1*/
777 *addrp = ((*addrp) & 0xFF000000) | (piQxelXor[0] & 0xFFFFFF);
781 *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
782 *addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
791 maskbits(y1_or_e1, x1_or_len, e, e3, x1_or_len)
797 *addrp++ = ((*addrp) & 0xFFFFFF) | (piQxelXor[0] & 0xFF000000);
798 *addrp++ = piQxelXor[1];
799 *addrp++ = piQxelXor[2];
802 *addrp++ = ((*addrp) & 0xFFFF) | (piQxelXor[1] & 0xFFFF0000);
803 *addrp++ = piQxelXor[2];
806 *addrp++ = ((*addrp) & 0xFF) | (piQxelXor[2] & 0xFFFFFF00);
810 *addrp++ = piQxelXor[0];
811 *addrp++ = piQxelXor[1];
812 *addrp++ = piQxelXor[2];
814 switch(rightIndex++){
818 *addrp = ((*addrp) & 0xFF000000) | (piQxelXor[0] & 0xFFFFFF);
821 *addrp++ = piQxelXor[0];
822 *addrp = ((*addrp) & 0xFFFF0000) | (piQxelXor[1] & 0xFFFF);
825 *addrp++ = piQxelXor[0];
826 *addrp++ = piQxelXor[1];
827 *addrp = ((*addrp) & 0xFFFFFF00) | (piQxelXor[2] & 0xFF);
833 switch(rightIndex&3){
835 *addrp = ((*addrp) & (0xFF000000 | ~e3))
836 | (piQxelXor[0] & 0xFFFFFF & e3);
839 *addrp++ = ((*addrp) & (0xFFFFFF | ~(e3<<24)))
840 | (piQxelXor[0] & 0xFF000000 & (e3<<24));
841 *addrp = ((*addrp) & (0xFFFF0000|~(e3 >> 8)))
842 | (piQxelXor[1] & 0xFFFF & (e3 >> 8));
845 *addrp++ = ((*addrp) & (0xFFFF|~(e3 << 16)))
846 | (piQxelXor[1] & 0xFFFF0000 & (e3 << 16));
847 *addrp = ((*addrp) & (0xFFFFFF00|~(e3>>16)))
848 | (piQxelXor[2] & 0xFF & (e3 >> 16));
851 *addrp++ = ((*addrp) & (0xFF|~(e3<<8)))
852 | (piQxelXor[2] & 0xFFFFFF00 & (e3<<8));
860 addrp = (PixelType *)((char *)addrLineEnd + ((xOffset * 3) & ~0x03));
863 RROP_SOLID24(addrp, xOffset);
865 maskbits(xOffset, x1_or_len, e, e3, x1_or_len);
868 RROP_SOLID_MASK(addrp, e, pidx-1);
873 while (--x1_or_len >= 0){
874 RROP_SOLID(addrp, pidx);
880 RROP_SOLID_MASK(addrp, e3, pidx);
884 #else /* PSZ == 24 */
885 if (y1_or_e1 + x1_or_len <= PPW)
889 maskpartialbits(y1_or_e1, x1_or_len, e)
890 RROP_SOLID_MASK((unsigned long *) addrp, e);
895 maskbits(y1_or_e1, x1_or_len, e, e3, x1_or_len)
898 RROP_SOLID_MASK((unsigned long *) addrp, e);
902 RROP_SPAN_lu(addrp, x1_or_len)
904 RROP_SPAN(addrp, x1_or_len)
908 RROP_SOLID_MASK_lu((unsigned long *) addrp, e3);
910 RROP_SOLID_MASK((unsigned long *) addrp, e3);
913 #endif /* PSZ == 24 */
915 #endif /* POLYSEGMENT */
919 return (xSegment *) ppt - pSegInit;
925 #endif /* EITHER_MODE */
934 return ((DDXPointPtr) ppt - pptInit) - 1;
936 #endif /* POLYSEGMENT */
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 */
952 if (pGC->capStyle != CapNotLast &&
953 ((_x2 != pptInitOrig->x) ||
954 (_y2 != pptInitOrig->y) ||
955 (ppt == ((int *)pptInitOrig) + 2)))
956 #endif /* PREVIOUS */
958 if (pGC->capStyle != CapNotLast &&
959 ((C2 != *((int *) pptInitOrig)) ||
960 (ppt == ((int *)pptInitOrig) + 2)))
961 #endif /* !PREVIOUS */
966 RROP_FETCH_GCPRIV(devPriv);
972 *addrp = ((*addrp)&0xFF000000)|(piQxelXor[0] & 0xFFFFFF);
975 *addrp = ((*addrp)&0xFF)|(piQxelXor[2] & 0xFFFFFF00);
978 *addrp = ((*addrp)&0xFFFFFF)|(piQxelXor[0] & 0xFF000000);
979 *(addrp+1) = ((*(addrp+1))&0xFFFF0000)|(piQxelXor[1] & 0xFFFF);
982 *addrp = ((*addrp)&0xFFFF)|(piQxelXor[1] & 0xFFFF0000);
983 *(addrp+1) = ((*(addrp+1))&0xFFFFFF00)|(piQxelXor[2] & 0xFF);
990 *addrp ^= (piQxelXor[0] & 0xFFFFFF);
993 *addrp ^= (piQxelXor[2] & 0xFFFFFF00);
996 *addrp ^= (piQxelXor[0] & 0xFF000000);
997 *(addrp+1) ^= (piQxelXor[1] & 0xFFFF);
1000 *addrp ^= (piQxelXor[1] & 0xFFFF0000);
1001 *(addrp+1) ^= (piQxelXor[2] & 0xFF);
1006 switch(xOffset & 3){
1008 *addrp &= (piQxelAnd[0] | 0xFF000000);
1011 *addrp &= (piQxelAnd[2] | 0xFF);
1014 *addrp &= (0xFFFFFF|piQxelAnd[0]);
1015 *(addrp+1) &= (0xFFFF0000|piQxelAnd[1]);
1018 *addrp &= (0xFFFF|piQxelAnd[1]);
1019 *(addrp+1) &= (0xFFFFFF00|piQxelAnd[2]);
1024 switch(xOffset & 3){
1026 *addrp |= (piQxelOr[0] & 0xFFFFFF);
1029 *addrp |= (piQxelOr[2] & 0xFFFFFF00);
1032 *addrp |= (piQxelOr[0] & 0xFF000000);
1033 *(addrp+1) |= (piQxelOr[1] & 0xFFFF);
1036 *addrp |= (piQxelOr[1] & 0xFFFF0000);
1037 *(addrp+1) |= (piQxelOr[2] & 0xFF);
1042 switch(xOffset & 3){
1044 *addrp = (((*addrp)&(piQxelAnd[0] |0xFF000000))^(piQxelXor[0] & 0xFFFFFF));
1047 *addrp = (((*addrp)&(piQxelAnd[2]|0xFF))^(piQxelXor[2] & 0xFFFFFF00));
1050 *addrp = (((*addrp)&(piQxelAnd[0]|0xFFFFFF))^(piQxelXor[0] & 0xFF000000));
1051 *(addrp+1) = (((*(addrp+1))&(piQxelAnd[1]|0xFFFF0000))^(piQxelXor[1] & 0xFFFF));
1054 *addrp = (((*addrp)&(piQxelAnd[1]|0xFFFF))^(piQxelXor[1] & 0xFFFF0000));
1055 *(addrp+1) = (((*(addrp+1))&(piQxelAnd[2]|0xFFFFFF00))^(piQxelXor[2] & 0xFF));
1063 #endif /* !POLYSEGMENT */
1067 #endif /* INCLUDE_DRAW */
1070 #ifdef INCLUDE_OTHERS
1075 cfb8SegmentSS1Rect (pDrawable, pGC, nseg, pSegInit)
1076 DrawablePtr pDrawable;
1084 cfbPrivGCPtr devPriv;
1086 devPriv = cfbGetGCPrivate(pGC);
1088 if (REGION_NUM_RECTS(devPriv->pCompositeClip) != 1)
1090 cfbSegmentSS(pDrawable, pGC, nseg, pSegInit);
1094 switch (devPriv->rop)
1097 func = cfb8SegmentSS1RectCopy;
1098 clip = cfb8ClippedLineCopy;
1100 if (cfbGetPixelWidth (pDrawable) == WIDTH_FAST)
1101 func = cfb8SegmentSS1RectShiftCopy;
1105 func = cfb8SegmentSS1RectXor;
1106 clip = cfb8ClippedLineXor;
1109 func = cfb8SegmentSS1RectGeneral;
1110 clip = cfb8ClippedLineGeneral;
1115 drawn = (*func) (pDrawable, pGC, nseg, pSegInit);
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);
1128 #else /* POLYSEGMENT */
1131 cfb8LineSS1Rect (pDrawable, pGC, mode, npt, pptInit)
1132 DrawablePtr pDrawable;
1136 DDXPointPtr pptInit;
1141 cfbPrivGCPtr devPriv;
1143 DDXPointPtr pptInitOrig = pptInit;
1145 devPriv = cfbGetGCPrivate(pGC);
1147 if (REGION_NUM_RECTS(devPriv->pCompositeClip) != 1)
1149 cfbLineSS(pDrawable, pGC, mode, npt, pptInit);
1153 switch (devPriv->rop)
1156 func = cfb8LineSS1RectCopy;
1157 clip = cfb8ClippedLineCopy;
1158 if (mode == CoordModePrevious)
1159 func = cfb8LineSS1RectPreviousCopy;
1162 func = cfb8LineSS1RectXor;
1163 clip = cfb8ClippedLineXor;
1166 func = cfb8LineSS1RectGeneral;
1167 clip = cfb8ClippedLineGeneral;
1170 if (mode == CoordModePrevious)
1176 drawn = (*func) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig,
1177 &x1, &y1, &x2, &y2);
1180 (*clip) (pDrawable, pGC, x1, y1, x2, y2,
1181 &devPriv->pCompositeClip->extents,
1182 drawn != npt - 1 || pGC->capStyle == CapNotLast);
1193 drawn = (*func) (pDrawable, pGC, mode, npt, pptInit, pptInitOrig,
1194 &x1, &y1, &x2, &y2);
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);
1208 #endif /* else POLYSEGMENT */
1209 #endif /* INCLUDE_OTHERS */
1211 #if !defined(POLYSEGMENT) && !defined (PREVIOUS)
1214 RROP_NAME (cfb8ClippedLine) (pDrawable, pGC, x1, y1, x2, y2, boxp, shorten)
1215 DrawablePtr pDrawable;
1229 int new_x1, new_y1, new_x2, new_y2;
1230 Bool pt1_clipped, pt2_clipped;
1231 int changex, changey, result;
1234 PixelType *addrLineEnd;
1239 unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
1241 cfbGetPixelWidthAndPointer(pDrawable, nwidth, addr);
1243 xorg = pDrawable->x;
1244 yorg = pDrawable->y;
1251 OUTCODES (oc1, x1, y1, boxp);
1252 OUTCODES (oc2, x2, y2, boxp);
1257 CalcLineDeltas(x1, y1, x2, y2, adx, ady, stepx, stepy, 1, nwidth, octant);
1271 SetYMajorOctant(octant);
1277 FIXUP_ERROR(e, octant, bias);
1286 if (IsXMajorOctant(octant))
1288 result = miZeroClipLine(boxp->x1, boxp->y1, boxp->x2 - 1, boxp->y2 - 1,
1289 &new_x1, &new_y1, &new_x2, &new_y2,
1291 &pt1_clipped, &pt2_clipped,
1292 octant, bias, oc1, oc2);
1296 len = abs(new_x2 - new_x1) - 1; /* this routine needs the "-1" */
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)
1303 if (pt2_clipped || !shorten)
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;
1316 result = miZeroClipLine(boxp->x1, boxp->y1, boxp->x2 - 1, boxp->y2 - 1,
1317 &new_x1, &new_y1, &new_x2, &new_y2,
1319 &pt1_clipped, &pt2_clipped,
1320 octant, bias, oc1, oc2);
1324 len = abs(new_y2 - new_y1) - 1; /* this routine needs the "-1" */
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)
1331 if (pt2_clipped || !shorten)
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;
1345 register PixelType *addrp;
1352 addrLineEnd = addr + (y1 * nwidth);
1353 addrb = (char *)addrLineEnd + x1 * 3;
1354 if (stepx == 1 || stepx == -1){
1356 stepy3 = stepy * sizeof (long);
1358 stepx3 = stepx * sizeof (long);
1362 addrp = addr + (y1 * nwidth) + x1;
1374 #define body { RROP_SOLID(addrp); addrp += stepx; }
1376 while (len >= PGSZB)
1387 case 7: body case 6: body case 5: body case 4: body
1389 case 3: body case 2: body case 1: body
1394 #endif /* !REARRANGE */
1409 RROP_SOLID(addrp); \
1420 #ifdef LARGE_INSTRUCTION_CACHE
1421 while ((len -= PGSZB) >= 0)
1430 case -1: body case -2: body case -3: body
1432 case -4: body case -5: body case -6: body case -7: body
1435 #else /* !LARGE_INSTRUCTION_CACHE */
1438 while ((len -= 2) >= 0)
1446 #endif /* LARGE_INSTRUCTION_CACHE */
1457 #endif /* !POLYSEGMENT && !PREVIOUS */
1458 #endif /* PIXEL_ADDR */