1
2#ifdef HAVE_XORG_CONFIG_H
3#include <xorg-config.h>
4#endif
5
6#include "misc.h"
7#include "xf86.h"
8#include "xf86_OSproc.h"
9
10#include <X11/X.h>
11#include "scrnintstr.h"
12#include "pixmapstr.h"
13#include "xf86str.h"
14#include "mi.h"
15#include "mispans.h"
16#include "xaa.h"
17#include "xaalocal.h"
18
19
20static void XAARenderSolidSpans(
21	GCPtr, int, DDXPointPtr, int*, int, int, int);
22static void XAARenderColor8x8Spans(
23	GCPtr, int, DDXPointPtr, int*, int, int, int);
24static void XAARenderMono8x8Spans(
25	GCPtr, int, DDXPointPtr, int*, int, int, int);
26static void XAARenderCacheBltSpans(
27	GCPtr, int, DDXPointPtr, int*, int, int, int);
28static void XAARenderColorExpandSpans(
29	GCPtr, int, DDXPointPtr, int*, int, int, int);
30static void XAARenderCacheExpandSpans(
31	GCPtr, int, DDXPointPtr, int*, int, int, int);
32static void XAARenderPixmapCopySpans(
33	GCPtr, int, DDXPointPtr, int*, int, int, int);
34
35void
36XAAFillSpans(
37    DrawablePtr pDraw,
38    GC		*pGC,
39    int		nInit,		/* number of spans to fill */
40    DDXPointPtr pptInit,	/* pointer to list of start points */
41    int *pwidthInit,		/* pointer to list of n widths */
42    int fSorted
43){
44    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
45    int type = 0;
46    ClipAndRenderSpansFunc function;
47    Bool fastClip = FALSE;
48
49    if((nInit <= 0) || !pGC->planemask)
50        return;
51
52    if(!RegionNumRects(pGC->pCompositeClip))
53	return;
54
55    switch(pGC->fillStyle) {
56    case FillSolid:
57	type = DO_SOLID;
58	break;
59    case FillStippled:
60	type = (*infoRec->StippledFillChooser)(pGC);
61	break;
62    case FillOpaqueStippled:
63	if((pGC->fgPixel == pGC->bgPixel) && infoRec->FillSpansSolid &&
64                CHECK_PLANEMASK(pGC,infoRec->FillSpansSolidFlags) &&
65                CHECK_ROP(pGC,infoRec->FillSpansSolidFlags) &&
66                CHECK_ROPSRC(pGC,infoRec->FillSpansSolidFlags) &&
67                CHECK_FG(pGC,infoRec->FillSpansSolidFlags))
68	    type = DO_SOLID;
69	else
70	    type = (*infoRec->OpaqueStippledFillChooser)(pGC);
71	break;
72    case FillTiled:
73	type = (*infoRec->TiledFillChooser)(pGC);
74	break;
75    }
76
77    switch(type) {
78    case DO_SOLID:
79	function = XAARenderSolidSpans;
80	if(infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL)
81		fastClip = TRUE;
82	break;
83    case DO_COLOR_8x8:
84	function = XAARenderColor8x8Spans;
85	if(infoRec->ClippingFlags & HARDWARE_CLIP_COLOR_8x8_FILL)
86		fastClip = TRUE;
87	break;
88    case DO_MONO_8x8:
89	function = XAARenderMono8x8Spans;
90	if(infoRec->ClippingFlags & HARDWARE_CLIP_MONO_8x8_FILL)
91		fastClip = TRUE;
92	break;
93    case DO_CACHE_BLT:
94	function = XAARenderCacheBltSpans;
95	if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY)
96		fastClip = TRUE;
97	break;
98    case DO_COLOR_EXPAND:
99	function = XAARenderColorExpandSpans;
100	break;
101    case DO_CACHE_EXPAND:
102	function = XAARenderCacheExpandSpans;
103	if(infoRec->ClippingFlags &
104			HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND)
105		fastClip = TRUE;
106	break;
107    case DO_PIXMAP_COPY:
108	function = XAARenderPixmapCopySpans;
109	if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY)
110		fastClip = TRUE;
111	break;
112    case DO_IMAGE_WRITE:
113    default:
114	(*XAAFallbackOps.FillSpans)(pDraw, pGC, nInit, pptInit,
115				pwidthInit, fSorted);
116	return;
117    }
118
119
120    if((nInit < 10) || (RegionNumRects(pGC->pCompositeClip) != 1))
121	fastClip = FALSE;
122
123    if(fastClip) {
124	infoRec->ClipBox = &pGC->pCompositeClip->extents;
125	(*function)(pGC, nInit, pptInit, pwidthInit, fSorted,
126					pDraw->x, pDraw->y);
127	infoRec->ClipBox = NULL;
128    } else
129	XAAClipAndRenderSpans(pGC, pptInit, pwidthInit, nInit, fSorted,
130					function, pDraw->x, pDraw->y);
131}
132
133
134	/*********************\
135	|     Solid Spans     |
136	\*********************/
137
138
139static void
140XAARenderSolidSpans(
141    GCPtr pGC,
142    int	n,
143    DDXPointPtr ppt,
144    int *pwidth,
145    int fSorted,
146    int xorg, int yorg
147){
148    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
149
150    (*infoRec->FillSolidSpans) (infoRec->pScrn, pGC->fgPixel,
151		pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted);
152}
153
154
155	/************************\
156	|     Mono 8x8 Spans     |
157	\************************/
158
159
160static void
161XAARenderMono8x8Spans(
162    GCPtr pGC,
163    int	n,
164    DDXPointPtr ppt,
165    int *pwidth,
166    int fSorted,
167    int xorg, int yorg
168){
169   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
170   XAAPixmapPtr pPriv;
171   int fg, bg;
172
173   switch(pGC->fillStyle) {
174   case FillStippled:
175      pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
176      fg = pGC->fgPixel;  bg = -1;
177      break;
178   case FillOpaqueStippled:
179      pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
180      fg = pGC->fgPixel;  bg = pGC->bgPixel;
181      break;
182   case FillTiled:
183      pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
184      fg = pPriv->fg;  bg = pPriv->bg;
185      break;
186   default:	/* Muffle compiler */
187      pPriv = NULL;	/* Kaboom */
188      fg = -1;  bg = -1;
189      break;
190   }
191
192   (*infoRec->FillMono8x8PatternSpans) (infoRec->pScrn,
193                fg, bg, pGC->alu, pGC->planemask,
194                n, ppt, pwidth, fSorted, pPriv->pattern0, pPriv->pattern1,
195                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
196}
197
198
199	/*************************\
200	|     Color 8x8 Spans     |
201	\*************************/
202
203
204static void
205XAARenderColor8x8Spans(
206    GCPtr pGC,
207    int	n,
208    DDXPointPtr ppt,
209    int *pwidth,
210    int fSorted,
211    int xorg, int yorg
212){
213   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
214   XAACacheInfoPtr pCache;
215   PixmapPtr pPix;
216   int fg, bg;
217
218   switch(pGC->fillStyle) {
219   case FillStippled:
220      pPix = pGC->stipple;
221      fg = pGC->fgPixel;  bg = -1;
222      break;
223   case FillOpaqueStippled:
224      pPix = pGC->stipple;
225      fg = pGC->fgPixel;  bg = pGC->bgPixel;
226      break;
227   case FillTiled:
228      pPix = pGC->tile.pixmap;
229      fg = -1;  bg = -1;
230      break;
231   default:	/* Muffle compiler */
232      pPix = NULL;
233      fg = -1;  bg = -1;
234      break;
235   }
236
237   pCache = (*infoRec->CacheColor8x8Pattern)(infoRec->pScrn, pPix, fg, bg);
238
239   (*infoRec->FillColor8x8PatternSpans) (infoRec->pScrn,
240                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
241                (yorg + pGC->patOrg.x), (xorg + pGC->patOrg.y));
242}
243
244
245	/****************************\
246	|     Color Expand Spans     |
247	\****************************/
248
249
250static void
251XAARenderColorExpandSpans(
252    GCPtr pGC,
253    int	n,
254    DDXPointPtr ppt,
255    int *pwidth,
256    int fSorted,
257    int xorg, int yorg
258){
259   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
260   int fg, bg;
261
262   switch(pGC->fillStyle) {
263   case FillStippled:
264      fg = pGC->fgPixel;  bg = -1;
265      break;
266   case FillOpaqueStippled:
267      fg = pGC->fgPixel;  bg = pGC->bgPixel;
268      break;
269   default:	/* Muffle compiler */
270      fg = -1;  bg = -1;
271      break;
272   }
273
274   (*infoRec->FillColorExpandSpans) (infoRec->pScrn, fg, bg,
275                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted,
276                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
277                pGC->stipple);
278
279}
280
281
282	/*************************\
283	|     Cache Blt Spans     |
284	\*************************/
285
286
287static void
288XAARenderCacheBltSpans(
289    GCPtr pGC,
290    int	n,
291    DDXPointPtr ppt,
292    int *pwidth,
293    int fSorted,
294    int xorg, int yorg
295){
296   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
297   XAACacheInfoPtr pCache;
298
299   switch(pGC->fillStyle) {
300   case FillStippled:
301      pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
302					pGC->fgPixel, -1);
303      break;
304   case FillOpaqueStippled:
305      pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
306					pGC->fgPixel, pGC->bgPixel);
307      break;
308   case FillTiled:
309      pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
310      break;
311   default:	/* Muffle compiler */
312      pCache = NULL;
313      break;
314   }
315
316   (*infoRec->FillCacheBltSpans) (infoRec->pScrn,
317                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
318                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
319
320}
321
322
323	/****************************\
324	|     Cache Expand Spans     |
325	\****************************/
326
327
328static void
329XAARenderCacheExpandSpans(
330    GCPtr pGC,
331    int	n,
332    DDXPointPtr ppt,
333    int *pwidth,
334    int fSorted,
335    int xorg, int yorg
336){
337   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
338   int fg, bg;
339
340   switch(pGC->fillStyle) {
341   case FillStippled:
342      fg = pGC->fgPixel;  bg = -1;
343      break;
344   case FillOpaqueStippled:
345      fg = pGC->fgPixel;  bg = pGC->bgPixel;
346      break;
347   default:	/* Muffle compiler */
348      fg = -1;  bg = -1;
349      break;
350   }
351
352   (*infoRec->FillCacheExpandSpans) (infoRec->pScrn, fg, bg,
353                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted,
354                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
355                pGC->stipple);
356}
357
358
359	/***************************\
360	|     Pixmap Copy Spans     |
361	\***************************/
362
363
364static void
365XAARenderPixmapCopySpans(
366    GCPtr pGC,
367    int	n,
368    DDXPointPtr ppt,
369    int *pwidth,
370    int fSorted,
371    int xorg, int yorg
372){
373   XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
374   XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
375   XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
376
377   pCache->x = pPriv->offscreenArea->box.x1;
378   pCache->y = pPriv->offscreenArea->box.y1;
379   pCache->w = pCache->orig_w =
380		pPriv->offscreenArea->box.x2 - pCache->x;
381   pCache->h = pCache->orig_h =
382		pPriv->offscreenArea->box.y2 - pCache->y;
383   pCache->trans_color = -1;
384
385   (*infoRec->FillCacheBltSpans) (infoRec->pScrn,
386                pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
387                (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
388}
389
390
391
392
393
394	/****************\
395	|     Solid      |
396	\****************/
397
398
399void
400XAAFillSolidSpans(
401   ScrnInfoPtr pScrn,
402   int fg, int rop,
403   unsigned int planemask,
404   int n,
405   DDXPointPtr ppt,
406   int *pwidth, int fSorted
407){
408    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
409
410    (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
411
412    if(infoRec->ClipBox)
413	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
414		infoRec->ClipBox->x1, infoRec->ClipBox->y1,
415		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
416
417    while(n--) {
418	if (*pwidth > 0)
419            (*infoRec->SubsequentSolidFillRect)(pScrn, ppt->x, ppt->y,
420								*pwidth, 1);
421	ppt++; pwidth++;
422    }
423
424    if(infoRec->ClipBox)
425	(*infoRec->DisableClipping)(infoRec->pScrn);
426
427    SET_SYNC_FLAG(infoRec);
428}
429
430	/***************\
431	|   Mono 8x8    |
432	\***************/
433
434
435void
436XAAFillMono8x8PatternSpansScreenOrigin(
437   ScrnInfoPtr pScrn,
438   int fg, int bg, int rop,
439   unsigned int planemask,
440   int n,
441   DDXPointPtr ppt,
442   int *pwidth, int fSorted,
443   int pattern0, int pattern1,
444   int xorigin, int yorigin
445){
446    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
447    int patx = pattern0, paty = pattern1;
448    int xorg = (-xorigin) & 0x07;
449    int yorg = (-yorigin) & 0x07;
450
451
452    if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS) {
453   	if(!(infoRec->Mono8x8PatternFillFlags &
454				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
455	    XAARotateMonoPattern(&patx, &paty, xorg, yorg,
456				(infoRec->Mono8x8PatternFillFlags &
457				BIT_ORDER_IN_BYTE_MSBFIRST));
458	    xorg = patx; yorg = paty;
459        }
460    } else {
461	XAACacheInfoPtr pCache =
462		(*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
463	patx = pCache->x;  paty = pCache->y;
464   	if(!(infoRec->Mono8x8PatternFillFlags &
465				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
466	    int slot = (yorg << 3) + xorg;
467	    patx += pCache->offsets[slot].x;
468	    paty += pCache->offsets[slot].y;
469	    xorg = patx;  yorg = paty;
470	}
471    }
472
473    (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
474	fg, bg, rop, planemask);
475
476    if(infoRec->ClipBox)
477	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
478		infoRec->ClipBox->x1, infoRec->ClipBox->y1,
479		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
480
481     while(n--) {
482        (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
483			xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
484	ppt++; pwidth++;
485     }
486
487     if(infoRec->ClipBox)
488	(*infoRec->DisableClipping)(infoRec->pScrn);
489
490     SET_SYNC_FLAG(infoRec);
491}
492
493
494void
495XAAFillMono8x8PatternSpans(
496   ScrnInfoPtr pScrn,
497   int fg, int bg, int rop,
498   unsigned int planemask,
499   int n,
500   DDXPointPtr ppt,
501   int *pwidth, int fSorted,
502   int pattern0, int pattern1,
503   int xorigin, int yorigin
504){
505    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
506    int patx = pattern0, paty = pattern1;
507    int xorg, yorg, slot;
508    XAACacheInfoPtr pCache = NULL;
509
510
511    if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){
512	pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
513	patx = pCache->x;  paty = pCache->y;
514    }
515
516    (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
517					fg, bg, rop, planemask);
518
519    if(infoRec->ClipBox)
520	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
521		infoRec->ClipBox->x1, infoRec->ClipBox->y1,
522		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
523
524     while(n--) {
525	xorg = (ppt->x - xorigin) & 0x07;
526	yorg = (ppt->y - yorigin) & 0x07;
527
528   	if(!(infoRec->Mono8x8PatternFillFlags &
529				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
530	    if(infoRec->Mono8x8PatternFillFlags &
531				HARDWARE_PATTERN_PROGRAMMED_BITS) {
532		patx = pattern0; paty = pattern1;
533		XAARotateMonoPattern(&patx, &paty, xorg, yorg,
534				(infoRec->Mono8x8PatternFillFlags &
535				BIT_ORDER_IN_BYTE_MSBFIRST));
536		xorg = patx; yorg = paty;
537	    } else {
538		slot = (yorg << 3) + xorg;
539	    	xorg = patx + pCache->offsets[slot].x;
540	    	yorg = paty + pCache->offsets[slot].y;
541	    }
542        }
543
544        (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
545			xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
546	ppt++; pwidth++;
547     }
548
549     if(infoRec->ClipBox)
550	(*infoRec->DisableClipping)(infoRec->pScrn);
551
552     SET_SYNC_FLAG(infoRec);
553}
554
555
556
557	/****************\
558	|   Color 8x8    |
559	\****************/
560
561
562void
563XAAFillColor8x8PatternSpansScreenOrigin(
564   ScrnInfoPtr pScrn,
565   int rop,
566   unsigned int planemask,
567   int n,
568   DDXPointPtr ppt,
569   int *pwidth, int fSorted,
570   XAACacheInfoPtr pCache,
571   int xorigin, int yorigin
572){
573    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
574    int patx = pCache->x, paty = pCache->y;
575    int xorg = (-xorigin) & 0x07;
576    int yorg = (-yorigin) & 0x07;
577
578
579    if(!(infoRec->Color8x8PatternFillFlags &
580					HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
581	int slot = (yorg << 3) + xorg;
582	paty += pCache->offsets[slot].y;
583	patx += pCache->offsets[slot].x;
584	xorg = patx;  yorg = paty;
585    }
586
587    (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty,
588			 rop, planemask, pCache->trans_color);
589
590    if(infoRec->ClipBox)
591	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
592		infoRec->ClipBox->x1, infoRec->ClipBox->y1,
593		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
594
595     while(n--) {
596        (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
597			xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
598	ppt++; pwidth++;
599     }
600
601    if(infoRec->ClipBox)
602	(*infoRec->DisableClipping)(infoRec->pScrn);
603
604     SET_SYNC_FLAG(infoRec);
605}
606
607
608void
609XAAFillColor8x8PatternSpans(
610   ScrnInfoPtr pScrn,
611   int rop,
612   unsigned int planemask,
613   int n,
614   DDXPointPtr ppt,
615   int *pwidth, int fSorted,
616   XAACacheInfoPtr pCache,
617   int xorigin, int yorigin
618){
619    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
620    int xorg, yorg, slot;
621
622    (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y,
623			 rop, planemask, pCache->trans_color);
624
625    if(infoRec->ClipBox)
626	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
627		infoRec->ClipBox->x1, infoRec->ClipBox->y1,
628		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
629
630     while(n--) {
631	xorg = (ppt->x - xorigin) & 0x07;
632	yorg = (ppt->y - yorigin) & 0x07;
633
634   	if(!(infoRec->Color8x8PatternFillFlags &
635				HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
636	    slot = (yorg << 3) + xorg;
637	    yorg = pCache->y + pCache->offsets[slot].y;
638	    xorg = pCache->x + pCache->offsets[slot].x;
639        }
640
641        (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
642			xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
643	ppt++; pwidth++;
644     }
645
646     if(infoRec->ClipBox)
647	(*infoRec->DisableClipping)(infoRec->pScrn);
648
649     SET_SYNC_FLAG(infoRec);
650}
651
652	/*****************\
653	|   Cache Blit    |
654	\*****************/
655
656
657void
658XAAFillCacheBltSpans(
659   ScrnInfoPtr pScrn,
660   int rop,
661   unsigned int planemask,
662   int n,
663   DDXPointPtr ppt,
664   int *pwidth,
665   int fSorted,
666   XAACacheInfoPtr pCache,
667   int xorg, int yorg
668){
669    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
670    int x, w, phaseX, phaseY, blit_w;
671
672    (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
673		pCache->trans_color);
674
675    if(infoRec->ClipBox)
676	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
677		infoRec->ClipBox->x1, infoRec->ClipBox->y1,
678		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
679
680     while(n--) {
681	x = ppt->x;
682	w = *pwidth;
683	phaseX = (x - xorg) % pCache->orig_w;
684	if(phaseX < 0) phaseX += pCache->orig_w;
685	phaseY = (ppt->y - yorg) % pCache->orig_h;
686	if(phaseY < 0) phaseY += pCache->orig_h;
687
688	while(1) {
689	    blit_w = pCache->w - phaseX;
690	    if(blit_w > w) blit_w = w;
691
692            (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
693		pCache->x + phaseX, pCache->y + phaseY,
694		x, ppt->y, blit_w, 1);
695
696	    w -= blit_w;
697	    if(!w) break;
698	    x += blit_w;
699	    phaseX = (phaseX + blit_w) % pCache->orig_w;
700	}
701	ppt++; pwidth++;
702     }
703
704     if(infoRec->ClipBox)
705	(*infoRec->DisableClipping)(infoRec->pScrn);
706
707     SET_SYNC_FLAG(infoRec);
708}
709
710
711	/****************\
712	|  Cache Expand  |
713	\****************/
714
715
716void
717XAAFillCacheExpandSpans(
718   ScrnInfoPtr pScrn,
719   int fg, int bg, int rop,
720   unsigned int planemask,
721   int n,
722   DDXPointPtr ppt,
723   int *pwidth,
724   int fSorted,
725   int xorg, int yorg,
726   PixmapPtr pPix
727){
728    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
729    int x, w, phaseX, phaseY, blit_w, cacheWidth;
730    XAACacheInfoPtr pCache;
731
732    pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix);
733
734    cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
735	infoRec->CacheColorExpandDensity;
736
737    (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop,
738							planemask);
739
740    if(infoRec->ClipBox)
741	(*infoRec->SetClippingRectangle)(infoRec->pScrn,
742		infoRec->ClipBox->x1, infoRec->ClipBox->y1,
743		infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
744
745     while(n--) {
746	x = ppt->x;
747	w = *pwidth;
748	phaseX = (x - xorg) % pCache->orig_w;
749	if(phaseX < 0) phaseX += pCache->orig_w;
750	phaseY = (ppt->y - yorg) % pCache->orig_h;
751	if(phaseY < 0) phaseY += pCache->orig_h;
752
753	while(1) {
754	    blit_w = cacheWidth - phaseX;
755	    if(blit_w > w) blit_w = w;
756
757	    (*infoRec->SubsequentScreenToScreenColorExpandFill)(
758			pScrn, x, ppt->y, blit_w, 1,
759			pCache->x, pCache->y + phaseY, phaseX);
760
761	    w -= blit_w;
762	    if(!w) break;
763	    x += blit_w;
764	    phaseX = (phaseX + blit_w) % pCache->orig_w;
765	}
766	ppt++; pwidth++;
767     }
768
769     if(infoRec->ClipBox)
770	(*infoRec->DisableClipping)(infoRec->pScrn);
771
772     SET_SYNC_FLAG(infoRec);
773}
774
775
776
777void
778XAAClipAndRenderSpans(
779    GCPtr pGC,
780    DDXPointPtr	ppt,
781    int		*pwidth,
782    int		nspans,
783    int		fSorted,
784    ClipAndRenderSpansFunc func,
785    int 	xorg,
786    int		yorg
787){
788    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
789    DDXPointPtr pptNew, pptBase;
790    int	*pwidthBase, *pwidthNew;
791    int	Right, numRects, MaxBoxes;
792
793    MaxBoxes = infoRec->PreAllocSize/(sizeof(DDXPointRec) + sizeof(int));
794    pptBase = (DDXPointRec*)infoRec->PreAllocMem;
795    pwidthBase = (int*)(&pptBase[MaxBoxes]);
796
797    pptNew = pptBase;
798    pwidthNew = pwidthBase;
799
800    numRects = RegionNumRects(pGC->pCompositeClip);
801
802    if(numRects == 1) {
803        BoxPtr pextent = RegionRects(pGC->pCompositeClip);
804
805	while(nspans--) {
806	    if ((pextent->y1 <= ppt->y) && (ppt->y < pextent->y2)) {
807		pptNew->x = max(pextent->x1, ppt->x);
808		Right = ppt->x + *pwidth;
809		*pwidthNew = min(pextent->x2, Right) - pptNew->x;
810
811		if (*pwidthNew > 0) {
812		    pptNew->y = ppt->y;
813		    pptNew++;
814		    pwidthNew++;
815
816		    if(pptNew >= (pptBase + MaxBoxes)) {
817			(*func)(pGC, MaxBoxes, pptBase, pwidthBase, fSorted,
818								xorg, yorg);
819			pptNew = pptBase;
820			pwidthNew = pwidthBase;
821		    }
822		}
823	    }
824	    ppt++;
825	    pwidth++;
826	}
827    } else if (numRects) {
828	BoxPtr	pbox;
829	int nbox;
830
831	while(nspans--) {
832	    nbox = numRects;
833	    pbox = RegionRects(pGC->pCompositeClip);
834
835	    /* find the first band */
836	    while(nbox && (pbox->y2 <= ppt->y)) {
837		pbox++;
838		nbox--;
839	    }
840
841	    if(nbox && (pbox->y1 <= ppt->y)) {
842		int orig_y = pbox->y1;
843		Right = ppt->x + *pwidth;
844		while(nbox && (orig_y == pbox->y1)) {
845		    if(pbox->x2 <= ppt->x) {
846			nbox--;
847			pbox++;
848			continue;
849		    }
850
851		    if(pbox->x1 >= Right) {
852			nbox = 0;
853			break;
854		    }
855
856		    pptNew->x = max(pbox->x1, ppt->x);
857		    *pwidthNew = min(pbox->x2, Right) - pptNew->x;
858		    if(*pwidthNew > 0) {
859			pptNew->y = ppt->y;
860			pptNew++;
861			pwidthNew++;
862
863			if(pptNew >= (pptBase + MaxBoxes)) {
864			    (*func)(pGC, MaxBoxes, pptBase, pwidthBase,
865							fSorted, xorg, yorg);
866			    pptNew = pptBase;
867			    pwidthNew = pwidthBase;
868			}
869		    }
870		    pbox++;
871		    nbox--;
872		}
873	    }
874	    ppt++;
875	    pwidth++;
876	}
877    }
878
879    if(pptNew != pptBase)
880	(*func)(pGC, pptNew - pptBase, pptBase, pwidthBase, fSorted,
881						xorg, yorg);
882}
883