winfillsp.c revision 706f2543
1/* 2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 *"Software"), to deal in the Software without restriction, including 7 *without limitation the rights to use, copy, modify, merge, publish, 8 *distribute, sublicense, and/or sell copies of the Software, and to 9 *permit persons to whom the Software is furnished to do so, subject to 10 *the following conditions: 11 * 12 *The above copyright notice and this permission notice shall be 13 *included in all copies or substantial portions of the Software. 14 * 15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 *Except as contained in this notice, the name of the XFree86 Project 24 *shall not be used in advertising or otherwise to promote the sale, use 25 *or other dealings in this Software without prior written authorization 26 *from the XFree86 Project. 27 * 28 * Authors: Harold L Hunt II 29 * Alan Hourihane <alanh@fairlite.demon.co.uk> 30 */ 31 32#ifdef HAVE_XWIN_CONFIG_H 33#include <xwin-config.h> 34#endif 35#include "win.h" 36 37 38extern void ROP16(HDC hdc, int rop); 39 40#define TRANSLATE_COLOR(color) \ 41{ \ 42 if (pDrawable->depth == 15) \ 43 color = ((color & 0x1F) << 19) | ((color & 0x03E0) << 6) | \ 44 ((color & 0xF800) >> 8); \ 45 else if (pDrawable->depth == 16) \ 46 color = ((color & 0x1F) << 19) | ((color & 0x07E0) << 5) | \ 47 ((color & 0xF800) >> 8); \ 48 else if (pDrawable->depth == 24 || pDrawable->depth == 32) \ 49 color = ((color & 0xFF) << 16) | (color & 0xFF00) | \ 50 ((color & 0xFF0000) >> 16); \ 51} 52 53/* See Porting Layer Definition - p. 54 */ 54void 55winFillSpansNativeGDI (DrawablePtr pDrawable, 56 GCPtr pGC, 57 int iSpans, 58 DDXPointPtr pPoints, 59 int *piWidths, 60 int fSorted) 61{ 62 winGCPriv(pGC); 63 HBITMAP hbmpOrig = NULL, hbmpOrigStipple = NULL; 64 HBITMAP hPenOrig = NULL; 65 HBITMAP hBitmap = NULL; 66 PixmapPtr pPixmap = NULL; 67 winPrivPixmapPtr pPixmapPriv = NULL; 68 PixmapPtr pStipple = NULL; 69 winPrivPixmapPtr pStipplePriv = NULL; 70 PixmapPtr pTile = NULL; 71 winPrivPixmapPtr pTilePriv = NULL; 72 HDC hdcStipple = NULL, hdcTile = NULL; 73 HPEN hPen = NULL; 74 int iX; 75 int fg, bg; 76 RegionPtr pClip = pGC->pCompositeClip; 77 BoxPtr pextent, pbox; 78 int nbox; 79 int extentX1, extentX2, extentY1, extentY2; 80 int fullX1, fullX2, fullY1; 81 HRGN hrgn = NULL, combined = NULL; 82 83 nbox = RegionNumRects (pClip); 84 pbox = RegionRects (pClip); 85 86 if (!nbox) return; 87 88 combined = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); 89 nbox--; pbox++; 90 91 while (nbox--) 92 { 93 hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2); 94 CombineRgn (combined, combined, hrgn, RGN_OR); 95 DeleteObject (hrgn); 96 hrgn = NULL; 97 pbox++; 98 } 99 100 pextent = RegionExtents(pClip); 101 extentX1 = pextent->x1; 102 extentY1 = pextent->y1; 103 extentX2 = pextent->x2; 104 extentY2 = pextent->y2; 105 106 /* Branch on the type of drawable we have */ 107 switch (pDrawable->type) 108 { 109 case DRAWABLE_PIXMAP: 110 111 SelectClipRgn (pGCPriv->hdcMem, combined); 112 DeleteObject (combined); 113 combined = NULL; 114 115 /* Get a pixmap pointer from the drawable pointer, and fetch privates */ 116 pPixmap = (PixmapPtr) pDrawable; 117 pPixmapPriv = winGetPixmapPriv (pPixmap); 118 119 /* Select the drawable pixmap into memory hdc */ 120 hbmpOrig = SelectObject (pGCPriv->hdcMem, pPixmapPriv->hBitmap); 121 if (hbmpOrig == NULL) 122 FatalError ("winFillSpans - DRAWABLE_PIXMAP - " 123 "SelectObject () failed on\n\tpPixmapPriv->hBitmap: " 124 "%08x\n", (unsigned int) pPixmapPriv->hBitmap); 125 126 /* Branch on the fill type */ 127 switch (pGC->fillStyle) 128 { 129 case FillSolid: 130 131 ROP16 (pGCPriv->hdcMem, pGC->alu); 132 133 if (pDrawable->depth == 1) 134 { 135 if (pGC->fgPixel == 0) 136 hPenOrig = SelectObject (pGCPriv->hdcMem, 137 GetStockObject (BLACK_PEN)); 138 else 139 hPenOrig = SelectObject (pGCPriv->hdcMem, 140 GetStockObject (WHITE_PEN)); 141 } 142 else 143 { 144 fg = pGC->fgPixel; 145 TRANSLATE_COLOR (fg); 146 hPen = CreatePen (PS_SOLID, 0, fg); 147 hPenOrig = SelectObject (pGCPriv->hdcMem, hPen); 148 } 149 150 while (iSpans--) 151 { 152 fullX1 = pPoints->x; 153 fullY1 = pPoints->y; 154 fullX2 = fullX1 + (int) *piWidths; 155 pPoints++; 156 piWidths++; 157 158 if (fullY1 < extentY1 || extentY2 <= fullY1) 159 continue; 160 161 if (fullX1 < extentX1) 162 fullX1 = extentX1; 163 if (fullX2 > extentX2) 164 fullX2 = extentX2; 165 166 if (fullX1 >= fullX2) 167 continue; 168 169 MoveToEx (pGCPriv->hdcMem, fullX1, fullY1, NULL); 170 LineTo (pGCPriv->hdcMem, fullX2, fullY1); 171 } 172 173 SetROP2 (pGCPriv->hdcMem, R2_COPYPEN); 174 175 /* Give back the Pen */ 176 SelectObject (pGCPriv->hdcMem, hPenOrig); 177 178 if (pDrawable->depth != 1) 179 DeleteObject (hPen); 180 break; 181 182 case FillOpaqueStippled: 183 184 pStipple = pGC->stipple; 185 pStipplePriv = winGetPixmapPriv (pStipple); 186 187 /* Create a device-dependent bitmap for the stipple */ 188 hBitmap = CreateDIBitmap (pGCPriv->hdcMem, 189 (BITMAPINFOHEADER *)pStipplePriv->pbmih, 190 CBM_INIT, 191 pStipplePriv->pbBits, 192 (BITMAPINFO *)pStipplePriv->pbmih, 193 DIB_RGB_COLORS); 194 195 /* Create a memory DC to hold the stipple */ 196 hdcStipple = CreateCompatibleDC (pGCPriv->hdcMem); 197 198 /* Select the stipple bitmap into the stipple DC */ 199 hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); 200 if (hbmpOrigStipple == NULL) 201 FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " 202 "SelectObject () failed on hbmpOrigStipple\n"); 203 204 /* Make a temporary copy of the foreground and background colors */ 205 bg = pGC->bgPixel; 206 fg = pGC->fgPixel; 207 208 /* Translate the depth-dependent colors to Win32 COLORREFs */ 209 TRANSLATE_COLOR (fg); 210 TRANSLATE_COLOR (bg); 211 SetTextColor (pGCPriv->hdcMem, fg); 212 SetBkColor (pGCPriv->hdcMem, bg); 213 214 while (iSpans--) 215 { 216 int width = pStipple->drawable.width; 217 fullX1 = pPoints->x; 218 fullY1 = pPoints->y; 219 fullX2 = fullX1 + (int) *piWidths; 220 pPoints++; 221 piWidths++; 222 223 if (fullY1 < extentY1 || extentY2 <= fullY1) 224 continue; 225 226 if (fullX1 < extentX1) 227 fullX1 = extentX1; 228 if (fullX2 > extentX2) 229 fullX2 = extentX2; 230 231 if (fullX1 >= fullX2) 232 continue; 233 234 for (iX = fullX1; iX < fullX2; iX += width) 235 { 236 int xoffset; 237 238 if ((iX + pStipple->drawable.width) > fullX2) 239 width = fullX2 - iX; 240 else 241 width = pStipple->drawable.width; 242 243 if (iX == fullX1) 244 xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; 245 else 246 xoffset = 0; 247 248 if (xoffset + width > pStipple->drawable.width) 249 width = pStipple->drawable.width - xoffset; 250 251 BitBlt (pGCPriv->hdcMem, 252 iX, fullY1, 253 width, 1, 254 hdcStipple, 255 xoffset, 256 (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, 257 g_copyROP[pGC->alu]); 258 } 259 } 260 261 /* Clear the stipple HDC */ 262 SelectObject (hdcStipple, hbmpOrigStipple); 263 DeleteDC (hdcStipple); 264 265 /* Delete the device dependent stipple bitmap */ 266 DeleteObject (hBitmap); 267 268 break; 269 case FillStippled: 270 271 pStipple = pGC->stipple; 272 pStipplePriv = winGetPixmapPriv (pStipple); 273 274 /* Create a device-dependent bitmap for the stipple */ 275 hBitmap = CreateDIBitmap (pGCPriv->hdcMem, 276 (BITMAPINFOHEADER *)pStipplePriv->pbmih, 277 CBM_INIT, 278 pStipplePriv->pbBits, 279 (BITMAPINFO *)pStipplePriv->pbmih, 280 DIB_RGB_COLORS); 281 282 /* Create a memory DC to hold the stipple */ 283 hdcStipple = CreateCompatibleDC (pGCPriv->hdcMem); 284 285 /* Select the stipple bitmap into the stipple DC */ 286 hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); 287 if (hbmpOrigStipple == NULL) 288 FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " 289 "SelectObject () failed on hbmpOrigStipple\n"); 290 291 /* Make a temporary copy of the foreground and background colors */ 292 bg = pGC->bgPixel; 293 fg = pGC->fgPixel; 294 295 /* Translate the depth-dependent colors to Win32 COLORREFs */ 296 TRANSLATE_COLOR (fg); 297 TRANSLATE_COLOR (bg); 298 299 /* this is fudgy, we should only invert on the last one 300 * We need to get the black/white pixels right in the 301 * colormap. But yeah ! it's working.. 302 */ 303 if (pGC->bgPixel != -1 && pGC->fgPixel != -1) 304 { 305 SetTextColor (pGCPriv->hdcMem, fg); 306 SetBkColor (pGCPriv->hdcMem, bg); 307 BitBlt (hdcStipple, 308 0, 0, 309 pStipple->drawable.width, pStipple->drawable.height, 310 hdcStipple, 311 0, 0, 312 0x330008); 313 } 314 else if (pGC->bgPixel == -1) 315 { 316 SetTextColor (pGCPriv->hdcMem, fg); 317 SetBkMode (pGCPriv->hdcMem, TRANSPARENT); 318 BitBlt (hdcStipple, 319 0, 0, 320 pStipple->drawable.width, pStipple->drawable.height, 321 hdcStipple, 322 0, 0, 323 0x330008); 324 } 325 else if (pGC->fgPixel == -1) 326 { 327 SetTextColor (pGCPriv->hdcMem, bg); 328 SetBkMode (pGCPriv->hdcMem, TRANSPARENT); 329#if 0 330 BitBlt (hdcStipple, 331 0, 0, 332 pStipple->drawable.width, pStipple->drawable.height, 333 hdcStipple, 334 0, 0, 335 0x330008); 336#endif 337 } 338 339 while (iSpans--) 340 { 341 int width = pStipple->drawable.width; 342 fullX1 = pPoints->x; 343 fullY1 = pPoints->y; 344 fullX2 = fullX1 + (int) *piWidths; 345 pPoints++; 346 piWidths++; 347 348 if (fullY1 < extentY1 || extentY2 <= fullY1) 349 continue; 350 351 if (fullX1 < extentX1) 352 fullX1 = extentX1; 353 if (fullX2 > extentX2) 354 fullX2 = extentX2; 355 356 if (fullX1 >= fullX2) 357 continue; 358 359 for (iX = fullX1; iX < fullX2; iX += width) 360 { 361 int xoffset; 362 363 if ((iX + pStipple->drawable.width) > fullX2) 364 width = fullX2 - iX; 365 else 366 width = pStipple->drawable.width; 367 368 if (iX == fullX1) 369 xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; 370 else 371 xoffset = 0; 372 373 if (xoffset + width > pStipple->drawable.width) 374 width = pStipple->drawable.width - xoffset; 375 376 BitBlt (pGCPriv->hdcMem, 377 iX, fullY1, 378 width, 1, 379 hdcStipple, 380 xoffset, 381 (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, 382 g_copyROP[pGC->alu]); 383 } 384 } 385 386 /* Clear the stipple HDC */ 387 SelectObject (hdcStipple, hbmpOrigStipple); 388 DeleteDC (hdcStipple); 389 390 /* Delete the device dependent stipple bitmap */ 391 DeleteObject (hBitmap); 392 393 /* Restore the background mode */ 394 SetBkMode (pGCPriv->hdcMem, OPAQUE); 395 break; 396 397 case FillTiled: 398 399 /* Get a pixmap pointer from the tile pointer, and fetch privates */ 400 pTile = (PixmapPtr) pGC->tile.pixmap; 401 pTilePriv = winGetPixmapPriv (pTile); 402 403 /* Create a memory DC to hold the tile */ 404 hdcTile = CreateCompatibleDC (pGCPriv->hdcMem); 405 406 /* Select the tile into a DC */ 407 hbmpOrig = SelectObject (hdcTile, pTilePriv->hBitmap); 408 if (hbmpOrig == NULL) 409 FatalError ("winFillSpans - DRAWABLE_PIXMAP - FillTiled - " 410 "SelectObject () failed on pTilePriv->hBitmap\n"); 411 412 while (iSpans--) 413 { 414 int width = pTile->drawable.width; 415 fullX1 = pPoints->x; 416 fullY1 = pPoints->y; 417 fullX2 = fullX1 + (int) *piWidths; 418 pPoints++; 419 piWidths++; 420 421 if (fullY1 < extentY1 || extentY2 <= fullY1) 422 continue; 423 424 if (fullX1 < extentX1) 425 fullX1 = extentX1; 426 if (fullX2 > extentX2) 427 fullX2 = extentX2; 428 429 if (fullX1 >= fullX2) 430 continue; 431 432 for (iX = fullX1; iX < fullX2; iX += width) 433 { 434 int xoffset; 435 436 if ((iX + pTile->drawable.width) > fullX2) 437 width = fullX2 - iX; 438 else 439 width = pTile->drawable.width; 440 441 if (iX == fullX1) 442 xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pTile->drawable.width) - pTile->drawable.width)) % pTile->drawable.width; 443 else 444 xoffset = 0; 445 446 if (xoffset + width > pTile->drawable.width) 447 width = pTile->drawable.width - xoffset; 448 449 BitBlt (pGCPriv->hdcMem, 450 iX, fullY1, 451 width, 1, 452 hdcTile, 453 xoffset, 454 (fullY1 - (pDrawable->y + (pGC->patOrg.y % pTile->drawable.height) - pTile->drawable.height)) % pTile->drawable.height, 455 g_copyROP[pGC->alu]); 456 } 457 } 458 459 /* Push the tile pixmap out of the memory HDC */ 460 SelectObject (hdcTile, hbmpOrig); 461 462 /* Delete the tile */ 463 DeleteDC (hdcTile); 464 break; 465 466 default: 467 ErrorF ("winFillSpans - DRAWABLE_PIXMAP - Unknown fillStyle\n"); 468 break; 469 } 470 471 /* Reset clip region */ 472 SelectClipRgn (pGCPriv->hdcMem, NULL); 473 474 /* Push the drawable pixmap out of the GC HDC */ 475 SelectObject (pGCPriv->hdcMem, hbmpOrig); 476 break; 477 478 case DRAWABLE_WINDOW: 479 480 SelectClipRgn (pGCPriv->hdc, combined); 481 DeleteObject (combined); 482 combined = NULL; 483 484 /* Branch on fill style */ 485 switch (pGC->fillStyle) 486 { 487 case FillSolid: 488 489 ROP16 (pGCPriv->hdc, pGC->alu); 490 491 if (pDrawable->depth == 1) 492 { 493 if (pGC->fgPixel == 0) 494 hPenOrig = SelectObject (pGCPriv->hdc, 495 GetStockObject (BLACK_PEN)); 496 else 497 hPenOrig = SelectObject (pGCPriv->hdc, 498 GetStockObject (WHITE_PEN)); 499 } 500 else 501 { 502 fg = pGC->fgPixel; 503 TRANSLATE_COLOR (fg); 504 hPen = CreatePen (PS_SOLID, 0, fg); 505 hPenOrig = SelectObject (pGCPriv->hdc, hPen); 506 } 507 508 while (iSpans--) 509 { 510 fullX1 = pPoints->x; 511 fullY1 = pPoints->y; 512 fullX2 = fullX1 + (int) *piWidths; 513 pPoints++; 514 piWidths++; 515 516 if (fullY1 < extentY1 || extentY2 <= fullY1) 517 continue; 518 519 if (fullX1 < extentX1) 520 fullX1 = extentX1; 521 if (fullX2 > extentX2) 522 fullX2 = extentX2; 523 524 if (fullX1 >= fullX2) 525 continue; 526 527 MoveToEx (pGCPriv->hdc, fullX1, fullY1, NULL); 528 LineTo (pGCPriv->hdc, fullX2, fullY1); 529 } 530 531 SetROP2 (pGCPriv->hdc, R2_COPYPEN); 532 533 /* Give back the Brush */ 534 SelectObject (pGCPriv->hdc, hPenOrig); 535 536 if (pDrawable->depth != 1) 537 DeleteObject (hPen); 538 break; 539 540 case FillOpaqueStippled: 541 542 pStipple = pGC->stipple; 543 pStipplePriv = winGetPixmapPriv (pStipple); 544 545 /* Create a device-dependent bitmap for the stipple */ 546 hBitmap = CreateDIBitmap (pGCPriv->hdc, 547 (BITMAPINFOHEADER *)pStipplePriv->pbmih, 548 CBM_INIT, 549 pStipplePriv->pbBits, 550 (BITMAPINFO *)pStipplePriv->pbmih, 551 DIB_RGB_COLORS); 552 553 /* Create a memory DC to hold the stipple */ 554 hdcStipple = CreateCompatibleDC (pGCPriv->hdc); 555 556 /* Select the stipple bitmap into the stipple DC */ 557 hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); 558 if (hbmpOrigStipple == NULL) 559 FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " 560 "SelectObject () failed on hbmpOrigStipple\n"); 561 562 /* Make a temporary copy of the foreground and background colors */ 563 bg = pGC->bgPixel; 564 fg = pGC->fgPixel; 565 566 /* Translate the depth-dependent colors to Win32 COLORREFs */ 567 TRANSLATE_COLOR (fg); 568 TRANSLATE_COLOR (bg); 569 SetTextColor (pGCPriv->hdc, fg); 570 SetBkColor (pGCPriv->hdc, bg); 571 572 while (iSpans--) 573 { 574 int width = pStipple->drawable.width; 575 fullX1 = pPoints->x; 576 fullY1 = pPoints->y; 577 fullX2 = fullX1 + (int) *piWidths; 578 pPoints++; 579 piWidths++; 580 581 if (fullY1 < extentY1 || extentY2 <= fullY1) 582 continue; 583 584 if (fullX1 < extentX1) 585 fullX1 = extentX1; 586 if (fullX2 > extentX2) 587 fullX2 = extentX2; 588 589 if (fullX1 >= fullX2) 590 continue; 591 592 for (iX = fullX1; iX < fullX2; iX += width) 593 { 594 int xoffset; 595 596 if ((iX + pStipple->drawable.width) > fullX2) 597 width = fullX2 - iX; 598 else 599 width = pStipple->drawable.width; 600 601 if (iX == fullX1) 602 xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; 603 else 604 xoffset = 0; 605 606 if (xoffset + width > pStipple->drawable.width) 607 width = pStipple->drawable.width - xoffset; 608 609 BitBlt (pGCPriv->hdc, 610 iX, fullY1, 611 width, 1, 612 hdcStipple, 613 xoffset, 614 (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, 615 g_copyROP[pGC->alu]); 616 } 617 } 618 619 /* Clear the stipple HDC */ 620 SelectObject (hdcStipple, hbmpOrigStipple); 621 DeleteDC (hdcStipple); 622 623 /* Delete the device dependent stipple bitmap */ 624 DeleteObject (hBitmap); 625 626 break; 627 628 case FillStippled: 629 pStipple = pGC->stipple; 630 pStipplePriv = winGetPixmapPriv (pStipple); 631 632 /* Create a device-dependent bitmap for the stipple */ 633 hBitmap = CreateDIBitmap (pGCPriv->hdcMem, 634 (BITMAPINFOHEADER *)pStipplePriv->pbmih, 635 CBM_INIT, 636 pStipplePriv->pbBits, 637 (BITMAPINFO *)pStipplePriv->pbmih, 638 DIB_RGB_COLORS); 639 640 /* Create a memory DC to hold the stipple */ 641 hdcStipple = CreateCompatibleDC (pGCPriv->hdc); 642 643 /* Select the stipple bitmap into the stipple DC */ 644 hbmpOrigStipple = SelectObject (hdcStipple, hBitmap); 645 if (hbmpOrigStipple == NULL) 646 FatalError ("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - " 647 "SelectObject () failed on hbmpOrigStipple\n"); 648 649 /* Make a temporary copy of the foreground and background colors */ 650 bg = pGC->bgPixel; 651 fg = pGC->fgPixel; 652 653 /* Translate the depth-dependent colors to Win32 COLORREFs */ 654 TRANSLATE_COLOR (fg); 655 TRANSLATE_COLOR (bg); 656 657 /* this is fudgy, we should only invert on the last one 658 * We need to get the black/white pixels right in the 659 * colormap. But yeah ! it's working.. 660 */ 661 if (pGC->bgPixel != -1 && pGC->fgPixel != -1) 662 { 663 SetTextColor (pGCPriv->hdc, fg); 664 SetBkColor (pGCPriv->hdc, bg); 665 BitBlt (hdcStipple, 666 0, 0, 667 pStipple->drawable.width, pStipple->drawable.height, 668 hdcStipple, 669 0,0, 670 0x330008); 671 } 672 else if (pGC->bgPixel == -1) 673 { 674 SetTextColor (pGCPriv->hdc, fg); 675 SetBkMode (pGCPriv->hdc, TRANSPARENT); 676 BitBlt (hdcStipple, 677 0, 0, 678 pStipple->drawable.width, pStipple->drawable.height, 679 hdcStipple, 680 0,0, 681 0x330008); 682 } 683 else if (pGC->fgPixel == -1) 684 { 685 SetTextColor (pGCPriv->hdc, bg); 686 SetBkMode (pGCPriv->hdc, TRANSPARENT); 687#if 0 688 BitBlt (hdcStipple, 689 0, 0, 690 pStipple->drawable.width, pStipple->drawable.height, 691 hdcStipple, 692 0, 0, 693 0x330008); 694#endif 695 } 696 697 while (iSpans--) 698 { 699 int width = pStipple->drawable.width; 700 fullX1 = pPoints->x; 701 fullY1 = pPoints->y; 702 fullX2 = fullX1 + (int) *piWidths; 703 pPoints++; 704 piWidths++; 705 706 if (fullY1 < extentY1 || extentY2 <= fullY1) 707 continue; 708 709 if (fullX1 < extentX1) 710 fullX1 = extentX1; 711 if (fullX2 > extentX2) 712 fullX2 = extentX2; 713 714 if (fullX1 >= fullX2) 715 continue; 716 717 for (iX = fullX1; iX < fullX2; iX += width) 718 { 719 int xoffset; 720 721 if ((iX + pStipple->drawable.width) > fullX2) 722 width = fullX2 - iX; 723 else 724 width = pStipple->drawable.width; 725 726 if (iX == fullX1) 727 xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pStipple->drawable.width) - pStipple->drawable.width)) % pStipple->drawable.width; 728 else 729 xoffset = 0; 730 731 if (xoffset + width > pStipple->drawable.width) 732 width = pStipple->drawable.width - xoffset; 733 734 BitBlt (pGCPriv->hdc, 735 iX, fullY1, 736 width, 1, 737 hdcStipple, 738 xoffset, 739 (fullY1 - (pDrawable->y + (pGC->patOrg.y % pStipple->drawable.height) - pStipple->drawable.height)) % pStipple->drawable.height, 740 g_copyROP[pGC->alu]); 741 } 742 } 743 744 /* Clear the stipple HDC */ 745 SelectObject (hdcStipple, hbmpOrigStipple); 746 DeleteDC (hdcStipple); 747 748 /* Delete the device dependent stipple bitmap */ 749 DeleteObject (hBitmap); 750 751 /* Restore the background mode */ 752 SetBkMode (pGCPriv->hdc, OPAQUE); 753 break; 754 755 case FillTiled: 756 757 /* Get a pixmap pointer from the tile pointer, and fetch privates */ 758 pTile = (PixmapPtr) pGC->tile.pixmap; 759 pTilePriv = winGetPixmapPriv (pTile); 760 761 /* Select the tile into a DC */ 762 hbmpOrig = SelectObject (pGCPriv->hdcMem, pTilePriv->hBitmap); 763 if (hbmpOrig == NULL) 764 FatalError ("winFillSpans - DRAWABLE_WINDOW - FillTiled - " 765 "SelectObject () failed on pTilePriv->hBitmap\n"); 766 767 while (iSpans--) 768 { 769 int width = pTile->drawable.width; 770 fullX1 = pPoints->x; 771 fullY1 = pPoints->y; 772 fullX2 = fullX1 + (int) *piWidths; 773 pPoints++; 774 piWidths++; 775 776 if (fullY1 < extentY1 || extentY2 <= fullY1) 777 continue; 778 779 if (fullX1 < extentX1) 780 fullX1 = extentX1; 781 if (fullX2 > extentX2) 782 fullX2 = extentX2; 783 784 if (fullX1 >= fullX2) 785 continue; 786 787 for (iX = fullX1; iX < fullX2; iX += width) 788 { 789 int xoffset; 790 791 if ((iX + pTile->drawable.width) > fullX2) 792 width = fullX2 - iX; 793 else 794 width = pTile->drawable.width; 795 796 if (iX == fullX1) 797 xoffset = (fullX1 - (pDrawable->x + (pGC->patOrg.x % pTile->drawable.width) - pTile->drawable.width)) % pTile->drawable.width; 798 else 799 xoffset = 0; 800 801 if (xoffset + width > pTile->drawable.width) 802 width = pTile->drawable.width - xoffset; 803 804 BitBlt (pGCPriv->hdc, 805 iX, fullY1, 806 width, 1, 807 pGCPriv->hdcMem, 808 xoffset, 809 (fullY1 - (pDrawable->y + (pGC->patOrg.y % pTile->drawable.height) - pTile->drawable.height)) % pTile->drawable.height, 810 g_copyROP[pGC->alu]); 811 } 812 } 813 814 /* Push the tile pixmap out of the memory HDC */ 815 SelectObject (pGCPriv->hdcMem, hbmpOrig); 816 break; 817 818 default: 819 ErrorF ("winFillSpans - DRAWABLE_WINDOW - Unknown fillStyle\n"); 820 break; 821 } 822 823 /* Reset clip region */ 824 SelectClipRgn (pGCPriv->hdc, NULL); 825 break; 826 827 default: 828 ErrorF ("winFillSpans - Unknown drawable type\n"); 829 break; 830 } 831} 832