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
,
47 SURFACE
*BitmapDest
, *BitmapSrc
;
48 RECTL DestRect
, SourceRect
;
52 BlendObj
.BlendFunction
= BlendFunc
;
54 if (WidthDest
< 0 || HeightDest
< 0 || WidthSrc
< 0 || HeightSrc
< 0)
56 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
60 DPRINT("Locking DCs\n");
63 GDIOBJ_LockMultipleObjs(2, ahDC
, apObj
);
67 if ((NULL
== DCDest
) || (NULL
== DCSrc
))
69 DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest
, hDCSrc
);
70 SetLastWin32Error(ERROR_INVALID_HANDLE
);
71 if(DCSrc
) GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
72 if(DCDest
) GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
76 if (DCDest
->dctype
== DC_TYPE_INFO
|| DCDest
->dctype
== DCTYPE_INFO
)
78 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
79 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
80 /* Yes, Windows really returns TRUE in this case */
84 DestRect
.left
= XOriginDest
;
85 DestRect
.top
= YOriginDest
;
86 DestRect
.right
= XOriginDest
+ WidthDest
;
87 DestRect
.bottom
= YOriginDest
+ HeightDest
;
88 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
90 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
91 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
92 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
93 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
95 SourceRect
.left
= XOriginSrc
;
96 SourceRect
.top
= YOriginSrc
;
97 SourceRect
.right
= XOriginSrc
+ WidthSrc
;
98 SourceRect
.bottom
= YOriginSrc
+ HeightSrc
;
99 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
101 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
102 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
103 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
104 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
106 if (!DestRect
.right
||
111 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
112 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
116 /* Prepare DCs for blit */
117 DPRINT("Preparing DCs for blit\n");
118 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
120 /* Determine surfaces to be used in the bitblt */
121 BitmapDest
= DCDest
->dclevel
.pSurface
;
128 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
135 /* Create the XLATEOBJ. */
136 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
138 /* Perform the alpha blend operation */
139 DPRINT("Performing the alpha Blend\n");
140 bResult
= IntEngAlphaBlend(&BitmapDest
->SurfObj
,
142 DCDest
->rosdc
.CombinedClip
,
148 EXLATEOBJ_vCleanup(&exlo
);
150 DPRINT("Finishing blit\n");
151 DC_vFinishBlit(DCDest
, DCSrc
);
152 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
153 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
169 IN DWORD crBackColor
,
176 PDC_ATTR pdcattr
= NULL
;
177 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
178 RECTL DestRect
, SourceRect
;
182 XLATEOBJ
*XlateObj
= NULL
;
183 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
185 DPRINT("Locking DCs\n");
188 GDIOBJ_LockMultipleObjs(2, ahDC
, apObj
);
194 if(DCSrc
) GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
195 DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest
);
199 if (DCDest
->dctype
== DC_TYPE_INFO
)
201 if(DCSrc
) GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
202 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
203 /* Yes, Windows really returns TRUE in this case */
211 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
212 DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc
);
215 if (DCSrc
->dctype
== DC_TYPE_INFO
)
217 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
218 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
219 /* Yes, Windows really returns TRUE in this case */
225 DPRINT1("Getting a valid Source handle without using source!!!\n");
226 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
230 pdcattr
= DCDest
->pdcattr
;
232 DestRect
.left
= XDest
;
233 DestRect
.top
= YDest
;
234 DestRect
.right
= XDest
+Width
;
235 DestRect
.bottom
= YDest
+Height
;
236 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
238 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
239 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
240 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
241 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
243 SourcePoint
.x
= XSrc
;
244 SourcePoint
.y
= YSrc
;
248 IntLPtoDP(DCSrc
, (LPPOINT
)&SourcePoint
, 1);
250 SourcePoint
.x
+= DCSrc
->ptlDCOrig
.x
;
251 SourcePoint
.y
+= DCSrc
->ptlDCOrig
.y
;
252 /* Calculate Source Rect */
253 SourceRect
.left
= SourcePoint
.x
;
254 SourceRect
.top
= SourcePoint
.y
;
255 SourceRect
.right
= SourcePoint
.x
+ DestRect
.right
- DestRect
.left
;
256 SourceRect
.bottom
= SourcePoint
.y
+ DestRect
.bottom
- DestRect
.top
;
260 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
262 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
263 DC_vUpdateFillBrush(DCDest
);
265 /* Determine surfaces to be used in the bitblt */
266 BitmapDest
= DCDest
->dclevel
.pSurface
;
273 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
279 /* Create the XLATEOBJ. */
282 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
283 XlateObj
= &exlo
.xlo
;
286 /* Perform the bitblt operation */
287 Status
= IntEngBitBlt(&BitmapDest
->SurfObj
,
288 BitmapSrc
? &BitmapSrc
->SurfObj
: NULL
,
290 DCDest
->rosdc
.CombinedClip
,
295 &DCDest
->eboFill
.BrushObject
,
296 &DCDest
->dclevel
.pbrFill
->ptOrigin
,
300 EXLATEOBJ_vCleanup(&exlo
);
302 DC_vFinishBlit(DCDest
, DCSrc
);
305 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
307 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
330 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
331 PPALETTE PalSourceGDI
;
332 ULONG TransparentColor
= 0;
336 DPRINT("Locking DCs\n");
339 GDIOBJ_LockMultipleObjs(2, ahDC
, apObj
);
343 if ((NULL
== DCDest
) || (NULL
== DCSrc
))
345 DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hdcDst
, hdcSrc
);
346 SetLastWin32Error(ERROR_INVALID_HANDLE
);
347 if(DCSrc
) GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
348 if(DCDest
) GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
352 if (DCDest
->dctype
== DC_TYPE_INFO
|| DCDest
->dctype
== DCTYPE_INFO
)
354 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
355 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
356 /* Yes, Windows really returns TRUE in this case */
362 rcDest
.right
= rcDest
.left
+ cxDst
;
363 rcDest
.bottom
= rcDest
.top
+ cyDst
;
364 IntLPtoDP(DCDest
, (LPPOINT
)&rcDest
, 2);
366 rcDest
.left
+= DCDest
->ptlDCOrig
.x
;
367 rcDest
.top
+= DCDest
->ptlDCOrig
.y
;
368 rcDest
.right
+= DCDest
->ptlDCOrig
.x
;
369 rcDest
.bottom
+= DCDest
->ptlDCOrig
.y
;
373 rcSrc
.right
= rcSrc
.left
+ cxSrc
;
374 rcSrc
.bottom
= rcSrc
.top
+ cySrc
;
375 IntLPtoDP(DCSrc
, (LPPOINT
)&rcSrc
, 2);
377 rcSrc
.left
+= DCSrc
->ptlDCOrig
.x
;
378 rcSrc
.top
+= DCSrc
->ptlDCOrig
.y
;
379 rcSrc
.right
+= DCSrc
->ptlDCOrig
.x
;
380 rcSrc
.bottom
+= DCSrc
->ptlDCOrig
.y
;
382 /* Prepare for blit */
383 DC_vPrepareDCsForBlit(DCDest
, rcDest
, DCSrc
, rcSrc
);
385 BitmapDest
= DCDest
->dclevel
.pSurface
;
391 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
399 GDIOBJ_IncrementShareCount(&BitmapSrc
->ppal
->BaseObject
);
400 PalSourceGDI
= BitmapSrc
->ppal
;
403 PalSourceGDI
= PALETTE_ShareLockPalette(pPrimarySurface
->devinfo
.hpalDefault
) ;
407 SetLastWin32Error(ERROR_INVALID_HANDLE
);
411 /* Translate Transparent (RGB) Color to the source palette */
412 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, PalSourceGDI
, 0, 0, 0);
413 TransparentColor
= XLATEOBJ_iXlate(&exlo
.xlo
, (ULONG
)TransColor
);
414 EXLATEOBJ_vCleanup(&exlo
);
415 PALETTE_ShareUnlockPalette(PalSourceGDI
);
417 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
419 Ret
= IntEngTransparentBlt(&BitmapDest
->SurfObj
, &BitmapSrc
->SurfObj
,
420 DCDest
->rosdc
.CombinedClip
, &exlo
.xlo
, &rcDest
, &rcSrc
,
421 TransparentColor
, 0);
423 EXLATEOBJ_vCleanup(&exlo
);
426 DC_vFinishBlit(DCDest
, DCSrc
);
427 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
428 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
433 /***********************************************************************
435 * Ported from WINE by sedwards 11-4-03
437 * Someone thought it would be faster to do it here and then switch back
438 * to GDI32. I dunno. Write a test and let me know.
439 * A. It should be in here!
443 SwapROP3_SrcDst(BYTE bRop3
)
445 return (bRop3
& 0x99) | ((bRop3
& 0x22) << 1) | ((bRop3
& 0x44) >> 1);
448 #define FRGND_ROP3(ROP4) ((ROP4) & 0x00FFFFFF)
449 #define BKGND_ROP3(ROP4) (ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
450 #define DSTCOPY 0x00AA0029
451 #define DSTERASE 0x00220326 /* dest = dest & (~src) : DSna */
467 IN DWORD crBackColor
)
469 HBITMAP hOldMaskBitmap
, hBitmap2
, hOldBitmap2
, hBitmap3
, hOldBitmap3
;
470 HDC hDCMask
, hDC1
, hDC2
;
471 static const DWORD ROP3Table
[256] =
473 0x00000042, 0x00010289,
474 0x00020C89, 0x000300AA,
475 0x00040C88, 0x000500A9,
476 0x00060865, 0x000702C5,
477 0x00080F08, 0x00090245,
478 0x000A0329, 0x000B0B2A,
479 0x000C0324, 0x000D0B25,
480 0x000E08A5, 0x000F0001,
481 0x00100C85, 0x001100A6,
482 0x00120868, 0x001302C8,
483 0x00140869, 0x001502C9,
484 0x00165CCA, 0x00171D54,
485 0x00180D59, 0x00191CC8,
486 0x001A06C5, 0x001B0768,
487 0x001C06CA, 0x001D0766,
488 0x001E01A5, 0x001F0385,
489 0x00200F09, 0x00210248,
490 0x00220326, 0x00230B24,
491 0x00240D55, 0x00251CC5,
492 0x002606C8, 0x00271868,
493 0x00280369, 0x002916CA,
494 0x002A0CC9, 0x002B1D58,
495 0x002C0784, 0x002D060A,
496 0x002E064A, 0x002F0E2A,
497 0x0030032A, 0x00310B28,
498 0x00320688, 0x00330008,
499 0x003406C4, 0x00351864,
500 0x003601A8, 0x00370388,
501 0x0038078A, 0x00390604,
502 0x003A0644, 0x003B0E24,
503 0x003C004A, 0x003D18A4,
504 0x003E1B24, 0x003F00EA,
505 0x00400F0A, 0x00410249,
506 0x00420D5D, 0x00431CC4,
507 0x00440328, 0x00450B29,
508 0x004606C6, 0x0047076A,
509 0x00480368, 0x004916C5,
510 0x004A0789, 0x004B0605,
511 0x004C0CC8, 0x004D1954,
512 0x004E0645, 0x004F0E25,
513 0x00500325, 0x00510B26,
514 0x005206C9, 0x00530764,
515 0x005408A9, 0x00550009,
516 0x005601A9, 0x00570389,
517 0x00580785, 0x00590609,
518 0x005A0049, 0x005B18A9,
519 0x005C0649, 0x005D0E29,
520 0x005E1B29, 0x005F00E9,
521 0x00600365, 0x006116C6,
522 0x00620786, 0x00630608,
523 0x00640788, 0x00650606,
524 0x00660046, 0x006718A8,
525 0x006858A6, 0x00690145,
526 0x006A01E9, 0x006B178A,
527 0x006C01E8, 0x006D1785,
528 0x006E1E28, 0x006F0C65,
529 0x00700CC5, 0x00711D5C,
530 0x00720648, 0x00730E28,
531 0x00740646, 0x00750E26,
532 0x00761B28, 0x007700E6,
533 0x007801E5, 0x00791786,
534 0x007A1E29, 0x007B0C68,
535 0x007C1E24, 0x007D0C69,
536 0x007E0955, 0x007F03C9,
537 0x008003E9, 0x00810975,
538 0x00820C49, 0x00831E04,
539 0x00840C48, 0x00851E05,
540 0x008617A6, 0x008701C5,
541 0x008800C6, 0x00891B08,
542 0x008A0E06, 0x008B0666,
543 0x008C0E08, 0x008D0668,
544 0x008E1D7C, 0x008F0CE5,
545 0x00900C45, 0x00911E08,
546 0x009217A9, 0x009301C4,
547 0x009417AA, 0x009501C9,
548 0x00960169, 0x0097588A,
549 0x00981888, 0x00990066,
550 0x009A0709, 0x009B07A8,
551 0x009C0704, 0x009D07A6,
552 0x009E16E6, 0x009F0345,
553 0x00A000C9, 0x00A11B05,
554 0x00A20E09, 0x00A30669,
555 0x00A41885, 0x00A50065,
556 0x00A60706, 0x00A707A5,
557 0x00A803A9, 0x00A90189,
558 0x00AA0029, 0x00AB0889,
559 0x00AC0744, 0x00AD06E9,
560 0x00AE0B06, 0x00AF0229,
561 0x00B00E05, 0x00B10665,
562 0x00B21974, 0x00B30CE8,
563 0x00B4070A, 0x00B507A9,
564 0x00B616E9, 0x00B70348,
565 0x00B8074A, 0x00B906E6,
566 0x00BA0B09, 0x00BB0226,
567 0x00BC1CE4, 0x00BD0D7D,
568 0x00BE0269, 0x00BF08C9,
569 0x00C000CA, 0x00C11B04,
570 0x00C21884, 0x00C3006A,
571 0x00C40E04, 0x00C50664,
572 0x00C60708, 0x00C707AA,
573 0x00C803A8, 0x00C90184,
574 0x00CA0749, 0x00CB06E4,
575 0x00CC0020, 0x00CD0888,
576 0x00CE0B08, 0x00CF0224,
577 0x00D00E0A, 0x00D1066A,
578 0x00D20705, 0x00D307A4,
579 0x00D41D78, 0x00D50CE9,
580 0x00D616EA, 0x00D70349,
581 0x00D80745, 0x00D906E8,
582 0x00DA1CE9, 0x00DB0D75,
583 0x00DC0B04, 0x00DD0228,
584 0x00DE0268, 0x00DF08C8,
585 0x00E003A5, 0x00E10185,
586 0x00E20746, 0x00E306EA,
587 0x00E40748, 0x00E506E5,
588 0x00E61CE8, 0x00E70D79,
589 0x00E81D74, 0x00E95CE6,
590 0x00EA02E9, 0x00EB0849,
591 0x00EC02E8, 0x00ED0848,
592 0x00EE0086, 0x00EF0A08,
593 0x00F00021, 0x00F10885,
594 0x00F20B05, 0x00F3022A,
595 0x00F40B0A, 0x00F50225,
596 0x00F60265, 0x00F708C5,
597 0x00F802E5, 0x00F90845,
598 0x00FA0089, 0x00FB0A09,
599 0x00FC008A, 0x00FD0A0A,
600 0x00FE02A9, 0x00FF0062,
604 return NtGdiBitBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, FRGND_ROP3(dwRop
), 0, 0);
606 /* 1. make mask bitmap's dc */
607 hDCMask
= NtGdiCreateCompatibleDC(hdcDest
);
608 hOldMaskBitmap
= (HBITMAP
)NtGdiSelectBitmap(hDCMask
, hbmMask
);
610 /* 2. make masked Background bitmap */
612 /* 2.1 make bitmap */
613 hDC1
= NtGdiCreateCompatibleDC(hdcDest
);
614 hBitmap2
= NtGdiCreateCompatibleBitmap(hdcDest
, nWidth
, nHeight
);
615 hOldBitmap2
= (HBITMAP
)NtGdiSelectBitmap(hDC1
, hBitmap2
);
617 /* 2.2 draw dest bitmap and mask */
618 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, SRCCOPY
, 0, 0);
619 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hdcDest
, nXDest
, nYDest
, BKGND_ROP3(dwRop
), 0, 0);
620 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hDCMask
, xMask
, yMask
, DSTERASE
, 0, 0);
622 /* 3. make masked Foreground bitmap */
624 /* 3.1 make bitmap */
625 hDC2
= NtGdiCreateCompatibleDC(hdcDest
);
626 hBitmap3
= NtGdiCreateCompatibleBitmap(hdcDest
, nWidth
, nHeight
);
627 hOldBitmap3
= (HBITMAP
)NtGdiSelectBitmap(hDC2
, hBitmap3
);
629 /* 3.2 draw src bitmap and mask */
630 NtGdiBitBlt(hDC2
, 0, 0, nWidth
, nHeight
, hdcDest
, nXDest
, nYDest
, SRCCOPY
, 0, 0);
631 NtGdiBitBlt(hDC2
, 0, 0, nWidth
, nHeight
, hdcSrc
, nXSrc
, nYSrc
, FRGND_ROP3(dwRop
), 0,0);
632 NtGdiBitBlt(hDC2
, 0, 0, nWidth
, nHeight
, hDCMask
, xMask
, yMask
, SRCAND
, 0, 0);
634 /* 4. combine both and copy the result to hdcDest */
635 NtGdiBitBlt(hDC1
, 0, 0, nWidth
, nHeight
, hDC2
, 0, 0, SRCPAINT
, 0, 0);
636 NtGdiBitBlt(hdcDest
, nXDest
, nYDest
, nWidth
, nHeight
, hDC1
, 0, 0, SRCCOPY
, 0, 0);
638 /* 5. restore all objects */
639 NtGdiSelectBitmap(hDCMask
, hOldMaskBitmap
);
640 NtGdiSelectBitmap(hDC1
, hOldBitmap2
);
641 NtGdiSelectBitmap(hDC2
, hOldBitmap3
);
643 /* 6. delete all temp objects */
644 GreDeleteObject(hBitmap2
);
645 GreDeleteObject(hBitmap3
);
647 NtGdiDeleteObjectApp(hDC1
);
648 NtGdiDeleteObjectApp(hDC2
);
649 NtGdiDeleteObjectApp(hDCMask
);
667 IN DWORD crBackColor
)
686 IN DWORD dwBackColor
,
697 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
698 SURFACE
*BitmapMask
= NULL
;
704 XLATEOBJ
*XlateObj
= NULL
;
706 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
708 if (0 == WidthDest
|| 0 == HeightDest
|| 0 == WidthSrc
|| 0 == HeightSrc
)
710 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
714 DPRINT("Locking DCs\n");
718 GDIOBJ_LockMultipleObjs(3, ahDC
, apObj
);
725 if(DCSrc
) GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
726 if(DCMask
) GDIOBJ_UnlockObjByPtr(&DCMask
->BaseObject
);
727 DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest
);
731 if (DCDest
->dctype
== DC_TYPE_INFO
)
733 if(DCSrc
) GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
734 if(DCMask
) GDIOBJ_UnlockObjByPtr(&DCMask
->BaseObject
);
735 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
736 /* Yes, Windows really returns TRUE in this case */
744 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
745 if(DCMask
) GDIOBJ_UnlockObjByPtr(&DCMask
->BaseObject
);
746 DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc
);
749 if (DCSrc
->dctype
== DC_TYPE_INFO
)
751 GDIOBJ_UnlockObjByPtr(&DCDest
->BaseObject
);
752 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
753 if(DCMask
) GDIOBJ_UnlockObjByPtr(&DCMask
->BaseObject
);
754 /* Yes, Windows really returns TRUE in this case */
760 DPRINT1("Getting a valid Source handle without using source!!!\n");
761 GDIOBJ_UnlockObjByPtr(&DCSrc
->BaseObject
);
765 pdcattr
= DCDest
->pdcattr
;
767 DestRect
.left
= XOriginDest
;
768 DestRect
.top
= YOriginDest
;
769 DestRect
.right
= XOriginDest
+WidthDest
;
770 DestRect
.bottom
= YOriginDest
+HeightDest
;
771 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
773 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
774 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
775 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
776 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
778 SourceRect
.left
= XOriginSrc
;
779 SourceRect
.top
= YOriginSrc
;
780 SourceRect
.right
= XOriginSrc
+WidthSrc
;
781 SourceRect
.bottom
= YOriginSrc
+HeightSrc
;
785 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
787 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
788 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
789 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
790 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
796 /* Only prepare Source and Dest, hdcMask represents a DIB */
797 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
799 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
800 DC_vUpdateFillBrush(DCDest
);
802 /* Determine surfaces to be used in the bitblt */
803 BitmapDest
= DCDest
->dclevel
.pSurface
;
804 if (BitmapDest
== NULL
)
808 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
809 if (BitmapSrc
== NULL
)
812 /* Create the XLATEOBJ. */
813 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
814 XlateObj
= &exlo
.xlo
;
817 /* Offset the brush */
818 BrushOrigin
.x
+= DCDest
->ptlDCOrig
.x
;
819 BrushOrigin
.y
+= DCDest
->ptlDCOrig
.y
;
821 /* Make mask surface for source surface */
822 if (BitmapSrc
&& DCMask
)
824 BitmapMask
= DCMask
->dclevel
.pSurface
;
826 (BitmapMask
->SurfObj
.sizlBitmap
.cx
< WidthSrc
||
827 BitmapMask
->SurfObj
.sizlBitmap
.cy
< HeightSrc
))
829 DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
830 BitmapMask
->SurfObj
.sizlBitmap
.cx
, BitmapMask
->SurfObj
.sizlBitmap
.cy
,
831 WidthSrc
, HeightSrc
);
832 EXLATEOBJ_vCleanup(&exlo
);
835 /* Create mask offset point */
836 MaskPoint
.x
= XOriginMask
;
837 MaskPoint
.y
= YOriginMask
;
838 IntLPtoDP(DCMask
, &MaskPoint
, 1);
839 MaskPoint
.x
+= DCMask
->ptlDCOrig
.x
;
840 MaskPoint
.y
+= DCMask
->ptlDCOrig
.x
;
843 /* Perform the bitblt operation */
844 Status
= IntEngStretchBlt(&BitmapDest
->SurfObj
,
846 BitmapMask
? &BitmapMask
->SurfObj
: NULL
,
847 DCDest
->rosdc
.CombinedClip
,
851 BitmapMask
? &MaskPoint
: NULL
,
852 &DCDest
->eboFill
.BrushObject
,
857 EXLATEOBJ_vCleanup(&exlo
);
861 DC_vFinishBlit(DCDest
, DCSrc
);
889 IN DWORD dwBackColor
)
891 return GreStretchBltMask(
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 DC_vPrepareDCsForBlit(pdc
, DestRect
, NULL
, DestRect
);
967 psurf
= pdc
->dclevel
.pSurface
;
969 if (pdc
->pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
970 DC_vUpdateFillBrush(pdc
);
972 EBRUSHOBJ_vInit(&eboFill
, pbrush
, pdc
);
978 pdc
->rosdc
.CombinedClip
,
983 &eboFill
.BrushObject
,
985 ROP3_TO_ROP4(dwRop
));
987 DC_vFinishBlit(pdc
, NULL
);
989 EBRUSHOBJ_vCleanup(&eboFill
);
1006 pdc
= DC_LockDc(hDC
);
1009 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1013 if (pdc
->dctype
== DC_TYPE_INFO
)
1016 /* Yes, Windows really returns TRUE in this case */
1020 for (i
= 0; i
< cRects
; i
++)
1022 pbrush
= BRUSH_LockBrush(pRects
->hBrush
);
1033 BRUSH_UnlockBrush(pbrush
);
1058 BOOL UsesSource
= ROP3_USES_SOURCE(ROP
);
1061 /* in this case we call on GdiMaskBlt */
1062 return NtGdiMaskBlt(hDC
, XLeft
, YLeft
, Width
, Height
, 0,0,0,0,0,0,ROP
,0);
1065 dc
= DC_LockDc(hDC
);
1068 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1071 if (dc
->dctype
== DC_TYPE_INFO
)
1074 /* Yes, Windows really returns TRUE in this case */
1078 pdcattr
= dc
->pdcattr
;
1080 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
1081 DC_vUpdateFillBrush(dc
);
1083 pbrush
= BRUSH_LockBrush(pdcattr
->hbrush
);
1086 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1091 ret
= IntPatBlt(dc
, XLeft
, YLeft
, Width
, Height
, ROP
, pbrush
);
1093 BRUSH_UnlockBrush(pbrush
);
1103 IN PPOLYPATBLT pRects
,
1108 NTSTATUS Status
= STATUS_SUCCESS
;
1113 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, TAG_PATBLT
);
1116 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
1121 ProbeForRead(pRects
,
1122 cRects
* sizeof(PATRECT
),
1126 cRects
* sizeof(PATRECT
));
1128 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1130 Status
= _SEH2_GetExceptionCode();
1134 if (!NT_SUCCESS(Status
))
1136 ExFreePoolWithTag(rb
, TAG_PATBLT
);
1137 SetLastNtError(Status
);
1142 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, rb
, cRects
, Mode
);
1145 ExFreePoolWithTag(rb
, TAG_PATBLT
);