summaryrefslogtreecommitdiff
path: root/cfb/cfbfillsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfb/cfbfillsp.c')
-rw-r--r--cfb/cfbfillsp.c960
1 files changed, 960 insertions, 0 deletions
diff --git a/cfb/cfbfillsp.c b/cfb/cfbfillsp.c
new file mode 100644
index 000000000..b0de9bd7d
--- /dev/null
+++ b/cfb/cfbfillsp.c
@@ -0,0 +1,960 @@
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or The Open Group
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and The Open Group make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $Xorg: cfbfillsp.c,v 1.4 2001/02/09 02:04:37 xorgcvs Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+#include "cfb.h"
+#include "cfbmskbits.h"
+
+#include "mergerop.h"
+
+#if PSZ == 8
+#include "cfb8bit.h"
+#endif
+
+#define MFB_CONSTS_ONLY
+#include "maskbits.h"
+
+#include "mi.h"
+#include "mispans.h"
+
+/* scanline filling for color frame buffer
+ written by drewry, oct 1986 modified by smarks
+ changes for compatibility with Little-endian systems Jul 1987; MIT:yba.
+
+ these routines all clip. they assume that anything that has called
+them has already translated the points (i.e. pGC->miTranslate is
+non-zero, which is howit gets set in cfbCreateGC().)
+
+ the number of new scnalines created by clipping ==
+MaxRectsPerBand * nSpans.
+
+ FillSolid is overloaded to be used for OpaqueStipple as well,
+if fgPixel == bgPixel.
+Note that for solids, PrivGC.rop == PrivGC.ropOpStip
+
+
+ FillTiled is overloaded to be used for OpaqueStipple, if
+fgPixel != bgPixel. based on the fill style, it uses
+{RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip}
+*/
+
+#ifdef notdef
+#include <stdio.h>
+static
+dumpspans(n, ppt, pwidth)
+ int n;
+ DDXPointPtr ppt;
+ int *pwidth;
+{
+ fprintf(stderr,"%d spans\n", n);
+ while (n--) {
+ fprintf(stderr, "[%d,%d] %d\n", ppt->x, ppt->y, *pwidth);
+ ppt++;
+ pwidth++;
+ }
+ fprintf(stderr, "\n");
+}
+#endif
+
+/* Fill spans with tiles that aren't 32 bits wide */
+void
+cfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+DrawablePtr pDrawable;
+GC *pGC;
+int nInit; /* number of spans to fill */
+DDXPointPtr pptInit; /* pointer to list of start points */
+int *pwidthInit; /* pointer to list of n widths */
+int fSorted;
+{
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ void (*fill)();
+ int xrot, yrot;
+
+ if (!(pGC->planemask))
+ return;
+
+ if (pGC->tile.pixmap->drawable.width & PIM)
+ {
+ fill = cfbFillSpanTileOddGeneral;
+ if ((pGC->planemask & PMSK) == PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = cfbFillSpanTileOddCopy;
+ }
+ }
+ else
+ {
+ fill = cfbFillSpanTile32sGeneral;
+ if ((pGC->planemask & PMSK) == PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = cfbFillSpanTile32sCopy;
+ }
+ }
+ n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
+ if ( n == 0 )
+ return;
+ pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!ppt || !pwidth)
+ {
+ if (ppt) DEALLOCATE_LOCAL(ppt);
+ if (pwidth) DEALLOCATE_LOCAL(pwidth);
+ return;
+ }
+ n = miClipSpans( cfbGetCompositeClip(pGC),
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ xrot = pDrawable->x + pGC->patOrg.x;
+ yrot = pDrawable->y + pGC->patOrg.y;
+
+ (*fill) (pDrawable, n, ppt, pwidth, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
+
+ DEALLOCATE_LOCAL(ppt);
+ DEALLOCATE_LOCAL(pwidth);
+}
+
+#if PSZ == 8
+
+void
+cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+DrawablePtr pDrawable;
+GC *pGC;
+int nInit; /* number of spans to fill */
+DDXPointPtr pptInit; /* pointer to list of start points */
+int *pwidthInit; /* pointer to list of n widths */
+int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidth; /* pointer to list of n widths */
+ int *pwidthFree;/* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ unsigned long *pdstBase; /* pointer to start of bitmap */
+ int nlwDst; /* width in longwords of bitmap */
+ register unsigned long *pdst; /* pointer to current word in bitmap */
+ PixmapPtr pStipple; /* pointer to stipple we want to fill with */
+ int nlw;
+ int x, y, w, xrem, xSrc, ySrc;
+ int stwidth, stippleWidth;
+ int stippleHeight;
+ register unsigned long bits, inputBits;
+ register int partBitsLeft;
+ int nextPartBits;
+ int bitsLeft, bitsWhole;
+ unsigned long *srcTemp, *srcStart;
+ unsigned long *psrcBase;
+ unsigned long startmask, endmask;
+
+ if (pGC->fillStyle == FillStippled)
+ cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
+ else
+ cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
+
+ if (cfb8StippleRRop == GXnoop)
+ return;
+
+ n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
+ if ( n == 0 )
+ return;
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans( cfbGetCompositeClip(pGC),
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ /*
+ * OK, so what's going on here? We have two Drawables:
+ *
+ * The Stipple:
+ * Depth = 1
+ * Width = stippleWidth
+ * Words per scanline = stwidth
+ * Pointer to pixels = pStipple->devPrivate.ptr
+ */
+
+ pStipple = pGC->stipple;
+
+ stwidth = pStipple->devKind >> PWSH;
+ stippleWidth = pStipple->drawable.width;
+ stippleHeight = pStipple->drawable.height;
+ psrcBase = (unsigned long *) pStipple->devPrivate.ptr;
+
+ /*
+ * The Target:
+ * Depth = PSZ
+ * Width = determined from *pwidth
+ * Words per scanline = nlwDst
+ * Pointer to pixels = addrlBase
+ */
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
+
+ /* this replaces rotating the stipple. Instead we just adjust the offset
+ * at which we start grabbing bits from the stipple.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and xrem always stay within the stipple bounds.
+ */
+
+ modulus (pGC->patOrg.x, stippleWidth, xSrc);
+ xSrc += pDrawable->x - stippleWidth;
+ modulus (pGC->patOrg.y, stippleHeight, ySrc);
+ ySrc += pDrawable->y - stippleHeight;
+
+ bitsWhole = stippleWidth;
+
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ w = *pwidth++;
+ pdst = pdstBase + y * nlwDst + (x >> PWSH);
+ y = (y - ySrc) % stippleHeight;
+ srcStart = psrcBase + y * stwidth;
+ xrem = ((x & ~(PGSZB-1)) - xSrc) % stippleWidth;
+ srcTemp = srcStart + (xrem >> MFB_PWSH);
+ bitsLeft = stippleWidth - (xrem & ~MFB_PIM);
+ xrem &= MFB_PIM;
+ NextUnnaturalStippleWord
+ if (partBitsLeft < xrem)
+ FatalError ("cfbUnnaturalStippleFS bad partBitsLeft %d xrem %d",
+ partBitsLeft, xrem);
+ NextSomeBits (inputBits, xrem);
+ partBitsLeft -= xrem;
+ if (((x & PIM) + w) <= PPW)
+ {
+ maskpartialbits (x, w, startmask)
+ NextUnnaturalStippleBits
+ *pdst = MaskRRopPixels(*pdst,bits,startmask);
+ }
+ else
+ {
+ maskbits (x, w, startmask, endmask, nlw);
+ nextPartBits = (x & (PGSZB-1)) + w;
+ if (nextPartBits < partBitsLeft)
+ {
+ if (startmask)
+ {
+ MaskRRopBitGroup(pdst,GetBitGroup(inputBits),startmask)
+ pdst++;
+ NextBitGroup (inputBits);
+ }
+ while (nlw--)
+ {
+ RRopBitGroup (pdst, GetBitGroup (inputBits));
+ pdst++;
+ NextBitGroup (inputBits);
+ }
+ if (endmask)
+ {
+ MaskRRopBitGroup(pdst,GetBitGroup(inputBits),endmask)
+ }
+ }
+ else if (bitsLeft != bitsWhole && nextPartBits < partBitsLeft + bitsLeft)
+ {
+ NextUnnaturalStippleBitsFast
+ if (startmask)
+ {
+ *pdst = MaskRRopPixels(*pdst,bits,startmask);
+ pdst++;
+ NextUnnaturalStippleBitsFast
+ }
+ while (nlw--)
+ {
+ *pdst = RRopPixels(*pdst,bits);
+ pdst++;
+ NextUnnaturalStippleBitsFast
+ }
+ if (endmask)
+ *pdst = MaskRRopPixels (*pdst,bits,endmask);
+ }
+ else
+ {
+ NextUnnaturalStippleBits
+ if (startmask)
+ {
+ *pdst = MaskRRopPixels(*pdst,bits,startmask);
+ pdst++;
+ NextUnnaturalStippleBits
+ }
+ while (nlw--)
+ {
+ *pdst = RRopPixels(*pdst,bits);
+ pdst++;
+ NextUnnaturalStippleBits
+ }
+ if (endmask)
+ *pdst = MaskRRopPixels(*pdst,bits,endmask);
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+#else /* PSZ != 8 */
+
+/* Fill spans with stipples that aren't 32 bits wide */
+void
+cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+DrawablePtr pDrawable;
+GC *pGC;
+int nInit; /* number of spans to fill */
+DDXPointPtr pptInit; /* pointer to list of start points */
+int *pwidthInit; /* pointer to list of n widths */
+int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ int iline; /* first line of tile to use */
+ unsigned long *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register unsigned long *pdst; /* pointer to current word in bitmap */
+ PixmapPtr pStipple; /* pointer to stipple we want to fill with */
+ register int w;
+ int width, x, xrem, xSrc, ySrc;
+ unsigned long tmpSrc, tmpDst1, tmpDst2;
+ int stwidth, stippleWidth;
+ unsigned long *psrcS;
+ int rop, stiprop;
+ int stippleHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ unsigned long fgfill, bgfill;
+
+ if (!(pGC->planemask))
+ return;
+
+ n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
+ if ( n == 0 )
+ return;
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans( cfbGetCompositeClip(pGC),
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+ rop = pGC->alu;
+ if (pGC->fillStyle == FillStippled) {
+ switch (rop) {
+ case GXand:
+ case GXcopy:
+ case GXnoop:
+ case GXor:
+ stiprop = rop;
+ break;
+ default:
+ stiprop = rop;
+ rop = GXcopy;
+ }
+ }
+ fgfill = PFILL(pGC->fgPixel);
+ bgfill = PFILL(pGC->bgPixel);
+
+ /*
+ * OK, so what's going on here? We have two Drawables:
+ *
+ * The Stipple:
+ * Depth = 1
+ * Width = stippleWidth
+ * Words per scanline = stwidth
+ * Pointer to pixels = pStipple->devPrivate.ptr
+ */
+ pStipple = pGC->stipple;
+
+ stwidth = pStipple->devKind / PGSZB;
+ stippleWidth = pStipple->drawable.width;
+ stippleHeight = pStipple->drawable.height;
+
+ /*
+ * The Target:
+ * Depth = PSZ
+ * Width = determined from *pwidth
+ * Words per scanline = nlwidth
+ * Pointer to pixels = addrlBase
+ */
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrlBase)
+
+ /* this replaces rotating the stipple. Instead we just adjust the offset
+ * at which we start grabbing bits from the stipple.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and xrem always stay within the stipple bounds.
+ */
+ modulus (pGC->patOrg.x, stippleWidth, xSrc);
+ xSrc += pDrawable->x - stippleWidth;
+ modulus (pGC->patOrg.y, stippleHeight, ySrc);
+ ySrc += pDrawable->y - stippleHeight;
+
+ while (n--)
+ {
+ iline = (ppt->y - ySrc) % stippleHeight;
+ x = ppt->x;
+ pdst = addrlBase + (ppt->y * nlwidth);
+ psrcS = (unsigned long *) pStipple->devPrivate.ptr + (iline * stwidth);
+
+ if (*pwidth)
+ {
+ width = *pwidth;
+ while(width > 0)
+ {
+ int xtemp, tmpx;
+ register unsigned long *ptemp;
+ register unsigned long *pdsttmp;
+ /*
+ * Do a stripe through the stipple & destination w pixels
+ * wide. w is not more than:
+ * - the width of the destination
+ * - the width of the stipple
+ * - the distance between x and the next word
+ * boundary in the destination
+ * - the distance between x and the next word
+ * boundary in the stipple
+ */
+
+ /* width of dest/stipple */
+ xrem = (x - xSrc) % stippleWidth;
+ w = min((stippleWidth - xrem), width);
+ /* dist to word bound in dest */
+ w = min(w, PPW - (x & PIM));
+ /* dist to word bound in stip */
+ w = min(w, MFB_PPW - (x & MFB_PIM));
+
+ xtemp = (xrem & MFB_PIM);
+ ptemp = (unsigned long *)(psrcS + (xrem >> MFB_PWSH));
+ tmpx = x & PIM;
+ pdsttmp = pdst + (x>>PWSH);
+ switch ( pGC->fillStyle ) {
+ case FillOpaqueStippled:
+ getstipplepixels(ptemp, xtemp, w, 0, &bgfill, &tmpDst1);
+ getstipplepixels(ptemp, xtemp, w, 1, &fgfill, &tmpDst2);
+ break;
+ case FillStippled:
+ /* Fill tmpSrc with the source pixels */
+ getbits(pdsttmp, tmpx, w, tmpSrc);
+ getstipplepixels(ptemp, xtemp, w, 0, &tmpSrc, &tmpDst1);
+ if (rop != stiprop) {
+ putbitsrop(fgfill, 0, w, &tmpSrc, pGC->planemask, stiprop);
+ } else {
+ tmpSrc = fgfill;
+ }
+ getstipplepixels(ptemp, xtemp, w, 1, &tmpSrc, &tmpDst2);
+ break;
+ }
+ tmpDst2 |= tmpDst1;
+ putbitsrop(tmpDst2, tmpx, w, pdsttmp, pGC->planemask, rop);
+ x += w;
+ width -= w;
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+#endif /* PSZ == 8 */
+
+#if PSZ == 8
+
+void
+cfb8Stipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidth; /* pointer to list of n widths */
+ unsigned long *src; /* pointer to bits in stipple, if needed */
+ int stippleHeight; /* height of the stipple */
+ PixmapPtr stipple;
+
+ int nlwDst; /* width in longwords of the dest pixmap */
+ int x,y,w; /* current span */
+ unsigned long startmask;
+ unsigned long endmask;
+ register unsigned long *dst; /* pointer to bits we're writing */
+ register int nlw;
+ unsigned long *dstTmp;
+ int nlwTmp;
+
+ unsigned long *pbits; /* pointer to start of pixmap */
+ register unsigned long xor;
+ register unsigned long mask;
+ register unsigned long bits; /* bits from stipple */
+ int wEnd;
+
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ cfbPrivGCPtr devPriv;
+
+ devPriv = cfbGetGCPrivate(pGC);
+ cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
+ n = nInit * miFindMaxBand(devPriv->pCompositeClip);
+ if ( n == 0 )
+ return;
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(devPriv->pCompositeClip,
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ stipple = devPriv->pRotatedPixmap;
+ src = (unsigned long *)stipple->devPrivate.ptr;
+ stippleHeight = stipple->drawable.height;
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
+
+ while (n--)
+ {
+ w = *pwidth++;
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ dst = pbits + (y * nlwDst) + (x >> PWSH);
+ if (((x & PIM) + w) <= PPW)
+ {
+ maskpartialbits(x, w, startmask);
+ endmask = 0;
+ nlw = 0;
+ }
+ else
+ {
+ maskbits (x, w, startmask, endmask, nlw);
+ }
+ bits = src[y % stippleHeight];
+ RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
+ if (cfb8StippleRRop == GXcopy)
+ {
+ xor = devPriv->xor;
+ if (w < (PGSZ*2))
+ {
+ if (startmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ *dst = (*dst & ~(mask & startmask)) |
+ (xor & (mask & startmask));
+ dst++;
+ RotBitsLeft (bits, PGSZB);
+ }
+ while (nlw--)
+ {
+ WriteBitGroup (dst,xor,GetBitGroup(bits))
+ dst++;
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ *dst = (*dst & ~(mask & endmask)) |
+ (xor & (mask & endmask));
+ }
+ }
+ else
+ { /* XXX constants probably not OK here */
+ wEnd = 7 - (nlw & 7);
+ nlw = (nlw >> 3) + 1;
+ dstTmp = dst;
+ nlwTmp = nlw;
+ if (startmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ *dstTmp = (*dstTmp & ~(mask & startmask)) |
+ (xor & (mask & startmask));
+ dstTmp++;
+ RotBitsLeft (bits, PGSZB);
+ }
+ w = 7 - wEnd;
+ while (w--)
+ {
+ dst = dstTmp;
+ dstTmp++;
+ nlw = nlwTmp;
+#if defined(__GNUC__) && defined(mc68020)
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ xor = xor & mask;
+ mask = ~mask;
+ while (nlw--)
+ {
+ *dst = (*dst & mask) | xor;
+ dst += 8;
+ }
+ xor = devPriv->xor;
+#else
+#define SwitchBitsLoop(body) \
+ while (nlw--) \
+ { \
+ body \
+ dst += 8; \
+ }
+ SwitchBitGroup(dst, xor, GetBitGroup(bits));
+#undef SwitchBitsLoop
+#endif
+ NextBitGroup (bits);
+ }
+ nlwTmp--;
+ w = wEnd + 1;
+ if (endmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ dst = dstTmp + (nlwTmp << 3);
+ *dst = (*dst & ~(mask & endmask)) |
+ (xor & (mask & endmask));
+ }
+ while (w--)
+ {
+ nlw = nlwTmp;
+ dst = dstTmp;
+ dstTmp++;
+#if defined(__GNUC__) && defined(mc68020)
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ xor = xor & mask;
+ mask = ~mask;
+ while (nlw--)
+ {
+ *dst = (*dst & mask) | xor;
+ dst += 8;
+ }
+ xor = devPriv->xor;
+#else
+#define SwitchBitsLoop(body) \
+ while (nlw--) \
+ { \
+ body \
+ dst += 8; \
+ }
+ SwitchBitGroup(dst, xor, GetBitGroup(bits));
+#undef SwitchBitsLoop
+#endif
+ NextBitGroup (bits);
+ }
+ }
+ }
+ else
+ {
+ if (startmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, startmask);
+ dst++;
+ RotBitsLeft (bits, PGSZB);
+ }
+ while (nlw--)
+ {
+ RRopBitGroup(dst, GetBitGroup(bits));
+ dst++;
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, endmask);
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+void
+cfb8OpaqueStipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidth; /* pointer to list of n widths */
+ unsigned long *src; /* pointer to bits in stipple, if needed */
+ int stippleHeight; /* height of the stipple */
+ PixmapPtr stipple;
+
+ int nlwDst; /* width in longwords of the dest pixmap */
+ int x,y,w; /* current span */
+ unsigned long startmask;
+ unsigned long endmask;
+ register unsigned long *dst; /* pointer to bits we're writing */
+ register int nlw;
+ unsigned long *dstTmp;
+ int nlwTmp;
+
+ unsigned long *pbits; /* pointer to start of pixmap */
+ register unsigned long xor;
+ register unsigned long mask;
+ register unsigned long bits; /* bits from stipple */
+ int wEnd;
+
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ cfbPrivGCPtr devPriv;
+
+ devPriv = cfbGetGCPrivate(pGC);
+
+ cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
+
+ n = nInit * miFindMaxBand(devPriv->pCompositeClip);
+ if ( n == 0 )
+ return;
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(devPriv->pCompositeClip,
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ stipple = devPriv->pRotatedPixmap;
+ src = (unsigned long *)stipple->devPrivate.ptr;
+ stippleHeight = stipple->drawable.height;
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
+
+ while (n--)
+ {
+ w = *pwidth++;
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ dst = pbits + (y * nlwDst) + (x >> PWSH);
+ if (((x & PIM) + w) <= PPW)
+ {
+ maskpartialbits(x, w, startmask);
+ endmask = 0;
+ nlw = 0;
+ }
+ else
+ {
+ maskbits (x, w, startmask, endmask, nlw);
+ }
+ bits = src[y % stippleHeight];
+ RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
+ if (cfb8StippleRRop == GXcopy)
+ {
+ xor = devPriv->xor;
+ if (w < PGSZ*2)
+ {
+ if (startmask)
+ {
+ *dst = *dst & ~startmask |
+ GetPixelGroup (bits) & startmask;
+ dst++;
+ RotBitsLeft (bits, PGSZB);
+ }
+ while (nlw--)
+ {
+ *dst++ = GetPixelGroup(bits);
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ *dst = *dst & ~endmask |
+ GetPixelGroup (bits) & endmask;
+ }
+ }
+ else
+ { /* XXX consts probably not OK here */
+ wEnd = 7 - (nlw & 7);
+ nlw = (nlw >> 3) + 1;
+ dstTmp = dst;
+ nlwTmp = nlw;
+ if (startmask)
+ {
+ *dstTmp = *dstTmp & ~startmask |
+ GetPixelGroup (bits) & startmask;
+ dstTmp++;
+ RotBitsLeft (bits, PGSZB);
+ }
+ w = 7 - wEnd;
+ while (w--)
+ {
+ nlw = nlwTmp;
+ dst = dstTmp;
+ dstTmp++;
+ xor = GetPixelGroup (bits);
+ while (nlw--)
+ {
+ *dst = xor;
+ dst += 8;
+ }
+ NextBitGroup (bits);
+ }
+ nlwTmp--;
+ w = wEnd + 1;
+ if (endmask)
+ {
+ dst = dstTmp + (nlwTmp << 3);
+ *dst = (*dst & ~endmask) |
+ GetPixelGroup (bits) & endmask;
+ }
+ while (w--)
+ {
+ nlw = nlwTmp;
+ dst = dstTmp;
+ dstTmp++;
+ xor = GetPixelGroup (bits);
+ while (nlw--)
+ {
+ *dst = xor;
+ dst += 8;
+ }
+ NextBitGroup (bits);
+ }
+ }
+ }
+ else
+ {
+ if (startmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, startmask);
+ dst++;
+ RotBitsLeft (bits, PGSZB);
+ }
+ while (nlw--)
+ {
+ RRopBitGroup(dst, GetBitGroup(bits));
+ dst++;
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, endmask);
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+#endif /* PSZ == 8 */