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
,
295 EXLATEOBJ_vCleanup(&exlo
);
297 if (UsesSource
&& hDCSrc
!= hDCDest
)
322 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
323 HPALETTE SourcePalette
= 0, DestPalette
= 0;
324 PPALETTE PalDestGDI
, PalSourceGDI
;
325 ULONG TransparentColor
= 0;
329 if(!(DCDest
= DC_LockDc(hdcDst
)))
331 DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcDst
);
332 SetLastWin32Error(ERROR_INVALID_HANDLE
);
335 if (DCDest
->dctype
== DC_TYPE_INFO
)
338 /* Yes, Windows really returns TRUE in this case */
342 if((hdcDst
!= hdcSrc
) && !(DCSrc
= DC_LockDc(hdcSrc
)))
345 DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcSrc
);
346 SetLastWin32Error(ERROR_INVALID_HANDLE
);
355 if (DCSrc
->dctype
== DC_TYPE_INFO
)
362 /* Yes, Windows really returns TRUE in this case */
366 BitmapDest
= DCDest
->dclevel
.pSurface
;
372 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
378 DestPalette
= BitmapDest
->hDIBPalette
;
379 if (!DestPalette
) DestPalette
= pPrimarySurface
->devinfo
.hpalDefault
;
381 SourcePalette
= BitmapSrc
->hDIBPalette
;
382 if (!SourcePalette
) SourcePalette
= pPrimarySurface
->devinfo
.hpalDefault
;
384 if(!(PalSourceGDI
= PALETTE_LockPalette(SourcePalette
)))
386 SetLastWin32Error(ERROR_INVALID_HANDLE
);
389 PALETTE_UnlockPalette(PalSourceGDI
);
391 if(DestPalette
!= SourcePalette
)
393 if (!(PalDestGDI
= PALETTE_LockPalette(DestPalette
)))
395 SetLastWin32Error(ERROR_INVALID_HANDLE
);
398 PALETTE_UnlockPalette(PalDestGDI
);
402 PalDestGDI
= PalSourceGDI
;
405 /* Translate Transparent (RGB) Color to the source palette */
406 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, PalSourceGDI
, 0, 0, 0);
407 TransparentColor
= XLATEOBJ_iXlate(&exlo
.xlo
, (ULONG
)TransColor
);
408 EXLATEOBJ_vCleanup(&exlo
);
410 EXLATEOBJ_vInitialize(&exlo
, PalSourceGDI
, PalDestGDI
, 0, 0, 0);
414 rcDest
.right
= rcDest
.left
+ cxDst
;
415 rcDest
.bottom
= rcDest
.top
+ cyDst
;
416 IntLPtoDP(DCDest
, (LPPOINT
)&rcDest
, 2);
418 rcDest
.left
+= DCDest
->ptlDCOrig
.x
;
419 rcDest
.top
+= DCDest
->ptlDCOrig
.y
;
420 rcDest
.right
+= DCDest
->ptlDCOrig
.x
;
421 rcDest
.bottom
+= DCDest
->ptlDCOrig
.y
;
425 rcSrc
.right
= rcSrc
.left
+ cxSrc
;
426 rcSrc
.bottom
= rcSrc
.top
+ cySrc
;
427 IntLPtoDP(DCSrc
, (LPPOINT
)&rcSrc
, 2);
429 rcSrc
.left
+= DCSrc
->ptlDCOrig
.x
;
430 rcSrc
.top
+= DCSrc
->ptlDCOrig
.y
;
431 rcSrc
.right
+= DCSrc
->ptlDCOrig
.x
;
432 rcSrc
.bottom
+= DCSrc
->ptlDCOrig
.y
;
434 Ret
= IntEngTransparentBlt(&BitmapDest
->SurfObj
, &BitmapSrc
->SurfObj
,
435 DCDest
->rosdc
.CombinedClip
, &exlo
.xlo
, &rcDest
, &rcSrc
,
436 TransparentColor
, 0);
444 EXLATEOBJ_vCleanup(&exlo
);
448 /***********************************************************************
450 * Ported from WINE by sedwards 11-4-03
452 * Someone thought it would be faster to do it here and then switch back
453 * to GDI32. I dunno. Write a test and let me know.
454 * A. It should be in here!
457 static const DWORD ROP3Table
[256] =
459 0x000042, 0x010289, 0x020C89, 0x0300AA, 0x040C88, 0x0500A9, 0x060865, 0x0702C5,
460 0x080F08, 0x090245, 0x0A0329, 0x0B0B2A, 0x0C0324, 0x0D0B25, 0x0E08A5, 0x0F0001,
461 0x100C85, 0x1100A6, 0x120868, 0x1302C8, 0x140869, 0x1502C9, 0x165CCA, 0x171D54,
462 0x180D59, 0x191CC8, 0x1A06C5, 0x1B0768, 0x1C06CA, 0x1D0766, 0x1E01A5, 0x1F0385,
463 0x200F09, 0x210248, 0x220326, 0x230B24, 0x240D55, 0x251CC5, 0x2606C8, 0x271868,
464 0x280369, 0x2916CA, 0x2A0CC9, 0x2B1D58, 0x2C0784, 0x2D060A, 0x2E064A, 0x2F0E2A,
465 0x30032A, 0x310B28, 0x320688, 0x330008, 0x3406C4, 0x351864, 0x3601A8, 0x370388,
466 0x38078A, 0x390604, 0x3A0644, 0x3B0E24, 0x3C004A, 0x3D18A4, 0x3E1B24, 0x3F00EA,
467 0x400F0A, 0x410249, 0x420D5D, 0x431CC4, 0x440328, 0x450B29, 0x4606C6, 0x47076A,
468 0x480368, 0x4916C5, 0x4A0789, 0x4B0605, 0x4C0CC8, 0x4D1954, 0x4E0645, 0x4F0E25,
469 0x500325, 0x510B26, 0x5206C9, 0x530764, 0x5408A9, 0x550009, 0x5601A9, 0x570389,
470 0x580785, 0x590609, 0x5A0049, 0x5B18A9, 0x5C0649, 0x5D0E29, 0x5E1B29, 0x5F00E9,
471 0x600365, 0x6116C6, 0x620786, 0x630608, 0x640788, 0x650606, 0x660046, 0x6718A8,
472 0x6858A6, 0x690145, 0x6A01E9, 0x6B178A, 0x6C01E8, 0x6D1785, 0x6E1E28, 0x6F0C65,
473 0x700CC5, 0x711D5C, 0x720648, 0x730E28, 0x740646, 0x750E26, 0x761B28, 0x7700E6,
474 0x7801E5, 0x791786, 0x7A1E29, 0x7B0C68, 0x7C1E24, 0x7D0C69, 0x7E0955, 0x7F03C9,
475 0x8003E9, 0x810975, 0x820C49, 0x831E04, 0x840C48, 0x851E05, 0x8617A6, 0x8701C5,
476 0x8800C6, 0x891B08, 0x8A0E06, 0x8B0666, 0x8C0E08, 0x8D0668, 0x8E1D7C, 0x8F0CE5,
477 0x900C45, 0x911E08, 0x9217A9, 0x9301C4, 0x9417AA, 0x9501C9, 0x960169, 0x97588A,
478 0x981888, 0x990066, 0x9A0709, 0x9B07A8, 0x9C0704, 0x9D07A6, 0x9E16E6, 0x9F0345,
479 0xA000C9, 0xA11B05, 0xA20E09, 0xA30669, 0xA41885, 0xA50065, 0xA60706, 0xA707A5,
480 0xA803A9, 0xA90189, 0xAA0029, 0xAB0889, 0xAC0744, 0xAD06E9, 0xAE0B06, 0xAF0229,
481 0xB00E05, 0xB10665, 0xB21974, 0xB30CE8, 0xB4070A, 0xB507A9, 0xB616E9, 0xB70348,
482 0xB8074A, 0xB906E6, 0xBA0B09, 0xBB0226, 0xBC1CE4, 0xBD0D7D, 0xBE0269, 0xBF08C9,
483 0xC000CA, 0xC11B04, 0xC21884, 0xC3006A, 0xC40E04, 0xC50664, 0xC60708, 0xC707AA,
484 0xC803A8, 0xC90184, 0xCA0749, 0xCB06E4, 0xCC0020, 0xCD0888, 0xCE0B08, 0xCF0224,
485 0xD00E0A, 0xD1066A, 0xD20705, 0xD307A4, 0xD41D78, 0xD50CE9, 0xD616EA, 0xD70349,
486 0xD80745, 0xD906E8, 0xDA1CE9, 0xDB0D75, 0xDC0B04, 0xDD0228, 0xDE0268, 0xDF08C8,
487 0xE003A5, 0xE10185, 0xE20746, 0xE306EA, 0xE40748, 0xE506E5, 0xE61CE8, 0xE70D79,
488 0xE81D74, 0xE95CE6, 0xEA02E9, 0xEB0849, 0xEC02E8, 0xED0848, 0xEE0086, 0xEF0A08,
489 0xF00021, 0xF10885, 0xF20B05, 0xF3022A, 0xF40B0A, 0xF50225, 0xF60265, 0xF708C5,
490 0xF802E5, 0xF90845, 0xFA0089, 0xFB0A09, 0xFC008A, 0xFD0A0A, 0xFE02A9, 0xFF0062,
494 SwapROP3_SrcDst(BYTE bRop3
)
496 return (bRop3
& 0x99) | ((bRop3
& 0x22) << 1) | ((bRop3
& 0x44) >> 1);
499 #define FRGND_ROP3(ROP4) ((ROP4) & 0x00FFFFFF)
500 #define BKGND_ROP3(ROP4) (ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
501 #define DSTCOPY 0x00AA0029
502 #define DSTERASE 0x00220326 /* dest = dest & (~src) : DSna */
504 /* NOTE: An alternative algorithm could use a pattern brush, created from
505 * the mask bitmap and then use raster operation 0xCA to combine the fore
506 * and background bitmaps. In this case erasing the bits beforehand would be
507 * unneccessary. On the other hand the Operation does not provide an optimized
508 * version in the DIB code, while SRCAND and SRCPAINT do.
509 * A fully correct implementation would call Eng/DrvBitBlt, but our
510 * EngBitBlt completely ignores the mask surface.
514 * ------------------------------------------
515 * 0 0 0 0 0000xax = 000ax = 00x = 0
516 * 0 0 1 1 1001xax = 101ax = 10x = 1
517 * 0 1 0 0 0010xax = 001ax = 00x = 0
518 * 0 1 1 1 1011xax = 100ax = 10x = 1
519 * 1 0 0 0 0100xax = 010ax = 00x = 0
520 * 1 0 1 0 1101xax = 111ax = 11x = 0
521 * 1 1 0 1 0110xax = 011ax = 01x = 1
522 * 1 1 1 1 1111xax = 110ax = 10x = 1
524 * Operation index = 11001010 = 0xCA = PSaDPnao = DPSDxax
525 * ^ no, this is not random letters, its reverse Polish notation
542 IN DWORD crBackColor
)
544 HBITMAP hbmFore
, hbmBack
;
545 HDC hdcMask
, hdcFore
, hdcBack
;
548 COLORREF crFore
, crBack
;
551 return NtGdiBitBlt(hdcDest
,
563 /* Lock the dest DC */
564 pdc
= DC_LockDc(hdcDest
);
565 if (!pdc
) return FALSE
;
567 /* Get brush and colors from dest dc */
568 hbr
= pdc
->pdcattr
->hbrush
;
569 crFore
= pdc
->pdcattr
->crForegroundClr
;
570 crBack
= pdc
->pdcattr
->crBackgroundClr
;
575 /* 1. Create mask bitmap's dc */
576 hdcMask
= NtGdiCreateCompatibleDC(hdcDest
);
577 NtGdiSelectBitmap(hdcMask
, hbmMask
);
579 /* 2. Create masked Background bitmap */
581 /* 2.1 Create bitmap */
582 hdcBack
= NtGdiCreateCompatibleDC(hdcDest
);
583 hbmBack
= NtGdiCreateCompatibleBitmap(hdcDest
, nWidth
, nHeight
);
584 NtGdiSelectBitmap(hdcBack
, hbmBack
);
586 /* 2.2 Copy source bitmap */
587 NtGdiSelectBrush(hdcBack
, hbr
);
588 IntGdiSetBkColor(hdcBack
, crBack
);
589 IntGdiSetTextColor(hdcBack
, crFore
);
590 NtGdiBitBlt(hdcBack
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, SRCCOPY
, 0, 0);
592 /* 2.3 Do the background rop */
593 NtGdiBitBlt(hdcBack
, 0, 0, nWidth
, nHeight
, hdcDest
, nXDest
, nYDest
, BKGND_ROP3(dwRop
), 0, 0);
595 /* 2.4 Erase the foreground pixels */
596 IntGdiSetBkColor(hdcBack
, 0xffffffff);
597 IntGdiSetTextColor(hdcBack
, 0);
598 NtGdiBitBlt(hdcBack
, 0, 0, nWidth
, nHeight
, hdcMask
, xMask
, yMask
, SRCAND
, 0, 0);
600 /* 3. Create masked Foreground bitmap */
602 /* 3.1 Create bitmap */
603 hdcFore
= NtGdiCreateCompatibleDC(hdcDest
);
604 hbmFore
= NtGdiCreateCompatibleBitmap(hdcDest
, nWidth
, nHeight
);
605 NtGdiSelectBitmap(hdcFore
, hbmFore
);
607 /* 3.2 Copy the dest bitmap */
608 NtGdiSelectBrush(hdcFore
, hbr
);
609 IntGdiSetBkColor(hdcFore
, crBack
);
610 IntGdiSetTextColor(hdcFore
, crFore
);
611 NtGdiBitBlt(hdcFore
, 0, 0, nWidth
, nHeight
, hdcDest
, nXDest
, nYDest
, SRCCOPY
, 0, 0);
613 /* 2.3 Do the foreground rop */
614 NtGdiBitBlt(hdcFore
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, FRGND_ROP3(dwRop
), 0,0);
616 /* 2.4 Erase the background pixels */
617 IntGdiSetBkColor(hdcFore
, 0);
618 IntGdiSetTextColor(hdcFore
, 0xffffffff);
619 NtGdiBitBlt(hdcFore
, 0, 0, nWidth
, nHeight
, hdcMask
, xMask
, yMask
, SRCAND
, 0, 0);
621 /* 3. Combine the fore and background into the background bitmap */
622 NtGdiBitBlt(hdcBack
, 0, 0, nWidth
, nHeight
, hdcFore
, 0, 0, SRCPAINT
, 0, 0);
624 /* 4. Copy the result to hdcDest */
625 NtGdiBitBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hdcBack
, 0, 0, SRCCOPY
, 0, 0);
627 /* 5. delete all temp objects */
628 NtGdiDeleteObjectApp(hdcBack
);
629 NtGdiDeleteObjectApp(hdcFore
);
630 NtGdiDeleteObjectApp(hdcMask
);
631 GreDeleteObject(hbmFore
);
632 GreDeleteObject(hbmBack
);
650 IN DWORD crBackColor
)
669 IN DWORD dwBackColor
,
678 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
679 SURFACE
*BitmapMask
= NULL
;
685 XLATEOBJ
*XlateObj
= NULL
;
687 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
689 if (0 == WidthDest
|| 0 == HeightDest
|| 0 == WidthSrc
|| 0 == HeightSrc
)
691 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
695 DCDest
= DC_LockDc(hDCDest
);
698 DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCDest
);
699 SetLastWin32Error(ERROR_INVALID_HANDLE
);
703 if (DCDest
->dctype
== DC_TYPE_INFO
)
706 /* Yes, Windows really returns TRUE in this case */
712 if (hDCSrc
!= hDCDest
)
714 DCSrc
= DC_LockDc(hDCSrc
);
718 DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCSrc
);
719 SetLastWin32Error(ERROR_INVALID_HANDLE
);
722 if (DCSrc
->dctype
== DC_TYPE_INFO
)
726 /* Yes, Windows really returns TRUE in this case */
736 pdcattr
= DCDest
->pdcattr
;
738 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
739 DC_vUpdateFillBrush(DCDest
);
741 DestRect
.left
= XOriginDest
;
742 DestRect
.top
= YOriginDest
;
743 DestRect
.right
= XOriginDest
+WidthDest
;
744 DestRect
.bottom
= YOriginDest
+HeightDest
;
745 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
747 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
748 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
749 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
750 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
752 SourceRect
.left
= XOriginSrc
;
753 SourceRect
.top
= YOriginSrc
;
754 SourceRect
.right
= XOriginSrc
+WidthSrc
;
755 SourceRect
.bottom
= YOriginSrc
+HeightSrc
;
759 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
761 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
762 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
763 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
764 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
770 /* Determine surfaces to be used in the bitblt */
771 BitmapDest
= DCDest
->dclevel
.pSurface
;
772 if (BitmapDest
== NULL
)
776 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
777 if (BitmapSrc
== NULL
)
780 /* Create the XLATEOBJ. */
781 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
782 XlateObj
= &exlo
.xlo
;
785 /* Offset the brush */
786 BrushOrigin
.x
+= DCDest
->ptlDCOrig
.x
;
787 BrushOrigin
.y
+= DCDest
->ptlDCOrig
.y
;
789 /* Make mask surface for source surface */
790 if (BitmapSrc
&& hDCMask
)
792 DCMask
= DC_LockDc(hDCMask
);
795 BitmapMask
= DCMask
->dclevel
.pSurface
;
797 (BitmapMask
->SurfObj
.sizlBitmap
.cx
< WidthSrc
||
798 BitmapMask
->SurfObj
.sizlBitmap
.cy
< HeightSrc
))
800 DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
801 BitmapMask
->SurfObj
.sizlBitmap
.cx
, BitmapMask
->SurfObj
.sizlBitmap
.cy
,
802 WidthSrc
, HeightSrc
);
805 /* Create mask offset point */
806 MaskPoint
.x
= XOriginMask
;
807 MaskPoint
.y
= YOriginMask
;
808 IntLPtoDP(DCMask
, &MaskPoint
, 1);
809 MaskPoint
.x
+= DCMask
->ptlDCOrig
.x
;
810 MaskPoint
.y
+= DCMask
->ptlDCOrig
.x
;
814 /* Perform the bitblt operation */
815 Status
= IntEngStretchBlt(&BitmapDest
->SurfObj
,
817 BitmapMask
? &BitmapMask
->SurfObj
: NULL
,
818 DCDest
->rosdc
.CombinedClip
,
822 BitmapMask
? &MaskPoint
: NULL
,
823 &DCDest
->eboFill
.BrushObject
,
830 EXLATEOBJ_vCleanup(&exlo
);
832 if (UsesSource
&& hDCSrc
!= hDCDest
)
859 IN DWORD dwBackColor
)
861 return GreStretchBltMask(
898 psurf
= pdc
->dclevel
.pSurface
;
901 SetLastWin32Error(ERROR_INVALID_HANDLE
);
905 if (pbrush
->flAttrs
& GDIBRUSH_IS_NULL
)
912 DestRect
.left
= XLeft
;
913 DestRect
.right
= XLeft
+ Width
;
917 DestRect
.left
= XLeft
+ Width
+ 1;
918 DestRect
.right
= XLeft
+ 1;
923 DestRect
.top
= YLeft
;
924 DestRect
.bottom
= YLeft
+ Height
;
928 DestRect
.top
= YLeft
+ Height
+ 1;
929 DestRect
.bottom
= YLeft
+ 1;
932 IntLPtoDP(pdc
, (LPPOINT
)&DestRect
, 2);
934 DestRect
.left
+= pdc
->ptlDCOrig
.x
;
935 DestRect
.top
+= pdc
->ptlDCOrig
.y
;
936 DestRect
.right
+= pdc
->ptlDCOrig
.x
;
937 DestRect
.bottom
+= pdc
->ptlDCOrig
.y
;
939 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
;
940 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
;
942 EBRUSHOBJ_vInit(&eboFill
, pbrush
, pdc
);
948 pdc
->rosdc
.CombinedClip
,
953 &eboFill
.BrushObject
, // use pDC->eboFill
955 ROP3_TO_ROP4(dwRop
));
957 EBRUSHOBJ_vCleanup(&eboFill
);
974 pdc
= DC_LockDc(hDC
);
977 SetLastWin32Error(ERROR_INVALID_HANDLE
);
981 if (pdc
->dctype
== DC_TYPE_INFO
)
984 /* Yes, Windows really returns TRUE in this case */
988 for (i
= 0; i
< cRects
; i
++)
990 pbrush
= BRUSH_LockBrush(pRects
->hBrush
);
1001 BRUSH_UnlockBrush(pbrush
);
1026 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
1029 /* in this case we call on GdiMaskBlt */
1030 return NtGdiMaskBlt(hDC
, XLeft
, YLeft
, Width
, Height
, 0,0,0,0,0,0,ROP
,0);
1033 dc
= DC_LockDc(hDC
);
1036 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1039 if (dc
->dctype
== DC_TYPE_INFO
)
1042 /* Yes, Windows really returns TRUE in this case */
1046 pdcattr
= dc
->pdcattr
;
1048 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
1049 DC_vUpdateFillBrush(dc
);
1051 pbrush
= BRUSH_LockBrush(pdcattr
->hbrush
);
1054 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1059 ret
= IntPatBlt(dc
, XLeft
, YLeft
, Width
, Height
, ROP
, pbrush
);
1061 BRUSH_UnlockBrush(pbrush
);
1071 IN PPOLYPATBLT pRects
,
1076 NTSTATUS Status
= STATUS_SUCCESS
;
1081 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, TAG_PATBLT
);
1084 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
1089 ProbeForRead(pRects
,
1090 cRects
* sizeof(PATRECT
),
1094 cRects
* sizeof(PATRECT
));
1096 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1098 Status
= _SEH2_GetExceptionCode();
1102 if (!NT_SUCCESS(Status
))
1104 ExFreePoolWithTag(rb
, TAG_PATBLT
);
1105 SetLastNtError(Status
);
1110 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, rb
, cRects
, Mode
);
1113 ExFreePoolWithTag(rb
, TAG_PATBLT
);