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
,
714 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
715 SURFACE
*BitmapMask
= NULL
;
721 XLATEOBJ
*XlateObj
= NULL
;
723 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
725 if (0 == WidthDest
|| 0 == HeightDest
|| 0 == WidthSrc
|| 0 == HeightSrc
)
727 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
731 DCDest
= DC_LockDc(hDCDest
);
734 DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCDest
);
735 SetLastWin32Error(ERROR_INVALID_HANDLE
);
739 if (DCDest
->dctype
== DC_TYPE_INFO
)
742 /* Yes, Windows really returns TRUE in this case */
748 if (hDCSrc
!= hDCDest
)
750 DCSrc
= DC_LockDc(hDCSrc
);
754 DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCSrc
);
755 SetLastWin32Error(ERROR_INVALID_HANDLE
);
758 if (DCSrc
->dctype
== DC_TYPE_INFO
)
762 /* Yes, Windows really returns TRUE in this case */
772 pdcattr
= DCDest
->pdcattr
;
774 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
775 DC_vUpdateFillBrush(DCDest
);
777 DestRect
.left
= XOriginDest
;
778 DestRect
.top
= YOriginDest
;
779 DestRect
.right
= XOriginDest
+WidthDest
;
780 DestRect
.bottom
= YOriginDest
+HeightDest
;
781 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
783 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
784 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
785 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
786 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
788 SourceRect
.left
= XOriginSrc
;
789 SourceRect
.top
= YOriginSrc
;
790 SourceRect
.right
= XOriginSrc
+WidthSrc
;
791 SourceRect
.bottom
= YOriginSrc
+HeightSrc
;
795 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
797 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
798 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
799 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
800 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
806 /* Determine surfaces to be used in the bitblt */
807 BitmapDest
= DCDest
->dclevel
.pSurface
;
808 if (BitmapDest
== NULL
)
812 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
813 if (BitmapSrc
== NULL
)
816 /* Create the XLATEOBJ. */
817 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
818 XlateObj
= &exlo
.xlo
;
821 /* Offset the brush */
822 BrushOrigin
.x
+= DCDest
->ptlDCOrig
.x
;
823 BrushOrigin
.y
+= DCDest
->ptlDCOrig
.y
;
825 /* Make mask surface for source surface */
826 if (BitmapSrc
&& hDCMask
)
828 DCMask
= DC_LockDc(hDCMask
);
831 BitmapMask
= DCMask
->dclevel
.pSurface
;
833 (BitmapMask
->SurfObj
.sizlBitmap
.cx
< WidthSrc
||
834 BitmapMask
->SurfObj
.sizlBitmap
.cy
< HeightSrc
))
836 DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
837 BitmapMask
->SurfObj
.sizlBitmap
.cx
, BitmapMask
->SurfObj
.sizlBitmap
.cy
,
838 WidthSrc
, HeightSrc
);
841 /* Create mask offset point */
842 MaskPoint
.x
= XOriginMask
;
843 MaskPoint
.y
= YOriginMask
;
844 IntLPtoDP(DCMask
, &MaskPoint
, 1);
845 MaskPoint
.x
+= DCMask
->ptlDCOrig
.x
;
846 MaskPoint
.y
+= DCMask
->ptlDCOrig
.x
;
850 /* Perform the bitblt operation */
851 Status
= IntEngStretchBlt(&BitmapDest
->SurfObj
,
853 BitmapMask
? &BitmapMask
->SurfObj
: NULL
,
854 DCDest
->rosdc
.CombinedClip
,
858 BitmapMask
? &MaskPoint
: NULL
,
859 &DCDest
->eboFill
.BrushObject
,
866 EXLATEOBJ_vCleanup(&exlo
);
868 if (UsesSource
&& hDCSrc
!= hDCDest
)
895 IN DWORD dwBackColor
)
897 return GreStretchBltMask(
934 psurf
= pdc
->dclevel
.pSurface
;
937 SetLastWin32Error(ERROR_INVALID_HANDLE
);
941 if (pbrush
->flAttrs
& GDIBRUSH_IS_NULL
)
948 DestRect
.left
= XLeft
;
949 DestRect
.right
= XLeft
+ Width
;
953 DestRect
.left
= XLeft
+ Width
+ 1;
954 DestRect
.right
= XLeft
+ 1;
959 DestRect
.top
= YLeft
;
960 DestRect
.bottom
= YLeft
+ Height
;
964 DestRect
.top
= YLeft
+ Height
+ 1;
965 DestRect
.bottom
= YLeft
+ 1;
968 IntLPtoDP(pdc
, (LPPOINT
)&DestRect
, 2);
970 DestRect
.left
+= pdc
->ptlDCOrig
.x
;
971 DestRect
.top
+= pdc
->ptlDCOrig
.y
;
972 DestRect
.right
+= pdc
->ptlDCOrig
.x
;
973 DestRect
.bottom
+= pdc
->ptlDCOrig
.y
;
975 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
;
976 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
;
978 EBRUSHOBJ_vInit(&eboFill
, pbrush
, pdc
);
984 pdc
->rosdc
.CombinedClip
,
989 &eboFill
.BrushObject
, // use pDC->eboFill
991 ROP3_TO_ROP4(dwRop
));
993 EBRUSHOBJ_vCleanup(&eboFill
);
1010 pdc
= DC_LockDc(hDC
);
1013 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1017 if (pdc
->dctype
== DC_TYPE_INFO
)
1020 /* Yes, Windows really returns TRUE in this case */
1024 for (i
= 0; i
< cRects
; i
++)
1026 pbrush
= BRUSH_LockBrush(pRects
->hBrush
);
1037 BRUSH_UnlockBrush(pbrush
);
1062 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
1065 /* in this case we call on GdiMaskBlt */
1066 return NtGdiMaskBlt(hDC
, XLeft
, YLeft
, Width
, Height
, 0,0,0,0,0,0,ROP
,0);
1069 dc
= DC_LockDc(hDC
);
1072 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1075 if (dc
->dctype
== DC_TYPE_INFO
)
1078 /* Yes, Windows really returns TRUE in this case */
1082 pdcattr
= dc
->pdcattr
;
1084 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
1085 DC_vUpdateFillBrush(dc
);
1087 pbrush
= BRUSH_LockBrush(pdcattr
->hbrush
);
1090 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1095 ret
= IntPatBlt(dc
, XLeft
, YLeft
, Width
, Height
, ROP
, pbrush
);
1097 BRUSH_UnlockBrush(pbrush
);
1107 IN PPOLYPATBLT pRects
,
1112 NTSTATUS Status
= STATUS_SUCCESS
;
1117 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, TAG_PATBLT
);
1120 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
1125 ProbeForRead(pRects
,
1126 cRects
* sizeof(PATRECT
),
1130 cRects
* sizeof(PATRECT
));
1132 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1134 Status
= _SEH2_GetExceptionCode();
1138 if (!NT_SUCCESS(Status
))
1140 ExFreePoolWithTag(rb
, TAG_PATBLT
);
1141 SetLastNtError(Status
);
1146 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, rb
, cRects
, Mode
);
1149 ExFreePoolWithTag(rb
, TAG_PATBLT
);