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
10 DBG_DEFAULT_CHANNEL(GdiBlt
);
12 #define ROP_USES_SOURCE(Rop) (((((Rop) & 0xCC0000) >> 2) != ((Rop) & 0x330000)) || ((((Rop) & 0xCC000000) >> 2) != ((Rop) & 0x33000000)))
13 #define ROP_USES_MASK(Rop) (((Rop) & 0xFF000000) != (((Rop) & 0xff0000) << 8))
15 #define FIXUP_ROP(Rop) if(((Rop) & 0xFF000000) == 0) Rop = MAKEROP4((Rop), (Rop))
16 #define ROP_TO_ROP4(Rop) ((Rop) >> 16)
30 BLENDFUNCTION BlendFunc
,
37 SURFACE
*BitmapDest
, *BitmapSrc
;
38 RECTL DestRect
, SourceRect
;
42 BlendObj
.BlendFunction
= BlendFunc
;
44 if (WidthDest
< 0 || HeightDest
< 0 || WidthSrc
< 0 || HeightSrc
< 0)
46 EngSetLastError(ERROR_INVALID_PARAMETER
);
50 TRACE("Locking DCs\n");
53 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
55 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hDCDest
, hDCSrc
);
56 EngSetLastError(ERROR_INVALID_HANDLE
);
62 if (DCDest
->dctype
== DC_TYPE_INFO
|| DCDest
->dctype
== DCTYPE_INFO
)
64 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
65 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
66 /* Yes, Windows really returns TRUE in this case */
70 DestRect
.left
= XOriginDest
;
71 DestRect
.top
= YOriginDest
;
72 DestRect
.right
= XOriginDest
+ WidthDest
;
73 DestRect
.bottom
= YOriginDest
+ HeightDest
;
74 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
76 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
77 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
78 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
79 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
81 SourceRect
.left
= XOriginSrc
;
82 SourceRect
.top
= YOriginSrc
;
83 SourceRect
.right
= XOriginSrc
+ WidthSrc
;
84 SourceRect
.bottom
= YOriginSrc
+ HeightSrc
;
85 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
87 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
88 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
89 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
90 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
92 if (!DestRect
.right
||
97 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
98 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
102 /* Prepare DCs for blit */
103 TRACE("Preparing DCs for blit\n");
104 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
106 /* Determine surfaces to be used in the bitblt */
107 BitmapDest
= DCDest
->dclevel
.pSurface
;
114 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
121 /* Create the XLATEOBJ. */
122 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
124 /* Perform the alpha blend operation */
125 TRACE("Performing the alpha blend\n");
126 bResult
= IntEngAlphaBlend(&BitmapDest
->SurfObj
,
128 DCDest
->rosdc
.CombinedClip
,
134 EXLATEOBJ_vCleanup(&exlo
);
136 TRACE("Finishing blit\n");
137 DC_vFinishBlit(DCDest
, DCSrc
);
138 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
139 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
155 IN DWORD crBackColor
,
160 if (ROP
& CAPTUREBLT
)
161 return NtGdiStretchBlt(hDCDest
,
174 dwTRop
= ROP
& ~(NOMIRRORBITMAP
|CAPTUREBLT
);
176 /* Forward to NtGdiMaskBlt */
177 // TODO: What's fl for? LOL not to send this to MaskBit!
178 return NtGdiMaskBlt(hDCDest
,
211 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
212 ULONG TransparentColor
= 0;
216 TRACE("Locking DCs\n");
219 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
221 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDst
, hdcSrc
);
222 EngSetLastError(ERROR_INVALID_HANDLE
);
228 if (DCDest
->dctype
== DC_TYPE_INFO
|| DCDest
->dctype
== DCTYPE_INFO
)
230 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
231 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
232 /* Yes, Windows really returns TRUE in this case */
238 rcDest
.right
= rcDest
.left
+ cxDst
;
239 rcDest
.bottom
= rcDest
.top
+ cyDst
;
240 IntLPtoDP(DCDest
, (LPPOINT
)&rcDest
, 2);
242 rcDest
.left
+= DCDest
->ptlDCOrig
.x
;
243 rcDest
.top
+= DCDest
->ptlDCOrig
.y
;
244 rcDest
.right
+= DCDest
->ptlDCOrig
.x
;
245 rcDest
.bottom
+= DCDest
->ptlDCOrig
.y
;
249 rcSrc
.right
= rcSrc
.left
+ cxSrc
;
250 rcSrc
.bottom
= rcSrc
.top
+ cySrc
;
251 IntLPtoDP(DCSrc
, (LPPOINT
)&rcSrc
, 2);
253 rcSrc
.left
+= DCSrc
->ptlDCOrig
.x
;
254 rcSrc
.top
+= DCSrc
->ptlDCOrig
.y
;
255 rcSrc
.right
+= DCSrc
->ptlDCOrig
.x
;
256 rcSrc
.bottom
+= DCSrc
->ptlDCOrig
.y
;
258 /* Prepare for blit */
259 DC_vPrepareDCsForBlit(DCDest
, rcDest
, DCSrc
, rcSrc
);
261 BitmapDest
= DCDest
->dclevel
.pSurface
;
267 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
273 /* Translate Transparent (RGB) Color to the source palette */
274 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, BitmapSrc
->ppal
, 0, 0, 0);
275 TransparentColor
= XLATEOBJ_iXlate(&exlo
.xlo
, (ULONG
)TransColor
);
276 EXLATEOBJ_vCleanup(&exlo
);
278 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
280 Ret
= IntEngTransparentBlt(&BitmapDest
->SurfObj
, &BitmapSrc
->SurfObj
,
281 DCDest
->rosdc
.CombinedClip
, &exlo
.xlo
, &rcDest
, &rcSrc
,
282 TransparentColor
, 0);
284 EXLATEOBJ_vCleanup(&exlo
);
287 DC_vFinishBlit(DCDest
, DCSrc
);
288 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
289 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
308 IN DWORD crBackColor
)
314 PDC_ATTR pdcattr
= NULL
;
315 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
, *psurfMask
= NULL
;
316 RECTL DestRect
, SourceRect
;
317 POINTL SourcePoint
, MaskPoint
;
320 XLATEOBJ
*XlateObj
= NULL
;
321 BOOL UsesSource
= ROP_USES_SOURCE(dwRop
);
326 UsesMask
= ROP_USES_MASK(dwRop
);
328 //DPRINT1("dwRop : 0x%08x\n", dwRop);
329 if (!hdcDest
|| (UsesSource
&& !hdcSrc
))
331 EngSetLastError(ERROR_INVALID_PARAMETER
);
335 /* Take care of mask bitmap */
338 psurfMask
= SURFACE_ShareLockSurface(hbmMask
);
341 EngSetLastError(ERROR_INVALID_HANDLE
);
350 EngSetLastError(ERROR_INVALID_PARAMETER
);
353 if(gajBitsPerFormat
[psurfMask
->SurfObj
.iBitmapFormat
] != 1)
355 EngSetLastError(ERROR_INVALID_PARAMETER
);
356 SURFACE_ShareUnlockSurface(psurfMask
);
362 WARN("Getting Mask bitmap without needing it?\n");
363 SURFACE_ShareUnlockSurface(psurfMask
);
369 /* Take care of source and destination bitmap */
370 TRACE("Locking DCs\n");
372 ahDC
[1] = UsesSource
? hdcSrc
: NULL
;
373 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
375 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDest
, hdcSrc
);
376 EngSetLastError(ERROR_INVALID_HANDLE
);
385 if(DCSrc
) DC_UnlockDc(DCSrc
);
386 WARN("Invalid destination dc handle (0x%p) passed to NtGdiBitBlt\n", hdcDest
);
390 if (DCDest
->dctype
== DC_TYPE_INFO
)
392 if(DCSrc
) DC_UnlockDc(DCSrc
);
394 /* Yes, Windows really returns TRUE in this case */
401 if (DCSrc
->dctype
== DC_TYPE_INFO
)
405 /* Yes, Windows really returns TRUE in this case */
410 pdcattr
= DCDest
->pdcattr
;
412 DestRect
.left
= nXDest
;
413 DestRect
.top
= nYDest
;
414 DestRect
.right
= nXDest
+ nWidth
;
415 DestRect
.bottom
= nYDest
+ nHeight
;
416 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
418 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
419 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
420 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
421 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
423 SourcePoint
.x
= nXSrc
;
424 SourcePoint
.y
= nYSrc
;
428 IntLPtoDP(DCSrc
, (LPPOINT
)&SourcePoint
, 1);
430 SourcePoint
.x
+= DCSrc
->ptlDCOrig
.x
;
431 SourcePoint
.y
+= DCSrc
->ptlDCOrig
.y
;
432 /* Calculate Source Rect */
433 SourceRect
.left
= SourcePoint
.x
;
434 SourceRect
.top
= SourcePoint
.y
;
435 SourceRect
.right
= SourcePoint
.x
+ DestRect
.right
- DestRect
.left
;
436 SourceRect
.bottom
= SourcePoint
.y
+ DestRect
.bottom
- DestRect
.top
;
442 SourceRect
.right
= 0;
443 SourceRect
.bottom
= 0;
447 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
449 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
450 DC_vUpdateFillBrush(DCDest
);
452 /* Determine surfaces to be used in the bitblt */
453 BitmapDest
= DCDest
->dclevel
.pSurface
;
460 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
466 /* Create the XLATEOBJ. */
469 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
470 XlateObj
= &exlo
.xlo
;
474 /* Perform the bitblt operation */
475 Status
= IntEngBitBlt(&BitmapDest
->SurfObj
,
476 BitmapSrc
? &BitmapSrc
->SurfObj
: NULL
,
477 psurfMask
? &psurfMask
->SurfObj
: NULL
,
478 DCDest
->rosdc
.CombinedClip
,
483 &DCDest
->eboFill
.BrushObject
,
484 &DCDest
->dclevel
.pbrFill
->ptOrigin
,
488 EXLATEOBJ_vCleanup(&exlo
);
490 DC_vFinishBlit(DCDest
, DCSrc
);
496 if(psurfMask
) SURFACE_ShareUnlockSurface(psurfMask
);
514 IN DWORD crBackColor
)
516 FIXME("NtGdiPlgBlt: unimplemented.\n");
533 IN DWORD dwBackColor
,
544 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
545 SURFACE
*BitmapMask
= NULL
;
551 XLATEOBJ
*XlateObj
= NULL
;
557 UsesSource
= ROP_USES_SOURCE(ROP
);
558 UsesMask
= ROP_USES_MASK(ROP
);
560 if (0 == WidthDest
|| 0 == HeightDest
|| 0 == WidthSrc
|| 0 == HeightSrc
)
562 EngSetLastError(ERROR_INVALID_PARAMETER
);
566 if (!hDCDest
|| (UsesSource
&& !hDCSrc
) || (UsesMask
&& !hDCMask
))
568 EngSetLastError(ERROR_INVALID_PARAMETER
);
573 ahDC
[1] = UsesSource
? hDCSrc
: NULL
;
574 ahDC
[2] = UsesMask
? hDCMask
: NULL
;
575 if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
577 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to GreStretchBltMask\n", hDCDest
, hDCSrc
);
578 EngSetLastError(ERROR_INVALID_HANDLE
);
585 if (DCDest
->dctype
== DC_TYPE_INFO
)
587 if(DCSrc
) GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
588 if(DCMask
) GDIOBJ_vUnlockObject(&DCMask
->BaseObject
);
589 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
590 /* Yes, Windows really returns TRUE in this case */
596 if (DCSrc
->dctype
== DC_TYPE_INFO
)
598 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
599 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
600 if(DCMask
) GDIOBJ_vUnlockObject(&DCMask
->BaseObject
);
601 /* Yes, Windows really returns TRUE in this case */
606 pdcattr
= DCDest
->pdcattr
;
608 DestRect
.left
= XOriginDest
;
609 DestRect
.top
= YOriginDest
;
610 DestRect
.right
= XOriginDest
+WidthDest
;
611 DestRect
.bottom
= YOriginDest
+HeightDest
;
612 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
614 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
615 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
616 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
617 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
619 SourceRect
.left
= XOriginSrc
;
620 SourceRect
.top
= YOriginSrc
;
621 SourceRect
.right
= XOriginSrc
+WidthSrc
;
622 SourceRect
.bottom
= YOriginSrc
+HeightSrc
;
626 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
628 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
629 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
630 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
631 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
637 /* Only prepare Source and Dest, hdcMask represents a DIB */
638 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
640 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
641 DC_vUpdateFillBrush(DCDest
);
643 /* Determine surfaces to be used in the bitblt */
644 BitmapDest
= DCDest
->dclevel
.pSurface
;
645 if (BitmapDest
== NULL
)
649 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
650 if (BitmapSrc
== NULL
)
653 /* Create the XLATEOBJ. */
654 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
655 XlateObj
= &exlo
.xlo
;
658 /* Offset the brush */
659 BrushOrigin
.x
+= DCDest
->ptlDCOrig
.x
;
660 BrushOrigin
.y
+= DCDest
->ptlDCOrig
.y
;
662 /* Make mask surface for source surface */
663 if (BitmapSrc
&& DCMask
)
665 BitmapMask
= DCMask
->dclevel
.pSurface
;
667 (BitmapMask
->SurfObj
.sizlBitmap
.cx
< WidthSrc
||
668 BitmapMask
->SurfObj
.sizlBitmap
.cy
< HeightSrc
))
670 WARN("%dx%d mask is smaller than %dx%d bitmap\n",
671 BitmapMask
->SurfObj
.sizlBitmap
.cx
, BitmapMask
->SurfObj
.sizlBitmap
.cy
,
672 WidthSrc
, HeightSrc
);
673 EXLATEOBJ_vCleanup(&exlo
);
676 /* Create mask offset point */
677 MaskPoint
.x
= XOriginMask
;
678 MaskPoint
.y
= YOriginMask
;
679 IntLPtoDP(DCMask
, &MaskPoint
, 1);
680 MaskPoint
.x
+= DCMask
->ptlDCOrig
.x
;
681 MaskPoint
.y
+= DCMask
->ptlDCOrig
.y
;
684 /* Perform the bitblt operation */
685 Status
= IntEngStretchBlt(&BitmapDest
->SurfObj
,
686 BitmapSrc
? &BitmapSrc
->SurfObj
: NULL
,
687 BitmapMask
? &BitmapMask
->SurfObj
: NULL
,
688 DCDest
->rosdc
.CombinedClip
,
693 BitmapMask
? &MaskPoint
: NULL
,
694 &DCDest
->eboFill
.BrushObject
,
699 EXLATEOBJ_vCleanup(&exlo
);
703 DC_vFinishBlit(DCDest
, DCSrc
);
731 IN DWORD dwBackColor
)
733 DWORD dwTRop
= ROP
& ~(NOMIRRORBITMAP
|CAPTUREBLT
);
735 return GreStretchBltMask(
771 pbrush
= pebo
->pbrush
;
776 if (pbrush
->flAttrs
& BR_IS_NULL
)
783 DestRect
.left
= XLeft
;
784 DestRect
.right
= XLeft
+ Width
;
788 DestRect
.left
= XLeft
+ Width
+ 1;
789 DestRect
.right
= XLeft
+ 1;
794 DestRect
.top
= YLeft
;
795 DestRect
.bottom
= YLeft
+ Height
;
799 DestRect
.top
= YLeft
+ Height
+ 1;
800 DestRect
.bottom
= YLeft
+ 1;
803 IntLPtoDP(pdc
, (LPPOINT
)&DestRect
, 2);
805 DestRect
.left
+= pdc
->ptlDCOrig
.x
;
806 DestRect
.top
+= pdc
->ptlDCOrig
.y
;
807 DestRect
.right
+= pdc
->ptlDCOrig
.x
;
808 DestRect
.bottom
+= pdc
->ptlDCOrig
.y
;
810 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
+ XLeft
;
811 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
+ YLeft
;
813 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
;
814 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
;
817 DC_vPrepareDCsForBlit(pdc
, DestRect
, NULL
, DestRect
);
819 psurf
= pdc
->dclevel
.pSurface
;
825 pdc
->rosdc
.CombinedClip
,
834 DC_vFinishBlit(pdc
, NULL
);
852 pdc
= DC_LockDc(hDC
);
855 EngSetLastError(ERROR_INVALID_HANDLE
);
859 if (pdc
->dctype
== DC_TYPE_INFO
)
862 /* Yes, Windows really returns TRUE in this case */
866 for (i
= 0; i
< cRects
; i
++)
868 pbrush
= BRUSH_ShareLockBrush(pRects
->hBrush
);
870 /* Check if we could lock the brush */
873 /* Initialize a brush object */
874 EBRUSHOBJ_vInitFromDC(&eboFill
, pbrush
, pdc
);
885 /* Cleanup the brush object and unlock the brush */
886 EBRUSHOBJ_vCleanup(&eboFill
);
887 BRUSH_ShareUnlockBrush(pbrush
);
910 /* Mask away everything except foreground rop index */
911 dwRop
= dwRop
& 0x00FF0000;
914 /* Check if the rop uses a source */
915 if (ROP_USES_SOURCE(dwRop
))
917 /* This is not possible */
922 pdc
= DC_LockDc(hdcDest
);
925 EngSetLastError(ERROR_INVALID_HANDLE
);
929 /* Check if the DC has no surface (empty mem or info DC) */
930 if (pdc
->dclevel
.pSurface
== NULL
)
932 /* Nothing to do, Windows returns TRUE! */
937 /* Update the fill brush, if neccessary */
938 if (pdc
->pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
939 DC_vUpdateFillBrush(pdc
);
941 /* Call the internal function */
942 bResult
= IntPatBlt(pdc
, x
, y
, cx
, cy
, dwRop
, &pdc
->eboFill
);
944 /* Unlock the DC and return the result */
954 IN PPOLYPATBLT pRects
,
959 NTSTATUS Status
= STATUS_SUCCESS
;
964 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, GDITAG_PLGBLT_DATA
);
967 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
973 cRects
* sizeof(PATRECT
),
977 cRects
* sizeof(PATRECT
));
979 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
981 Status
= _SEH2_GetExceptionCode();
985 if (!NT_SUCCESS(Status
))
987 ExFreePoolWithTag(rb
, GDITAG_PLGBLT_DATA
);
988 SetLastNtError(Status
);
993 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, rb
, cRects
, Mode
);
996 ExFreePoolWithTag(rb
, GDITAG_PLGBLT_DATA
);
1008 _In_ COLORREF crColor
)
1011 ULONG iOldColor
, iSolidColor
;
1018 pdc
= DC_LockDc(hdc
);
1021 EngSetLastError(ERROR_INVALID_HANDLE
);
1025 /* Check if the DC has no surface (empty mem or info DC) */
1026 if (pdc
->dclevel
.pSurface
== NULL
)
1033 /* Translate the color to the target format */
1034 iSolidColor
= TranslateCOLORREF(pdc
, crColor
);
1036 /* Use the DC's text brush, which is always a solid brush */
1037 pebo
= &pdc
->eboText
;
1039 /* Save the old solid color and set the one for the pixel */
1040 iOldColor
= EBRUSHOBJ_iSetSolidColor(pebo
, iSolidColor
);
1042 /* Save dirty flags and reset dirty text brush flag */
1043 ulDirty
= pdc
->pdcattr
->ulDirty_
;
1044 pdc
->pdcattr
->ulDirty_
&= ~DIRTY_TEXT
;
1046 /* Call the internal function */
1047 bResult
= IntPatBlt(pdc
, x
, y
, 1, 1, PATCOPY
, pebo
);
1049 /* Restore old text brush color and dirty flags */
1050 EBRUSHOBJ_iSetSolidColor(pebo
, iOldColor
);
1051 pdc
->pdcattr
->ulDirty_
= ulDirty
;
1053 /* Initialize an XLATEOBJ from the target surface to RGB */
1054 EXLATEOBJ_vInitialize(&exlo
,
1055 pdc
->dclevel
.pSurface
->ppal
,
1058 pdc
->pdcattr
->crBackgroundClr
,
1059 pdc
->pdcattr
->crForegroundClr
);
1061 /* Translate the color back to RGB */
1062 crColor
= XLATEOBJ_iXlate(&exlo
.xlo
, iSolidColor
);
1064 /* Cleanup and return the target format color */
1065 EXLATEOBJ_vCleanup(&exlo
);
1070 /* Return the new RGB color or -1 on failure */
1071 return bResult
? crColor
: -1;
1082 ULONG ulRGBColor
= CLR_INVALID
;
1084 PSURFACE psurfSrc
, psurfDest
;
1087 pdc
= DC_LockDc(hdc
);
1090 EngSetLastError(ERROR_INVALID_HANDLE
);
1094 /* Check if the DC has no surface (empty mem or info DC) */
1095 psurfSrc
= pdc
->dclevel
.pSurface
;
1096 if (psurfSrc
== NULL
)
1102 /* Get the logical coordinates */
1106 /* Translate coordinates to device coordinates */
1107 IntLPtoDP(pdc
, &ptlSrc
, 1);
1108 ptlSrc
.x
+= pdc
->ptlDCOrig
.x
;
1109 ptlSrc
.y
+= pdc
->ptlDCOrig
.y
;
1111 /* Check if the pixel is outside the surface */
1112 if ((ptlSrc
.x
>= psurfSrc
->SurfObj
.sizlBitmap
.cx
) ||
1113 (ptlSrc
.y
>= psurfSrc
->SurfObj
.sizlBitmap
.cy
))
1119 /* Allocate a surface */
1120 psurfDest
= SURFACE_AllocSurface(STYPE_BITMAP
,
1129 RECTL rclDest
= {0, 0, 1, 1};
1132 /* Translate from the source palette to RGB color */
1133 EXLATEOBJ_vInitialize(&exlo
,
1137 RGB(0xff,0xff,0xff),
1140 /* Call the copy bits function */
1141 EngCopyBits(&psurfDest
->SurfObj
,
1148 /* Cleanup the XLATEOBJ */
1149 EXLATEOBJ_vCleanup(&exlo
);
1151 /* Delete the surface */
1152 GDIOBJ_vDeleteObject(&psurfDest
->BaseObject
);
1159 /* Return the new RGB color or -1 on failure */