1132 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1132 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			C
		
	
	
	
/* $XFree86: xc/programs/Xserver/afb/afbfillsp.c,v 3.3 2000/11/22 00:58:12 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 $ */
 | 
						|
 | 
						|
#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 "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);
 | 
						|
}
 |