1 /************************************************************
2 Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
6 Permission to use, copy, modify, and distribute this
7 software and its documentation for any purpose and without
8 fee is hereby granted, provided that the above copyright no-
9 tice appear in all copies and that both that copyright no-
10 tice and this permission notice appear in supporting docu-
11 mentation, and that the names of Sun or X Consortium
12 not be used in advertising or publicity pertaining to
13 distribution of the software without specific prior
14 written permission. Sun and X Consortium make no
15 representations about the suitability of this software for
16 any purpose. It is provided "as is" without any express or
19 SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
21 NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
22 ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
24 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
25 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
26 THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 ********************************************************/
30 /***********************************************************
32 Copyright (c) 1987 X Consortium
34 Permission is hereby granted, free of charge, to any person obtaining a copy
35 of this software and associated documentation files (the "Software"), to deal
36 in the Software without restriction, including without limitation the rights
37 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38 copies of the Software, and to permit persons to whom the Software is
39 furnished to do so, subject to the following conditions:
41 The above copyright notice and this permission notice shall be included in
42 all copies or substantial portions of the Software.
44 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
48 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
51 Except as contained in this notice, the name of the X Consortium shall not be
52 used in advertising or otherwise to promote the sale, use or other dealings
53 in this Software without prior written authorization from the X Consortium.
56 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
60 Permission to use, copy, modify, and distribute this software and its
61 documentation for any purpose and without fee is hereby granted,
62 provided that the above copyright notice appear in all copies and that
63 both that copyright notice and this permission notice appear in
64 supporting documentation, and that the name of Digital not be
65 used in advertising or publicity pertaining to distribution of the
66 software without specific, written prior permission.
68 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
69 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
70 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
71 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
72 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
73 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
76 ******************************************************************/
78 /* $XConsortium: cfbfillsp.c,v 5.24 94/04/17 20:28:48 dpw Exp $ */
79 /* $XFree86: xc/programs/Xserver/cfb/cfbfillsp.c,v 3.1 1996/12/09 11:50:54 dawes Exp $ */
86 #include "pixmapstr.h"
87 #include "scrnintstr.h"
88 #include "windowstr.h"
91 #include "cfbmskbits.h"
99 #define MFB_CONSTS_ONLY
100 #include "maskbits.h"
105 /* scanline filling for color frame buffer
106 written by drewry, oct 1986 modified by smarks
107 changes for compatibility with Little-endian systems Jul 1987; MIT:yba.
109 these routines all clip. they assume that anything that has called
110 them has already translated the points (i.e. pGC->miTranslate is
111 non-zero, which is howit gets set in cfbCreateGC().)
113 the number of new scnalines created by clipping ==
114 MaxRectsPerBand * nSpans.
116 FillSolid is overloaded to be used for OpaqueStipple as well,
117 if fgPixel == bgPixel.
118 Note that for solids, PrivGC.rop == PrivGC.ropOpStip
121 FillTiled is overloaded to be used for OpaqueStipple, if
122 fgPixel != bgPixel. based on the fill style, it uses
123 {RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip}
129 dumpspans(n, ppt, pwidth)
134 fprintf(stderr,"%d spans\n", n);
136 fprintf(stderr, "[%d,%d] %d\n", ppt->x, ppt->y, *pwidth);
140 fprintf(stderr, "\n");
144 /* Fill spans with tiles that aren't 32 bits wide */
146 cfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
147 DrawablePtr pDrawable;
149 int nInit; /* number of spans to fill */
150 DDXPointPtr pptInit; /* pointer to list of start points */
151 int *pwidthInit; /* pointer to list of n widths */
154 int n; /* number of spans to fill */
155 register DDXPointPtr ppt; /* pointer to list of start points */
156 register int *pwidth; /* pointer to list of n widths */
160 if (!(pGC->planemask))
164 if (pGC->tile.pixmap->drawable.width & 3)
166 if (pGC->tile.pixmap->drawable.width & PIM)
169 fill = cfbFillSpanTileOddGeneral;
170 if ((pGC->planemask & PMSK) == PMSK)
172 if (pGC->alu == GXcopy)
173 fill = cfbFillSpanTileOddCopy;
178 fill = cfbFillSpanTile32sGeneral;
179 if ((pGC->planemask & PMSK) == PMSK)
181 if (pGC->alu == GXcopy)
182 fill = cfbFillSpanTile32sCopy;
185 n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
188 pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int));
189 ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
192 if (ppt) DEALLOCATE_LOCAL(ppt);
193 if (pwidth) DEALLOCATE_LOCAL(pwidth);
196 n = miClipSpans( cfbGetCompositeClip(pGC),
197 pptInit, pwidthInit, nInit,
198 ppt, pwidth, fSorted);
200 xrot = pDrawable->x + pGC->patOrg.x;
201 yrot = pDrawable->y + pGC->patOrg.y;
203 (*fill) (pDrawable, n, ppt, pwidth, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
205 DEALLOCATE_LOCAL(ppt);
206 DEALLOCATE_LOCAL(pwidth);
212 cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
213 DrawablePtr pDrawable;
215 int nInit; /* number of spans to fill */
216 DDXPointPtr pptInit; /* pointer to list of start points */
217 int *pwidthInit; /* pointer to list of n widths */
220 /* next three parameters are post-clip */
221 int n; /* number of spans to fill */
222 DDXPointPtr ppt; /* pointer to list of start points */
223 int *pwidth; /* pointer to list of n widths */
224 int *pwidthFree;/* copies of the pointers to free */
226 unsigned long *pdstBase; /* pointer to start of bitmap */
227 int nlwDst; /* width in longwords of bitmap */
228 register unsigned long *pdst; /* pointer to current word in bitmap */
229 PixmapPtr pStipple; /* pointer to stipple we want to fill with */
231 int x, y, w, xrem, xSrc, ySrc;
232 int stwidth, stippleWidth;
234 register unsigned long bits, inputBits;
235 register int partBitsLeft;
237 int bitsLeft, bitsWhole;
238 unsigned long *srcTemp, *srcStart;
239 unsigned long *psrcBase;
240 unsigned long startmask, endmask;
242 if (pGC->fillStyle == FillStippled)
243 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
245 cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
247 if (cfb8StippleRRop == GXnoop)
250 n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
253 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
254 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
255 if(!pptFree || !pwidthFree)
257 if (pptFree) DEALLOCATE_LOCAL(pptFree);
258 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
264 n = miClipSpans( cfbGetCompositeClip(pGC),
265 pptInit, pwidthInit, nInit,
266 ppt, pwidth, fSorted);
269 * OK, so what's going on here? We have two Drawables:
273 * Width = stippleWidth
274 * Words per scanline = stwidth
275 * Pointer to pixels = pStipple->devPrivate.ptr
278 pStipple = pGC->stipple;
280 stwidth = pStipple->devKind >> PWSH;
281 stippleWidth = pStipple->drawable.width;
282 stippleHeight = pStipple->drawable.height;
283 psrcBase = (unsigned long *) pStipple->devPrivate.ptr;
288 * Width = determined from *pwidth
289 * Words per scanline = nlwDst
290 * Pointer to pixels = addrlBase
293 cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
295 /* this replaces rotating the stipple. Instead we just adjust the offset
296 * at which we start grabbing bits from the stipple.
297 * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
298 * so that iline and xrem always stay within the stipple bounds.
301 modulus (pGC->patOrg.x, stippleWidth, xSrc);
302 xSrc += pDrawable->x - stippleWidth;
303 modulus (pGC->patOrg.y, stippleHeight, ySrc);
304 ySrc += pDrawable->y - stippleHeight;
306 bitsWhole = stippleWidth;
314 pdst = pdstBase + y * nlwDst + (x >> PWSH);
315 y = (y - ySrc) % stippleHeight;
316 srcStart = psrcBase + y * stwidth;
317 xrem = ((x & ~(PGSZB-1)) - xSrc) % stippleWidth;
318 srcTemp = srcStart + (xrem >> MFB_PWSH);
319 bitsLeft = stippleWidth - (xrem & ~MFB_PIM);
321 NextUnnaturalStippleWord
322 if (partBitsLeft < xrem)
323 FatalError ("cfbUnnaturalStippleFS bad partBitsLeft %d xrem %d",
325 NextSomeBits (inputBits, xrem);
326 partBitsLeft -= xrem;
327 if (((x & PIM) + w) <= PPW)
329 maskpartialbits (x, w, startmask)
330 NextUnnaturalStippleBits
331 *pdst = MaskRRopPixels(*pdst,bits,startmask);
335 maskbits (x, w, startmask, endmask, nlw);
336 nextPartBits = (x & (PGSZB-1)) + w;
337 if (nextPartBits < partBitsLeft)
341 MaskRRopBitGroup(pdst,GetBitGroup(inputBits),startmask)
343 NextBitGroup (inputBits);
347 RRopBitGroup (pdst, GetBitGroup (inputBits));
349 NextBitGroup (inputBits);
353 MaskRRopBitGroup(pdst,GetBitGroup(inputBits),endmask)
356 else if (bitsLeft != bitsWhole && nextPartBits < partBitsLeft + bitsLeft)
358 NextUnnaturalStippleBitsFast
361 *pdst = MaskRRopPixels(*pdst,bits,startmask);
363 NextUnnaturalStippleBitsFast
367 *pdst = RRopPixels(*pdst,bits);
369 NextUnnaturalStippleBitsFast
372 *pdst = MaskRRopPixels (*pdst,bits,endmask);
376 NextUnnaturalStippleBits
379 *pdst = MaskRRopPixels(*pdst,bits,startmask);
381 NextUnnaturalStippleBits
385 *pdst = RRopPixels(*pdst,bits);
387 NextUnnaturalStippleBits
390 *pdst = MaskRRopPixels(*pdst,bits,endmask);
394 DEALLOCATE_LOCAL(pptFree);
395 DEALLOCATE_LOCAL(pwidthFree);
400 /* Fill spans with stipples that aren't 32 bits wide */
402 cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
403 DrawablePtr pDrawable;
405 int nInit; /* number of spans to fill */
406 DDXPointPtr pptInit; /* pointer to list of start points */
407 int *pwidthInit; /* pointer to list of n widths */
410 /* next three parameters are post-clip */
411 int n; /* number of spans to fill */
412 register DDXPointPtr ppt; /* pointer to list of start points */
413 register int *pwidth; /* pointer to list of n widths */
414 int iline; /* first line of tile to use */
415 unsigned long *addrlBase; /* pointer to start of bitmap */
416 int nlwidth; /* width in longwords of bitmap */
417 register unsigned long *pdst; /* pointer to current word in bitmap */
418 PixmapPtr pStipple; /* pointer to stipple we want to fill with */
420 int width, x, xrem, xSrc, ySrc;
421 unsigned long tmpSrc, tmpDst1, tmpDst2;
422 int stwidth, stippleWidth;
423 unsigned long *psrcS;
426 int *pwidthFree; /* copies of the pointers to free */
428 unsigned long fgfill, bgfill;
430 if (!(pGC->planemask))
433 n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
436 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
437 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
438 if(!pptFree || !pwidthFree)
440 if (pptFree) DEALLOCATE_LOCAL(pptFree);
441 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
446 n = miClipSpans( cfbGetCompositeClip(pGC),
447 pptInit, pwidthInit, nInit,
448 ppt, pwidth, fSorted);
450 if (pGC->fillStyle == FillStippled) {
463 fgfill = PFILL(pGC->fgPixel);
464 bgfill = PFILL(pGC->bgPixel);
467 * OK, so what's going on here? We have two Drawables:
471 * Width = stippleWidth
472 * Words per scanline = stwidth
473 * Pointer to pixels = pStipple->devPrivate.ptr
475 pStipple = pGC->stipple;
477 stwidth = pStipple->devKind / PGSZB;
478 stippleWidth = pStipple->drawable.width;
479 stippleHeight = pStipple->drawable.height;
484 * Width = determined from *pwidth
485 * Words per scanline = nlwidth
486 * Pointer to pixels = addrlBase
489 cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrlBase)
491 /* this replaces rotating the stipple. Instead we just adjust the offset
492 * at which we start grabbing bits from the stipple.
493 * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
494 * so that iline and xrem always stay within the stipple bounds.
496 modulus (pGC->patOrg.x, stippleWidth, xSrc);
497 xSrc += pDrawable->x - stippleWidth;
498 modulus (pGC->patOrg.y, stippleHeight, ySrc);
499 ySrc += pDrawable->y - stippleHeight;
503 iline = (ppt->y - ySrc) % stippleHeight;
505 pdst = addrlBase + (ppt->y * nlwidth);
506 psrcS = (unsigned long *) pStipple->devPrivate.ptr + (iline * stwidth);
514 register unsigned long *ptemp;
515 register unsigned long *pdsttmp;
517 * Do a stripe through the stipple & destination w pixels
518 * wide. w is not more than:
519 * - the width of the destination
520 * - the width of the stipple
521 * - the distance between x and the next word
522 * boundary in the destination
523 * - the distance between x and the next word
524 * boundary in the stipple
527 /* width of dest/stipple */
528 xrem = (x - xSrc) % stippleWidth;
532 w = min((stippleWidth - xrem), width);
533 /* dist to word bound in dest */
534 w = min(w, PPW - (x & PIM));
535 /* dist to word bound in stip */
536 w = min(w, MFB_PPW - (x & MFB_PIM));
539 xtemp = (xrem & MFB_PIM);
540 ptemp = (unsigned long *)(psrcS + (xrem >> MFB_PWSH));
543 pdsttmp = pdst + ((x * 3)>>2);
546 pdsttmp = pdst + (x>>PWSH);
548 switch ( pGC->fillStyle ) {
549 case FillOpaqueStippled:
551 getstipplepixels24(ptemp, xtemp, 0, &bgfill, &tmpDst1, xrem);
552 getstipplepixels24(ptemp, xtemp, 1, &fgfill, &tmpDst2, xrem);
554 getstipplepixels(ptemp, xtemp, w, 0, &bgfill, &tmpDst1);
555 getstipplepixels(ptemp, xtemp, w, 1, &fgfill, &tmpDst2);
559 /* Fill tmpSrc with the source pixels */
561 getbits24(pdsttmp, tmpSrc, x);
562 getstipplepixels24(ptemp, xtemp, 0, &tmpSrc, &tmpDst1, xrem);
564 getbits(pdsttmp, tmpx, w, tmpSrc);
565 getstipplepixels(ptemp, xtemp, w, 0, &tmpSrc, &tmpDst1);
567 if (rop != stiprop) {
569 putbitsrop24(fgfill, 0, &tmpSrc, pGC->planemask, stiprop);
571 putbitsrop(fgfill, 0, w, &tmpSrc, pGC->planemask, stiprop);
577 getstipplepixels24(ptemp, xtemp, 1, &tmpSrc, &tmpDst2, xrem);
579 getstipplepixels(ptemp, xtemp, w, 1, &tmpSrc, &tmpDst2);
585 putbitsrop24(tmpDst2, tmpx, pdsttmp, pGC->planemask, rop);
587 putbitsrop(tmpDst2, tmpx, w, pdsttmp, pGC->planemask, rop);
596 DEALLOCATE_LOCAL(pptFree);
597 DEALLOCATE_LOCAL(pwidthFree);
600 #endif /* PSZ == 8 */
605 cfb8Stipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
606 DrawablePtr pDrawable;
608 int nInit; /* number of spans to fill */
609 DDXPointPtr pptInit; /* pointer to list of start points */
610 int *pwidthInit; /* pointer to list of n widths */
613 /* next three parameters are post-clip */
614 int n; /* number of spans to fill */
615 DDXPointPtr ppt; /* pointer to list of start points */
616 int *pwidth; /* pointer to list of n widths */
617 unsigned long *src; /* pointer to bits in stipple, if needed */
618 int stippleHeight; /* height of the stipple */
621 int nlwDst; /* width in longwords of the dest pixmap */
622 int x,y,w; /* current span */
623 unsigned long startmask;
624 unsigned long endmask;
625 register unsigned long *dst; /* pointer to bits we're writing */
627 unsigned long *dstTmp;
630 unsigned long *pbits; /* pointer to start of pixmap */
631 register unsigned long xor;
632 register unsigned long mask;
633 register unsigned long bits; /* bits from stipple */
636 int *pwidthFree; /* copies of the pointers to free */
638 cfbPrivGCPtr devPriv;
640 devPriv = cfbGetGCPrivate(pGC);
641 cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
642 n = nInit * miFindMaxBand(devPriv->pCompositeClip);
645 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
646 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
647 if(!pptFree || !pwidthFree)
649 if (pptFree) DEALLOCATE_LOCAL(pptFree);
650 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
655 n = miClipSpans(devPriv->pCompositeClip,
656 pptInit, pwidthInit, nInit,
657 ppt, pwidth, fSorted);
659 stipple = devPriv->pRotatedPixmap;
660 src = (unsigned long *)stipple->devPrivate.ptr;
661 stippleHeight = stipple->drawable.height;
663 cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
671 dst = pbits + (y * nlwDst) + (x >> PWSH);
672 if (((x & PIM) + w) <= PPW)
674 maskpartialbits(x, w, startmask);
680 maskbits (x, w, startmask, endmask, nlw);
682 bits = src[y % stippleHeight];
683 RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
685 if (cfb8StippleRRop == GXcopy)
692 mask = cfb8PixelMasks[GetBitGroup(bits)];
693 *dst = (*dst & ~(mask & startmask)) |
694 (xor & (mask & startmask));
696 RotBitsLeft (bits, PGSZB);
700 WriteBitGroup (dst,xor,GetBitGroup(bits))
702 RotBitsLeft (bits, PGSZB);
706 mask = cfb8PixelMasks[GetBitGroup(bits)];
707 *dst = (*dst & ~(mask & endmask)) |
708 (xor & (mask & endmask));
712 { /* XXX constants probably not OK here */
713 wEnd = 7 - (nlw & 7);
714 nlw = (nlw >> 3) + 1;
719 mask = cfb8PixelMasks[GetBitGroup(bits)];
720 *dstTmp = (*dstTmp & ~(mask & startmask)) |
721 (xor & (mask & startmask));
723 RotBitsLeft (bits, PGSZB);
731 #if defined(__GNUC__) && defined(mc68020)
732 mask = cfb8PixelMasks[GetBitGroup(bits)];
737 *dst = (*dst & mask) | xor;
742 #define SwitchBitsLoop(body) \
748 SwitchBitGroup(dst, xor, GetBitGroup(bits));
749 #undef SwitchBitsLoop
757 mask = cfb8PixelMasks[GetBitGroup(bits)];
758 dst = dstTmp + (nlwTmp << 3);
759 *dst = (*dst & ~(mask & endmask)) |
760 (xor & (mask & endmask));
767 #if defined(__GNUC__) && defined(mc68020)
768 mask = cfb8PixelMasks[GetBitGroup(bits)];
773 *dst = (*dst & mask) | xor;
778 #define SwitchBitsLoop(body) \
784 SwitchBitGroup(dst, xor, GetBitGroup(bits));
785 #undef SwitchBitsLoop
792 #endif /* PPW == 4 */
796 xor = GetBitGroup(bits);
797 *dst = MaskRRopPixels(*dst, xor, startmask);
799 RotBitsLeft (bits, PGSZB);
803 RRopBitGroup(dst, GetBitGroup(bits));
805 RotBitsLeft (bits, PGSZB);
809 xor = GetBitGroup(bits);
810 *dst = MaskRRopPixels(*dst, xor, endmask);
814 DEALLOCATE_LOCAL(pptFree);
815 DEALLOCATE_LOCAL(pwidthFree);
819 cfb8OpaqueStipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
820 DrawablePtr pDrawable;
822 int nInit; /* number of spans to fill */
823 DDXPointPtr pptInit; /* pointer to list of start points */
824 int *pwidthInit; /* pointer to list of n widths */
827 /* next three parameters are post-clip */
828 int n; /* number of spans to fill */
829 DDXPointPtr ppt; /* pointer to list of start points */
830 int *pwidth; /* pointer to list of n widths */
831 unsigned long *src; /* pointer to bits in stipple, if needed */
832 int stippleHeight; /* height of the stipple */
835 int nlwDst; /* width in longwords of the dest pixmap */
836 int x,y,w; /* current span */
837 unsigned long startmask;
838 unsigned long endmask;
839 register unsigned long *dst; /* pointer to bits we're writing */
841 unsigned long *dstTmp;
844 unsigned long *pbits; /* pointer to start of pixmap */
845 register unsigned long xor;
846 register unsigned long mask;
847 register unsigned long bits; /* bits from stipple */
850 int *pwidthFree; /* copies of the pointers to free */
852 cfbPrivGCPtr devPriv;
854 devPriv = cfbGetGCPrivate(pGC);
856 cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
858 n = nInit * miFindMaxBand(devPriv->pCompositeClip);
861 pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
862 pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
863 if(!pptFree || !pwidthFree)
865 if (pptFree) DEALLOCATE_LOCAL(pptFree);
866 if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
871 n = miClipSpans(devPriv->pCompositeClip,
872 pptInit, pwidthInit, nInit,
873 ppt, pwidth, fSorted);
875 stipple = devPriv->pRotatedPixmap;
876 src = (unsigned long *)stipple->devPrivate.ptr;
877 stippleHeight = stipple->drawable.height;
879 cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
887 dst = pbits + (y * nlwDst) + (x >> PWSH);
888 if (((x & PIM) + w) <= PPW)
890 maskpartialbits(x, w, startmask);
896 maskbits (x, w, startmask, endmask, nlw);
898 bits = src[y % stippleHeight];
899 RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
901 if (cfb8StippleRRop == GXcopy)
908 *dst = *dst & ~startmask |
909 GetPixelGroup (bits) & startmask;
911 RotBitsLeft (bits, PGSZB);
915 *dst++ = GetPixelGroup(bits);
916 RotBitsLeft (bits, PGSZB);
920 *dst = *dst & ~endmask |
921 GetPixelGroup (bits) & endmask;
925 { /* XXX consts probably not OK here */
926 wEnd = 7 - (nlw & 7);
927 nlw = (nlw >> 3) + 1;
932 *dstTmp = *dstTmp & ~startmask |
933 GetPixelGroup (bits) & startmask;
935 RotBitsLeft (bits, PGSZB);
943 xor = GetPixelGroup (bits);
955 dst = dstTmp + (nlwTmp << 3);
956 *dst = (*dst & ~endmask) |
957 GetPixelGroup (bits) & endmask;
964 xor = GetPixelGroup (bits);
975 #endif /* PPW == 4 */
979 xor = GetBitGroup(bits);
980 *dst = MaskRRopPixels(*dst, xor, startmask);
982 RotBitsLeft (bits, PGSZB);
986 RRopBitGroup(dst, GetBitGroup(bits));
988 RotBitsLeft (bits, PGSZB);
992 xor = GetBitGroup(bits);
993 *dst = MaskRRopPixels(*dst, xor, endmask);
997 DEALLOCATE_LOCAL(pptFree);
998 DEALLOCATE_LOCAL(pwidthFree);
1001 #endif /* PSZ == 8 */