summaryrefslogtreecommitdiff
path: root/afb/afbfillsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'afb/afbfillsp.c')
-rw-r--r--afb/afbfillsp.c1127
1 files changed, 1127 insertions, 0 deletions
diff --git a/afb/afbfillsp.c b/afb/afbfillsp.c
new file mode 100644
index 000000000..69985aebc
--- /dev/null
+++ b/afb/afbfillsp.c
@@ -0,0 +1,1127 @@
+/* $XFree86: xc/programs/Xserver/afb/afbfillsp.c,v 3.4 2001/10/28 03:32:58 tsi Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+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.
+
+******************************************************************/
+/* $XConsortium: afbfillsp.c,v 5.13 94/04/17 20:28:21 dpw Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "afb.h"
+
+#include "maskbits.h"
+
+#include "mergerop.h"
+
+#include "servermd.h"
+#include "mi.h"
+#include "mispans.h"
+
+/* scanline filling for monochrome frame buffer
+ written by drewry, oct 1986
+
+ 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 afbCreateGC().)
+
+ the number of new scnalines created by clipping ==
+MaxRectsPerBand * nSpans.
+
+*/
+
+
+void
+afbSolidFS(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 */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl;/* pointer to current longword in bitmap */
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int depthDst;
+ int sizeDst;
+ int d;
+ unsigned char *rrops;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ 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(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst,
+ pBase);
+ rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops;
+ while (n--) {
+ addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth);
+
+ for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ if (*pwidth) {
+ addrl = addrlBase;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ /* all bits inside same longword */
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl &= ~startmask;
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ &= ~startmask;
+ Duff (nlmiddle, *addrl++ = 0x0);
+ if (endmask)
+ *addrl &= ~endmask;
+ }
+ break;
+
+ case RROP_WHITE:
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ /* all bits inside same longword */
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl |= startmask;
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ |= startmask;
+ Duff (nlmiddle, *addrl++ = ~0);
+ if (endmask)
+ *addrl |= endmask;
+ }
+ break;
+ case RROP_INVERT:
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ /* all bits inside same longword */
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl ^= startmask;
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ ^= startmask;
+ Duff (nlmiddle, *addrl++ ^= ~0);
+ if (endmask)
+ *addrl ^= endmask;
+ }
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+void
+afbStippleFS(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 */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl;/* pointer to current longword in bitmap */
+ register PixelType src;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pStipple;
+ PixelType *psrc;
+ int tileHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int d;
+ int depthDst;
+ int sizeDst;
+ unsigned char *rrops;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ 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(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst,
+ pBase);
+
+ pStipple = pGC->pRotatedPixmap;
+ tileHeight = pStipple->drawable.height;
+ psrc = (PixelType *)(pStipple->devPrivate.ptr);
+
+ rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops;
+
+ while (n--) {
+ src = psrc[ppt->y % tileHeight];
+ addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth);
+ for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ addrl = addrlBase;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ /* all bits inside same longword */
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl &= ~(src & startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ &= ~(src & startmask);
+ Duff (nlmiddle, *addrl++ &= ~src);
+ if (endmask)
+ *addrl &= ~(src & endmask);
+ }
+ break;
+ case RROP_WHITE:
+ /* all bits inside same longword */
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl |= (src & startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ |= (src & startmask);
+ Duff (nlmiddle, *addrl++ |= src);
+ if (endmask)
+ *addrl |= (src & endmask);
+ }
+ break;
+ case RROP_INVERT:
+ /* all bits inside same longword */
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl ^= (src & startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ ^= (src & startmask);
+ Duff (nlmiddle, *addrl++ ^= src);
+ if (endmask)
+ *addrl ^= (src & endmask);
+ }
+ break;
+
+ case RROP_NOP:
+ break;
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+void
+afbTileFS(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 */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl; /* pointer to current longword in bitmap */
+ register PixelType src;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pTile;
+ PixelType *psrc;
+ int tileHeight;
+ int rop;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int sizeDst;
+ int depthDst;
+ int d;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ 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(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst,
+ pBase);
+
+ pTile = pGC->pRotatedPixmap;
+ tileHeight = pTile->drawable.height;
+ psrc = (PixelType *)(pTile->devPrivate.ptr);
+ rop = pGC->alu;
+
+ switch(rop) {
+ case GXcopy:
+#define DoMaskCopyRop(src,dst,mask) (((dst) & ~(mask)) | ((src) & (mask)))
+ while (n--) {
+ if (*pwidth) {
+ addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth);
+
+ for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ if (!(pGC->planemask & (1 << d)))
+ continue;
+
+ addrl = addrlBase;
+ src = psrc[ppt->y % tileHeight + tileHeight * d];
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask) {
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--) {
+ *addrl = src;
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskCopyRop (src, *addrl, endmask);
+ }
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ break;
+
+ default:
+ {
+ register DeclareMergeRop ();
+
+ InitializeMergeRop(rop,~0);
+ while (n--) {
+ if (*pwidth) {
+ addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth);
+ for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ if (!(pGC->planemask & (1 << d)))
+ continue;
+
+ addrl = addrlBase;
+
+ src = psrc[ppt->y % tileHeight + tileHeight * d];
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask) {
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--) {
+ *addrl = DoMergeRop (src, *addrl);
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskMergeRop (src, *addrl, endmask);
+ }
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ break;
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+void
+afbOpaqueStippleFS(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 */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl; /* pointer to current longword in bitmap */
+ register PixelType src = 0;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pTile;
+ PixelType *psrc;
+ int tileHeight;
+ int rop;
+ unsigned char *rropsOS;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int sizeDst;
+ int depthDst;
+ int d;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ 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(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst,
+ pBase);
+
+ pTile = pGC->pRotatedPixmap;
+ tileHeight = pTile->drawable.height;
+ psrc = (PixelType *)(pTile->devPrivate.ptr);
+ rop = pGC->alu;
+ rropsOS = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rropOS;
+
+ switch(rop) {
+ case GXcopy:
+ while (n--) {
+ addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth);
+ if (*pwidth) {
+ for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ src = 0;
+ break;
+ case RROP_WHITE:
+ src = ~0;
+ break;
+ case RROP_INVERT:
+ src = ~psrc[ppt->y % tileHeight];
+ break;
+ case RROP_COPY:
+ src = psrc[ppt->y % tileHeight];
+ break;
+ case RROP_NOP:
+ continue;
+ }
+
+ addrl = addrlBase;
+
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask) {
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--) {
+ *addrl = src;
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskCopyRop (src, *addrl, endmask);
+ }
+ } /* for (d = ...) */
+ }
+
+ pwidth++;
+ ppt++;
+ }
+ break;
+
+ default:
+ {
+ register DeclareMergeRop ();
+
+ InitializeMergeRop(rop,~0);
+ while (n--) {
+ addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth);
+ if (*pwidth) {
+ for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ src = 0;
+ break;
+ case RROP_WHITE:
+ src = ~0;
+ break;
+ case RROP_INVERT:
+ src = ~psrc[ppt->y % tileHeight];
+ break;
+ case RROP_COPY:
+ src = psrc[ppt->y % tileHeight];
+ break;
+ case RROP_NOP:
+ continue;
+ }
+
+ addrl = addrlBase;
+
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask) {
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--) {
+ *addrl = DoMergeRop (src, *addrl);
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskMergeRop (src, *addrl, endmask);
+ }
+ } /* for (d = ...) */
+ }
+ pwidth++;
+ ppt++;
+ } /* while (n) */
+ break;
+ }
+ } /* switch (rop) */
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+/* Fill spans with tiles that aren't PPW bits wide */
+void
+afbUnnaturalTileFS(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 iline; /* first line of tile to use */
+ /* 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 */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *pdst;/* pointer to current word in bitmap */
+ register PixelType *psrc;/* pointer to current word in tile */
+ register int nlMiddle;
+ register int rop, nstart;
+ PixelType startmask;
+ PixmapPtr pTile; /* pointer to tile we want to fill with */
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ int tlwidth, rem, tileWidth, tileHeight, endinc;
+ PixelType endmask, *psrcT;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int sizeDst;
+ int sizeTile;
+ int depthDst;
+ register int d;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ 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(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ pTile = pGC->tile.pixmap;
+ tlwidth = pTile->devKind / PGSZB;
+ rop = pGC->alu;
+
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+
+ afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst,
+ pBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+ sizeTile = tlwidth * tileHeight;
+
+ /* this replaces rotating the tile. Instead we just adjust the offset
+ * at which we start grabbing bits from the tile.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and rem always stay within the tile bounds.
+ */
+ xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
+ ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
+
+ while (n--) {
+ iline = (ppt->y - ySrc) % tileHeight;
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth);
+
+ for (d = 0; d < depthDst; d++, psrcT += sizeTile, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ if (!(pGC->planemask & (1 << d)))
+ continue;
+
+ if (*pwidth) {
+ x = ppt->x;
+ pdst = addrlBase;
+ width = *pwidth;
+ while(width > 0) {
+ psrc = psrcT;
+ w = min(tileWidth, width);
+ if((rem = (x - xSrc) % tileWidth) != 0) {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+ getandputrop((psrc+endinc), (rem&PIM), (x & PIM), w, pdst, rop);
+ if((x & PIM) + w >= PPW)
+ pdst++;
+ } else if(((x & PIM) + w) < PPW) {
+ /* doing < PPW bits is easy, and worth special-casing */
+ putbitsrop(*psrc, x & PIM, w, pdst, rop);
+ } else {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if(startmask) {
+ putbitsrop(*psrc, (x & PIM), nstart, pdst, rop);
+ pdst++;
+ if(srcStartOver)
+ psrc++;
+ }
+
+ while(nlMiddle--) {
+ getandputrop0(psrc, nstart, PPW, pdst, rop);
+ pdst++;
+ psrc++;
+ }
+ if(endmask) {
+ getandputrop0(psrc, nstart, nend, pdst, rop);
+ }
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+/* Fill spans with stipples that aren't PPW bits wide */
+void
+afbUnnaturalStippleFS(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 */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *pdst; /* pointer to current word in bitmap */
+ register PixelType *psrc; /* pointer to current word in tile */
+ register int nlMiddle;
+ register int rop, nstart;
+ PixelType startmask;
+ PixmapPtr pTile; /* pointer to tile we want to fill with */
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ PixelType endmask, *psrcT;
+ int tlwidth, rem, tileWidth, endinc;
+ int tileHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ unsigned char *rrops;
+ register int d;
+ int sizeDst;
+ int depthDst;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ 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(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ pTile = pGC->stipple;
+ tlwidth = pTile->devKind / PGSZB;
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+ afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst,
+ pBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+ rrops = ((afbPrivGC *)(pGC->devPrivates[afbGCPrivateIndex].ptr))->rrops;
+
+ /* 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 rem always stay within the tile bounds.
+ */
+ xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
+ ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
+ while (n--) {
+ iline = (ppt->y - ySrc) % tileHeight;
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth);
+
+ for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ rop = rrops[d];
+ if (rop == RROP_NOP)
+ continue;
+
+ pdst = addrlBase;
+ x = ppt->x;
+
+ if (*pwidth) {
+ width = *pwidth;
+ while(width > 0) {
+ psrc = psrcT;
+ w = min(tileWidth, width);
+ if((rem = (x - xSrc) % tileWidth) != 0) {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+ getandputrrop((psrc + endinc), (rem & PIM), (x & PIM),
+ w, pdst, rop)
+ if((x & PIM) + w >= PPW)
+ pdst++;
+ } else if(((x & PIM) + w) < PPW) {
+ /* doing < PPW bits is easy, and worth special-casing */
+ putbitsrrop(*psrc, x & PIM, w, pdst, rop);
+ } else {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if(startmask) {
+ putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop);
+ pdst++;
+ if(srcStartOver)
+ psrc++;
+ }
+
+ while(nlMiddle--) {
+ getandputrrop0(psrc, nstart, PPW, pdst, rop);
+ pdst++;
+ psrc++;
+ }
+ if(endmask) {
+ getandputrrop0(psrc, nstart, nend, pdst, rop);
+ }
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+/* Fill spans with OpaqueStipples that aren't PPW bits wide */
+void
+afbUnnaturalOpaqueStippleFS(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 iline; /* first line of tile to use */
+ /* 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 */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *pdst;/* pointer to current word in bitmap */
+ register PixelType *psrc;/* pointer to current word in tile */
+ register int nlMiddle;
+ register int d;
+ register PixelType tmpsrc = 0;
+ register PixelType tmpdst;
+ register int alu, nstart;
+ register unsigned char *rropsOS;
+ PixelType startmask;
+ PixmapPtr pTile; /* pointer to tile we want to fill with */
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ int tlwidth, rem, tileWidth, tileHeight, endinc;
+ PixelType endmask, *psrcT;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int sizeDst;
+ int depthDst;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ 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(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ pTile = pGC->stipple;
+ tlwidth = pTile->devKind / PGSZB;
+ alu = pGC->alu;
+
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+
+ afbGetPixelWidthSizeDepthAndPointer(pDrawable, nlwidth, sizeDst, depthDst,
+ pBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+ rropsOS = afbGetGCPrivate(pGC)->rropOS;
+
+ /* this replaces rotating the tile. Instead we just adjust the offset
+ * at which we start grabbing bits from the tile.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and rem always stay within the tile bounds.
+ */
+ xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
+ ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
+
+ while (n--) {
+ iline = (ppt->y - ySrc) % tileHeight;
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ addrlBase = afbScanline(pBase, ppt->x, ppt->y, nlwidth);
+
+ for (d = 0; d < depthDst; d++, addrlBase += sizeDst) { /* @@@ NEXT PLANE @@@ */
+ if (!(pGC->planemask & (1 << d)))
+ continue;
+
+ if (*pwidth) {
+ x = ppt->x;
+ pdst = addrlBase;
+ width = *pwidth;
+ while(width > 0) {
+ psrc = psrcT;
+ w = min(tileWidth, width);
+ if((rem = (x - xSrc) % tileWidth) != 0) {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+
+ case RROP_COPY:
+ getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
+ break;
+
+ case RROP_INVERT:
+ getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
+ tmpsrc = ~tmpsrc;
+ break;
+ }
+
+ if (alu != GXcopy) {
+ getbits (pdst, (x & PIM), w, tmpdst);
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+
+ putbits (tmpsrc, (x & PIM), w, pdst);
+ if((x & PIM) + w >= PPW)
+ pdst++;
+ } else if(((x & PIM) + w) < PPW) {
+ /* doing < PPW bits is easy, and worth special-casing */
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+ case RROP_COPY:
+ tmpsrc = *psrc;
+ break;
+ case RROP_INVERT:
+ tmpsrc = ~*psrc;
+ break;
+ }
+ if (alu != GXcopy) {
+ getbits (pdst, (x & PIM), w, tmpdst);
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+ putbits (tmpsrc, (x & PIM), w, pdst);
+ } else {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if(startmask) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+ case RROP_COPY:
+ tmpsrc = *psrc;
+ break;
+ case RROP_INVERT:
+ tmpsrc = ~*psrc;
+ break;
+ }
+ if (alu != GXcopy) {
+ getbits (pdst, (x & PIM), nstart, tmpdst);
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+ putbits (tmpsrc, (x & PIM), nstart, pdst);
+ pdst++;
+ if(srcStartOver)
+ psrc++;
+ }
+
+ while(nlMiddle--) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+ case RROP_COPY:
+ getbits (psrc, nstart, PPW, tmpsrc);
+ break;
+ case RROP_INVERT:
+ getbits (psrc, nstart, PPW, tmpsrc);
+ tmpsrc = ~tmpsrc;
+ break;
+ }
+ if (alu != GXcopy) {
+ tmpdst = *pdst;
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+ *pdst++ = tmpsrc;
+ /*putbits (tmpsrc, 0, PPW, pdst);
+ pdst++;*/
+ psrc++;
+ }
+ if(endmask) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+
+ case RROP_COPY:
+ getbits (psrc, nstart, nend, tmpsrc);
+ break;
+
+ case RROP_INVERT:
+ getbits (psrc, nstart, nend, tmpsrc);
+ tmpsrc = ~tmpsrc;
+ break;
+ }
+ if (alu != GXcopy) {
+ tmpdst = *pdst;
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+ putbits (tmpsrc, 0, nend, pdst);
+ }
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}