Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xwin / winfillsp.c
CommitLineData
a09e091a
JB
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
37extern void ROP16(HDC hdc, int rop);
38
39#define TRANSLATE_COLOR(color) \
40{ \
41 if (pDrawable->depth == 15) \
42 color = ((color & 0x1F) << 19) | ((color & 0x03E0) << 6) | \
43 ((color & 0xF800) >> 8); \
44 else if (pDrawable->depth == 16) \
45 color = ((color & 0x1F) << 19) | ((color & 0x07E0) << 5) | \
46 ((color & 0xF800) >> 8); \
47 else if (pDrawable->depth == 24 || pDrawable->depth == 32) \
48 color = ((color & 0xFF) << 16) | (color & 0xFF00) | \
49 ((color & 0xFF0000) >> 16); \
50}
51
52/* See Porting Layer Definition - p. 54 */
53void
54winFillSpansNativeGDI(DrawablePtr pDrawable,
55 GCPtr pGC,
56 int iSpans,
57 DDXPointPtr pPoints, int *piWidths, int fSorted)
58{
59 winGCPriv(pGC);
60 HBITMAP hbmpOrig = NULL, hbmpOrigStipple = NULL;
61 HBITMAP hPenOrig = NULL;
62 HBITMAP hBitmap = NULL;
63 PixmapPtr pPixmap = NULL;
64 winPrivPixmapPtr pPixmapPriv = NULL;
65 PixmapPtr pStipple = NULL;
66 winPrivPixmapPtr pStipplePriv = NULL;
67 PixmapPtr pTile = NULL;
68 winPrivPixmapPtr pTilePriv = NULL;
69 HDC hdcStipple = NULL, hdcTile = NULL;
70 HPEN hPen = NULL;
71 int iX;
72 int fg, bg;
73 RegionPtr pClip = pGC->pCompositeClip;
74 BoxPtr pextent, pbox;
75 int nbox;
76 int extentX1, extentX2, extentY1, extentY2;
77 int fullX1, fullX2, fullY1;
78 HRGN hrgn = NULL, combined = NULL;
79
80 nbox = RegionNumRects(pClip);
81 pbox = RegionRects(pClip);
82
83 if (!nbox)
84 return;
85
86 combined = CreateRectRgn(pbox->x1, pbox->y1, pbox->x2, pbox->y2);
87 nbox--;
88 pbox++;
89
90 while (nbox--) {
91 hrgn = CreateRectRgn(pbox->x1, pbox->y1, pbox->x2, pbox->y2);
92 CombineRgn(combined, combined, hrgn, RGN_OR);
93 DeleteObject(hrgn);
94 hrgn = NULL;
95 pbox++;
96 }
97
98 pextent = RegionExtents(pClip);
99 extentX1 = pextent->x1;
100 extentY1 = pextent->y1;
101 extentX2 = pextent->x2;
102 extentY2 = pextent->y2;
103
104 /* Branch on the type of drawable we have */
105 switch (pDrawable->type) {
106 case DRAWABLE_PIXMAP:
107
108 SelectClipRgn(pGCPriv->hdcMem, combined);
109 DeleteObject(combined);
110 combined = NULL;
111
112 /* Get a pixmap pointer from the drawable pointer, and fetch privates */
113 pPixmap = (PixmapPtr) pDrawable;
114 pPixmapPriv = winGetPixmapPriv(pPixmap);
115
116 /* Select the drawable pixmap into memory hdc */
117 hbmpOrig = SelectObject(pGCPriv->hdcMem, pPixmapPriv->hBitmap);
118 if (hbmpOrig == NULL)
119 FatalError("winFillSpans - DRAWABLE_PIXMAP - "
120 "SelectObject () failed on\n\tpPixmapPriv->hBitmap: "
121 "%p\n", pPixmapPriv->hBitmap);
122
123 /* Branch on the fill type */
124 switch (pGC->fillStyle) {
125 case FillSolid:
126
127 ROP16(pGCPriv->hdcMem, pGC->alu);
128
129 if (pDrawable->depth == 1) {
130 if (pGC->fgPixel == 0)
131 hPenOrig = SelectObject(pGCPriv->hdcMem,
132 GetStockObject(BLACK_PEN));
133 else
134 hPenOrig = SelectObject(pGCPriv->hdcMem,
135 GetStockObject(WHITE_PEN));
136 }
137 else {
138 fg = pGC->fgPixel;
139 TRANSLATE_COLOR(fg);
140 hPen = CreatePen(PS_SOLID, 0, fg);
141 hPenOrig = SelectObject(pGCPriv->hdcMem, hPen);
142 }
143
144 while (iSpans--) {
145 fullX1 = pPoints->x;
146 fullY1 = pPoints->y;
147 fullX2 = fullX1 + (int) *piWidths;
148 pPoints++;
149 piWidths++;
150
151 if (fullY1 < extentY1 || extentY2 <= fullY1)
152 continue;
153
154 if (fullX1 < extentX1)
155 fullX1 = extentX1;
156 if (fullX2 > extentX2)
157 fullX2 = extentX2;
158
159 if (fullX1 >= fullX2)
160 continue;
161
162 MoveToEx(pGCPriv->hdcMem, fullX1, fullY1, NULL);
163 LineTo(pGCPriv->hdcMem, fullX2, fullY1);
164 }
165
166 SetROP2(pGCPriv->hdcMem, R2_COPYPEN);
167
168 /* Give back the Pen */
169 SelectObject(pGCPriv->hdcMem, hPenOrig);
170
171 if (pDrawable->depth != 1)
172 DeleteObject(hPen);
173 break;
174
175 case FillOpaqueStippled:
176
177 pStipple = pGC->stipple;
178 pStipplePriv = winGetPixmapPriv(pStipple);
179
180 /* Create a device-dependent bitmap for the stipple */
181 hBitmap = CreateDIBitmap(pGCPriv->hdcMem,
182 (BITMAPINFOHEADER *) pStipplePriv->pbmih,
183 CBM_INIT,
184 pStipplePriv->pbBits,
185 (BITMAPINFO *) pStipplePriv->pbmih,
186 DIB_RGB_COLORS);
187
188 /* Create a memory DC to hold the stipple */
189 hdcStipple = CreateCompatibleDC(pGCPriv->hdcMem);
190
191 /* Select the stipple bitmap into the stipple DC */
192 hbmpOrigStipple = SelectObject(hdcStipple, hBitmap);
193 if (hbmpOrigStipple == NULL)
194 FatalError("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - "
195 "SelectObject () failed on hbmpOrigStipple\n");
196
197 /* Make a temporary copy of the foreground and background colors */
198 bg = pGC->bgPixel;
199 fg = pGC->fgPixel;
200
201 /* Translate the depth-dependent colors to Win32 COLORREFs */
202 TRANSLATE_COLOR(fg);
203 TRANSLATE_COLOR(bg);
204 SetTextColor(pGCPriv->hdcMem, fg);
205 SetBkColor(pGCPriv->hdcMem, bg);
206
207 while (iSpans--) {
208 int width = pStipple->drawable.width;
209
210 fullX1 = pPoints->x;
211 fullY1 = pPoints->y;
212 fullX2 = fullX1 + (int) *piWidths;
213 pPoints++;
214 piWidths++;
215
216 if (fullY1 < extentY1 || extentY2 <= fullY1)
217 continue;
218
219 if (fullX1 < extentX1)
220 fullX1 = extentX1;
221 if (fullX2 > extentX2)
222 fullX2 = extentX2;
223
224 if (fullX1 >= fullX2)
225 continue;
226
227 for (iX = fullX1; iX < fullX2; iX += width) {
228 int xoffset;
229
230 if ((iX + pStipple->drawable.width) > fullX2)
231 width = fullX2 - iX;
232 else
233 width = pStipple->drawable.width;
234
235 if (iX == fullX1)
236 xoffset =
237 (fullX1 -
238 (pDrawable->x +
239 (pGC->patOrg.x % pStipple->drawable.width) -
240 pStipple->drawable.width)) %
241 pStipple->drawable.width;
242 else
243 xoffset = 0;
244
245 if (xoffset + width > pStipple->drawable.width)
246 width = pStipple->drawable.width - xoffset;
247
248 BitBlt(pGCPriv->hdcMem,
249 iX, fullY1,
250 width, 1,
251 hdcStipple,
252 xoffset,
253 (fullY1 -
254 (pDrawable->y +
255 (pGC->patOrg.y % pStipple->drawable.height) -
256 pStipple->drawable.height)) %
257 pStipple->drawable.height, 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 SetTextColor(pGCPriv->hdcMem, fg);
305 SetBkColor(pGCPriv->hdcMem, bg);
306 BitBlt(hdcStipple,
307 0, 0,
308 pStipple->drawable.width, pStipple->drawable.height,
309 hdcStipple, 0, 0, 0x330008);
310 }
311 else if (pGC->bgPixel == -1) {
312 SetTextColor(pGCPriv->hdcMem, fg);
313 SetBkMode(pGCPriv->hdcMem, TRANSPARENT);
314 BitBlt(hdcStipple,
315 0, 0,
316 pStipple->drawable.width, pStipple->drawable.height,
317 hdcStipple, 0, 0, 0x330008);
318 }
319 else if (pGC->fgPixel == -1) {
320 SetTextColor(pGCPriv->hdcMem, bg);
321 SetBkMode(pGCPriv->hdcMem, TRANSPARENT);
322#if 0
323 BitBlt(hdcStipple,
324 0, 0,
325 pStipple->drawable.width, pStipple->drawable.height,
326 hdcStipple, 0, 0, 0x330008);
327#endif
328 }
329
330 while (iSpans--) {
331 int width = pStipple->drawable.width;
332
333 fullX1 = pPoints->x;
334 fullY1 = pPoints->y;
335 fullX2 = fullX1 + (int) *piWidths;
336 pPoints++;
337 piWidths++;
338
339 if (fullY1 < extentY1 || extentY2 <= fullY1)
340 continue;
341
342 if (fullX1 < extentX1)
343 fullX1 = extentX1;
344 if (fullX2 > extentX2)
345 fullX2 = extentX2;
346
347 if (fullX1 >= fullX2)
348 continue;
349
350 for (iX = fullX1; iX < fullX2; iX += width) {
351 int xoffset;
352
353 if ((iX + pStipple->drawable.width) > fullX2)
354 width = fullX2 - iX;
355 else
356 width = pStipple->drawable.width;
357
358 if (iX == fullX1)
359 xoffset =
360 (fullX1 -
361 (pDrawable->x +
362 (pGC->patOrg.x % pStipple->drawable.width) -
363 pStipple->drawable.width)) %
364 pStipple->drawable.width;
365 else
366 xoffset = 0;
367
368 if (xoffset + width > pStipple->drawable.width)
369 width = pStipple->drawable.width - xoffset;
370
371 BitBlt(pGCPriv->hdcMem,
372 iX, fullY1,
373 width, 1,
374 hdcStipple,
375 xoffset,
376 (fullY1 -
377 (pDrawable->y +
378 (pGC->patOrg.y % pStipple->drawable.height) -
379 pStipple->drawable.height)) %
380 pStipple->drawable.height, g_copyROP[pGC->alu]);
381 }
382 }
383
384 /* Clear the stipple HDC */
385 SelectObject(hdcStipple, hbmpOrigStipple);
386 DeleteDC(hdcStipple);
387
388 /* Delete the device dependent stipple bitmap */
389 DeleteObject(hBitmap);
390
391 /* Restore the background mode */
392 SetBkMode(pGCPriv->hdcMem, OPAQUE);
393 break;
394
395 case FillTiled:
396
397 /* Get a pixmap pointer from the tile pointer, and fetch privates */
398 pTile = (PixmapPtr) pGC->tile.pixmap;
399 pTilePriv = winGetPixmapPriv(pTile);
400
401 /* Create a memory DC to hold the tile */
402 hdcTile = CreateCompatibleDC(pGCPriv->hdcMem);
403
404 /* Select the tile into a DC */
405 hbmpOrig = SelectObject(hdcTile, pTilePriv->hBitmap);
406 if (hbmpOrig == NULL)
407 FatalError("winFillSpans - DRAWABLE_PIXMAP - FillTiled - "
408 "SelectObject () failed on pTilePriv->hBitmap\n");
409
410 while (iSpans--) {
411 int width = pTile->drawable.width;
412
413 fullX1 = pPoints->x;
414 fullY1 = pPoints->y;
415 fullX2 = fullX1 + (int) *piWidths;
416 pPoints++;
417 piWidths++;
418
419 if (fullY1 < extentY1 || extentY2 <= fullY1)
420 continue;
421
422 if (fullX1 < extentX1)
423 fullX1 = extentX1;
424 if (fullX2 > extentX2)
425 fullX2 = extentX2;
426
427 if (fullX1 >= fullX2)
428 continue;
429
430 for (iX = fullX1; iX < fullX2; iX += width) {
431 int xoffset;
432
433 if ((iX + pTile->drawable.width) > fullX2)
434 width = fullX2 - iX;
435 else
436 width = pTile->drawable.width;
437
438 if (iX == fullX1)
439 xoffset =
440 (fullX1 -
441 (pDrawable->x +
442 (pGC->patOrg.x % pTile->drawable.width) -
443 pTile->drawable.width)) % pTile->drawable.width;
444 else
445 xoffset = 0;
446
447 if (xoffset + width > pTile->drawable.width)
448 width = pTile->drawable.width - xoffset;
449
450 BitBlt(pGCPriv->hdcMem,
451 iX, fullY1,
452 width, 1,
453 hdcTile,
454 xoffset,
455 (fullY1 -
456 (pDrawable->y +
457 (pGC->patOrg.y % pTile->drawable.height) -
458 pTile->drawable.height)) % pTile->drawable.height,
459 g_copyROP[pGC->alu]);
460 }
461 }
462
463 /* Push the tile pixmap out of the memory HDC */
464 SelectObject(hdcTile, hbmpOrig);
465
466 /* Delete the tile */
467 DeleteDC(hdcTile);
468 break;
469
470 default:
471 ErrorF("winFillSpans - DRAWABLE_PIXMAP - Unknown fillStyle\n");
472 break;
473 }
474
475 /* Reset clip region */
476 SelectClipRgn(pGCPriv->hdcMem, NULL);
477
478 /* Push the drawable pixmap out of the GC HDC */
479 SelectObject(pGCPriv->hdcMem, hbmpOrig);
480 break;
481
482 case DRAWABLE_WINDOW:
483
484 SelectClipRgn(pGCPriv->hdc, combined);
485 DeleteObject(combined);
486 combined = NULL;
487
488 /* Branch on fill style */
489 switch (pGC->fillStyle) {
490 case FillSolid:
491
492 ROP16(pGCPriv->hdc, pGC->alu);
493
494 if (pDrawable->depth == 1) {
495 if (pGC->fgPixel == 0)
496 hPenOrig = SelectObject(pGCPriv->hdc,
497 GetStockObject(BLACK_PEN));
498 else
499 hPenOrig = SelectObject(pGCPriv->hdc,
500 GetStockObject(WHITE_PEN));
501 }
502 else {
503 fg = pGC->fgPixel;
504 TRANSLATE_COLOR(fg);
505 hPen = CreatePen(PS_SOLID, 0, fg);
506 hPenOrig = SelectObject(pGCPriv->hdc, hPen);
507 }
508
509 while (iSpans--) {
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 int width = pStipple->drawable.width;
574
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 int xoffset;
594
595 if ((iX + pStipple->drawable.width) > fullX2)
596 width = fullX2 - iX;
597 else
598 width = pStipple->drawable.width;
599
600 if (iX == fullX1)
601 xoffset =
602 (fullX1 -
603 (pDrawable->x +
604 (pGC->patOrg.x % pStipple->drawable.width) -
605 pStipple->drawable.width)) %
606 pStipple->drawable.width;
607 else
608 xoffset = 0;
609
610 if (xoffset + width > pStipple->drawable.width)
611 width = pStipple->drawable.width - xoffset;
612
613 BitBlt(pGCPriv->hdc,
614 iX, fullY1,
615 width, 1,
616 hdcStipple,
617 xoffset,
618 (fullY1 -
619 (pDrawable->y +
620 (pGC->patOrg.y % pStipple->drawable.height) -
621 pStipple->drawable.height)) %
622 pStipple->drawable.height, g_copyROP[pGC->alu]);
623 }
624 }
625
626 /* Clear the stipple HDC */
627 SelectObject(hdcStipple, hbmpOrigStipple);
628 DeleteDC(hdcStipple);
629
630 /* Delete the device dependent stipple bitmap */
631 DeleteObject(hBitmap);
632
633 break;
634
635 case FillStippled:
636 pStipple = pGC->stipple;
637 pStipplePriv = winGetPixmapPriv(pStipple);
638
639 /* Create a device-dependent bitmap for the stipple */
640 hBitmap = CreateDIBitmap(pGCPriv->hdcMem,
641 (BITMAPINFOHEADER *) pStipplePriv->pbmih,
642 CBM_INIT,
643 pStipplePriv->pbBits,
644 (BITMAPINFO *) pStipplePriv->pbmih,
645 DIB_RGB_COLORS);
646
647 /* Create a memory DC to hold the stipple */
648 hdcStipple = CreateCompatibleDC(pGCPriv->hdc);
649
650 /* Select the stipple bitmap into the stipple DC */
651 hbmpOrigStipple = SelectObject(hdcStipple, hBitmap);
652 if (hbmpOrigStipple == NULL)
653 FatalError("winFillSpans () - DRAWABLE_PIXMAP - FillStippled - "
654 "SelectObject () failed on hbmpOrigStipple\n");
655
656 /* Make a temporary copy of the foreground and background colors */
657 bg = pGC->bgPixel;
658 fg = pGC->fgPixel;
659
660 /* Translate the depth-dependent colors to Win32 COLORREFs */
661 TRANSLATE_COLOR(fg);
662 TRANSLATE_COLOR(bg);
663
664 /* this is fudgy, we should only invert on the last one
665 * We need to get the black/white pixels right in the
666 * colormap. But yeah ! it's working..
667 */
668 if (pGC->bgPixel != -1 && pGC->fgPixel != -1) {
669 SetTextColor(pGCPriv->hdc, fg);
670 SetBkColor(pGCPriv->hdc, bg);
671 BitBlt(hdcStipple,
672 0, 0,
673 pStipple->drawable.width, pStipple->drawable.height,
674 hdcStipple, 0, 0, 0x330008);
675 }
676 else if (pGC->bgPixel == -1) {
677 SetTextColor(pGCPriv->hdc, fg);
678 SetBkMode(pGCPriv->hdc, TRANSPARENT);
679 BitBlt(hdcStipple,
680 0, 0,
681 pStipple->drawable.width, pStipple->drawable.height,
682 hdcStipple, 0, 0, 0x330008);
683 }
684 else if (pGC->fgPixel == -1) {
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, 0, 0, 0x330008);
692#endif
693 }
694
695 while (iSpans--) {
696 int width = pStipple->drawable.width;
697
698 fullX1 = pPoints->x;
699 fullY1 = pPoints->y;
700 fullX2 = fullX1 + (int) *piWidths;
701 pPoints++;
702 piWidths++;
703
704 if (fullY1 < extentY1 || extentY2 <= fullY1)
705 continue;
706
707 if (fullX1 < extentX1)
708 fullX1 = extentX1;
709 if (fullX2 > extentX2)
710 fullX2 = extentX2;
711
712 if (fullX1 >= fullX2)
713 continue;
714
715 for (iX = fullX1; iX < fullX2; iX += width) {
716 int xoffset;
717
718 if ((iX + pStipple->drawable.width) > fullX2)
719 width = fullX2 - iX;
720 else
721 width = pStipple->drawable.width;
722
723 if (iX == fullX1)
724 xoffset =
725 (fullX1 -
726 (pDrawable->x +
727 (pGC->patOrg.x % pStipple->drawable.width) -
728 pStipple->drawable.width)) %
729 pStipple->drawable.width;
730 else
731 xoffset = 0;
732
733 if (xoffset + width > pStipple->drawable.width)
734 width = pStipple->drawable.width - xoffset;
735
736 BitBlt(pGCPriv->hdc,
737 iX, fullY1,
738 width, 1,
739 hdcStipple,
740 xoffset,
741 (fullY1 -
742 (pDrawable->y +
743 (pGC->patOrg.y % pStipple->drawable.height) -
744 pStipple->drawable.height)) %
745 pStipple->drawable.height, g_copyROP[pGC->alu]);
746 }
747 }
748
749 /* Clear the stipple HDC */
750 SelectObject(hdcStipple, hbmpOrigStipple);
751 DeleteDC(hdcStipple);
752
753 /* Delete the device dependent stipple bitmap */
754 DeleteObject(hBitmap);
755
756 /* Restore the background mode */
757 SetBkMode(pGCPriv->hdc, OPAQUE);
758 break;
759
760 case FillTiled:
761
762 /* Get a pixmap pointer from the tile pointer, and fetch privates */
763 pTile = (PixmapPtr) pGC->tile.pixmap;
764 pTilePriv = winGetPixmapPriv(pTile);
765
766 /* Select the tile into a DC */
767 hbmpOrig = SelectObject(pGCPriv->hdcMem, pTilePriv->hBitmap);
768 if (hbmpOrig == NULL)
769 FatalError("winFillSpans - DRAWABLE_WINDOW - FillTiled - "
770 "SelectObject () failed on pTilePriv->hBitmap\n");
771
772 while (iSpans--) {
773 int width = pTile->drawable.width;
774
775 fullX1 = pPoints->x;
776 fullY1 = pPoints->y;
777 fullX2 = fullX1 + (int) *piWidths;
778 pPoints++;
779 piWidths++;
780
781 if (fullY1 < extentY1 || extentY2 <= fullY1)
782 continue;
783
784 if (fullX1 < extentX1)
785 fullX1 = extentX1;
786 if (fullX2 > extentX2)
787 fullX2 = extentX2;
788
789 if (fullX1 >= fullX2)
790 continue;
791
792 for (iX = fullX1; iX < fullX2; iX += width) {
793 int xoffset;
794
795 if ((iX + pTile->drawable.width) > fullX2)
796 width = fullX2 - iX;
797 else
798 width = pTile->drawable.width;
799
800 if (iX == fullX1)
801 xoffset =
802 (fullX1 -
803 (pDrawable->x +
804 (pGC->patOrg.x % pTile->drawable.width) -
805 pTile->drawable.width)) % pTile->drawable.width;
806 else
807 xoffset = 0;
808
809 if (xoffset + width > pTile->drawable.width)
810 width = pTile->drawable.width - xoffset;
811
812 BitBlt(pGCPriv->hdc,
813 iX, fullY1,
814 width, 1,
815 pGCPriv->hdcMem,
816 xoffset,
817 (fullY1 -
818 (pDrawable->y +
819 (pGC->patOrg.y % pTile->drawable.height) -
820 pTile->drawable.height)) % pTile->drawable.height,
821 g_copyROP[pGC->alu]);
822 }
823 }
824
825 /* Push the tile pixmap out of the memory HDC */
826 SelectObject(pGCPriv->hdcMem, hbmpOrig);
827 break;
828
829 default:
830 ErrorF("winFillSpans - DRAWABLE_WINDOW - Unknown fillStyle\n");
831 break;
832 }
833
834 /* Reset clip region */
835 SelectClipRgn(pGCPriv->hdc, NULL);
836 break;
837
838 default:
839 ErrorF("winFillSpans - Unknown drawable type\n");
840 break;
841 }
842}