2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 /* $Id: bitmaps.c 28300 2007-08-12 15:20:09Z tkreuzer $ */
40 BLENDFUNCTION BlendFunc
,
45 SURFACE
*BitmapDest
, *BitmapSrc
;
46 RECTL DestRect
, SourceRect
;
50 BlendObj
.BlendFunction
= BlendFunc
;
52 if (WidthDest
< 0 || HeightDest
< 0 || WidthSrc
< 0 || HeightSrc
< 0)
54 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
58 DCDest
= DC_LockDc(hDCDest
);
61 DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCDest
);
62 SetLastWin32Error(ERROR_INVALID_HANDLE
);
66 if (DCDest
->dctype
== DC_TYPE_INFO
)
69 /* Yes, Windows really returns TRUE in this case */
73 if (hDCSrc
!= hDCDest
)
75 DCSrc
= DC_LockDc(hDCSrc
);
79 DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCSrc
);
80 SetLastWin32Error(ERROR_INVALID_HANDLE
);
84 if (DCSrc
->dctype
== DC_TYPE_INFO
)
88 /* Yes, Windows really returns TRUE in this case */
97 DestRect
.left
= XOriginDest
;
98 DestRect
.top
= YOriginDest
;
99 DestRect
.right
= XOriginDest
+ WidthDest
;
100 DestRect
.bottom
= YOriginDest
+ HeightDest
;
101 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
103 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
104 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
105 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
106 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
108 SourceRect
.left
= XOriginSrc
;
109 SourceRect
.top
= YOriginSrc
;
110 SourceRect
.right
= XOriginSrc
+ WidthSrc
;
111 SourceRect
.bottom
= YOriginSrc
+ HeightSrc
;
112 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
114 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
115 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
116 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
117 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
119 if (!DestRect
.right
||
124 if (hDCSrc
!= hDCDest
)
130 /* Determine surfaces to be used in the bitblt */
131 BitmapDest
= DCDest
->dclevel
.pSurface
;
134 if (hDCSrc
!= hDCDest
)
140 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
143 if (hDCSrc
!= hDCDest
)
149 /* Create the XLATEOBJ. */
150 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
152 /* Perform the alpha blend operation */
153 bResult
= IntEngAlphaBlend(&BitmapDest
->SurfObj
,
155 DCDest
->rosdc
.CombinedClip
,
161 EXLATEOBJ_vCleanup(&exlo
);
163 if (hDCSrc
!= hDCDest
)
180 IN DWORD crBackColor
,
185 PDC_ATTR pdcattr
= NULL
;
186 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
191 XLATEOBJ
*XlateObj
= NULL
;
192 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
194 DCDest
= DC_LockDc(hDCDest
);
197 DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest
);
201 if (DCDest
->dctype
== DC_TYPE_INFO
)
204 /* Yes, Windows really returns TRUE in this case */
210 if (hDCSrc
!= hDCDest
)
212 DCSrc
= DC_LockDc(hDCSrc
);
216 DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc
);
219 if (DCSrc
->dctype
== DC_TYPE_INFO
)
223 /* Yes, Windows really returns TRUE in this case */
233 pdcattr
= DCDest
->pdcattr
;
235 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
236 DC_vUpdateFillBrush(DCDest
);
238 DestRect
.left
= XDest
;
239 DestRect
.top
= YDest
;
240 DestRect
.right
= XDest
+Width
;
241 DestRect
.bottom
= YDest
+Height
;
242 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
244 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
245 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
246 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
247 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
249 SourcePoint
.x
= XSrc
;
250 SourcePoint
.y
= YSrc
;
254 IntLPtoDP(DCSrc
, (LPPOINT
)&SourcePoint
, 1);
256 SourcePoint
.x
+= DCSrc
->ptlDCOrig
.x
;
257 SourcePoint
.y
+= DCSrc
->ptlDCOrig
.y
;
260 /* Determine surfaces to be used in the bitblt */
261 BitmapDest
= DCDest
->dclevel
.pSurface
;
268 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
274 /* Create the XLATEOBJ. */
277 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
278 XlateObj
= &exlo
.xlo
;
281 /* Perform the bitblt operation */
282 Status
= IntEngBitBlt(&BitmapDest
->SurfObj
,
283 BitmapSrc
? &BitmapSrc
->SurfObj
: NULL
,
285 DCDest
->rosdc
.CombinedClip
,
290 &DCDest
->eboFill
.BrushObject
,
291 &DCDest
->dclevel
.pbrFill
->ptOrigin
,
296 EXLATEOBJ_vCleanup(&exlo
);
297 if (UsesSource
&& hDCSrc
!= hDCDest
)
322 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
323 HPALETTE SourcePalette
= 0, DestPalette
= 0;
324 PPALETTE PalDestGDI
, PalSourceGDI
;
325 USHORT PalDestMode
, PalSrcMode
;
326 ULONG TransparentColor
= 0;
330 if(!(DCDest
= DC_LockDc(hdcDst
)))
332 DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcDst
);
333 SetLastWin32Error(ERROR_INVALID_HANDLE
);
336 if (DCDest
->dctype
== DC_TYPE_INFO
)
339 /* Yes, Windows really returns TRUE in this case */
343 if((hdcDst
!= hdcSrc
) && !(DCSrc
= DC_LockDc(hdcSrc
)))
346 DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcSrc
);
347 SetLastWin32Error(ERROR_INVALID_HANDLE
);
356 if (DCSrc
->dctype
== DC_TYPE_INFO
)
363 /* Yes, Windows really returns TRUE in this case */
367 BitmapDest
= DCDest
->dclevel
.pSurface
;
373 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
379 DestPalette
= BitmapDest
->hDIBPalette
;
380 if (!DestPalette
) DestPalette
= pPrimarySurface
->devinfo
.hpalDefault
;
382 SourcePalette
= BitmapSrc
->hDIBPalette
;
383 if (!SourcePalette
) SourcePalette
= pPrimarySurface
->devinfo
.hpalDefault
;
385 if(!(PalSourceGDI
= PALETTE_LockPalette(SourcePalette
)))
387 SetLastWin32Error(ERROR_INVALID_HANDLE
);
390 PalSrcMode
= PalSourceGDI
->Mode
;
391 PALETTE_UnlockPalette(PalSourceGDI
);
393 if(DestPalette
!= SourcePalette
)
395 if (!(PalDestGDI
= PALETTE_LockPalette(DestPalette
)))
397 SetLastWin32Error(ERROR_INVALID_HANDLE
);
400 PalDestMode
= PalDestGDI
->Mode
;
401 PALETTE_UnlockPalette(PalDestGDI
);
405 PalDestMode
= PalSrcMode
;
406 PalDestGDI
= PalSourceGDI
;
409 /* Translate Transparent (RGB) Color to the source palette */
410 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, PalSourceGDI
, 0, 0, 0);
411 TransparentColor
= XLATEOBJ_iXlate(&exlo
.xlo
, (ULONG
)TransColor
);
412 EXLATEOBJ_vCleanup(&exlo
);
414 EXLATEOBJ_vInitialize(&exlo
, PalSourceGDI
, PalDestGDI
, 0, 0, 0);
418 rcDest
.right
= rcDest
.left
+ cxDst
;
419 rcDest
.bottom
= rcDest
.top
+ cyDst
;
420 IntLPtoDP(DCDest
, (LPPOINT
)&rcDest
, 2);
422 rcDest
.left
+= DCDest
->ptlDCOrig
.x
;
423 rcDest
.top
+= DCDest
->ptlDCOrig
.y
;
424 rcDest
.right
+= DCDest
->ptlDCOrig
.x
;
425 rcDest
.bottom
+= DCDest
->ptlDCOrig
.y
;
429 rcSrc
.right
= rcSrc
.left
+ cxSrc
;
430 rcSrc
.bottom
= rcSrc
.top
+ cySrc
;
431 IntLPtoDP(DCSrc
, (LPPOINT
)&rcSrc
, 2);
433 rcSrc
.left
+= DCSrc
->ptlDCOrig
.x
;
434 rcSrc
.top
+= DCSrc
->ptlDCOrig
.y
;
435 rcSrc
.right
+= DCSrc
->ptlDCOrig
.x
;
436 rcSrc
.bottom
+= DCSrc
->ptlDCOrig
.y
;
438 Ret
= IntEngTransparentBlt(&BitmapDest
->SurfObj
, &BitmapSrc
->SurfObj
,
439 DCDest
->rosdc
.CombinedClip
, &exlo
.xlo
, &rcDest
, &rcSrc
,
440 TransparentColor
, 0);
448 EXLATEOBJ_vCleanup(&exlo
);
452 /***********************************************************************
454 * Ported from WINE by sedwards 11-4-03
456 * Someone thought it would be faster to do it here and then switch back
457 * to GDI32. I dunno. Write a test and let me know.
458 * A. It should be in here!
462 SwapROP3_SrcDst(BYTE bRop3
)
464 return (bRop3
& 0x99) | ((bRop3
& 0x22) << 1) | ((bRop3
& 0x44) >> 1);
467 #define FRGND_ROP3(ROP4) ((ROP4) & 0x00FFFFFF)
468 #define BKGND_ROP3(ROP4) (ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
469 #define DSTCOPY 0x00AA0029
470 #define DSTERASE 0x00220326 /* dest = dest & (~src) : DSna */
486 IN DWORD crBackColor
)
488 HBITMAP hOldMaskBitmap
, hBitmap2
, hOldBitmap2
, hBitmap3
, hOldBitmap3
;
489 HDC hDCMask
, hDC1
, hDC2
;
490 static const DWORD ROP3Table
[256] =
492 0x00000042, 0x00010289,
493 0x00020C89, 0x000300AA,
494 0x00040C88, 0x000500A9,
495 0x00060865, 0x000702C5,
496 0x00080F08, 0x00090245,
497 0x000A0329, 0x000B0B2A,
498 0x000C0324, 0x000D0B25,
499 0x000E08A5, 0x000F0001,
500 0x00100C85, 0x001100A6,
501 0x00120868, 0x001302C8,
502 0x00140869, 0x001502C9,
503 0x00165CCA, 0x00171D54,
504 0x00180D59, 0x00191CC8,
505 0x001A06C5, 0x001B0768,
506 0x001C06CA, 0x001D0766,
507 0x001E01A5, 0x001F0385,
508 0x00200F09, 0x00210248,
509 0x00220326, 0x00230B24,
510 0x00240D55, 0x00251CC5,
511 0x002606C8, 0x00271868,
512 0x00280369, 0x002916CA,
513 0x002A0CC9, 0x002B1D58,
514 0x002C0784, 0x002D060A,
515 0x002E064A, 0x002F0E2A,
516 0x0030032A, 0x00310B28,
517 0x00320688, 0x00330008,
518 0x003406C4, 0x00351864,
519 0x003601A8, 0x00370388,
520 0x0038078A, 0x00390604,
521 0x003A0644, 0x003B0E24,
522 0x003C004A, 0x003D18A4,
523 0x003E1B24, 0x003F00EA,
524 0x00400F0A, 0x00410249,
525 0x00420D5D, 0x00431CC4,
526 0x00440328, 0x00450B29,
527 0x004606C6, 0x0047076A,
528 0x00480368, 0x004916C5,
529 0x004A0789, 0x004B0605,
530 0x004C0CC8, 0x004D1954,
531 0x004E0645, 0x004F0E25,
532 0x00500325, 0x00510B26,
533 0x005206C9, 0x00530764,
534 0x005408A9, 0x00550009,
535 0x005601A9, 0x00570389,
536 0x00580785, 0x00590609,
537 0x005A0049, 0x005B18A9,
538 0x005C0649, 0x005D0E29,
539 0x005E1B29, 0x005F00E9,
540 0x00600365, 0x006116C6,
541 0x00620786, 0x00630608,
542 0x00640788, 0x00650606,
543 0x00660046, 0x006718A8,
544 0x006858A6, 0x00690145,
545 0x006A01E9, 0x006B178A,
546 0x006C01E8, 0x006D1785,
547 0x006E1E28, 0x006F0C65,
548 0x00700CC5, 0x00711D5C,
549 0x00720648, 0x00730E28,
550 0x00740646, 0x00750E26,
551 0x00761B28, 0x007700E6,
552 0x007801E5, 0x00791786,
553 0x007A1E29, 0x007B0C68,
554 0x007C1E24, 0x007D0C69,
555 0x007E0955, 0x007F03C9,
556 0x008003E9, 0x00810975,
557 0x00820C49, 0x00831E04,
558 0x00840C48, 0x00851E05,
559 0x008617A6, 0x008701C5,
560 0x008800C6, 0x00891B08,
561 0x008A0E06, 0x008B0666,
562 0x008C0E08, 0x008D0668,
563 0x008E1D7C, 0x008F0CE5,
564 0x00900C45, 0x00911E08,
565 0x009217A9, 0x009301C4,
566 0x009417AA, 0x009501C9,
567 0x00960169, 0x0097588A,
568 0x00981888, 0x00990066,
569 0x009A0709, 0x009B07A8,
570 0x009C0704, 0x009D07A6,
571 0x009E16E6, 0x009F0345,
572 0x00A000C9, 0x00A11B05,
573 0x00A20E09, 0x00A30669,
574 0x00A41885, 0x00A50065,
575 0x00A60706, 0x00A707A5,
576 0x00A803A9, 0x00A90189,
577 0x00AA0029, 0x00AB0889,
578 0x00AC0744, 0x00AD06E9,
579 0x00AE0B06, 0x00AF0229,
580 0x00B00E05, 0x00B10665,
581 0x00B21974, 0x00B30CE8,
582 0x00B4070A, 0x00B507A9,
583 0x00B616E9, 0x00B70348,
584 0x00B8074A, 0x00B906E6,
585 0x00BA0B09, 0x00BB0226,
586 0x00BC1CE4, 0x00BD0D7D,
587 0x00BE0269, 0x00BF08C9,
588 0x00C000CA, 0x00C11B04,
589 0x00C21884, 0x00C3006A,
590 0x00C40E04, 0x00C50664,
591 0x00C60708, 0x00C707AA,
592 0x00C803A8, 0x00C90184,
593 0x00CA0749, 0x00CB06E4,
594 0x00CC0020, 0x00CD0888,
595 0x00CE0B08, 0x00CF0224,
596 0x00D00E0A, 0x00D1066A,
597 0x00D20705, 0x00D307A4,
598 0x00D41D78, 0x00D50CE9,
599 0x00D616EA, 0x00D70349,
600 0x00D80745, 0x00D906E8,
601 0x00DA1CE9, 0x00DB0D75,
602 0x00DC0B04, 0x00DD0228,
603 0x00DE0268, 0x00DF08C8,
604 0x00E003A5, 0x00E10185,
605 0x00E20746, 0x00E306EA,
606 0x00E40748, 0x00E506E5,
607 0x00E61CE8, 0x00E70D79,
608 0x00E81D74, 0x00E95CE6,
609 0x00EA02E9, 0x00EB0849,
610 0x00EC02E8, 0x00ED0848,
611 0x00EE0086, 0x00EF0A08,
612 0x00F00021, 0x00F10885,
613 0x00F20B05, 0x00F3022A,
614 0x00F40B0A, 0x00F50225,
615 0x00F60265, 0x00F708C5,
616 0x00F802E5, 0x00F90845,
617 0x00FA0089, 0x00FB0A09,
618 0x00FC008A, 0x00FD0A0A,
619 0x00FE02A9, 0x00FF0062,
623 return NtGdiBitBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, FRGND_ROP3(dwRop
), 0, 0);
625 /* 1. make mask bitmap's dc */
626 hDCMask
= NtGdiCreateCompatibleDC(hdcDest
);
627 hOldMaskBitmap
= (HBITMAP
)NtGdiSelectBitmap(hDCMask
, hbmMask
);
629 /* 2. make masked Background bitmap */
631 /* 2.1 make bitmap */
632 hDC1
= NtGdiCreateCompatibleDC(hdcDest
);
633 hBitmap2
= NtGdiCreateCompatibleBitmap(hdcDest
, nWidth
, nHeight
);
634 hOldBitmap2
= (HBITMAP
)NtGdiSelectBitmap(hDC1
, hBitmap2
);
636 /* 2.2 draw dest bitmap and mask */
637 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, SRCCOPY
, 0, 0);
638 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hdcDest
, nXDest
, nYDest
, BKGND_ROP3(dwRop
), 0, 0);
639 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hDCMask
, xMask
, yMask
, DSTERASE
, 0, 0);
641 /* 3. make masked Foreground bitmap */
643 /* 3.1 make bitmap */
644 hDC2
= NtGdiCreateCompatibleDC(hdcDest
);
645 hBitmap3
= NtGdiCreateCompatibleBitmap(hdcDest
, nWidth
, nHeight
);
646 hOldBitmap3
= (HBITMAP
)NtGdiSelectBitmap(hDC2
, hBitmap3
);
648 /* 3.2 draw src bitmap and mask */
649 NtGdiBitBlt(hDC2
, 0, 0, nWidth
, nHeight
, hdcDest
, nXDest
, nYDest
, SRCCOPY
, 0, 0);
650 NtGdiBitBlt(hDC2
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, FRGND_ROP3(dwRop
), 0,0);
651 NtGdiBitBlt(hDC2
, 0, 0, nWidth
, nHeight
, hDCMask
, xMask
, yMask
, SRCAND
, 0, 0);
653 /* 4. combine both and copy the result to hdcDest */
654 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hDC2
, 0, 0, SRCPAINT
, 0, 0);
655 NtGdiBitBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hDC1
, 0, 0, SRCCOPY
, 0, 0);
657 /* 5. restore all objects */
658 NtGdiSelectBitmap(hDCMask
, hOldMaskBitmap
);
659 NtGdiSelectBitmap(hDC1
, hOldBitmap2
);
660 NtGdiSelectBitmap(hDC2
, hOldBitmap3
);
662 /* 6. delete all temp objects */
663 GreDeleteObject(hBitmap2
);
664 GreDeleteObject(hBitmap3
);
666 NtGdiDeleteObjectApp(hDC1
);
667 NtGdiDeleteObjectApp(hDC2
);
668 NtGdiDeleteObjectApp(hDCMask
);
686 IN DWORD crBackColor
)
705 IN DWORD dwBackColor
,
712 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
713 SURFACE
*BitmapMask
= NULL
;
718 XLATEOBJ
*XlateObj
= NULL
;
720 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
722 if (0 == WidthDest
|| 0 == HeightDest
|| 0 == WidthSrc
|| 0 == HeightSrc
)
724 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
728 DCDest
= DC_LockDc(hDCDest
);
731 DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCDest
);
732 SetLastWin32Error(ERROR_INVALID_HANDLE
);
736 if (DCDest
->dctype
== DC_TYPE_INFO
)
739 /* Yes, Windows really returns TRUE in this case */
745 if (hDCSrc
!= hDCDest
)
747 DCSrc
= DC_LockDc(hDCSrc
);
751 DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCSrc
);
752 SetLastWin32Error(ERROR_INVALID_HANDLE
);
755 if (DCSrc
->dctype
== DC_TYPE_INFO
)
759 /* Yes, Windows really returns TRUE in this case */
769 pdcattr
= DCDest
->pdcattr
;
771 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
772 DC_vUpdateFillBrush(DCDest
);
774 DestRect
.left
= XOriginDest
;
775 DestRect
.top
= YOriginDest
;
776 DestRect
.right
= XOriginDest
+WidthDest
;
777 DestRect
.bottom
= YOriginDest
+HeightDest
;
778 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
780 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
781 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
782 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
783 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
785 SourceRect
.left
= XOriginSrc
;
786 SourceRect
.top
= YOriginSrc
;
787 SourceRect
.right
= XOriginSrc
+WidthSrc
;
788 SourceRect
.bottom
= YOriginSrc
+HeightSrc
;
792 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
794 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
795 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
796 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
797 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
803 /* Determine surfaces to be used in the bitblt */
804 BitmapDest
= DCDest
->dclevel
.pSurface
;
805 if (BitmapDest
== NULL
)
809 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
810 if (BitmapSrc
== NULL
)
813 /* Create the XLATEOBJ. */
814 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
815 XlateObj
= &exlo
.xlo
;
818 /* Offset the brush */
819 BrushOrigin
.x
+= DCDest
->ptlDCOrig
.x
;
820 BrushOrigin
.y
+= DCDest
->ptlDCOrig
.y
;
822 /* Make mask surface for source surface */
823 if (BitmapSrc
&& hDCMask
)
825 DCMask
= DC_LockDc(hDCMask
);
828 BitmapMask
= DCMask
->dclevel
.pSurface
;
830 (BitmapMask
->SurfObj
.sizlBitmap
.cx
!= WidthSrc
||
831 BitmapMask
->SurfObj
.sizlBitmap
.cy
!= HeightSrc
))
833 DPRINT1("Mask and bitmap sizes don't match!\n");
839 /* Perform the bitblt operation */
840 Status
= IntEngStretchBlt(&BitmapDest
->SurfObj
,
842 BitmapMask
? &BitmapMask
->SurfObj
: NULL
,
843 DCDest
->rosdc
.CombinedClip
,
848 &DCDest
->eboFill
.BrushObject
,
855 EXLATEOBJ_vCleanup(&exlo
);
857 if (UsesSource
&& hDCSrc
!= hDCDest
)
884 IN DWORD dwBackColor
)
886 return GreStretchBltMask(
921 psurf
= pdc
->dclevel
.pSurface
;
924 SetLastWin32Error(ERROR_INVALID_HANDLE
);
928 if (pbrush
->flAttrs
& GDIBRUSH_IS_NULL
)
935 DestRect
.left
= XLeft
;
936 DestRect
.right
= XLeft
+ Width
;
940 DestRect
.left
= XLeft
+ Width
+ 1;
941 DestRect
.right
= XLeft
+ 1;
946 DestRect
.top
= YLeft
;
947 DestRect
.bottom
= YLeft
+ Height
;
951 DestRect
.top
= YLeft
+ Height
+ 1;
952 DestRect
.bottom
= YLeft
+ 1;
955 IntLPtoDP(pdc
, (LPPOINT
)&DestRect
, 2);
957 DestRect
.left
+= pdc
->ptlDCOrig
.x
;
958 DestRect
.top
+= pdc
->ptlDCOrig
.y
;
959 DestRect
.right
+= pdc
->ptlDCOrig
.x
;
960 DestRect
.bottom
+= pdc
->ptlDCOrig
.y
;
962 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
;
963 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
;
965 EBRUSHOBJ_vInit(&eboFill
, pbrush
, pdc
);
971 pdc
->rosdc
.CombinedClip
,
976 &eboFill
.BrushObject
, // use pDC->eboFill
978 ROP3_TO_ROP4(dwRop
));
980 EBRUSHOBJ_vCleanup(&eboFill
);
997 pdc
= DC_LockDc(hDC
);
1000 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1004 if (pdc
->dctype
== DC_TYPE_INFO
)
1007 /* Yes, Windows really returns TRUE in this case */
1011 for (i
= 0; i
< cRects
; i
++)
1013 pbrush
= BRUSH_LockBrush(pRects
->hBrush
);
1024 BRUSH_UnlockBrush(pbrush
);
1049 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
1052 /* in this case we call on GdiMaskBlt */
1053 return NtGdiMaskBlt(hDC
, XLeft
, YLeft
, Width
, Height
, 0,0,0,0,0,0,ROP
,0);
1056 dc
= DC_LockDc(hDC
);
1059 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1062 if (dc
->dctype
== DC_TYPE_INFO
)
1065 /* Yes, Windows really returns TRUE in this case */
1069 pdcattr
= dc
->pdcattr
;
1071 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
1072 DC_vUpdateFillBrush(dc
);
1074 pbrush
= BRUSH_LockBrush(pdcattr
->hbrush
);
1077 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1082 ret
= IntPatBlt(dc
, XLeft
, YLeft
, Width
, Height
, ROP
, pbrush
);
1084 BRUSH_UnlockBrush(pbrush
);
1094 IN PPOLYPATBLT pRects
,
1099 NTSTATUS Status
= STATUS_SUCCESS
;
1104 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, TAG_PATBLT
);
1107 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
1112 ProbeForRead(pRects
,
1113 cRects
* sizeof(PATRECT
),
1117 cRects
* sizeof(PATRECT
));
1119 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1121 Status
= _SEH2_GetExceptionCode();
1125 if (!NT_SUCCESS(Status
))
1127 ExFreePoolWithTag(rb
, TAG_PATBLT
);
1128 SetLastNtError(Status
);
1133 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, rb
, cRects
, Mode
);
1136 ExFreePoolWithTag(rb
, TAG_PATBLT
);