(file) Return to cfbsetsp.c CVS log (file) (dir) Up to [XFree86 CVS] / xc / programs / Xserver / cfb

  1 tsi   3.9 /* $XFree86: xc/programs/Xserver/cfb/cfbsetsp.c,v 3.8tsi Exp $ */
  2 dawes 1.1 /***********************************************************
  3           
  4 dawes 3.1 Copyright 1987, 1998  The Open Group
  5 dawes 1.1 
  6 dawes 3.5 Permission to use, copy, modify, distribute, and sell this software and its
  7           documentation for any purpose is hereby granted without fee, provided that
  8           the above copyright notice appear in all copies and that both that
  9           copyright notice and this permission notice appear in supporting
 10           documentation.
 11 dawes 1.1 
 12           The above copyright notice and this permission notice shall be included in
 13           all copies or substantial portions of the Software.
 14           
 15           THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16           IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17           FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 18 dawes 3.1 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 19 dawes 1.1 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 20           CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21           
 22 dawes 3.1 Except as contained in this notice, the name of The Open Group shall not be
 23 dawes 1.1 used in advertising or otherwise to promote the sale, use or other dealings
 24 dawes 3.1 in this Software without prior written authorization from The Open Group.
 25 dawes 1.1 
 26           
 27           Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 28           
 29                                   All Rights Reserved
 30           
 31           Permission to use, copy, modify, and distribute this software and its 
 32           documentation for any purpose and without fee is hereby granted, 
 33           provided that the above copyright notice appear in all copies and that
 34           both that copyright notice and this permission notice appear in 
 35           supporting documentation, and that the name of Digital not be
 36           used in advertising or publicity pertaining to distribution of the
 37           software without specific, written prior permission.  
 38           
 39           DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 40           ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 41           DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 42           ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 43           WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 44           ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 45           SOFTWARE.
 46 dawes 1.1 
 47           ******************************************************************/
 48           
 49 tsi   3.8 #include <X11/X.h>
 50           #include <X11/Xmd.h>
 51 dawes 1.1 #include "servermd.h"
 52           
 53           #include "misc.h"
 54           #include "regionstr.h"
 55           #include "gcstruct.h"
 56           #include "windowstr.h"
 57           #include "pixmapstr.h"
 58           #include "scrnintstr.h"
 59           
 60           #include "cfb.h"
 61           #include "cfbmskbits.h"
 62 tsi   3.9 #include "mergerop.h"
 63 dawes 1.1 
 64           /* cfbSetScanline -- copies the bits from psrc to the drawable starting at
 65            * (xStart, y) and continuing to (xEnd, y).  xOrigin tells us where psrc 
 66            * starts on the scanline. (I.e., if this scanline passes through multiple
 67            * boxes, we may not want to start grabbing bits at psrc but at some offset
 68            * further on.) 
 69            */
 70 dawes 3.7 /*
 71               int			xOrigin;	where this scanline starts
 72               int			xStart;		first bit to use from scanline
 73               int			xEnd;		last bit to use from scanline + 1
 74               int			alu;		raster op
 75               int			*pdstBase;	start of the drawable
 76               int			widthDst;	width of drawable in words
 77           */
 78           
 79 dawes 3.2 void
 80 dawes 3.7 cfbSetScanline(int y, int xOrigin, int xStart, int xEnd, unsigned int *psrc,
 81           	       int alu, int *pdstBase, int widthDst, unsigned long planemask)
 82 dawes 1.1 {
 83               int			w;		/* width of scanline in bits */
 84 dawes 3.7     int	*pdst;		/* where to put the bits */
 85               int	tmpSrc;		/* scratch buffer to collect bits in */
 86 dawes 1.1     int			offSrc;
 87 tsi   3.4     int			nl;
 88 dawes 3.0 #if PSZ == 24
 89 dawes 3.7     char *psrcb, *pdstb;
 90               int	xIndex;
 91 tsi   3.4 #else
 92 tsi   3.6     int			dstBit;		/* offset in bits from beginning of
 93           					 * word */
 94 dawes 3.7     int	nstart; 	/* number of bits from first partial */
 95 tsi   3.6 #if PSZ != 32 || PPW != 1
 96 dawes 3.7     int	nend; 		/* " " last partial word */
 97 tsi   3.6 #endif
 98 tsi   3.4     int			startmask, endmask, nlMiddle;
 99 dawes 3.0 #endif
100 dawes 1.1     DeclareMergeRop()
101           
102               InitializeMergeRop(alu,planemask);
103 dawes 3.0 #if PSZ == 24
104               pdst = pdstBase + (y * widthDst);
105               xIndex = xStart;
106 tsi   3.9     pdstb = (char *)pdst + (xStart * PSZB);
107 dawes 3.0     offSrc = xStart - xOrigin;
108 tsi   3.9     psrcb = (char *)psrc + (offSrc * PSZB);
109 dawes 3.0 #else
110 dawes 1.1     pdst = pdstBase + (y * widthDst) + (xStart >> PWSH); 
111               psrc += (xStart - xOrigin) >> PWSH;
112               offSrc = (xStart - xOrigin) & PIM;
113 dawes 3.0 #endif
114 dawes 1.1     w = xEnd - xStart;
115           
116 dawes 3.0 #if PSZ == 24
117               nl = w;
118               while (nl--){
119 tsi   3.9       psrc = (unsigned int *)((unsigned long)psrcb & ~(PGSZB - 1));
120 dawes 3.0       getbits24(psrc, tmpSrc, offSrc);
121 tsi   3.9       pdst = (int *)((unsigned long)pdstb & ~(PGSZB - 1));
122 dawes 3.0       DoMergeRop24(tmpSrc, pdst, xIndex);
123                 offSrc++;
124 tsi   3.9       psrcb += PSZB;
125 dawes 3.0       xIndex++;
126 tsi   3.9       pdstb += PSZB;
127 dawes 3.0     } 
128           #else /* PSZ == 24 */
129 tsi   3.6     dstBit = xStart & PIM;
130 dawes 1.1     if (dstBit + w <= PPW) 
131               { 
132           	maskpartialbits(dstBit, w, startmask);
133           	endmask = 0;
134           	nlMiddle = 0;
135               } 
136               else 
137               { 
138           	maskbits(xStart, w, startmask, endmask, nlMiddle);
139               }
140               if (startmask) 
141           	nstart = PPW - dstBit; 
142               else 
143           	nstart = 0; 
144 tsi   3.6 #if PSZ != 32 || PPW != 1
145 dawes 1.1     if (endmask) 
146           	nend = xEnd & PIM; 
147               else 
148           	nend = 0; 
149 tsi   3.6 #endif
150 dawes 1.1     if (startmask) 
151               { 
152           	getbits(psrc, offSrc, nstart, tmpSrc);
153           	putbitsmropshort(tmpSrc, dstBit, nstart, pdst);
154           	pdst++; 
155           	offSrc += nstart;
156           	if (offSrc > PLST)
157           	{
158           	    psrc++;
159           	    offSrc -= PPW;
160           	}
161               } 
162               nl = nlMiddle; 
163               while (nl--) 
164               { 
165           	getbits(psrc, offSrc, PPW, tmpSrc);
166           	*pdst = DoMergeRop(tmpSrc, *pdst);
167           	pdst++; 
168           	psrc++; 
169               } 
170               if (endmask) 
171 dawes 1.1     { 
172           	getbits(psrc, offSrc, nend, tmpSrc);
173           	putbitsmropshort(tmpSrc, 0, nend, pdst);
174               } 
175 dawes 3.0 #endif /* PSZ == 24 */
176 dawes 1.1 }
177           
178           
179           
180           /* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
181            * ppt[i] using the raster op from the GC.  If fSorted is TRUE, the scanlines
182            * are in increasing Y order.
183            * Source bit lines are server scanline padded so that they always begin
184            * on a word boundary.
185            */ 
186           void
187 dawes 3.7 cfbSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pcharsrc, DDXPointPtr ppt,
188           	    int *pwidth, int nspans, int fSorted)
189 dawes 1.1 {
190               unsigned int	*psrc = (unsigned int *)pcharsrc;
191 dawes 3.2     CfbBits	*pdstBase;	/* start of dst bitmap */
192 dawes 1.1     int 		widthDst;	/* width of bitmap in words */
193 dawes 3.7     BoxPtr 	pbox, pboxLast, pboxTest;
194               DDXPointPtr pptLast;
195 dawes 1.1     int 		alu;
196               RegionPtr 		prgnDst;
197               int			xStart, xEnd;
198               int			yMax;
199           
200               alu = pGC->alu;
201               prgnDst = cfbGetCompositeClip(pGC);
202               pptLast = ppt + nspans;
203           
204               cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase)
205           
206               yMax = (int) pDrawable->y + (int) pDrawable->height;
207           
208               pbox = REGION_RECTS(prgnDst);
209               pboxLast = pbox + REGION_NUM_RECTS(prgnDst);
210           
211               if(fSorted)
212               {
213               /* scan lines sorted in ascending order. Because they are sorted, we
214                * don't have to check each scanline against each clip box.  We can be
215                * sure that this scanline only has to be clipped to boxes at or after the
216 dawes 1.1      * beginning of this y-band 
217                */
218           	pboxTest = pbox;
219           	while(ppt < pptLast)
220           	{
221           	    pbox = pboxTest;
222           	    if(ppt->y >= yMax)
223           		break;
224           	    while(pbox < pboxLast)
225           	    {
226           		if(pbox->y1 > ppt->y)
227           		{
228           		    /* scanline is before clip box */
229           		    break;
230           		}
231           		else if(pbox->y2 <= ppt->y)
232           		{
233           		    /* clip box is before scanline */
234           		    pboxTest = ++pbox;
235           		    continue;
236           		}
237 dawes 1.1 		else if(pbox->x1 > ppt->x + *pwidth) 
238           		{
239           		    /* clip box is to right of scanline */
240           		    break;
241           		}
242           		else if(pbox->x2 <= ppt->x)
243           		{
244           		    /* scanline is to right of clip box */
245           		    pbox++;
246           		    continue;
247           		}
248           
249           		/* at least some of the scanline is in the current clip box */
250           		xStart = max(pbox->x1, ppt->x);
251           		xEnd = min(ppt->x + *pwidth, pbox->x2);
252           		cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
253           		    (int *)pdstBase, widthDst, pGC->planemask);
254           		if(ppt->x + *pwidth <= pbox->x2)
255           		{
256           		    /* End of the line, as it were */
257           		    break;
258 dawes 1.1 		}
259           		else
260           		    pbox++;
261           	    }
262           	    /* We've tried this line against every box; it must be outside them
263           	     * all.  move on to the next point */
264           	    ppt++;
265           	    psrc += PixmapWidthInPadUnits(*pwidth, pDrawable->depth);
266           	    pwidth++;
267           	}
268               }
269               else
270               {
271               /* scan lines not sorted. We must clip each line against all the boxes */
272           	while(ppt < pptLast)
273           	{
274           	    if(ppt->y >= 0 && ppt->y < yMax)
275           	    {
276           		
277           		for(pbox = REGION_RECTS(prgnDst); pbox< pboxLast; pbox++)
278           		{
279 dawes 1.1 		    if(pbox->y1 > ppt->y)
280           		    {
281           			/* rest of clip region is above this scanline,
282           			 * skip it */
283           			break;
284           		    }
285           		    if(pbox->y2 <= ppt->y)
286           		    {
287           			/* clip box is below scanline */
288           			pbox++;
289           			break;
290           		    }
291           		    if(pbox->x1 <= ppt->x + *pwidth &&
292           		       pbox->x2 > ppt->x)
293           		    {
294           			xStart = max(pbox->x1, ppt->x);
295           			xEnd = min(pbox->x2, ppt->x + *pwidth);
296           			cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
297           			    (int *)pdstBase, widthDst, pGC->planemask);
298           		    }
299           
300 dawes 1.1 		}
301           	    }
302           	psrc += PixmapWidthInPadUnits(*pwidth, pDrawable->depth);
303           	ppt++;
304           	pwidth++;
305           	}
306               }
307           }
308           

Powered by
ViewCVS 0.9.2