]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbfillsp.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbfillsp.c
1 /************************************************************
2 Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
3
4                     All Rights Reserved
5
6 Permission  to  use,  copy,  modify,  and  distribute   this
7 software  and  its documentation for any purpose and without
8 fee is hereby granted, provided that the above copyright no-
9 tice  appear  in all copies and that both that copyright no-
10 tice and this permission notice appear in  supporting  docu-
11 mentation,  and  that the names of Sun or X Consortium
12 not be used in advertising or publicity pertaining to 
13 distribution  of  the software  without specific prior 
14 written permission. Sun and X Consortium make no 
15 representations about the suitability of this software for 
16 any purpose. It is provided "as is" without any express or 
17 implied warranty.
18
19 SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
20 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
21 NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
22 ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
24 PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
25 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
26 THE USE OR PERFORMANCE OF THIS SOFTWARE.
27
28 ********************************************************/
29
30 /***********************************************************
31
32 Copyright (c) 1987  X Consortium
33
34 Permission is hereby granted, free of charge, to any person obtaining a copy
35 of this software and associated documentation files (the "Software"), to deal
36 in the Software without restriction, including without limitation the rights
37 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38 copies of the Software, and to permit persons to whom the Software is
39 furnished to do so, subject to the following conditions:
40
41 The above copyright notice and this permission notice shall be included in
42 all copies or substantial portions of the Software.
43
44 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
47 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
48 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
49 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
50
51 Except as contained in this notice, the name of the X Consortium shall not be
52 used in advertising or otherwise to promote the sale, use or other dealings
53 in this Software without prior written authorization from the X Consortium.
54
55
56 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
57
58                         All Rights Reserved
59
60 Permission to use, copy, modify, and distribute this software and its 
61 documentation for any purpose and without fee is hereby granted, 
62 provided that the above copyright notice appear in all copies and that
63 both that copyright notice and this permission notice appear in 
64 supporting documentation, and that the name of Digital not be
65 used in advertising or publicity pertaining to distribution of the
66 software without specific, written prior permission.  
67
68 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
69 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
70 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
71 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
72 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
73 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
74 SOFTWARE.
75
76 ******************************************************************/
77
78 /* $XConsortium: cfbfillsp.c,v 5.24 94/04/17 20:28:48 dpw Exp $ */
79 /* $XFree86: xc/programs/Xserver/cfb/cfbfillsp.c,v 3.1 1996/12/09 11:50:54 dawes Exp $ */
80
81 #include "X.h"
82 #include "Xmd.h"
83 #include "servermd.h"
84 #include "gcstruct.h"
85 #include "window.h"
86 #include "pixmapstr.h"
87 #include "scrnintstr.h"
88 #include "windowstr.h"
89
90 #include "cfb.h"
91 #include "cfbmskbits.h"
92
93 #include "mergerop.h"
94
95 #if PSZ == 8
96 #include "cfb8bit.h"
97 #endif
98
99 #define MFB_CONSTS_ONLY
100 #include "maskbits.h"
101
102 #include "mi.h"
103 #include "mispans.h"
104
105 /* scanline filling for color frame buffer
106    written by drewry, oct 1986 modified by smarks
107    changes for compatibility with Little-endian systems Jul 1987; MIT:yba.
108
109    these routines all clip.  they assume that anything that has called
110 them has already translated the points (i.e. pGC->miTranslate is
111 non-zero, which is howit gets set in cfbCreateGC().)
112
113    the number of new scnalines created by clipping ==
114 MaxRectsPerBand * nSpans.
115
116     FillSolid is overloaded to be used for OpaqueStipple as well,
117 if fgPixel == bgPixel.  
118 Note that for solids, PrivGC.rop == PrivGC.ropOpStip
119
120
121     FillTiled is overloaded to be used for OpaqueStipple, if
122 fgPixel != bgPixel.  based on the fill style, it uses
123 {RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip}
124 */
125
126 #ifdef  notdef
127 #include        <stdio.h>
128 static
129 dumpspans(n, ppt, pwidth)
130     int n;
131     DDXPointPtr ppt;
132     int *pwidth;
133 {
134     fprintf(stderr,"%d spans\n", n);
135     while (n--) {
136         fprintf(stderr, "[%d,%d] %d\n", ppt->x, ppt->y, *pwidth);
137         ppt++;
138         pwidth++;
139     }
140     fprintf(stderr, "\n");
141 }
142 #endif
143
144 /* Fill spans with tiles that aren't 32 bits wide */
145 void
146 cfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
147 DrawablePtr pDrawable;
148 GC              *pGC;
149 int             nInit;          /* number of spans to fill */
150 DDXPointPtr pptInit;            /* pointer to list of start points */
151 int *pwidthInit;                /* pointer to list of n widths */
152 int fSorted;
153 {
154     int n;                      /* number of spans to fill */
155     register DDXPointPtr ppt;   /* pointer to list of start points */
156     register int *pwidth;       /* pointer to list of n widths */
157     void    (*fill)();
158     int xrot, yrot;
159
160     if (!(pGC->planemask))
161         return;
162
163 #if PSZ == 24
164     if (pGC->tile.pixmap->drawable.width & 3)
165 #else
166     if (pGC->tile.pixmap->drawable.width & PIM)
167 #endif
168     {
169         fill = cfbFillSpanTileOddGeneral;
170         if ((pGC->planemask & PMSK) == PMSK)
171         {
172             if (pGC->alu == GXcopy)
173                 fill = cfbFillSpanTileOddCopy;
174         }
175     }
176     else
177     {
178         fill = cfbFillSpanTile32sGeneral;
179         if ((pGC->planemask & PMSK) == PMSK)
180         {
181             if (pGC->alu == GXcopy)
182                 fill = cfbFillSpanTile32sCopy;
183         }
184     }
185     n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
186     if ( n == 0 )
187         return;
188     pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int));
189     ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
190     if(!ppt || !pwidth)
191     {
192         if (ppt) DEALLOCATE_LOCAL(ppt);
193         if (pwidth) DEALLOCATE_LOCAL(pwidth);
194         return;
195     }
196     n = miClipSpans( cfbGetCompositeClip(pGC),
197                      pptInit, pwidthInit, nInit, 
198                      ppt, pwidth, fSorted);
199
200     xrot = pDrawable->x + pGC->patOrg.x;
201     yrot = pDrawable->y + pGC->patOrg.y;
202
203     (*fill) (pDrawable, n, ppt, pwidth, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
204
205     DEALLOCATE_LOCAL(ppt);
206     DEALLOCATE_LOCAL(pwidth);
207 }
208
209 #if PSZ == 8
210
211 void
212 cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
213 DrawablePtr pDrawable;
214 GC              *pGC;
215 int             nInit;          /* number of spans to fill */
216 DDXPointPtr pptInit;            /* pointer to list of start points */
217 int *pwidthInit;                /* pointer to list of n widths */
218 int fSorted;
219 {
220                                 /* next three parameters are post-clip */
221     int             n;          /* number of spans to fill */
222     DDXPointPtr     ppt;        /* pointer to list of start points */
223     int             *pwidth;    /* pointer to list of n widths */
224     int             *pwidthFree;/* copies of the pointers to free */
225     DDXPointPtr     pptFree;
226     unsigned long   *pdstBase;  /* pointer to start of bitmap */
227     int             nlwDst;     /* width in longwords of bitmap */
228     register unsigned long    *pdst;    /* pointer to current word in bitmap */
229     PixmapPtr       pStipple;   /* pointer to stipple we want to fill with */
230     int             nlw;
231     int             x, y, w, xrem, xSrc, ySrc;
232     int             stwidth, stippleWidth;
233     int             stippleHeight;
234     register unsigned long  bits, inputBits;
235     register int    partBitsLeft;
236     int             nextPartBits;
237     int             bitsLeft, bitsWhole;
238     unsigned long   *srcTemp, *srcStart;
239     unsigned long   *psrcBase;
240     unsigned long   startmask, endmask;
241
242     if (pGC->fillStyle == FillStippled)
243         cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
244     else
245         cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
246
247     if (cfb8StippleRRop == GXnoop)
248         return;
249
250     n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
251     if ( n == 0 )
252         return;
253     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
254     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
255     if(!pptFree || !pwidthFree)
256     {
257         if (pptFree) DEALLOCATE_LOCAL(pptFree);
258         if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
259         return;
260     }
261
262     pwidth = pwidthFree;
263     ppt = pptFree;
264     n = miClipSpans( cfbGetCompositeClip(pGC),
265                      pptInit, pwidthInit, nInit, 
266                      ppt, pwidth, fSorted);
267
268     /*
269      *  OK,  so what's going on here?  We have two Drawables:
270      *
271      *  The Stipple:
272      *          Depth = 1
273      *          Width = stippleWidth
274      *          Words per scanline = stwidth
275      *          Pointer to pixels = pStipple->devPrivate.ptr
276      */
277
278     pStipple = pGC->stipple;
279
280     stwidth = pStipple->devKind >> PWSH;
281     stippleWidth = pStipple->drawable.width;
282     stippleHeight = pStipple->drawable.height;
283     psrcBase = (unsigned long *) pStipple->devPrivate.ptr;
284
285     /*
286      *  The Target:
287      *          Depth = PSZ
288      *          Width = determined from *pwidth
289      *          Words per scanline = nlwDst
290      *          Pointer to pixels = addrlBase
291      */
292
293     cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
294
295     /* this replaces rotating the stipple. Instead we just adjust the offset
296      * at which we start grabbing bits from the stipple.
297      * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
298      * so that iline and xrem always stay within the stipple bounds.
299      */
300
301     modulus (pGC->patOrg.x, stippleWidth, xSrc);
302     xSrc += pDrawable->x - stippleWidth;
303     modulus (pGC->patOrg.y, stippleHeight, ySrc);
304     ySrc += pDrawable->y - stippleHeight;
305
306     bitsWhole = stippleWidth;
307
308     while (n--)
309     {
310         x = ppt->x;
311         y = ppt->y;
312         ppt++;
313         w = *pwidth++;
314         pdst = pdstBase + y * nlwDst + (x >> PWSH);
315         y = (y - ySrc) % stippleHeight;
316         srcStart = psrcBase + y * stwidth;
317         xrem = ((x & ~(PGSZB-1)) - xSrc) % stippleWidth;
318         srcTemp = srcStart + (xrem >> MFB_PWSH);
319         bitsLeft = stippleWidth - (xrem & ~MFB_PIM);
320         xrem &= MFB_PIM;
321         NextUnnaturalStippleWord
322         if (partBitsLeft < xrem)
323             FatalError ("cfbUnnaturalStippleFS bad partBitsLeft %d xrem %d",
324                         partBitsLeft, xrem);
325         NextSomeBits (inputBits, xrem);
326         partBitsLeft -= xrem;
327         if (((x & PIM) + w) <= PPW)
328         {
329             maskpartialbits (x, w, startmask)
330             NextUnnaturalStippleBits
331             *pdst = MaskRRopPixels(*pdst,bits,startmask);
332         }
333         else
334         {
335             maskbits (x, w, startmask, endmask, nlw);
336             nextPartBits = (x & (PGSZB-1)) + w;
337             if (nextPartBits < partBitsLeft)
338             {
339                 if (startmask)
340                 {
341                     MaskRRopBitGroup(pdst,GetBitGroup(inputBits),startmask)
342                     pdst++;
343                     NextBitGroup (inputBits);
344                 }
345                 while (nlw--)
346                 {
347                     RRopBitGroup (pdst, GetBitGroup (inputBits));
348                     pdst++;
349                     NextBitGroup (inputBits);
350                 }
351                 if (endmask)
352                 {
353                     MaskRRopBitGroup(pdst,GetBitGroup(inputBits),endmask)
354                 }
355             }
356             else if (bitsLeft != bitsWhole && nextPartBits < partBitsLeft + bitsLeft)
357             {
358                 NextUnnaturalStippleBitsFast
359                 if (startmask)
360                 {
361                     *pdst = MaskRRopPixels(*pdst,bits,startmask);
362                     pdst++;
363                     NextUnnaturalStippleBitsFast
364                 }
365                 while (nlw--)
366                 {
367                     *pdst = RRopPixels(*pdst,bits);
368                     pdst++;
369                     NextUnnaturalStippleBitsFast
370                 }
371                 if (endmask)
372                     *pdst = MaskRRopPixels (*pdst,bits,endmask);
373             }
374             else
375             {
376                 NextUnnaturalStippleBits
377                 if (startmask)
378                 {
379                     *pdst = MaskRRopPixels(*pdst,bits,startmask);
380                     pdst++;
381                     NextUnnaturalStippleBits
382                 }
383                 while (nlw--)
384                 {
385                     *pdst = RRopPixels(*pdst,bits);
386                     pdst++;
387                     NextUnnaturalStippleBits
388                 }
389                 if (endmask)
390                     *pdst = MaskRRopPixels(*pdst,bits,endmask);
391             }
392         }
393     }
394     DEALLOCATE_LOCAL(pptFree);
395     DEALLOCATE_LOCAL(pwidthFree);
396 }
397
398 #else /* PSZ != 8 */
399
400 /* Fill spans with stipples that aren't 32 bits wide */
401 void
402 cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
403 DrawablePtr pDrawable;
404 GC              *pGC;
405 int             nInit;          /* number of spans to fill */
406 DDXPointPtr pptInit;            /* pointer to list of start points */
407 int *pwidthInit;                /* pointer to list of n widths */
408 int fSorted;
409 {
410                                 /* next three parameters are post-clip */
411     int                     n;          /* number of spans to fill */
412     register DDXPointPtr    ppt;        /* pointer to list of start points */
413     register int            *pwidth;    /* pointer to list of n widths */
414     int                     iline;      /* first line of tile to use */
415     unsigned long           *addrlBase; /* pointer to start of bitmap */
416     int                     nlwidth;    /* width in longwords of bitmap */
417     register unsigned long  *pdst;      /* pointer to current word in bitmap */
418     PixmapPtr               pStipple;   /* pointer to stipple we want to fill with */
419     register int            w;
420     int                     width,  x, xrem, xSrc, ySrc;
421     unsigned long           tmpSrc, tmpDst1, tmpDst2;
422     int                     stwidth, stippleWidth;
423     unsigned long           *psrcS;
424     int                     rop, stiprop;
425     int                     stippleHeight;
426     int                     *pwidthFree;    /* copies of the pointers to free */
427     DDXPointPtr             pptFree;
428     unsigned long           fgfill, bgfill;
429
430     if (!(pGC->planemask))
431         return;
432
433     n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
434     if ( n == 0 )
435         return;
436     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
437     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
438     if(!pptFree || !pwidthFree)
439     {
440         if (pptFree) DEALLOCATE_LOCAL(pptFree);
441         if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
442         return;
443     }
444     pwidth = pwidthFree;
445     ppt = pptFree;
446     n = miClipSpans( cfbGetCompositeClip(pGC),
447                      pptInit, pwidthInit, nInit, 
448                      ppt, pwidth, fSorted);
449     rop = pGC->alu;
450     if (pGC->fillStyle == FillStippled) {
451         switch (rop) {
452             case GXand:
453             case GXcopy:
454             case GXnoop:
455             case GXor:
456                 stiprop = rop;
457                 break;
458             default:
459                 stiprop = rop;
460                 rop = GXcopy;
461         }
462     }
463     fgfill = PFILL(pGC->fgPixel);
464     bgfill = PFILL(pGC->bgPixel);
465
466     /*
467      *  OK,  so what's going on here?  We have two Drawables:
468      *
469      *  The Stipple:
470      *          Depth = 1
471      *          Width = stippleWidth
472      *          Words per scanline = stwidth
473      *          Pointer to pixels = pStipple->devPrivate.ptr
474      */
475     pStipple = pGC->stipple;
476
477     stwidth = pStipple->devKind / PGSZB;
478     stippleWidth = pStipple->drawable.width;
479     stippleHeight = pStipple->drawable.height;
480
481     /*
482      *  The Target:
483      *          Depth = PSZ
484      *          Width = determined from *pwidth
485      *          Words per scanline = nlwidth
486      *          Pointer to pixels = addrlBase
487      */
488
489     cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrlBase)
490
491     /* this replaces rotating the stipple. Instead we just adjust the offset
492      * at which we start grabbing bits from the stipple.
493      * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
494      * so that iline and xrem always stay within the stipple bounds.
495      */
496     modulus (pGC->patOrg.x, stippleWidth, xSrc);
497     xSrc += pDrawable->x - stippleWidth;
498     modulus (pGC->patOrg.y, stippleHeight, ySrc);
499     ySrc += pDrawable->y - stippleHeight;
500
501     while (n--)
502     {
503         iline = (ppt->y - ySrc) % stippleHeight;
504         x = ppt->x;
505         pdst = addrlBase + (ppt->y * nlwidth);
506         psrcS = (unsigned long *) pStipple->devPrivate.ptr + (iline * stwidth);
507
508         if (*pwidth)
509         {
510             width = *pwidth;
511             while(width > 0)
512             {
513                 int xtemp, tmpx;
514                 register unsigned long *ptemp;
515                 register unsigned long *pdsttmp;
516                 /*
517                  *  Do a stripe through the stipple & destination w pixels
518                  *  wide.  w is not more than:
519                  *      -       the width of the destination
520                  *      -       the width of the stipple
521                  *      -       the distance between x and the next word 
522                  *              boundary in the destination
523                  *      -       the distance between x and the next word
524                  *              boundary in the stipple
525                  */
526
527                 /* width of dest/stipple */
528                 xrem = (x - xSrc) % stippleWidth;
529 #if PSZ == 24
530                 w = 1;
531 #else
532                 w = min((stippleWidth - xrem), width);
533                 /* dist to word bound in dest */
534                 w = min(w, PPW - (x & PIM));
535                 /* dist to word bound in stip */
536                 w = min(w, MFB_PPW - (x & MFB_PIM));
537 #endif
538
539                 xtemp = (xrem & MFB_PIM);
540                 ptemp = (unsigned long *)(psrcS + (xrem >> MFB_PWSH));
541 #if PSZ == 24
542                 tmpx = x & 3;
543                 pdsttmp = pdst + ((x * 3)>>2);
544 #else
545                 tmpx = x & PIM;
546                 pdsttmp = pdst + (x>>PWSH);
547 #endif
548                 switch ( pGC->fillStyle ) {
549                     case FillOpaqueStippled:
550 #if PSZ == 24
551                         getstipplepixels24(ptemp, xtemp, 0, &bgfill, &tmpDst1, xrem);
552                         getstipplepixels24(ptemp, xtemp, 1, &fgfill, &tmpDst2, xrem);
553 #else
554                         getstipplepixels(ptemp, xtemp, w, 0, &bgfill, &tmpDst1);
555                         getstipplepixels(ptemp, xtemp, w, 1, &fgfill, &tmpDst2);
556 #endif
557                         break;
558                     case FillStippled:
559                         /* Fill tmpSrc with the source pixels */
560 #if PSZ == 24
561                         getbits24(pdsttmp, tmpSrc, x);
562                         getstipplepixels24(ptemp, xtemp, 0, &tmpSrc, &tmpDst1, xrem);
563 #else
564                         getbits(pdsttmp, tmpx, w, tmpSrc);
565                         getstipplepixels(ptemp, xtemp, w, 0, &tmpSrc, &tmpDst1);
566 #endif
567                         if (rop != stiprop) {
568 #if PSZ == 24
569                             putbitsrop24(fgfill, 0, &tmpSrc, pGC->planemask, stiprop);
570 #else
571                             putbitsrop(fgfill, 0, w, &tmpSrc, pGC->planemask, stiprop);
572 #endif
573                         } else {
574                             tmpSrc = fgfill;
575                         }
576 #if PSZ == 24
577                         getstipplepixels24(ptemp, xtemp, 1, &tmpSrc, &tmpDst2, xrem);
578 #else
579                         getstipplepixels(ptemp, xtemp, w, 1, &tmpSrc, &tmpDst2);
580 #endif
581                         break;
582                 }
583                 tmpDst2 |= tmpDst1;
584 #if PSZ == 24
585                 putbitsrop24(tmpDst2, tmpx, pdsttmp, pGC->planemask, rop);
586 #else
587                 putbitsrop(tmpDst2, tmpx, w, pdsttmp, pGC->planemask, rop);
588 #endif
589                 x += w;
590                 width -= w;
591             }
592         }
593         ppt++;
594         pwidth++;
595     }
596     DEALLOCATE_LOCAL(pptFree);
597     DEALLOCATE_LOCAL(pwidthFree);
598 }
599
600 #endif /* PSZ == 8 */
601
602 #if PSZ == 8
603
604 void
605 cfb8Stipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
606     DrawablePtr pDrawable;
607     GCPtr       pGC;
608     int         nInit;                  /* number of spans to fill */
609     DDXPointPtr pptInit;                /* pointer to list of start points */
610     int         *pwidthInit;            /* pointer to list of n widths */
611     int         fSorted;
612 {
613                                 /* next three parameters are post-clip */
614     int             n;                  /* number of spans to fill */
615     DDXPointPtr     ppt;                /* pointer to list of start points */
616     int             *pwidth;            /* pointer to list of n widths */
617     unsigned long   *src;               /* pointer to bits in stipple, if needed */
618     int             stippleHeight;      /* height of the stipple */
619     PixmapPtr       stipple;
620
621     int             nlwDst;             /* width in longwords of the dest pixmap */
622     int             x,y,w;              /* current span */
623     unsigned long   startmask;
624     unsigned long   endmask;
625     register unsigned long *dst;        /* pointer to bits we're writing */
626     register int    nlw;
627     unsigned long   *dstTmp;
628     int             nlwTmp;
629
630     unsigned long   *pbits;             /* pointer to start of pixmap */
631     register unsigned long  xor;
632     register unsigned long  mask;
633     register unsigned long  bits;       /* bits from stipple */
634     int             wEnd;
635
636     int             *pwidthFree;        /* copies of the pointers to free */
637     DDXPointPtr     pptFree;
638     cfbPrivGCPtr    devPriv;
639
640     devPriv = cfbGetGCPrivate(pGC);
641     cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
642     n = nInit * miFindMaxBand(devPriv->pCompositeClip);
643     if ( n == 0 )
644         return;
645     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
646     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
647     if(!pptFree || !pwidthFree)
648     {
649         if (pptFree) DEALLOCATE_LOCAL(pptFree);
650         if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
651         return;
652     }
653     pwidth = pwidthFree;
654     ppt = pptFree;
655     n = miClipSpans(devPriv->pCompositeClip,
656                      pptInit, pwidthInit, nInit,
657                      ppt, pwidth, fSorted);
658
659     stipple = devPriv->pRotatedPixmap;
660     src = (unsigned long *)stipple->devPrivate.ptr;
661     stippleHeight = stipple->drawable.height;
662
663     cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
664
665     while (n--)
666     {
667         w = *pwidth++;
668         x = ppt->x;
669         y = ppt->y;
670         ppt++;
671         dst = pbits + (y * nlwDst) + (x >> PWSH);
672         if (((x & PIM) + w) <= PPW)
673         {
674             maskpartialbits(x, w, startmask);
675             endmask = 0;
676             nlw = 0;
677         }
678         else
679         {
680             maskbits (x, w, startmask, endmask, nlw);
681         }
682         bits = src[y % stippleHeight];
683         RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
684 #if PPW == 4
685         if (cfb8StippleRRop == GXcopy)
686         {
687             xor = devPriv->xor;
688             if (w < (PGSZ*2))
689             {
690                 if (startmask)
691                 {
692                     mask = cfb8PixelMasks[GetBitGroup(bits)];
693                     *dst = (*dst & ~(mask & startmask)) |
694                            (xor & (mask & startmask));
695                     dst++;
696                     RotBitsLeft (bits, PGSZB);
697                 }
698                 while (nlw--)
699                 {
700                     WriteBitGroup (dst,xor,GetBitGroup(bits))
701                     dst++;
702                     RotBitsLeft (bits, PGSZB);
703                 }
704                 if (endmask)
705                 {
706                     mask = cfb8PixelMasks[GetBitGroup(bits)];
707                     *dst = (*dst & ~(mask & endmask)) |
708                            (xor & (mask & endmask));
709                 }
710             }
711             else
712             { /* XXX constants probably not OK here */
713                 wEnd = 7 - (nlw & 7);
714                 nlw = (nlw >> 3) + 1;
715                 dstTmp = dst;
716                 nlwTmp = nlw;
717                 if (startmask)
718                 {
719                     mask = cfb8PixelMasks[GetBitGroup(bits)];
720                     *dstTmp = (*dstTmp & ~(mask & startmask)) |
721                            (xor & (mask & startmask));
722                     dstTmp++;
723                     RotBitsLeft (bits, PGSZB);
724                 }
725                 w = 7 - wEnd;
726                 while (w--)
727                 {
728                     dst = dstTmp;
729                     dstTmp++;
730                     nlw = nlwTmp;
731 #if defined(__GNUC__) && defined(mc68020)
732                     mask = cfb8PixelMasks[GetBitGroup(bits)];
733                     xor = xor & mask;
734                     mask = ~mask;
735                     while (nlw--)
736                     {
737                         *dst = (*dst & mask) | xor;
738                         dst += 8;
739                     }
740                     xor = devPriv->xor;
741 #else
742 #define SwitchBitsLoop(body) \
743     while (nlw--)       \
744     {           \
745         body    \
746         dst += 8;       \
747     }
748                     SwitchBitGroup(dst, xor, GetBitGroup(bits));
749 #undef SwitchBitsLoop
750 #endif
751                     NextBitGroup (bits);
752                 }
753                 nlwTmp--;
754                 w = wEnd + 1;
755                 if (endmask)
756                 {
757                     mask = cfb8PixelMasks[GetBitGroup(bits)];
758                     dst = dstTmp + (nlwTmp << 3);
759                     *dst = (*dst & ~(mask & endmask)) |
760                            (xor &  (mask & endmask));
761                 }
762                 while (w--)
763                 {
764                     nlw = nlwTmp;
765                     dst = dstTmp;
766                     dstTmp++;
767 #if defined(__GNUC__) && defined(mc68020)
768                     mask = cfb8PixelMasks[GetBitGroup(bits)];
769                     xor = xor & mask;
770                     mask = ~mask;
771                     while (nlw--)
772                     {
773                         *dst = (*dst & mask) | xor;
774                         dst += 8;
775                     }
776                     xor = devPriv->xor;
777 #else
778 #define SwitchBitsLoop(body) \
779         while (nlw--)   \
780         {               \
781             body        \
782             dst += 8;   \
783         }
784                     SwitchBitGroup(dst, xor, GetBitGroup(bits));
785 #undef SwitchBitsLoop
786 #endif
787                     NextBitGroup (bits);
788                 }
789             }
790         }
791         else
792 #endif /* PPW == 4 */
793         {
794             if (startmask)
795             {
796                 xor = GetBitGroup(bits);
797                 *dst = MaskRRopPixels(*dst, xor, startmask);
798                 dst++;
799                 RotBitsLeft (bits, PGSZB);
800             }
801             while (nlw--)
802             {
803                 RRopBitGroup(dst, GetBitGroup(bits));
804                 dst++;
805                 RotBitsLeft (bits, PGSZB);
806             }
807             if (endmask)
808             {
809                 xor = GetBitGroup(bits);
810                 *dst = MaskRRopPixels(*dst, xor, endmask);
811             }
812         }
813     }
814     DEALLOCATE_LOCAL(pptFree);
815     DEALLOCATE_LOCAL(pwidthFree);
816 }
817
818 void
819 cfb8OpaqueStipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
820     DrawablePtr pDrawable;
821     GCPtr       pGC;
822     int         nInit;                  /* number of spans to fill */
823     DDXPointPtr pptInit;                /* pointer to list of start points */
824     int         *pwidthInit;            /* pointer to list of n widths */
825     int         fSorted;
826 {
827                                 /* next three parameters are post-clip */
828     int             n;                  /* number of spans to fill */
829     DDXPointPtr     ppt;                /* pointer to list of start points */
830     int             *pwidth;            /* pointer to list of n widths */
831     unsigned long   *src;               /* pointer to bits in stipple, if needed */
832     int             stippleHeight;      /* height of the stipple */
833     PixmapPtr       stipple;
834
835     int             nlwDst;             /* width in longwords of the dest pixmap */
836     int             x,y,w;              /* current span */
837     unsigned long   startmask;
838     unsigned long   endmask;
839     register unsigned long *dst;        /* pointer to bits we're writing */
840     register int    nlw;
841     unsigned long   *dstTmp;
842     int             nlwTmp;
843
844     unsigned long   *pbits;             /* pointer to start of pixmap */
845     register unsigned long  xor;
846     register unsigned long  mask;
847     register unsigned long  bits;       /* bits from stipple */
848     int             wEnd;
849
850     int             *pwidthFree;        /* copies of the pointers to free */
851     DDXPointPtr     pptFree;
852     cfbPrivGCPtr    devPriv;
853
854     devPriv = cfbGetGCPrivate(pGC);
855
856     cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
857
858     n = nInit * miFindMaxBand(devPriv->pCompositeClip);
859     if ( n == 0 )
860         return;
861     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
862     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
863     if(!pptFree || !pwidthFree)
864     {
865         if (pptFree) DEALLOCATE_LOCAL(pptFree);
866         if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
867         return;
868     }
869     pwidth = pwidthFree;
870     ppt = pptFree;
871     n = miClipSpans(devPriv->pCompositeClip,
872                      pptInit, pwidthInit, nInit,
873                      ppt, pwidth, fSorted);
874
875     stipple = devPriv->pRotatedPixmap;
876     src = (unsigned long *)stipple->devPrivate.ptr;
877     stippleHeight = stipple->drawable.height;
878
879     cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
880
881     while (n--)
882     {
883         w = *pwidth++;
884         x = ppt->x;
885         y = ppt->y;
886         ppt++;
887         dst = pbits + (y * nlwDst) + (x >> PWSH);
888         if (((x & PIM) + w) <= PPW)
889         {
890             maskpartialbits(x, w, startmask);
891             endmask = 0;
892             nlw = 0;
893         }
894         else
895         {
896             maskbits (x, w, startmask, endmask, nlw);
897         }
898         bits = src[y % stippleHeight];
899         RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
900 #if PPW == 4
901         if (cfb8StippleRRop == GXcopy)
902         {
903             xor = devPriv->xor;
904             if (w < PGSZ*2)
905             {
906                 if (startmask)
907                 {
908                     *dst = *dst & ~startmask |
909                            GetPixelGroup (bits) & startmask;
910                     dst++;
911                     RotBitsLeft (bits, PGSZB);
912                 }
913                 while (nlw--)
914                 {
915                     *dst++ = GetPixelGroup(bits);
916                     RotBitsLeft (bits, PGSZB);
917                 }
918                 if (endmask)
919                 {
920                     *dst = *dst & ~endmask |
921                            GetPixelGroup (bits) & endmask;
922                 }
923             }
924             else
925             { /* XXX consts probably not OK here */
926                 wEnd = 7 - (nlw & 7);
927                 nlw = (nlw >> 3) + 1;
928                 dstTmp = dst;
929                 nlwTmp = nlw;
930                 if (startmask)
931                 {
932                     *dstTmp = *dstTmp & ~startmask |
933                            GetPixelGroup (bits) & startmask;
934                     dstTmp++;
935                     RotBitsLeft (bits, PGSZB);
936                 }
937                 w = 7 - wEnd;
938                 while (w--)
939                 {
940                     nlw = nlwTmp;
941                     dst = dstTmp;
942                     dstTmp++;
943                     xor = GetPixelGroup (bits);
944                     while (nlw--)
945                     {
946                         *dst = xor;
947                         dst += 8;
948                     }
949                     NextBitGroup (bits);
950                 }
951                 nlwTmp--;
952                 w = wEnd + 1;
953                 if (endmask)
954                 {
955                     dst = dstTmp + (nlwTmp << 3);
956                     *dst = (*dst & ~endmask) |
957                            GetPixelGroup (bits) & endmask;
958                 }
959                 while (w--)
960                 {
961                     nlw = nlwTmp;
962                     dst = dstTmp;
963                     dstTmp++;
964                     xor = GetPixelGroup (bits);
965                     while (nlw--)
966                     {
967                         *dst = xor;
968                         dst += 8;
969                     }
970                     NextBitGroup (bits);
971                 }
972             }
973         }
974         else
975 #endif /* PPW == 4 */
976         {
977             if (startmask)
978             {
979                 xor = GetBitGroup(bits);
980                 *dst = MaskRRopPixels(*dst, xor, startmask);
981                 dst++;
982                 RotBitsLeft (bits, PGSZB);
983             }
984             while (nlw--)
985             {
986                 RRopBitGroup(dst, GetBitGroup(bits));
987                 dst++;
988                 RotBitsLeft (bits, PGSZB);
989             }
990             if (endmask)
991             {
992                 xor = GetBitGroup(bits);
993                 *dst = MaskRRopPixels(*dst, xor, endmask);
994             }
995         }
996     }
997     DEALLOCATE_LOCAL(pptFree);
998     DEALLOCATE_LOCAL(pwidthFree);
999 }
1000
1001 #endif /* PSZ == 8 */