1 2/* 3 * Copyright 1996 The XFree86 Project 4 * 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: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 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. 22 * 23 */ 24 25/* 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. 29 * 30 */ 31 32 33#ifdef HAVE_XORG_CONFIG_H 34#include <xorg-config.h> 35#endif 36 37#include "misc.h" 38#include "xf86.h" 39#include "xf86_OSproc.h" 40 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" 47 48#include "xaa.h" 49#include "xaalocal.h" 50 51#define POLY_USE_MI 0 52#define POLY_FULLY_CLIPPED 1 53#define POLY_IS_EASY 2 54 55 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; \ 83} 84 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 } \ 92} 93 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; \ 103 } \ 104 } \ 105} 106 107 108/* 109 XAAIsEasyPoly - 110 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. 116*/ 117 118int 119XAAIsEasyPolygon( 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 127){ 128 int c = 0, vertex1, vertex2; 129 130 *topY = 32767; 131 *bottomY = 0; 132 133 origin -= (origin & 0x8000) << 1; 134 vertex1 = extents->x1 - origin; 135 vertex2 = extents->x2 - origin /* - 0x00010001 */; 136 /* I think this was an error in cfb ^ */ 137 138 if (shape == Convex) { 139 while (count--) { 140 c = *((int*)ptsIn); 141 if (((c - vertex1) | (vertex2 - c)) & 0x80008000) 142 return POLY_USE_MI; 143 144 c = intToY(c); 145 if (c < *topY) { 146 *topY = c; 147 *topPoint = ptsIn; 148 } 149 ptsIn++; 150 if (c > *bottomY) *bottomY = c; 151 } 152 } else { 153 int yFlip = 0; 154 int dx2, dx1, x1, x2; 155 156 x2 = x1 = -1; 157 dx2 = dx1 = 1; 158 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; 167 } 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++; 178 } 179 x1 = c; 180 } 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; 189 } 190 } 191 if (*topY == *bottomY) 192 return POLY_FULLY_CLIPPED; 193 194 return POLY_IS_EASY; 195} 196 197void 198XAAFillPolygonSolid( 199 DrawablePtr pDraw, 200 GCPtr pGC, 201 int shape, 202 int mode, 203 int count, 204 DDXPointPtr ptsIn 205){ 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; 215 216 if(!RegionNumRects(pGC->pCompositeClip)) 217 return; 218 219 if (mode == CoordModePrevious) { 220 register DDXPointPtr ppt = ptsIn + 1; 221 222 for (origin = 1; origin < count; origin++, ppt++) { 223 ppt->x += (ppt-1)->x; 224 ppt->y += (ppt-1)->y; 225 } 226 mode = CoordModeOrigin; 227 } 228 229 if (RegionNumRects(pGC->pCompositeClip) != 1) { 230 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn); 231 return; 232 } 233 234 origin = coordToInt(pDraw->x, pDraw->y); 235 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; 242 } 243 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; 251 252 (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu, 253 pGC->planemask); 254 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; 267 } 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; 281 } 282 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) 292 } 293 if(y == maxy) break; 294 if(!h) continue; 295 } 296 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; 312 } 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) 325 } 326 } 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); 334 335 y += h; 336 h = 0; 337 } 338 if (y == maxy) break; 339 } 340 SET_SYNC_FLAG(infoRec); 341} 342 343 344 345 346void 347XAAFillPolygonHelper( 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 360){ 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; 368 369 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; 377 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; 390 } 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; 404 } 405 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) 415 } 416 if(y == maxy) break; 417 if(!h) continue; 418 } 419 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; 433 } 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) 446 } 447 } 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); 455 456 y += h; 457 h = 0; 458 } 459 if (y == maxy) break; 460 } 461} 462 463 /*****************\ 464 | Solid Helpers | 465 \*****************/ 466 467static void 468SolidTrapHelper( 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 475){ 476 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 477 478 (*infoRec->SubsequentSolidFillTrap) (pScrn, 479 y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2); 480} 481 482static void 483SolidRectHelper ( 484 ScrnInfoPtr pScrn, 485 int x, int y, int w, int h, 486 int xorg, int yorg, 487 XAACacheInfoPtr pCache 488){ 489 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 490 491 (*infoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); 492} 493 494 495 /*********************\ 496 | Mono 8x8 Patterns | 497 \*********************/ 498 499static void 500Mono8x8PatternTrapHelper_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 507){ 508 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 509 510 (*infoRec->SubsequentMono8x8PatternFillTrap) (pScrn, xorg, yorg, 511 y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2); 512} 513 514static void 515Mono8x8PatternRectHelper_ScreenOrigin ( 516 ScrnInfoPtr pScrn, 517 int x, int y, int w, int h, 518 int xorg, int yorg, 519 XAACacheInfoPtr pCache 520){ 521 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 522 523 (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg, 524 x, y, w, h); 525} 526 527static void 528Mono8x8PatternRectHelper ( 529 ScrnInfoPtr pScrn, 530 int x, int y, int w, int h, 531 int xorg, int yorg, 532 XAACacheInfoPtr pCache 533){ 534 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 535 536 xorg = (x - xorg) & 0x07; 537 yorg = (y - yorg) & 0x07; 538 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; 553 } 554 } 555 556 557 (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg, 558 x, y, w, h); 559} 560 561 562 563 /****************\ 564 | Cache Expand | 565 \****************/ 566 567 568static void 569CacheExpandRectHelper ( 570 ScrnInfoPtr pScrn, 571 int X, int Y, int Width, int Height, 572 int xorg, int yorg, 573 XAACacheInfoPtr pCache 574){ 575 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 576 int x, phaseY, phaseX, skipleft, w, blit_w, blit_h; 577 int cacheWidth; 578 579 cacheWidth = (pCache->w * pScrn->bitsPerPixel) / 580 infoRec->CacheColorExpandDensity; 581 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; 586 587 while(1) { 588 w = Width; skipleft = phaseX; x = X; 589 blit_h = pCache->h - phaseY; 590 if(blit_h > Height) blit_h = Height; 591 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; 602 } 603 Height -= blit_h; 604 if(!Height) break; 605 Y += blit_h; 606 phaseY = (phaseY + blit_h) % pCache->orig_h; 607 } 608} 609 610 611 612 /**************\ 613 | Cache Blit | 614 \**************/ 615 616 617static void 618CacheBltRectHelper ( 619 ScrnInfoPtr pScrn, 620 int X, int Y, int Width, int Height, 621 int xorg, int yorg, 622 XAACacheInfoPtr pCache 623){ 624 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 625 int x, phaseY, phaseX, skipleft, w, blit_w, blit_h; 626 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; 631 632 while(1) { 633 w = Width; skipleft = phaseX; x = X; 634 blit_h = pCache->h - phaseY; 635 if(blit_h > Height) blit_h = Height; 636 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; 647 } 648 Height -= blit_h; 649 if(!Height) break; 650 Y += blit_h; 651 phaseY = (phaseY + blit_h) % pCache->orig_h; 652 } 653} 654 655 656 /**********************\ 657 | Stippled Polygons | 658 \**********************/ 659 660 661void 662XAAFillPolygonStippled( 663 DrawablePtr pDraw, 664 GCPtr pGC, 665 int shape, 666 int mode, 667 int count, 668 DDXPointPtr ptsIn 669){ 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; 678 679 if(!RegionNumRects(pGC->pCompositeClip)) 680 return; 681 682 if (mode == CoordModePrevious) { 683 register DDXPointPtr ppt = ptsIn + 1; 684 685 for (origin = 1; origin < count; origin++, ppt++) { 686 ppt->x += (ppt-1)->x; 687 ppt->y += (ppt-1)->y; 688 } 689 mode = CoordModeOrigin; 690 } 691 692 if (RegionNumRects(pGC->pCompositeClip) != 1) { 693 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn); 694 return; 695 } 696 697 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; 704 } 705 706 707 if(!type) { 708 (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn); 709 return; 710 } 711 712 if((type == DO_COLOR_EXPAND) || (type == DO_COLOR_8x8)) { 713 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn); 714 return; 715 } 716 717 origin = pDraw->x; 718 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; 725 } 726 727 xorg = (pDraw->x + pGC->patOrg.x); 728 yorg = (pDraw->y + pGC->patOrg.y); 729 730 731 if((fg == bg) && (bg != -1) && infoRec->SetupForSolidFill) { 732 733 (*infoRec->SetupForSolidFill)(infoRec->pScrn, fg, 734 pGC->alu, pGC->planemask); 735 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; 753 } 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; 764 } 765 } 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; 779 } 780 RectFunc = Mono8x8PatternRectHelper; 781 } 782 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); 788 789 (*infoRec->SetupForScreenToScreenColorExpandFill)( 790 infoRec->pScrn, fg, bg, pGC->alu, pGC->planemask); 791 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); 799 800 RectFunc = CacheBltRectHelper; 801 break; 802 default: 803 return; 804 } 805 806 807 XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint, 808 y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache); 809 810 SET_SYNC_FLAG(infoRec); 811} 812 813 814 815 816 /*******************\ 817 | Tiled Polygons | 818 \*******************/ 819 820 821void 822XAAFillPolygonTiled( 823 DrawablePtr pDraw, 824 GCPtr pGC, 825 int shape, 826 int mode, 827 int count, 828 DDXPointPtr ptsIn 829){ 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; 838 839 if(!RegionNumRects(pGC->pCompositeClip)) 840 return; 841 842 if (mode == CoordModePrevious) { 843 register DDXPointPtr ppt = ptsIn + 1; 844 845 for (origin = 1; origin < count; origin++, ppt++) { 846 ppt->x += (ppt-1)->x; 847 ppt->y += (ppt-1)->y; 848 } 849 mode = CoordModeOrigin; 850 } 851 852 if (RegionNumRects(pGC->pCompositeClip) != 1) { 853 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn); 854 return; 855 } 856 857 858 type = (*infoRec->TiledFillChooser)(pGC); 859 860 if(!type || (type == DO_IMAGE_WRITE)) { 861 (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn); 862 return; 863 } 864 865 if(type == DO_COLOR_8x8) { 866 miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn); 867 return; 868 } 869 870 origin = pDraw->x; 871 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; 878 } 879 880 xorg = (pDraw->x + pGC->patOrg.x); 881 yorg = (pDraw->y + pGC->patOrg.y); 882 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; 897 } 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; 908 } 909 } 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; 919 } 920 else { 921 pCache = &(infoRec->ScratchCacheInfoRec); 922 pCache->pat0 = patx; 923 pCache->pat1 = paty; 924 } 925 RectFunc = Mono8x8PatternRectHelper; 926 } 927 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); 935 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; 946 947 (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1, 948 pGC->alu, pGC->planemask, -1); 949 950 RectFunc = CacheBltRectHelper; 951 break; 952 default: 953 return; 954 } 955 956 XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint, 957 y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache); 958 959 SET_SYNC_FLAG(infoRec); 960} 961 962 963