aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/mfb/mfbfillsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/mfb/mfbfillsp.c')
-rw-r--r--xorg-server/mfb/mfbfillsp.c1029
1 files changed, 1029 insertions, 0 deletions
diff --git a/xorg-server/mfb/mfbfillsp.c b/xorg-server/mfb/mfbfillsp.c
new file mode 100644
index 000000000..c073535df
--- /dev/null
+++ b/xorg-server/mfb/mfbfillsp.c
@@ -0,0 +1,1029 @@
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "mfb.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 mfbCreateGC().)
+
+ the number of new scnalines created by clipping ==
+MaxRectsPerBand * nSpans.
+
+ FillSolid is overloaded to be used for OpaqueStipple as well,
+if fgPixel == bgPixel.
+
+
+ FillTiled is overloaded to be used for OpaqueStipple, if
+fgPixel != bgPixel. based on the fill style, it uses
+{RotatedPixmap, gc.alu} or {RotatedPixmap, PrivGC.ropOpStip}
+*/
+
+
+void
+mfbBlackSolidFS(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 */
+ 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;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)xalloc(n * sizeof(int));
+ pptFree = (DDXPointRec *)xalloc(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) xfree(pptFree);
+ if (pwidthFree) xfree(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+
+ if (*pwidth)
+ {
+ 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;
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ xfree(pptFree);
+ xfree(pwidthFree);
+}
+
+
+
+void
+mfbWhiteSolidFS(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 */
+ 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;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)xalloc(n * sizeof(int));
+ pptFree = (DDXPointRec *)xalloc(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) xfree(pptFree);
+ if (pwidthFree) xfree(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+
+ if (*pwidth)
+ {
+ 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;
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ xfree(pptFree);
+ xfree(pwidthFree);
+}
+
+
+
+void
+mfbInvertSolidFS(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 */
+ 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;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)xalloc(n * sizeof(int));
+ pptFree = (DDXPointRec *)xalloc(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) xfree(pptFree);
+ if (pwidthFree) xfree(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+
+ if (*pwidth)
+ {
+ 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;
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ xfree(pptFree);
+ xfree(pwidthFree);
+}
+
+
+void
+mfbWhiteStippleFS(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 */
+ 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;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)xalloc(n * sizeof(int));
+ pptFree = (DDXPointRec *)xalloc(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) xfree(pptFree);
+ if (pwidthFree) xfree(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ pStipple = pGC->pRotatedPixmap;
+ tileHeight = pStipple->drawable.height;
+ psrc = (PixelType *)(pStipple->devPrivate.ptr);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight];
+
+ /* 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);
+ }
+ pwidth++;
+ ppt++;
+ }
+ xfree(pptFree);
+ xfree(pwidthFree);
+}
+
+
+void
+mfbBlackStippleFS(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 */
+ 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;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)xalloc(n * sizeof(int));
+ pptFree = (DDXPointRec *)xalloc(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) xfree(pptFree);
+ if (pwidthFree) xfree(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ pStipple = pGC->pRotatedPixmap;
+ tileHeight = pStipple->drawable.height;
+ psrc = (PixelType *)(pStipple->devPrivate.ptr);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight];
+
+ /* 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);
+ }
+ pwidth++;
+ ppt++;
+ }
+ xfree(pptFree);
+ xfree(pwidthFree);
+}
+
+
+void
+mfbInvertStippleFS(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 */
+ 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;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)xalloc(n * sizeof(int));
+ pptFree = (DDXPointRec *)xalloc(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) xfree(pptFree);
+ if (pwidthFree) xfree(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ pStipple = pGC->pRotatedPixmap;
+ tileHeight = pStipple->drawable.height;
+ psrc = (PixelType *)(pStipple->devPrivate.ptr);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight];
+
+ /* 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);
+ }
+ pwidth++;
+ ppt++;
+ }
+ xfree(pptFree);
+ xfree(pwidthFree);
+}
+
+
+/* this works with tiles of width == PPW */
+#define FILLSPANPPW(ROP) \
+ while (n--) \
+ { \
+ if (*pwidth) \
+ { \
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth); \
+ src = psrc[ppt->y % tileHeight]; \
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) \
+ { \
+ maskpartialbits(ppt->x, *pwidth, startmask); \
+ *addrl = (*addrl & ~startmask) | \
+ (ROP(src, *addrl) & startmask); \
+ } \
+ else \
+ { \
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); \
+ if (startmask) \
+ { \
+ *addrl = (*addrl & ~startmask) | \
+ (ROP(src, *addrl) & startmask); \
+ addrl++; \
+ } \
+ while (nlmiddle--) \
+ { \
+ *addrl = ROP(src, *addrl); \
+ addrl++; \
+ } \
+ if (endmask) \
+ *addrl = (*addrl & ~endmask) | \
+ (ROP(src, *addrl) & endmask); \
+ } \
+ } \
+ pwidth++; \
+ ppt++; \
+ }
+
+
+
+void
+mfbTileFS(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 */
+ 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;
+ MfbBits flip;
+
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)xalloc(n * sizeof(int));
+ pptFree = (DDXPointRec *)xalloc(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) xfree(pptFree);
+ if (pwidthFree) xfree(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ pTile = pGC->pRotatedPixmap;
+ tileHeight = pTile->drawable.height;
+ psrc = (PixelType *)(pTile->devPrivate.ptr);
+ if (pGC->fillStyle == FillTiled)
+ rop = pGC->alu;
+ else
+ rop = ((mfbPrivGC *)dixLookupPrivate(&pGC->devPrivates,
+ mfbGetGCPrivateKey()))->ropOpStip;
+
+ flip = 0;
+ switch(rop)
+ {
+ case GXcopyInverted: /* for opaque stipples */
+ flip = ~0;
+ case GXcopy:
+ {
+
+#define DoMaskCopyRop(src,dst,mask) (((dst) & ~(mask)) | ((src) & (mask)))
+
+ while (n--)
+ {
+ if (*pwidth)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight] ^ flip;
+ 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)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight];
+ 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;
+ }
+ xfree(pptFree);
+ xfree(pwidthFree);
+}
+
+
+/* Fill spans with tiles that aren't PPW bits wide */
+void
+mfbUnnaturalTileFS(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 */
+ 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;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)xalloc(n * sizeof(int));
+ pptFree = (DDXPointRec *)xalloc(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) xfree(pptFree);
+ if (pwidthFree) xfree(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ if (pGC->fillStyle == FillTiled)
+ {
+ pTile = pGC->tile.pixmap;
+ tlwidth = pTile->devKind / PGSZB;
+ rop = pGC->alu;
+ }
+ else
+ {
+ pTile = pGC->stipple;
+ tlwidth = pTile->devKind / PGSZB;
+ rop = ((mfbPrivGC *)dixLookupPrivate(&pGC->devPrivates,
+ mfbGetGCPrivateKey()))->ropOpStip;
+ }
+
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+
+ /* 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;
+ pdst = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ 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;
+ 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 defined(__alpha__) || defined(__alpha)
+ /*
+ * XXX workaround an egcs 1.1.2 code generation
+ * bug. This version might actually be faster.
+ */
+ psrc += srcStartOver;
+#else
+ if(srcStartOver)
+ psrc++;
+#endif
+ }
+
+ while(nlMiddle--)
+ {
+ getandputrop0(psrc, nstart, PPW, pdst, rop);
+ pdst++;
+ psrc++;
+ }
+ if(endmask)
+ {
+ getandputrop0(psrc, nstart, nend, pdst, rop);
+ }
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ xfree(pptFree);
+ xfree(pwidthFree);
+}
+
+
+/* Fill spans with stipples that aren't PPW bits wide */
+void
+mfbUnnaturalStippleFS(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 */
+ 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;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)xalloc(n * sizeof(int));
+ pptFree = (DDXPointRec *)xalloc(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) xfree(pptFree);
+ if (pwidthFree) xfree(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ pTile = pGC->stipple;
+ rop = ((mfbPrivGC *)dixLookupPrivate(&pGC->devPrivates,
+ mfbGetGCPrivateKey()))->rop;
+ tlwidth = pTile->devKind / PGSZB;
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+
+ /* 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;
+ pdst = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ 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++;
+ }
+ xfree(pptFree);
+ xfree(pwidthFree);
+}