1
2#ifdef HAVE_XORG_CONFIG_H
3#include <xorg-config.h>
4#endif
5
6#include "xaa.h"
7#include "xaalocal.h"
8#include "xaacexp.h"
9#include "xf86.h"
10
11static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int);
12static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int);
13static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int);
14static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int);
15static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int);
16static CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int);
17
18#ifdef TRIPLE_BITS
19#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3)
20#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc3)
21#else
22#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc)
23#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc)
24#endif
25
26StippleScanlineProcPtr stipple_scanline_func[6] = {
27   StipplePowerOfTwo,
28   StippleUpTo32,
29   StippleOver32,
30   StipplePowerOfTwo_Inverted,
31   StippleUpTo32_Inverted,
32   StippleOver32_Inverted
33};
34
35StippleScanlineProcPtr *stipple_get_scanline_func(void) {
36   return stipple_scanline_func;
37}
38
39#ifdef FIXEDBASE
40# define DEST(i)	*dest
41# define RETURN(i)	return(dest)
42#else
43# define DEST(i)	dest[i]
44# define RETURN(i)	return(dest + i)
45#endif
46
47
48/* TRIPLE_BITS pattern expansion */
49#ifdef TRIPLE_BITS
50#define EXPAND_PAT \
51	CARD32 pat1 = byte_expand3[pat & 0xFF], \
52	       pat2 = byte_expand3[(pat & 0xFF00) >> 8], \
53	       pat3 = byte_expand3[(pat & 0xFF0000) >> 16], \
54	       pat4 = byte_expand3[(pat & 0xFF000000) >> 24], \
55	       patA = pat1 | (pat2 << 24), \
56	       patB = (pat2 >> 8) | (pat3 << 16), \
57	       patC = (pat3 >> 16) | (pat4 << 8)
58#ifdef FIXED_BASE
59#define WRITE_PAT1 { \
60	*dest = patA; }
61#define WRITE_PAT2 { \
62	*dest = patA; \
63	*dest = patB; }
64#define WRITE_PAT3 { \
65	*dest = patA; \
66	*dest = patB; \
67	*dest = patC; }
68#else
69#define WRITE_PAT1 { \
70	*(dest++) = patA; }
71#define WRITE_PAT2 { \
72	*(dest) = patA; \
73	*(dest + 1) = patB; \
74	dest += 2; }
75#define WRITE_PAT3 { \
76	*(dest) = patA; \
77	*(dest + 1) = patB; \
78	*(dest + 2) = patC; \
79	dest += 3; }
80#endif
81#endif
82
83
84#if !defined(FIXEDBASE) && !defined(MSBFIRST) && !defined(TRIPLE_BITS)
85
86unsigned int XAAShiftMasks[32] = {
87  /* gcc is rather pedantic about SHIFT_R(0xFFFFFFFF,32) */
88          0x00000000    , SHIFT_R(0xFFFFFFFF,31),
89  SHIFT_R(0xFFFFFFFF,30), SHIFT_R(0xFFFFFFFF,29),
90  SHIFT_R(0xFFFFFFFF,28), SHIFT_R(0xFFFFFFFF,27),
91  SHIFT_R(0xFFFFFFFF,26), SHIFT_R(0xFFFFFFFF,25),
92  SHIFT_R(0xFFFFFFFF,24), SHIFT_R(0xFFFFFFFF,23),
93  SHIFT_R(0xFFFFFFFF,22), SHIFT_R(0xFFFFFFFF,21),
94  SHIFT_R(0xFFFFFFFF,20), SHIFT_R(0xFFFFFFFF,19),
95  SHIFT_R(0xFFFFFFFF,18), SHIFT_R(0xFFFFFFFF,17),
96  SHIFT_R(0xFFFFFFFF,16), SHIFT_R(0xFFFFFFFF,15),
97  SHIFT_R(0xFFFFFFFF,14), SHIFT_R(0xFFFFFFFF,13),
98  SHIFT_R(0xFFFFFFFF,12), SHIFT_R(0xFFFFFFFF,11),
99  SHIFT_R(0xFFFFFFFF,10), SHIFT_R(0xFFFFFFFF,9),
100  SHIFT_R(0xFFFFFFFF,8),  SHIFT_R(0xFFFFFFFF,7),
101  SHIFT_R(0xFFFFFFFF,6),  SHIFT_R(0xFFFFFFFF,5),
102  SHIFT_R(0xFFFFFFFF,4),  SHIFT_R(0xFFFFFFFF,3),
103  SHIFT_R(0xFFFFFFFF,2),  SHIFT_R(0xFFFFFFFF,1)
104};
105
106#endif
107
108void
109#ifdef TRIPLE_BITS
110EXPNAME(XAAFillColorExpandRects3)(
111#else
112EXPNAME(XAAFillColorExpandRects)(
113#endif
114   ScrnInfoPtr pScrn,
115   int fg, int bg, int rop,
116   unsigned int planemask,
117   int nBox,
118   BoxPtr pBox,
119   int xorg, int yorg,
120   PixmapPtr pPix
121){
122    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
123    CARD32 *base;
124    Bool TwoPass = FALSE, FirstPass = TRUE;
125    StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
126    int stipplewidth = pPix->drawable.width;
127    int stippleheight = pPix->drawable.height;
128    int srcwidth = pPix->devKind;
129    int dwords, srcy, srcx, funcNo = 2, h;
130    unsigned char *src = (unsigned char*)pPix->devPrivate.ptr;
131    unsigned char *srcp;
132    int flag;
133
134    if(stipplewidth <= 32) {
135	if(stipplewidth & (stipplewidth - 1))
136	  funcNo = 1;
137	else
138	  funcNo = 0;
139    }
140    StippleFunc = stipple_scanline_func[funcNo];
141    SecondFunc = stipple_scanline_func[funcNo];
142    FirstFunc = stipple_scanline_func[funcNo + 3];
143
144#ifdef TRIPLE_BITS
145    if((bg == -1) ||
146	(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
147	(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
148	(CHECK_RGB_EQUAL(bg))))) {
149#else
150    if((bg == -1) ||
151	!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
152#endif
153	/* one pass */
154    } else if((rop == GXcopy) && infoRec->FillSolidRects) {
155	/* one pass but we fill background rects first */
156	(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
157	bg = -1;
158    } else {
159	/* gotta do two passes */
160	TwoPass = TRUE;
161    }
162
163    if(!TwoPass)
164	(*infoRec->SetupForCPUToScreenColorExpandFill)(
165					pScrn, fg, bg, rop, planemask);
166
167    while(nBox--) {
168#ifdef TRIPLE_BITS
169	dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
170#else
171	dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
172#endif
173
174SECOND_PASS:
175	if(TwoPass) {
176	    (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
177			(FirstPass) ? bg : fg, -1, rop, planemask);
178	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
179	}
180
181	h = pBox->y2 - pBox->y1;
182	flag = (infoRec->CPUToScreenColorExpandFillFlags
183		& CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
184
185        (*infoRec->SubsequentCPUToScreenColorExpandFill)(
186			pScrn, pBox->x1, pBox->y1,
187 			pBox->x2 - pBox->x1, h, 0);
188
189	base = (CARD32*)infoRec->ColorExpandBase;
190
191	srcy = (pBox->y1 - yorg) % stippleheight;
192	if(srcy < 0) srcy += stippleheight;
193	srcx = (pBox->x1 - xorg) % stipplewidth;
194	if(srcx < 0) srcx += stipplewidth;
195
196	srcp = (srcwidth * srcy) + src;
197
198#ifndef FIXEDBASE
199	if((dwords * h) <= infoRec->ColorExpandRange) {
200	   while(h--) {
201		base = (*StippleFunc)(
202			base, (CARD32*)srcp, srcx, stipplewidth, dwords);
203		srcy++;
204		srcp += srcwidth;
205		if (srcy >= stippleheight) {
206		   srcy = 0;
207		   srcp = src;
208		}
209	   }
210	} else
211#endif
212	   while(h--) {
213		(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
214		srcy++;
215		srcp += srcwidth;
216		if (srcy >= stippleheight) {
217		   srcy = 0;
218		   srcp = src;
219		}
220	   }
221
222	  if (flag) {
223	      base = (CARD32*)infoRec->ColorExpandBase;
224	      base[0] = 0x00000000;
225	  }
226
227	if(TwoPass) {
228	   if(FirstPass) {
229		FirstPass = FALSE;
230		goto SECOND_PASS;
231	   } else FirstPass = TRUE;
232	}
233
234	pBox++;
235     }
236
237    if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
238	(*infoRec->Sync)(pScrn);
239    else SET_SYNC_FLAG(infoRec);
240}
241
242
243
244void
245#ifdef TRIPLE_BITS
246EXPNAME(XAAFillColorExpandSpans3)(
247#else
248EXPNAME(XAAFillColorExpandSpans)(
249#endif
250   ScrnInfoPtr pScrn,
251   int fg, int bg, int rop,
252   unsigned int planemask,
253   int n,
254   DDXPointPtr ppt,
255   int *pwidth,
256   int fSorted,
257   int xorg, int yorg,
258   PixmapPtr pPix
259){
260    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
261    CARD32 *base;
262    Bool TwoPass = FALSE, FirstPass = TRUE;
263    StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
264    int stipplewidth = pPix->drawable.width;
265    int stippleheight = pPix->drawable.height;
266    int dwords, srcy, srcx, funcNo = 2;
267    unsigned char *srcp;
268
269    if(stipplewidth <= 32) {
270	if(stipplewidth & (stipplewidth - 1))
271	  funcNo = 1;
272	else
273	  funcNo = 0;
274    }
275    StippleFunc = stipple_scanline_func[funcNo];
276    SecondFunc = stipple_scanline_func[funcNo];
277    FirstFunc = stipple_scanline_func[funcNo + 3];
278
279#ifdef TRIPLE_BITS
280    if((bg == -1) ||
281	(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
282	(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
283	(CHECK_RGB_EQUAL(bg))))) {
284#else
285    if((bg == -1) ||
286	!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
287#endif
288	/* one pass */
289    } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
290	/* one pass but we fill background rects first */
291	(*infoRec->FillSolidSpans)(
292		pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
293	bg = -1;
294    } else {
295	/* gotta do two passes */
296	TwoPass = TRUE;
297    }
298
299    if(!TwoPass)
300	(*infoRec->SetupForCPUToScreenColorExpandFill)(
301				pScrn, fg, bg, rop, planemask);
302
303    while(n--) {
304#ifdef TRIPLE_BITS
305	dwords = (3 * *pwidth + 31) >> 5;
306#else
307	dwords = (*pwidth + 31) >> 5;
308#endif
309
310	srcy = (ppt->y - yorg) % stippleheight;
311	if(srcy < 0) srcy += stippleheight;
312	srcx = (ppt->x - xorg) % stipplewidth;
313	if(srcx < 0) srcx += stipplewidth;
314
315	srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
316
317SECOND_PASS:
318	if(TwoPass) {
319	    (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
320			(FirstPass) ? bg : fg, -1, rop, planemask);
321	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
322	}
323
324        (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y,
325 			*pwidth, 1, 0);
326
327	base = (CARD32*)infoRec->ColorExpandBase;
328
329	(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
330
331	if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD)
332			&& (dwords & 0x01)) {
333	    base = (CARD32*)infoRec->ColorExpandBase;
334	    base[0] = 0x00000000;
335    	}
336
337	if(TwoPass) {
338	   if(FirstPass) {
339		FirstPass = FALSE;
340		goto SECOND_PASS;
341	   } else FirstPass = TRUE;
342	}
343
344	ppt++; pwidth++;
345     }
346
347    if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
348	(*infoRec->Sync)(pScrn);
349    else SET_SYNC_FLAG(infoRec);
350}
351
352
353#ifndef FIXEDBASE
354
355void
356#ifdef TRIPLE_BITS
357EXPNAME(XAAFillScanlineColorExpandRects3)(
358#else
359EXPNAME(XAAFillScanlineColorExpandRects)(
360#endif
361   ScrnInfoPtr pScrn,
362   int fg, int bg, int rop,
363   unsigned int planemask,
364   int nBox,
365   BoxPtr pBox,
366   int xorg, int yorg,
367   PixmapPtr pPix
368){
369    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
370    CARD32 *base;
371    Bool TwoPass = FALSE, FirstPass = TRUE;
372    StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
373    int stipplewidth = pPix->drawable.width;
374    int stippleheight = pPix->drawable.height;
375    int srcwidth = pPix->devKind;
376    int dwords, srcy, srcx, funcNo = 2, bufferNo, h;
377    unsigned char *src = pPix->devPrivate.ptr;
378    unsigned char *srcp;
379
380    if(stipplewidth <= 32) {
381	if(stipplewidth & (stipplewidth - 1))
382	  funcNo = 1;
383	else
384	  funcNo = 0;
385    }
386    StippleFunc = stipple_scanline_func[funcNo];
387    SecondFunc = stipple_scanline_func[funcNo];
388    FirstFunc = stipple_scanline_func[funcNo + 3];
389
390#ifdef TRIPLE_BITS
391    if((bg == -1) ||
392      (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
393      (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
394      (CHECK_RGB_EQUAL(bg))))) {
395#else
396    if((bg == -1) ||
397      !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
398#endif
399	/* one pass */
400    } else if((rop == GXcopy) && infoRec->FillSolidRects) {
401	/* one pass but we fill background rects first */
402	(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
403	bg = -1;
404    } else {
405	/* gotta do two passes */
406	TwoPass = TRUE;
407    }
408
409    if(!TwoPass)
410	(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
411				pScrn, fg, bg, rop, planemask);
412
413    while(nBox--) {
414#ifdef TRIPLE_BITS
415	dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
416#else
417	dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
418#endif
419
420SECOND_PASS:
421	if(TwoPass) {
422	    (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
423			(FirstPass) ? bg : fg, -1, rop, planemask);
424	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
425	}
426
427	h = pBox->y2 - pBox->y1;
428
429        (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
430		pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0);
431
432	bufferNo = 0;
433
434	srcy = (pBox->y1 - yorg) % stippleheight;
435	if(srcy < 0) srcy += stippleheight;
436	srcx = (pBox->x1 - xorg) % stipplewidth;
437	if(srcx < 0) srcx += stipplewidth;
438
439	srcp = (srcwidth * srcy) + src;
440
441	while(h--) {
442   	    base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
443	    (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
444	    (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
445	    if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
446		bufferNo = 0;
447	    srcy++;
448	    srcp += srcwidth;
449	    if (srcy >= stippleheight) {
450		srcy = 0;
451		srcp = src;
452	    }
453	}
454
455	if(TwoPass) {
456	   if(FirstPass) {
457		FirstPass = FALSE;
458		goto SECOND_PASS;
459	   } else FirstPass = TRUE;
460	}
461
462	pBox++;
463     }
464
465     SET_SYNC_FLAG(infoRec);
466}
467
468void
469#ifdef TRIPLE_BITS
470EXPNAME(XAAFillScanlineColorExpandSpans3)(
471#else
472EXPNAME(XAAFillScanlineColorExpandSpans)(
473#endif
474   ScrnInfoPtr pScrn,
475   int fg, int bg, int rop,
476   unsigned int planemask,
477   int n,
478   DDXPointPtr ppt,
479   int *pwidth,
480   int fSorted,
481   int xorg, int yorg,
482   PixmapPtr pPix
483){
484    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
485    CARD32 *base;
486    Bool TwoPass = FALSE, FirstPass = TRUE;
487    StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
488    int stipplewidth = pPix->drawable.width;
489    int stippleheight = pPix->drawable.height;
490    int dwords, srcy, srcx, funcNo = 2;
491    unsigned char *srcp;
492
493    if(stipplewidth <= 32) {
494	if(stipplewidth & (stipplewidth - 1))
495	  funcNo = 1;
496	else
497	  funcNo = 0;
498    }
499    StippleFunc = stipple_scanline_func[funcNo];
500    SecondFunc = stipple_scanline_func[funcNo];
501    FirstFunc = stipple_scanline_func[funcNo + 3];
502
503#ifdef TRIPLE_BITS
504    if((bg == -1) ||
505      (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
506      (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
507      (CHECK_RGB_EQUAL(bg))))) {
508#else
509    if((bg == -1) ||
510      !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
511#endif
512	/* one pass */
513    } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
514	/* one pass but we fill background rects first */
515	(*infoRec->FillSolidSpans)(
516		pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
517	bg = -1;
518    } else {
519	/* gotta do two passes */
520	TwoPass = TRUE;
521    }
522
523    if(!TwoPass)
524	(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
525				pScrn, fg, bg, rop, planemask);
526
527
528    while(n--) {
529#ifdef TRIPLE_BITS
530	dwords = (3 * *pwidth + 31) >> 5;
531#else
532	dwords = (*pwidth + 31) >> 5;
533#endif
534
535	srcy = (ppt->y - yorg) % stippleheight;
536	if(srcy < 0) srcy += stippleheight;
537	srcx = (ppt->x - xorg) % stipplewidth;
538	if(srcx < 0) srcx += stipplewidth;
539
540	srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
541
542SECOND_PASS:
543	if(TwoPass) {
544	    (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
545			(FirstPass) ? bg : fg, -1, rop, planemask);
546	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
547	}
548
549        (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
550				pScrn, ppt->x, ppt->y, *pwidth, 1, 0);
551
552	base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];
553
554	(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
555	(*infoRec->SubsequentColorExpandScanline)(pScrn, 0);
556
557	if(TwoPass) {
558	   if(FirstPass) {
559		FirstPass = FALSE;
560		goto SECOND_PASS;
561	   } else FirstPass = TRUE;
562	}
563
564	ppt++; pwidth++;
565     }
566
567     SET_SYNC_FLAG(infoRec);
568}
569
570#endif
571
572static CARD32 *
573StipplePowerOfTwo(
574   CARD32* dest, CARD32* src,
575   int shift, int width, int dwords
576){
577    CARD32 pat = *src;
578    if(width < 32) {
579	pat &= XAAShiftMasks[width];
580	while(width < 32) {
581	    pat |= SHIFT_L(pat,width);
582	    width <<= 1;
583	}
584    }
585
586    if(shift)
587	pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
588
589#ifdef MSBFIRST
590    pat = SWAP_BITS_IN_BYTES(pat);
591#endif
592
593#ifdef TRIPLE_BITS
594    {
595	EXPAND_PAT;
596
597	while(dwords >= 3) {
598	    WRITE_PAT3;
599	    dwords -= 3;
600	}
601	if (dwords == 2) {
602	    WRITE_PAT2;
603	} else if (dwords == 1) {
604	    WRITE_PAT1;
605	}
606
607	return dest;
608    }
609#else /* TRIPLE_BITS */
610   while(dwords >= 4) {
611	DEST(0) = pat;
612	DEST(1) = pat;
613	DEST(2) = pat;
614	DEST(3) = pat;
615	dwords -= 4;
616#ifndef FIXEDBASE
617	dest += 4;
618#endif
619   }
620
621   if(!dwords) return dest;
622   DEST(0) = pat;
623   if(dwords == 1) RETURN(1);
624   DEST(1) = pat;
625   if(dwords == 2) RETURN(2);
626   DEST(2) = pat;
627   RETURN(3);
628#endif /* TRIPLE_BITS */
629}
630
631static CARD32 *
632StipplePowerOfTwo_Inverted(
633   CARD32* dest, CARD32* src,
634   int shift, int width, int dwords
635){
636    CARD32 pat = *src;
637    if(width < 32) {
638	pat &= XAAShiftMasks[width];
639	while(width < 32) {
640	    pat |= SHIFT_L(pat,width);
641	    width <<= 1;
642	}
643    }
644
645    if(shift)
646	pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
647
648#ifdef MSBFIRST
649    pat = SWAP_BITS_IN_BYTES(pat);
650#endif
651
652   pat = ~pat;
653
654#ifdef TRIPLE_BITS
655    {
656	EXPAND_PAT;
657
658	while(dwords >= 3) {
659	    WRITE_PAT3;
660	    dwords -= 3;
661	}
662	if (dwords == 2) {
663	    WRITE_PAT2;
664	} else if (dwords == 1) {
665	    WRITE_PAT1;
666	}
667
668	return dest;
669    }
670#else /* TRIPLE_BITS */
671   while(dwords >= 4) {
672	DEST(0) = pat;
673	DEST(1) = pat;
674	DEST(2) = pat;
675	DEST(3) = pat;
676	dwords -= 4;
677#ifndef FIXEDBASE
678	dest += 4;
679#endif
680   }
681
682   if(!dwords) return dest;
683   DEST(0) = pat;
684   if(dwords == 1) RETURN(1);
685   DEST(1) = pat;
686   if(dwords == 2) RETURN(2);
687   DEST(2) = pat;
688   RETURN(3);
689#endif /* TRIPLE_BITS */
690}
691
692
693static CARD32 *
694StippleUpTo32(
695   CARD32* base, CARD32* src,
696   int shift, int width, int dwords
697){
698    CARD32 pat = *src & XAAShiftMasks[width];
699
700    while(width <= 15) {
701	pat |= SHIFT_L(pat,width);
702	width <<= 1;
703    }
704    pat |= SHIFT_L(pat,width);
705
706    while(dwords--) {
707	CARD32 bits = SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift);
708#ifdef TRIPLE_BITS
709	if(dwords >= 2) {
710	    WRITE_BITS3(bits);
711	    dwords -= 2;
712	} else if(dwords > 0) {
713	    WRITE_BITS2(bits);
714	    dwords--;
715	} else {
716	    WRITE_BITS1(bits);
717	}
718#else
719	WRITE_BITS(bits);
720#endif
721
722	shift += 32;
723	shift %= width;
724    }
725    return base;
726}
727
728
729static CARD32 *
730StippleUpTo32_Inverted(
731   CARD32* base, CARD32* src,
732   int shift, int width, int dwords
733){
734    CARD32 pat = *src & XAAShiftMasks[width];
735
736    while(width <= 15) {
737	pat |= SHIFT_L(pat,width);
738	width <<= 1;
739    }
740    pat |= SHIFT_L(pat,width);
741
742    while(dwords--) {
743	CARD32 bits = ~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift));
744#ifdef TRIPLE_BITS
745	if(dwords >= 2) {
746	    WRITE_BITS3(bits);
747	    dwords -= 2;
748	} else if(dwords > 0) {
749	    WRITE_BITS2(bits);
750	    dwords--;
751	} else {
752	    WRITE_BITS1(bits);
753	}
754#else
755	WRITE_BITS(bits);
756#endif
757
758	shift += 32;
759	shift %= width;
760    }
761    return base;
762}
763
764
765static CARD32 *
766StippleOver32(
767   CARD32* base, CARD32* src,
768   int offset, int width, int dwords
769){
770   CARD32* srcp;
771   CARD32 bits;
772   int bitsleft, shift, usable;
773
774   while(dwords--) {
775        bitsleft = width - offset;
776        srcp = src + (offset >> 5);
777        shift = offset & 31;
778        usable = 32 - shift;
779
780        if(bitsleft < 32) {
781            if(bitsleft <= usable) {
782                 bits = SHIFT_L(*src,bitsleft) |
783                       (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
784            } else {
785                 bits = SHIFT_L(*src,bitsleft) |
786                       (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
787                       (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
788            }
789        }
790        else if(shift)
791            bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
792        else
793            bits = *srcp;
794
795#ifdef TRIPLE_BITS
796	if(dwords >= 2) {
797	    WRITE_BITS3(bits);
798	    dwords -= 2;
799	} else if(dwords > 0) {
800	    WRITE_BITS2(bits);
801	    dwords--;
802	} else {
803	    WRITE_BITS1(bits);
804	}
805#else
806	WRITE_BITS(bits);
807#endif
808
809	offset += 32;
810	offset %= width;
811   }
812   return base;
813}
814
815
816static CARD32 *
817StippleOver32_Inverted(
818   CARD32* base, CARD32* src,
819   int offset, int width, int dwords
820){
821   CARD32* srcp;
822   CARD32 bits;
823   int bitsleft, shift, usable;
824
825   while(dwords--) {
826        bitsleft = width - offset;
827        srcp = src + (offset >> 5);
828        shift = offset & 31;
829        usable = 32 - shift;
830
831        if(bitsleft < 32) {
832            if(bitsleft <= usable) {
833                 bits = SHIFT_L(*src,bitsleft) |
834                       (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
835            } else {
836                 bits = SHIFT_L(*src,bitsleft) |
837                       (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
838                       (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
839            }
840        }
841        else if(shift)
842            bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
843        else
844            bits = *srcp;
845
846	bits = ~bits;
847
848#ifdef TRIPLE_BITS
849	if(dwords >= 2) {
850	    WRITE_BITS3(bits);
851	    dwords -= 2;
852	} else if(dwords > 0) {
853	    WRITE_BITS2(bits);
854	    dwords--;
855	} else {
856	    WRITE_BITS1(bits);
857	}
858#else
859	WRITE_BITS(bits);
860#endif
861
862	offset += 32;
863	offset %= width;
864   }
865   return base;
866}
867