2 * COPYRIGHT: GNU GPL, See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Bit blit functions
5 * FILE: subsys/win32k/objects/bitblt.c
14 #define ROP_USES_SOURCE(Rop) (((((Rop) & 0xCC0000) >> 2) != ((Rop) & 0x330000)) || ((((Rop) & 0xCC000000) >> 2) != ((Rop) & 0x33000000)))
15 #define ROP_USES_MASK(Rop) (((Rop) & 0xFF000000) != (((Rop) & 0xff0000) << 8))
17 #define FIXUP_ROP(Rop) if(((Rop) & 0xFF000000) == 0) Rop = MAKEROP4((Rop), (Rop))
18 #define ROP_TO_ROP4(Rop) ((Rop) >> 16)
21 TranslateCOLORREF(PDC pdc
, COLORREF crColor
)
23 PPALETTE ppalDC
, ppalSurface
;
24 ULONG index
, ulColor
, iBitmapFormat
;
27 switch (crColor
>> 24)
29 case 0x00: /* RGB color */
32 case 0x01: /* PALETTEINDEX */
33 index
= crColor
& 0xFFFFFF;
34 ppalDC
= pdc
->dclevel
.ppal
;
35 if (index
>= ppalDC
->NumColors
) index
= 0;
37 /* Get the RGB value */
38 crColor
= PALETTE_ulGetRGBColorFromIndex(ppalDC
, index
);
41 case 0x02: /* PALETTERGB */
43 if (pdc
->dclevel
.hpal
!= StockObjects
[DEFAULT_PALETTE
])
45 /* First find the nearest index in the dc palette */
46 ppalDC
= pdc
->dclevel
.ppal
;
47 index
= PALETTE_ulGetNearestIndex(ppalDC
, crColor
& 0xFFFFFF);
49 /* Get the RGB value */
50 crColor
= PALETTE_ulGetRGBColorFromIndex(ppalDC
, index
);
54 /* Use the pure color */
55 crColor
= crColor
& 0x00FFFFFF;
59 case 0x10: /* DIBINDEX */
60 /* Mask the value to match the target bpp */
61 iBitmapFormat
= pdc
->dclevel
.pSurface
->SurfObj
.iBitmapFormat
;
62 if (iBitmapFormat
== BMF_1BPP
) index
= crColor
& 0x1;
63 else if (iBitmapFormat
== BMF_4BPP
) index
= crColor
& 0xf;
64 else if (iBitmapFormat
== BMF_8BPP
) index
= crColor
& 0xFF;
65 else if (iBitmapFormat
== BMF_16BPP
) index
= crColor
& 0xFFFF;
66 else index
= crColor
& 0xFFFFFF;
70 DPRINT("Unsupported color type %d passed\n", crColor
>> 24);
74 /* Initialize an XLATEOBJ from RGB to the target surface */
75 ppalSurface
= pdc
->dclevel
.pSurface
->ppal
;
76 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, ppalSurface
, 0xFFFFFF, 0, 0);
78 /* Translate the color to the target format */
79 ulColor
= XLATEOBJ_iXlate(&exlo
.xlo
, crColor
);
81 /* Cleanup the XLATEOBJ */
82 EXLATEOBJ_vCleanup(&exlo
);
100 BLENDFUNCTION BlendFunc
,
107 SURFACE
*BitmapDest
, *BitmapSrc
;
108 RECTL DestRect
, SourceRect
;
112 BlendObj
.BlendFunction
= BlendFunc
;
114 if (WidthDest
< 0 || HeightDest
< 0 || WidthSrc
< 0 || HeightSrc
< 0)
116 EngSetLastError(ERROR_INVALID_PARAMETER
);
120 DPRINT("Locking DCs\n");
123 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
125 DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest
, hDCSrc
);
126 EngSetLastError(ERROR_INVALID_HANDLE
);
132 if (DCDest
->dctype
== DC_TYPE_INFO
|| DCDest
->dctype
== DCTYPE_INFO
)
134 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
135 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
136 /* Yes, Windows really returns TRUE in this case */
140 DestRect
.left
= XOriginDest
;
141 DestRect
.top
= YOriginDest
;
142 DestRect
.right
= XOriginDest
+ WidthDest
;
143 DestRect
.bottom
= YOriginDest
+ HeightDest
;
144 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
146 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
147 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
148 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
149 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
151 SourceRect
.left
= XOriginSrc
;
152 SourceRect
.top
= YOriginSrc
;
153 SourceRect
.right
= XOriginSrc
+ WidthSrc
;
154 SourceRect
.bottom
= YOriginSrc
+ HeightSrc
;
155 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
157 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
158 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
159 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
160 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
162 if (!DestRect
.right
||
167 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
168 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
172 /* Prepare DCs for blit */
173 DPRINT("Preparing DCs for blit\n");
174 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
176 /* Determine surfaces to be used in the bitblt */
177 BitmapDest
= DCDest
->dclevel
.pSurface
;
184 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
191 /* Create the XLATEOBJ. */
192 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
194 /* Perform the alpha blend operation */
195 DPRINT("Performing the alpha blend\n");
196 bResult
= IntEngAlphaBlend(&BitmapDest
->SurfObj
,
198 DCDest
->rosdc
.CombinedClip
,
204 EXLATEOBJ_vCleanup(&exlo
);
206 DPRINT("Finishing blit\n");
207 DC_vFinishBlit(DCDest
, DCSrc
);
208 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
209 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
225 IN DWORD crBackColor
,
228 /* Forward to NtGdiMaskBlt */
229 // TODO: What's fl for?
230 return NtGdiMaskBlt(hDCDest
,
263 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
264 ULONG TransparentColor
= 0;
268 DPRINT("Locking DCs\n");
271 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
273 DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hdcDst
, hdcSrc
);
274 EngSetLastError(ERROR_INVALID_HANDLE
);
280 if (DCDest
->dctype
== DC_TYPE_INFO
|| DCDest
->dctype
== DCTYPE_INFO
)
282 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
283 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
284 /* Yes, Windows really returns TRUE in this case */
290 rcDest
.right
= rcDest
.left
+ cxDst
;
291 rcDest
.bottom
= rcDest
.top
+ cyDst
;
292 IntLPtoDP(DCDest
, (LPPOINT
)&rcDest
, 2);
294 rcDest
.left
+= DCDest
->ptlDCOrig
.x
;
295 rcDest
.top
+= DCDest
->ptlDCOrig
.y
;
296 rcDest
.right
+= DCDest
->ptlDCOrig
.x
;
297 rcDest
.bottom
+= DCDest
->ptlDCOrig
.y
;
301 rcSrc
.right
= rcSrc
.left
+ cxSrc
;
302 rcSrc
.bottom
= rcSrc
.top
+ cySrc
;
303 IntLPtoDP(DCSrc
, (LPPOINT
)&rcSrc
, 2);
305 rcSrc
.left
+= DCSrc
->ptlDCOrig
.x
;
306 rcSrc
.top
+= DCSrc
->ptlDCOrig
.y
;
307 rcSrc
.right
+= DCSrc
->ptlDCOrig
.x
;
308 rcSrc
.bottom
+= DCSrc
->ptlDCOrig
.y
;
310 /* Prepare for blit */
311 DC_vPrepareDCsForBlit(DCDest
, rcDest
, DCSrc
, rcSrc
);
313 BitmapDest
= DCDest
->dclevel
.pSurface
;
319 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
325 /* Translate Transparent (RGB) Color to the source palette */
326 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, BitmapSrc
->ppal
, 0, 0, 0);
327 TransparentColor
= XLATEOBJ_iXlate(&exlo
.xlo
, (ULONG
)TransColor
);
328 EXLATEOBJ_vCleanup(&exlo
);
330 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
332 Ret
= IntEngTransparentBlt(&BitmapDest
->SurfObj
, &BitmapSrc
->SurfObj
,
333 DCDest
->rosdc
.CombinedClip
, &exlo
.xlo
, &rcDest
, &rcSrc
,
334 TransparentColor
, 0);
336 EXLATEOBJ_vCleanup(&exlo
);
339 DC_vFinishBlit(DCDest
, DCSrc
);
340 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
341 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
360 IN DWORD crBackColor
)
366 PDC_ATTR pdcattr
= NULL
;
367 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
, *psurfMask
= NULL
;
368 RECTL DestRect
, SourceRect
;
369 POINTL SourcePoint
, MaskPoint
;
372 XLATEOBJ
*XlateObj
= NULL
;
373 BOOL UsesSource
= ROP_USES_SOURCE(dwRop
);
378 UsesMask
= ROP_USES_MASK(dwRop
);
380 //DPRINT1("dwRop : 0x%08x\n", dwRop);
381 if (!hdcDest
|| (UsesSource
&& !hdcSrc
))
383 EngSetLastError(ERROR_INVALID_PARAMETER
);
387 /* Take care of mask bitmap */
390 psurfMask
= SURFACE_ShareLockSurface(hbmMask
);
393 EngSetLastError(ERROR_INVALID_HANDLE
);
402 EngSetLastError(ERROR_INVALID_PARAMETER
);
405 if(gajBitsPerFormat
[psurfMask
->SurfObj
.iBitmapFormat
] != 1)
407 EngSetLastError(ERROR_INVALID_PARAMETER
);
408 SURFACE_ShareUnlockSurface(psurfMask
);
414 DPRINT1("Getting Mask bitmap without needing it?\n");
415 SURFACE_ShareUnlockSurface(psurfMask
);
421 /* Take care of source and destination bitmap */
422 DPRINT("Locking DCs\n");
424 ahDC
[1] = UsesSource
? hdcSrc
: NULL
;
425 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
427 DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hdcDest
, hdcSrc
);
428 EngSetLastError(ERROR_INVALID_HANDLE
);
437 if(DCSrc
) DC_UnlockDc(DCSrc
);
438 DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hdcDest
);
442 if (DCDest
->dctype
== DC_TYPE_INFO
)
444 if(DCSrc
) DC_UnlockDc(DCSrc
);
446 /* Yes, Windows really returns TRUE in this case */
453 if (DCSrc
->dctype
== DC_TYPE_INFO
)
457 /* Yes, Windows really returns TRUE in this case */
462 pdcattr
= DCDest
->pdcattr
;
464 DestRect
.left
= nXDest
;
465 DestRect
.top
= nYDest
;
466 DestRect
.right
= nXDest
+ nWidth
;
467 DestRect
.bottom
= nYDest
+ nHeight
;
468 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
470 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
471 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
472 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
473 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
475 SourcePoint
.x
= nXSrc
;
476 SourcePoint
.y
= nYSrc
;
480 IntLPtoDP(DCSrc
, (LPPOINT
)&SourcePoint
, 1);
482 SourcePoint
.x
+= DCSrc
->ptlDCOrig
.x
;
483 SourcePoint
.y
+= DCSrc
->ptlDCOrig
.y
;
484 /* Calculate Source Rect */
485 SourceRect
.left
= SourcePoint
.x
;
486 SourceRect
.top
= SourcePoint
.y
;
487 SourceRect
.right
= SourcePoint
.x
+ DestRect
.right
- DestRect
.left
;
488 SourceRect
.bottom
= SourcePoint
.y
+ DestRect
.bottom
- DestRect
.top
;
492 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
494 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
495 DC_vUpdateFillBrush(DCDest
);
497 /* Determine surfaces to be used in the bitblt */
498 BitmapDest
= DCDest
->dclevel
.pSurface
;
505 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
511 /* Create the XLATEOBJ. */
514 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
515 XlateObj
= &exlo
.xlo
;
519 /* Perform the bitblt operation */
520 Status
= IntEngBitBlt(&BitmapDest
->SurfObj
,
521 BitmapSrc
? &BitmapSrc
->SurfObj
: NULL
,
522 psurfMask
? &psurfMask
->SurfObj
: NULL
,
523 DCDest
->rosdc
.CombinedClip
,
528 &DCDest
->eboFill
.BrushObject
,
529 &DCDest
->dclevel
.pbrFill
->ptOrigin
,
533 EXLATEOBJ_vCleanup(&exlo
);
535 DC_vFinishBlit(DCDest
, DCSrc
);
541 if(psurfMask
) SURFACE_ShareUnlockSurface(psurfMask
);
559 IN DWORD crBackColor
)
578 IN DWORD dwBackColor
,
589 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
590 SURFACE
*BitmapMask
= NULL
;
596 XLATEOBJ
*XlateObj
= NULL
;
602 UsesSource
= ROP_USES_SOURCE(ROP
);
603 UsesMask
= ROP_USES_MASK(ROP
);
605 if (0 == WidthDest
|| 0 == HeightDest
|| 0 == WidthSrc
|| 0 == HeightSrc
)
607 EngSetLastError(ERROR_INVALID_PARAMETER
);
611 if (!hDCDest
|| (UsesSource
&& !hDCSrc
) || (UsesMask
&& !hDCMask
))
613 EngSetLastError(ERROR_INVALID_PARAMETER
);
618 ahDC
[1] = UsesSource
? hDCSrc
: NULL
;
619 ahDC
[2] = UsesMask
? hDCMask
: NULL
;
620 if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
622 DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest
, hDCSrc
);
623 EngSetLastError(ERROR_INVALID_HANDLE
);
630 if (DCDest
->dctype
== DC_TYPE_INFO
)
632 if(DCSrc
) GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
633 if(DCMask
) GDIOBJ_vUnlockObject(&DCMask
->BaseObject
);
634 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
635 /* Yes, Windows really returns TRUE in this case */
641 if (DCSrc
->dctype
== DC_TYPE_INFO
)
643 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
644 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
645 if(DCMask
) GDIOBJ_vUnlockObject(&DCMask
->BaseObject
);
646 /* Yes, Windows really returns TRUE in this case */
651 pdcattr
= DCDest
->pdcattr
;
653 DestRect
.left
= XOriginDest
;
654 DestRect
.top
= YOriginDest
;
655 DestRect
.right
= XOriginDest
+WidthDest
;
656 DestRect
.bottom
= YOriginDest
+HeightDest
;
657 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
659 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
660 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
661 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
662 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
664 SourceRect
.left
= XOriginSrc
;
665 SourceRect
.top
= YOriginSrc
;
666 SourceRect
.right
= XOriginSrc
+WidthSrc
;
667 SourceRect
.bottom
= YOriginSrc
+HeightSrc
;
671 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
673 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
674 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
675 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
676 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
682 /* Only prepare Source and Dest, hdcMask represents a DIB */
683 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
685 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
686 DC_vUpdateFillBrush(DCDest
);
688 /* Determine surfaces to be used in the bitblt */
689 BitmapDest
= DCDest
->dclevel
.pSurface
;
690 if (BitmapDest
== NULL
)
694 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
695 if (BitmapSrc
== NULL
)
698 /* Create the XLATEOBJ. */
699 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
700 XlateObj
= &exlo
.xlo
;
703 /* Offset the brush */
704 BrushOrigin
.x
+= DCDest
->ptlDCOrig
.x
;
705 BrushOrigin
.y
+= DCDest
->ptlDCOrig
.y
;
707 /* Make mask surface for source surface */
708 if (BitmapSrc
&& DCMask
)
710 BitmapMask
= DCMask
->dclevel
.pSurface
;
712 (BitmapMask
->SurfObj
.sizlBitmap
.cx
< WidthSrc
||
713 BitmapMask
->SurfObj
.sizlBitmap
.cy
< HeightSrc
))
715 DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
716 BitmapMask
->SurfObj
.sizlBitmap
.cx
, BitmapMask
->SurfObj
.sizlBitmap
.cy
,
717 WidthSrc
, HeightSrc
);
718 EXLATEOBJ_vCleanup(&exlo
);
721 /* Create mask offset point */
722 MaskPoint
.x
= XOriginMask
;
723 MaskPoint
.y
= YOriginMask
;
724 IntLPtoDP(DCMask
, &MaskPoint
, 1);
725 MaskPoint
.x
+= DCMask
->ptlDCOrig
.x
;
726 MaskPoint
.y
+= DCMask
->ptlDCOrig
.y
;
729 /* Perform the bitblt operation */
730 Status
= IntEngStretchBlt(&BitmapDest
->SurfObj
,
732 BitmapMask
? &BitmapMask
->SurfObj
: NULL
,
733 DCDest
->rosdc
.CombinedClip
,
737 BitmapMask
? &MaskPoint
: NULL
,
738 &DCDest
->eboFill
.BrushObject
,
743 EXLATEOBJ_vCleanup(&exlo
);
747 DC_vFinishBlit(DCDest
, DCSrc
);
775 IN DWORD dwBackColor
)
777 return GreStretchBltMask(
810 PBRUSH pbrush
= pebo
->pbrush
;
816 if (pbrush
->flAttrs
& BR_IS_NULL
)
823 DestRect
.left
= XLeft
;
824 DestRect
.right
= XLeft
+ Width
;
828 DestRect
.left
= XLeft
+ Width
+ 1;
829 DestRect
.right
= XLeft
+ 1;
834 DestRect
.top
= YLeft
;
835 DestRect
.bottom
= YLeft
+ Height
;
839 DestRect
.top
= YLeft
+ Height
+ 1;
840 DestRect
.bottom
= YLeft
+ 1;
843 IntLPtoDP(pdc
, (LPPOINT
)&DestRect
, 2);
845 DestRect
.left
+= pdc
->ptlDCOrig
.x
;
846 DestRect
.top
+= pdc
->ptlDCOrig
.y
;
847 DestRect
.right
+= pdc
->ptlDCOrig
.x
;
848 DestRect
.bottom
+= pdc
->ptlDCOrig
.y
;
850 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
+ XLeft
;
851 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
+ YLeft
;
853 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
;
854 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
;
857 DC_vPrepareDCsForBlit(pdc
, DestRect
, NULL
, DestRect
);
859 psurf
= pdc
->dclevel
.pSurface
;
865 pdc
->rosdc
.CombinedClip
,
874 DC_vFinishBlit(pdc
, NULL
);
892 pdc
= DC_LockDc(hDC
);
895 EngSetLastError(ERROR_INVALID_HANDLE
);
899 if (pdc
->dctype
== DC_TYPE_INFO
)
902 /* Yes, Windows really returns TRUE in this case */
906 for (i
= 0; i
< cRects
; i
++)
908 pbrush
= BRUSH_ShareLockBrush(pRects
->hBrush
);
910 /* Check if we could lock the brush */
913 /* Initialize a brush object */
914 EBRUSHOBJ_vInit(&eboFill
, pbrush
, pdc
);
925 /* Cleanup the brush object and unlock the brush */
926 EBRUSHOBJ_vCleanup(&eboFill
);
927 BRUSH_ShareUnlockBrush(pbrush
);
950 /* Mask away everything except foreground rop index */
951 dwRop
= dwRop
& 0x00FF0000;
954 /* Check if the rop uses a source */
955 if (ROP_USES_SOURCE(dwRop
))
957 /* This is not possible */
962 pdc
= DC_LockDc(hdcDest
);
965 EngSetLastError(ERROR_INVALID_HANDLE
);
969 /* Check if the DC has no surface (empty mem or info DC) */
970 if (pdc
->dclevel
.pSurface
== NULL
)
972 /* Nothing to do, Windows returns TRUE! */
977 /* Update the fill brush, if neccessary */
978 if (pdc
->pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
979 DC_vUpdateFillBrush(pdc
);
981 /* Call the internal function */
982 bResult
= IntPatBlt(pdc
, x
, y
, cx
, cy
, dwRop
, &pdc
->eboFill
);
984 /* Unlock the DC and return the result */
994 IN PPOLYPATBLT pRects
,
999 NTSTATUS Status
= STATUS_SUCCESS
;
1004 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, GDITAG_PLGBLT_DATA
);
1007 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1012 ProbeForRead(pRects
,
1013 cRects
* sizeof(PATRECT
),
1017 cRects
* sizeof(PATRECT
));
1019 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1021 Status
= _SEH2_GetExceptionCode();
1025 if (!NT_SUCCESS(Status
))
1027 ExFreePoolWithTag(rb
, GDITAG_PLGBLT_DATA
);
1028 SetLastNtError(Status
);
1033 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, rb
, cRects
, Mode
);
1036 ExFreePoolWithTag(rb
, GDITAG_PLGBLT_DATA
);
1048 _In_ COLORREF crColor
)
1051 ULONG iOldColor
, iSolidColor
;
1058 pdc
= DC_LockDc(hdc
);
1061 EngSetLastError(ERROR_INVALID_HANDLE
);
1065 /* Check if the DC has no surface (empty mem or info DC) */
1066 if (pdc
->dclevel
.pSurface
== NULL
)
1073 /* Translate the color to the target format */
1074 iSolidColor
= TranslateCOLORREF(pdc
, crColor
);
1076 /* Use the DC's text brush, which is always a solid brush */
1077 pebo
= &pdc
->eboText
;
1079 /* Save the old solid color and set the one for the pixel */
1080 iOldColor
= EBRUSHOBJ_iSetSolidColor(pebo
, iSolidColor
);
1082 /* Save dirty flags and reset dirty text brush flag */
1083 ulDirty
= pdc
->pdcattr
->ulDirty_
;
1084 pdc
->pdcattr
->ulDirty_
&= ~DIRTY_TEXT
;
1086 /* Call the internal function */
1087 bResult
= IntPatBlt(pdc
, x
, y
, 1, 1, PATCOPY
, pebo
);
1089 /* Restore old text brush color and dirty flags */
1090 EBRUSHOBJ_iSetSolidColor(pebo
, iOldColor
);
1091 pdc
->pdcattr
->ulDirty_
= ulDirty
;
1093 /* Initialize an XLATEOBJ from the target surface to RGB */
1094 EXLATEOBJ_vInitialize(&exlo
,
1095 pdc
->dclevel
.pSurface
->ppal
,
1098 pdc
->pdcattr
->crBackgroundClr
,
1099 pdc
->pdcattr
->crForegroundClr
);
1101 /* Translate the color back to RGB */
1102 crColor
= XLATEOBJ_iXlate(&exlo
.xlo
, iSolidColor
);
1104 /* Cleanup and return the target format color */
1105 EXLATEOBJ_vCleanup(&exlo
);
1110 /* Return the new RGB color or -1 on failure */
1111 return bResult
? crColor
: -1;
1122 ULONG ulRGBColor
= CLR_INVALID
;
1124 PSURFACE psurfSrc
, psurfDest
;
1127 pdc
= DC_LockDc(hdc
);
1130 EngSetLastError(ERROR_INVALID_HANDLE
);
1134 /* Check if the DC has no surface (empty mem or info DC) */
1135 psurfSrc
= pdc
->dclevel
.pSurface
;
1136 if (psurfSrc
== NULL
)
1142 /* Get the logical coordinates */
1146 /* Translate coordinates to device coordinates */
1147 IntLPtoDP(pdc
, &ptlSrc
, 1);
1148 ptlSrc
.x
+= pdc
->ptlDCOrig
.x
;
1149 ptlSrc
.y
+= pdc
->ptlDCOrig
.y
;
1151 /* Check if the pixel is outside the surface */
1152 if ((ptlSrc
.x
>= psurfSrc
->SurfObj
.sizlBitmap
.cx
) ||
1153 (ptlSrc
.y
>= psurfSrc
->SurfObj
.sizlBitmap
.cy
))
1159 /* Allocate a surface */
1160 psurfDest
= SURFACE_AllocSurface(STYPE_BITMAP
,
1169 RECTL rclDest
= {0, 0, 1, 1};
1172 /* Translate from the source palette to RGB color */
1173 EXLATEOBJ_vInitialize(&exlo
,
1177 RGB(0xff,0xff,0xff),
1180 /* Call the copy bits function */
1181 EngCopyBits(&psurfDest
->SurfObj
,
1188 /* Cleanup the XLATEOBJ */
1189 EXLATEOBJ_vCleanup(&exlo
);
1191 /* Delete the surface */
1192 GDIOBJ_vDeleteObject(&psurfDest
->BaseObject
);
1199 /* Return the new RGB color or -1 on failure */