diff options
Diffstat (limited to 'afb/afbfillsp.c')
-rw-r--r-- | afb/afbfillsp.c | 1127 |
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); +} |