First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / xaa / xaaFillPoly.c
blob23c27818e0c0b0cba2f2a80c8ada8fc937468d19
2 /*
3 * Copyright 1996 The XFree86 Project
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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
18 * HARM HANEMAAYER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
26 * Written by Mark Vojkovich. Loosly based on an original version
27 * written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net) which
28 * only did solid rectangles and didn't have trapezoid support.
33 #ifdef HAVE_XORG_CONFIG_H
34 #include <xorg-config.h>
35 #endif
37 #include "misc.h"
38 #include "xf86.h"
39 #include "xf86_OSproc.h"
41 #include <X11/X.h>
42 #include "scrnintstr.h"
43 #include "pixmapstr.h"
44 #include "xf86str.h"
45 #include "mi.h"
46 #include "micoord.h"
48 #include "xaa.h"
49 #include "xaalocal.h"
51 #define POLY_USE_MI 0
52 #define POLY_FULLY_CLIPPED 1
53 #define POLY_IS_EASY 2
56 #define Setup(c,x,vertex,dx,dy,e,sign,step,DX) {\
57 x = intToX(vertex); \
58 if ((dy = intToY(c) - y)) { \
59 DX = dx = intToX(c) - x; \
60 step = 0; \
61 if (dx >= 0) \
62 { \
63 e = 0; \
64 sign = 1; \
65 if (dx >= dy) {\
66 step = dx / dy; \
67 dx %= dy; \
68 } \
69 } \
70 else \
71 { \
72 e = 1 - dy; \
73 sign = -1; \
74 dx = -dx; \
75 if (dx >= dy) { \
76 step = - (dx / dy); \
77 dx %= dy; \
78 } \
79 } \
80 } \
81 x += origin; \
82 vertex = c; \
85 #define Step(x,dx,dy,e,sign,step) {\
86 x += step; \
87 if ((e += dx) > 0) \
88 { \
89 x += sign; \
90 e -= dy; \
91 } \
94 #define FixError(x, dx, dy, e, sign, step, h) { \
95 e += (h) * dx; \
96 x += (h) * step; \
97 if(e > 0) { \
98 x += e * sign/dy; \
99 e %= dy; \
100 if(e) { \
101 x += sign; \
102 e -= dy; \
109 XAAIsEasyPoly -
111 Checks CoordModeOrigin one rect polygons to see if we need
112 to use Mi.
113 Returns: POLY_USE_MI, POLY_FULLY_CLIPPED or POLY_IS_EASY
114 as well as the pointer to the "top" point and the y
115 extents.
119 XAAIsEasyPolygon(
120 DDXPointPtr ptsIn,
121 int count,
122 BoxPtr extents,
123 int origin,
124 DDXPointPtr *topPoint, /* return */
125 int *topY, int *bottomY, /* return */
126 int shape
128 int c = 0, vertex1, vertex2;
130 *topY = 32767;
131 *bottomY = 0;
133 origin -= (origin & 0x8000) << 1;
134 vertex1 = *((int *) &extents->x1) - origin;
135 vertex2 = *((int *) &extents->x2) - origin /* - 0x00010001 */;
136 /* I think this was an error in cfb ^ */
138 if (shape == Convex) {
139 while (count--) {
140 c = *((int*)ptsIn);
141 if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
142 return POLY_USE_MI;
144 c = intToY(c);
145 if (c < *topY) {
146 *topY = c;
147 *topPoint = ptsIn;
149 ptsIn++;
150 if (c > *bottomY) *bottomY = c;
152 } else {
153 int yFlip = 0;
154 int dx2, dx1, x1, x2;
156 x2 = x1 = -1;
157 dx2 = dx1 = 1;
159 while (count--) {
160 c = *((int*)ptsIn);
161 if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
162 return POLY_USE_MI;
163 c = intToY(c);
164 if (c < *topY) {
165 *topY = c;
166 *topPoint = ptsIn;
168 ptsIn++;
169 if (c > *bottomY) *bottomY = c;
170 if (c == x1)
171 continue;
172 if (dx1 > 0) {
173 if (x2 < 0) x2 = c;
174 else dx2 = dx1 = (c - x1) >> 31;
175 } else if ((c - x1) >> 31 != dx1) {
176 dx1 = ~dx1;
177 yFlip++;
179 x1 = c;
181 x1 = (x2 - c) >> 31;
182 if (x1 != dx1) yFlip++;
183 if (x1 != dx2) yFlip++;
184 if (yFlip != 2) {
185 if(*topY == *bottomY)
186 return POLY_FULLY_CLIPPED;
187 else
188 return POLY_USE_MI;
191 if (*topY == *bottomY)
192 return POLY_FULLY_CLIPPED;
194 return POLY_IS_EASY;
197 void
198 XAAFillPolygonSolid(
199 DrawablePtr pDraw,
200 GCPtr pGC,
201 int shape,
202 int mode,
203 int count,
204 DDXPointPtr ptsIn
206 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
207 int origin, vertex1, vertex2;
208 int *vertex1p, *vertex2p, *endp;
209 int x1 = 0, x2 = 0;
210 int dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
211 int DX1 = 0, DX2 = 0, e1 = 0, e2 = 0;
212 int step1 = 0, step2 = 0, sign1 = 0, sign2 = 0;
213 int c, y, maxy, h, yoffset;
214 DDXPointPtr topPoint;
216 if(!REGION_NUM_RECTS(pGC->pCompositeClip))
217 return;
219 if (mode == CoordModePrevious) {
220 register DDXPointPtr ppt = ptsIn + 1;
222 for (origin = 1; origin < count; origin++, ppt++) {
223 ppt->x += (ppt-1)->x;
224 ppt->y += (ppt-1)->y;
226 mode = CoordModeOrigin;
229 if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
230 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
231 return;
234 origin = coordToInt(pDraw->x, pDraw->y);
236 switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
237 origin, &topPoint, &y, &maxy, shape) ) {
238 case POLY_USE_MI:
239 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
240 case POLY_FULLY_CLIPPED:
241 return;
244 endp = (int*)ptsIn + count;
245 vertex2p = vertex1p = (int *)topPoint;
246 origin = pDraw->x;
247 yoffset = pDraw->y;
248 vertex2 = vertex1 = *vertex2p++;
249 if (vertex2p == endp)
250 vertex2p = (int *) ptsIn;
252 (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
253 pGC->planemask);
255 while(1) {
256 if (y == intToY(vertex1)) {
257 do {
258 if (vertex1p == (int *) ptsIn)
259 vertex1p = endp;
260 c = *--vertex1p;
261 Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
262 } while (y >= intToY(vertex1));
263 h = dy1;
264 } else {
265 Step(x1,dx1,dy1,e1,sign1,step1)
266 h = intToY(vertex1) - y;
268 if (y == intToY(vertex2)) {
269 do {
270 c = *vertex2p++;
271 if (vertex2p == endp)
272 vertex2p = (int *) ptsIn;
273 Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
274 } while (y >= intToY(vertex2));
275 if (dy2 < h)
276 h = dy2;
277 } else {
278 Step(x2,dx2,dy2,e2,sign2,step2)
279 if ((c = (intToY(vertex2) - y)) < h)
280 h = c;
283 /* fill spans for this segment */
284 if(DX1 | DX2) {
285 if(infoRec->SubsequentSolidFillTrap && (h > 6)) {
286 if(x1 == x2) {
287 while(x1 == x2) {
288 y++;
289 if (!--h) break;
290 Step(x1,dx1,dy1,e1,sign1,step1)
291 Step(x2,dx2,dy2,e2,sign2,step2)
293 if(y == maxy) break;
294 if(!h) continue;
297 if(x1 < x2)
298 (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
299 y + yoffset, h,
300 x1, DX1, dy1, e1,
301 x2 - 1, DX2, dy2, e2);
302 else
303 (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
304 y + yoffset, h,
305 x2, DX2, dy2, e2,
306 x1 - 1, DX1, dy1, e1);
307 y += h;
308 if(--h) {
309 FixError(x1,dx1,dy1,e1,sign1,step1,h);
310 FixError(x2,dx2,dy2,e2,sign2,step2,h);
311 h = 0;
313 } else {
314 while(1) {
315 if (x2 > x1)
316 (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
317 x1, y + yoffset, x2 - x1, 1);
318 else if (x1 > x2)
319 (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
320 x2, y + yoffset, x1 - x2, 1);
321 y++;
322 if (!--h) break;
323 Step(x1,dx1,dy1,e1,sign1,step1)
324 Step(x2,dx2,dy2,e2,sign2,step2)
327 } else {
328 if (x2 > x1)
329 (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
330 x1, y + yoffset, x2 - x1, h);
331 else if (x1 > x2)
332 (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
333 x2, y + yoffset, x1 - x2, h);
335 y += h;
336 h = 0;
338 if (y == maxy) break;
340 SET_SYNC_FLAG(infoRec);
346 void
347 XAAFillPolygonHelper(
348 ScrnInfoPtr pScrn,
349 DDXPointPtr ptsIn,
350 int count,
351 DDXPointPtr topPoint,
352 int y,
353 int maxy,
354 int origin,
355 RectFuncPtr RectFunc,
356 TrapFuncPtr TrapFunc,
357 int xorg,
358 int yorg,
359 XAACacheInfoPtr pCache
361 int *vertex1p, *vertex2p, *endp;
362 int vertex1, vertex2;
363 int x1 = 0, x2 = 0;
364 int dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
365 int DX1 = 0, DX2 = 0, e1 = 0, e2 = 0;
366 int step1 = 0, step2 = 0, sign1 = 0, sign2 = 0;
367 int c, h, yoffset;
370 endp = (int*)ptsIn + count;
371 vertex2p = vertex1p = (int *)topPoint;
372 yoffset = intToY(origin);
373 origin = intToX(origin);
374 vertex2 = vertex1 = *vertex2p++;
375 if (vertex2p == endp)
376 vertex2p = (int *)ptsIn;
378 while(1) {
379 if (y == intToY(vertex1)) {
380 do {
381 if (vertex1p == (int *) ptsIn)
382 vertex1p = endp;
383 c = *--vertex1p;
384 Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
385 } while (y >= intToY(vertex1));
386 h = dy1;
387 } else {
388 Step(x1,dx1,dy1,e1,sign1,step1)
389 h = intToY(vertex1) - y;
391 if (y == intToY(vertex2)) {
392 do {
393 c = *vertex2p++;
394 if (vertex2p == endp)
395 vertex2p = (int *) ptsIn;
396 Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
397 } while (y >= intToY(vertex2));
398 if (dy2 < h)
399 h = dy2;
400 } else {
401 Step(x2,dx2,dy2,e2,sign2,step2)
402 if ((c = (intToY(vertex2) - y)) < h)
403 h = c;
406 /* fill spans for this segment */
407 if(DX1 | DX2) {
408 if(TrapFunc && (h > 6)) {
409 if(x1 == x2) {
410 while(x1 == x2) {
411 y++;
412 if (!--h) break;
413 Step(x1,dx1,dy1,e1,sign1,step1)
414 Step(x2,dx2,dy2,e2,sign2,step2)
416 if(y == maxy) break;
417 if(!h) continue;
420 if(x1 < x2)
421 (*TrapFunc)(pScrn, y + yoffset, h,
422 x1, DX1, dy1, e1,
423 x2 - 1, DX2, dy2, e2, xorg, yorg, pCache);
424 else
425 (*TrapFunc)(pScrn, y + yoffset, h,
426 x2, DX2, dy2, e2,
427 x1 - 1, DX1, dy1, e1, xorg, yorg, pCache);
428 y += h;
429 if(--h) {
430 FixError(x1,dx1,dy1,e1,sign1,step1,h);
431 FixError(x2,dx2,dy2,e2,sign2,step2,h);
432 h = 0;
434 } else {
435 while(1) {
436 if (x2 > x1)
437 (*RectFunc)(pScrn,
438 x1, y + yoffset, x2 - x1, 1, xorg, yorg, pCache);
439 else if (x1 > x2)
440 (*RectFunc)(pScrn,
441 x2, y + yoffset, x1 - x2, 1, xorg, yorg, pCache);
442 y++;
443 if (!--h) break;
444 Step(x1,dx1,dy1,e1,sign1,step1)
445 Step(x2,dx2,dy2,e2,sign2,step2)
448 } else {
449 if (x2 > x1)
450 (*RectFunc)(pScrn,
451 x1, y + yoffset, x2 - x1, h, xorg, yorg, pCache);
452 else if (x1 > x2)
453 (*RectFunc)(pScrn,
454 x2, y + yoffset, x1 - x2, h, xorg, yorg, pCache);
456 y += h;
457 h = 0;
459 if (y == maxy) break;
463 /*****************\
464 | Solid Helpers |
465 \*****************/
467 static void
468 SolidTrapHelper(
469 ScrnInfoPtr pScrn,
470 int y, int h,
471 int x1, int dx1, int dy1, int e1,
472 int x2, int dx2, int dy2, int e2,
473 int xorg, int yorg,
474 XAACacheInfoPtr pCache
476 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
478 (*infoRec->SubsequentSolidFillTrap) (pScrn,
479 y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
482 static void
483 SolidRectHelper (
484 ScrnInfoPtr pScrn,
485 int x, int y, int w, int h,
486 int xorg, int yorg,
487 XAACacheInfoPtr pCache
489 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
491 (*infoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
495 /*********************\
496 | Mono 8x8 Patterns |
497 \*********************/
499 static void
500 Mono8x8PatternTrapHelper_ScreenOrigin(
501 ScrnInfoPtr pScrn,
502 int y, int h,
503 int x1, int dx1, int dy1, int e1,
504 int x2, int dx2, int dy2, int e2,
505 int xorg, int yorg,
506 XAACacheInfoPtr pCache
508 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
510 (*infoRec->SubsequentMono8x8PatternFillTrap) (pScrn, xorg, yorg,
511 y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
514 static void
515 Mono8x8PatternRectHelper_ScreenOrigin (
516 ScrnInfoPtr pScrn,
517 int x, int y, int w, int h,
518 int xorg, int yorg,
519 XAACacheInfoPtr pCache
521 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
523 (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
524 x, y, w, h);
527 static void
528 Mono8x8PatternRectHelper (
529 ScrnInfoPtr pScrn,
530 int x, int y, int w, int h,
531 int xorg, int yorg,
532 XAACacheInfoPtr pCache
534 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
536 xorg = (x - xorg) & 0x07;
537 yorg = (y - yorg) & 0x07;
539 if(!(infoRec->Mono8x8PatternFillFlags &
540 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
541 if(infoRec->Mono8x8PatternFillFlags &
542 HARDWARE_PATTERN_PROGRAMMED_BITS) {
543 int patx = pCache->pat0;
544 int paty = pCache->pat1;
545 XAARotateMonoPattern(&patx, &paty, xorg, yorg,
546 (infoRec->Mono8x8PatternFillFlags &
547 BIT_ORDER_IN_BYTE_MSBFIRST));
548 xorg = patx; yorg = paty;
549 } else {
550 int slot = (yorg << 3) + xorg;
551 xorg = pCache->x + pCache->offsets[slot].x;
552 yorg = pCache->y + pCache->offsets[slot].y;
557 (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
558 x, y, w, h);
563 /****************\
564 | Cache Expand |
565 \****************/
568 static void
569 CacheExpandRectHelper (
570 ScrnInfoPtr pScrn,
571 int X, int Y, int Width, int Height,
572 int xorg, int yorg,
573 XAACacheInfoPtr pCache
575 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
576 int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;
577 int cacheWidth;
579 cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
580 infoRec->CacheColorExpandDensity;
582 phaseY = (Y - yorg) % pCache->orig_h;
583 if(phaseY < 0) phaseY += pCache->orig_h;
584 phaseX = (X - xorg) % pCache->orig_w;
585 if(phaseX < 0) phaseX += pCache->orig_w;
587 while(1) {
588 w = Width; skipleft = phaseX; x = X;
589 blit_h = pCache->h - phaseY;
590 if(blit_h > Height) blit_h = Height;
592 while(1) {
593 blit_w = cacheWidth - skipleft;
594 if(blit_w > w) blit_w = w;
595 (*infoRec->SubsequentScreenToScreenColorExpandFill)(
596 pScrn, x, Y, blit_w, blit_h,
597 pCache->x, pCache->y + phaseY, skipleft);
598 w -= blit_w;
599 if(!w) break;
600 x += blit_w;
601 skipleft = (skipleft + blit_w) % pCache->orig_w;
603 Height -= blit_h;
604 if(!Height) break;
605 Y += blit_h;
606 phaseY = (phaseY + blit_h) % pCache->orig_h;
612 /**************\
613 | Cache Blit |
614 \**************/
617 static void
618 CacheBltRectHelper (
619 ScrnInfoPtr pScrn,
620 int X, int Y, int Width, int Height,
621 int xorg, int yorg,
622 XAACacheInfoPtr pCache
624 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
625 int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;
627 phaseY = (Y - yorg) % pCache->orig_h;
628 if(phaseY < 0) phaseY += pCache->orig_h;
629 phaseX = (X - xorg) % pCache->orig_w;
630 if(phaseX < 0) phaseX += pCache->orig_w;
632 while(1) {
633 w = Width; skipleft = phaseX; x = X;
634 blit_h = pCache->h - phaseY;
635 if(blit_h > Height) blit_h = Height;
637 while(1) {
638 blit_w = pCache->w - skipleft;
639 if(blit_w > w) blit_w = w;
640 (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
641 pCache->x + skipleft, pCache->y + phaseY,
642 x, Y, blit_w, blit_h);
643 w -= blit_w;
644 if(!w) break;
645 x += blit_w;
646 skipleft = (skipleft + blit_w) % pCache->orig_w;
648 Height -= blit_h;
649 if(!Height) break;
650 Y += blit_h;
651 phaseY = (phaseY + blit_h) % pCache->orig_h;
656 /**********************\
657 | Stippled Polygons |
658 \**********************/
661 void
662 XAAFillPolygonStippled(
663 DrawablePtr pDraw,
664 GCPtr pGC,
665 int shape,
666 int mode,
667 int count,
668 DDXPointPtr ptsIn
670 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
671 XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
672 int origin, type, patx, paty, fg, bg;
673 int y, maxy, xorg, yorg;
674 DDXPointPtr topPoint;
675 XAACacheInfoPtr pCache = NULL;
676 RectFuncPtr RectFunc = NULL;
677 TrapFuncPtr TrapFunc = NULL;
679 if(!REGION_NUM_RECTS(pGC->pCompositeClip))
680 return;
682 if (mode == CoordModePrevious) {
683 register DDXPointPtr ppt = ptsIn + 1;
685 for (origin = 1; origin < count; origin++, ppt++) {
686 ppt->x += (ppt-1)->x;
687 ppt->y += (ppt-1)->y;
689 mode = CoordModeOrigin;
692 if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
693 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
694 return;
698 if(pGC->fillStyle == FillStippled) {
699 type = (*infoRec->StippledFillChooser)(pGC);
700 fg = pGC->fgPixel; bg = -1;
701 } else {
702 type = (*infoRec->OpaqueStippledFillChooser)(pGC);
703 fg = pGC->fgPixel; bg = pGC->bgPixel;
707 if(!type) {
708 (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
709 return;
712 if((type == DO_COLOR_EXPAND) || (type == DO_COLOR_8x8)) {
713 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
714 return;
717 origin = *((int *)&pDraw->x);
719 switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
720 origin, &topPoint, &y, &maxy, shape) ) {
721 case POLY_USE_MI:
722 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
723 case POLY_FULLY_CLIPPED:
724 return;
727 xorg = (pDraw->x + pGC->patOrg.x);
728 yorg = (pDraw->y + pGC->patOrg.y);
731 if((fg == bg) && (bg != -1) && infoRec->SetupForSolidFill) {
733 (*infoRec->SetupForSolidFill)(infoRec->pScrn, fg,
734 pGC->alu, pGC->planemask);
736 RectFunc = SolidRectHelper;
737 TrapFunc = infoRec->SubsequentSolidFillTrap ? SolidTrapHelper : NULL;
738 } else
739 switch(type) {
740 case DO_MONO_8x8:
741 patx = pPriv->pattern0; paty = pPriv->pattern1;
742 if(infoRec->Mono8x8PatternFillFlags &
743 HARDWARE_PATTERN_SCREEN_ORIGIN) {
744 xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
745 if(infoRec->Mono8x8PatternFillFlags &
746 HARDWARE_PATTERN_PROGRAMMED_BITS) {
747 if(!(infoRec->Mono8x8PatternFillFlags &
748 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
749 XAARotateMonoPattern(&patx, &paty, xorg, yorg,
750 (infoRec->Mono8x8PatternFillFlags &
751 BIT_ORDER_IN_BYTE_MSBFIRST));
752 xorg = patx; yorg = paty;
754 } else {
755 XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
756 infoRec->pScrn, patx, paty);
757 patx = pCache->x; paty = pCache->y;
758 if(!(infoRec->Mono8x8PatternFillFlags &
759 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
760 int slot = (yorg << 3) + xorg;
761 patx += pCache->offsets[slot].x;
762 paty += pCache->offsets[slot].y;
763 xorg = patx; yorg = paty;
766 RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
767 if(infoRec->SubsequentMono8x8PatternFillTrap)
768 TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
769 } else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
770 if(!(infoRec->Mono8x8PatternFillFlags &
771 HARDWARE_PATTERN_PROGRAMMED_BITS)){
772 pCache = (*infoRec->CacheMono8x8Pattern)(
773 infoRec->pScrn, patx, paty);
774 patx = pCache->x; paty = pCache->y;
775 } else {
776 pCache = &(infoRec->ScratchCacheInfoRec);
777 pCache->pat0 = patx;
778 pCache->pat1 = paty;
780 RectFunc = Mono8x8PatternRectHelper;
783 (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn,
784 patx, paty, fg, bg, pGC->alu, pGC->planemask);
785 break;
786 case DO_CACHE_EXPAND:
787 pCache = (*infoRec->CacheMonoStipple)(infoRec->pScrn, pGC->stipple);
789 (*infoRec->SetupForScreenToScreenColorExpandFill)(
790 infoRec->pScrn, fg, bg, pGC->alu, pGC->planemask);
792 RectFunc = CacheExpandRectHelper;
793 break;
794 case DO_CACHE_BLT:
795 pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
796 fg, bg);
797 (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
798 pGC->alu, pGC->planemask, pCache->trans_color);
800 RectFunc = CacheBltRectHelper;
801 break;
802 default:
803 return;
807 XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint,
808 y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);
810 SET_SYNC_FLAG(infoRec);
816 /*******************\
817 | Tiled Polygons |
818 \*******************/
821 void
822 XAAFillPolygonTiled(
823 DrawablePtr pDraw,
824 GCPtr pGC,
825 int shape,
826 int mode,
827 int count,
828 DDXPointPtr ptsIn
830 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
831 XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
832 int origin, type, patx, paty;
833 int y, maxy, xorg, yorg;
834 DDXPointPtr topPoint;
835 XAACacheInfoPtr pCache = NULL;
836 RectFuncPtr RectFunc = NULL;
837 TrapFuncPtr TrapFunc = NULL;
839 if(!REGION_NUM_RECTS(pGC->pCompositeClip))
840 return;
842 if (mode == CoordModePrevious) {
843 register DDXPointPtr ppt = ptsIn + 1;
845 for (origin = 1; origin < count; origin++, ppt++) {
846 ppt->x += (ppt-1)->x;
847 ppt->y += (ppt-1)->y;
849 mode = CoordModeOrigin;
852 if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
853 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
854 return;
858 type = (*infoRec->TiledFillChooser)(pGC);
860 if(!type || (type == DO_IMAGE_WRITE)) {
861 (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
862 return;
865 if(type == DO_COLOR_8x8) {
866 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
867 return;
870 origin = *((int *)&pDraw->x);
872 switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
873 origin, &topPoint, &y, &maxy, shape) ) {
874 case POLY_USE_MI:
875 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
876 case POLY_FULLY_CLIPPED:
877 return;
880 xorg = (pDraw->x + pGC->patOrg.x);
881 yorg = (pDraw->y + pGC->patOrg.y);
883 switch(type) {
884 case DO_MONO_8x8:
885 patx = pPriv->pattern0; paty = pPriv->pattern1;
886 if(infoRec->Mono8x8PatternFillFlags &
887 HARDWARE_PATTERN_SCREEN_ORIGIN) {
888 xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
889 if(infoRec->Mono8x8PatternFillFlags &
890 HARDWARE_PATTERN_PROGRAMMED_BITS) {
891 if(!(infoRec->Mono8x8PatternFillFlags &
892 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
893 XAARotateMonoPattern(&patx, &paty, xorg, yorg,
894 (infoRec->Mono8x8PatternFillFlags &
895 BIT_ORDER_IN_BYTE_MSBFIRST));
896 xorg = patx; yorg = paty;
898 } else {
899 XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
900 infoRec->pScrn, patx, paty);
901 patx = pCache->x; paty = pCache->y;
902 if(!(infoRec->Mono8x8PatternFillFlags &
903 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
904 int slot = (yorg << 3) + xorg;
905 patx += pCache->offsets[slot].x;
906 paty += pCache->offsets[slot].y;
907 xorg = patx; yorg = paty;
910 RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
911 if(infoRec->SubsequentMono8x8PatternFillTrap)
912 TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
913 } else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
914 if(!(infoRec->Mono8x8PatternFillFlags &
915 HARDWARE_PATTERN_PROGRAMMED_BITS)){
916 pCache = (*infoRec->CacheMono8x8Pattern)(
917 infoRec->pScrn, patx, paty);
918 patx = pCache->x; paty = pCache->y;
920 else {
921 pCache = &(infoRec->ScratchCacheInfoRec);
922 pCache->pat0 = patx;
923 pCache->pat1 = paty;
925 RectFunc = Mono8x8PatternRectHelper;
928 (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn,
929 patx, paty, pPriv->fg, pPriv->bg, pGC->alu, pGC->planemask);
930 break;
931 case DO_CACHE_BLT:
932 pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
933 (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
934 pGC->alu, pGC->planemask, -1);
936 RectFunc = CacheBltRectHelper;
937 break;
938 case DO_PIXMAP_COPY:
939 pCache = &(infoRec->ScratchCacheInfoRec);
940 pCache->x = pPriv->offscreenArea->box.x1;
941 pCache->y = pPriv->offscreenArea->box.y1;
942 pCache->w = pCache->orig_w =
943 pPriv->offscreenArea->box.x2 - pCache->x;
944 pCache->h = pCache->orig_h =
945 pPriv->offscreenArea->box.y2 - pCache->y;
947 (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
948 pGC->alu, pGC->planemask, -1);
950 RectFunc = CacheBltRectHelper;
951 break;
952 default:
953 return;
956 XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint,
957 y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);
959 SET_SYNC_FLAG(infoRec);