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 if ((hDCDest
== NULL
) || (hDCSrc
== NULL
))
52 EngSetLastError(ERROR_INVALID_PARAMETER
);
56 TRACE("Locking DCs\n");
59 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
61 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hDCDest
, hDCSrc
);
62 EngSetLastError(ERROR_INVALID_HANDLE
);
68 if (DCDest
->dctype
== DC_TYPE_INFO
|| DCDest
->dctype
== DCTYPE_INFO
)
70 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
71 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
72 /* Yes, Windows really returns TRUE in this case */
76 DestRect
.left
= XOriginDest
;
77 DestRect
.top
= YOriginDest
;
78 DestRect
.right
= XOriginDest
+ WidthDest
;
79 DestRect
.bottom
= YOriginDest
+ HeightDest
;
80 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
82 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
83 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
84 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
85 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
87 SourceRect
.left
= XOriginSrc
;
88 SourceRect
.top
= YOriginSrc
;
89 SourceRect
.right
= XOriginSrc
+ WidthSrc
;
90 SourceRect
.bottom
= YOriginSrc
+ HeightSrc
;
91 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
93 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
94 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
95 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
96 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
98 if (!DestRect
.right
||
103 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
104 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
108 /* Prepare DCs for blit */
109 TRACE("Preparing DCs for blit\n");
110 DC_vPrepareDCsForBlit(DCDest
, &DestRect
, DCSrc
, &SourceRect
);
112 /* Determine surfaces to be used in the bitblt */
113 BitmapDest
= DCDest
->dclevel
.pSurface
;
120 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
127 /* Create the XLATEOBJ. */
128 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
130 /* Perform the alpha blend operation */
131 TRACE("Performing the alpha blend\n");
132 bResult
= IntEngAlphaBlend(&BitmapDest
->SurfObj
,
140 EXLATEOBJ_vCleanup(&exlo
);
142 TRACE("Finishing blit\n");
143 DC_vFinishBlit(DCDest
, DCSrc
);
144 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
145 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
161 IN DWORD crBackColor
,
166 if (ROP
& CAPTUREBLT
)
167 return NtGdiStretchBlt(hDCDest
,
180 dwTRop
= ROP
& ~(NOMIRRORBITMAP
|CAPTUREBLT
);
182 /* Forward to NtGdiMaskBlt */
183 // TODO: What's fl for? LOL not to send this to MaskBit!
184 return NtGdiMaskBlt(hDCDest
,
217 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
218 ULONG TransparentColor
= 0;
222 if ((hdcDst
== NULL
) || (hdcSrc
== NULL
))
224 EngSetLastError(ERROR_INVALID_PARAMETER
);
228 TRACE("Locking DCs\n");
231 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
233 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDst
, hdcSrc
);
234 EngSetLastError(ERROR_INVALID_HANDLE
);
240 if (DCDest
->dctype
== DC_TYPE_INFO
|| DCDest
->dctype
== DCTYPE_INFO
)
242 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
243 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
244 /* Yes, Windows really returns TRUE in this case */
250 rcDest
.right
= rcDest
.left
+ cxDst
;
251 rcDest
.bottom
= rcDest
.top
+ cyDst
;
252 IntLPtoDP(DCDest
, (LPPOINT
)&rcDest
, 2);
254 rcDest
.left
+= DCDest
->ptlDCOrig
.x
;
255 rcDest
.top
+= DCDest
->ptlDCOrig
.y
;
256 rcDest
.right
+= DCDest
->ptlDCOrig
.x
;
257 rcDest
.bottom
+= DCDest
->ptlDCOrig
.y
;
261 rcSrc
.right
= rcSrc
.left
+ cxSrc
;
262 rcSrc
.bottom
= rcSrc
.top
+ cySrc
;
263 IntLPtoDP(DCSrc
, (LPPOINT
)&rcSrc
, 2);
265 rcSrc
.left
+= DCSrc
->ptlDCOrig
.x
;
266 rcSrc
.top
+= DCSrc
->ptlDCOrig
.y
;
267 rcSrc
.right
+= DCSrc
->ptlDCOrig
.x
;
268 rcSrc
.bottom
+= DCSrc
->ptlDCOrig
.y
;
270 /* Prepare for blit */
271 DC_vPrepareDCsForBlit(DCDest
, &rcDest
, DCSrc
, &rcSrc
);
273 BitmapDest
= DCDest
->dclevel
.pSurface
;
279 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
285 /* Translate Transparent (RGB) Color to the source palette */
286 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, BitmapSrc
->ppal
, 0, 0, 0);
287 TransparentColor
= XLATEOBJ_iXlate(&exlo
.xlo
, (ULONG
)TransColor
);
288 EXLATEOBJ_vCleanup(&exlo
);
290 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
292 Ret
= IntEngTransparentBlt(&BitmapDest
->SurfObj
, &BitmapSrc
->SurfObj
,
293 &DCDest
->co
.ClipObj
, &exlo
.xlo
, &rcDest
, &rcSrc
,
294 TransparentColor
, 0);
296 EXLATEOBJ_vCleanup(&exlo
);
299 DC_vFinishBlit(DCDest
, DCSrc
);
300 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
301 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
320 IN DWORD crBackColor
)
326 PDC_ATTR pdcattr
= NULL
;
327 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
, *psurfMask
= NULL
;
328 RECTL DestRect
, SourceRect
;
329 POINTL SourcePoint
, MaskPoint
;
332 XLATEOBJ
*XlateObj
= NULL
;
333 BOOL UsesSource
= ROP_USES_SOURCE(dwRop
);
338 UsesMask
= ROP_USES_MASK(dwRop
);
340 //DPRINT1("dwRop : 0x%08x\n", dwRop);
341 if (!hdcDest
|| (UsesSource
&& !hdcSrc
))
343 EngSetLastError(ERROR_INVALID_PARAMETER
);
347 /* Take care of mask bitmap */
350 psurfMask
= SURFACE_ShareLockSurface(hbmMask
);
353 EngSetLastError(ERROR_INVALID_HANDLE
);
362 EngSetLastError(ERROR_INVALID_PARAMETER
);
365 if(gajBitsPerFormat
[psurfMask
->SurfObj
.iBitmapFormat
] != 1)
367 EngSetLastError(ERROR_INVALID_PARAMETER
);
368 SURFACE_ShareUnlockSurface(psurfMask
);
374 WARN("Getting Mask bitmap without needing it?\n");
375 SURFACE_ShareUnlockSurface(psurfMask
);
381 /* Take care of source and destination bitmap */
382 TRACE("Locking DCs\n");
384 ahDC
[1] = UsesSource
? hdcSrc
: NULL
;
385 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
387 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDest
, hdcSrc
);
388 EngSetLastError(ERROR_INVALID_HANDLE
);
397 if(DCSrc
) DC_UnlockDc(DCSrc
);
398 WARN("Invalid destination dc handle (0x%p) passed to NtGdiBitBlt\n", hdcDest
);
402 if (DCDest
->dctype
== DC_TYPE_INFO
)
404 if(DCSrc
) DC_UnlockDc(DCSrc
);
406 /* Yes, Windows really returns TRUE in this case */
413 if (DCSrc
->dctype
== DC_TYPE_INFO
)
417 /* Yes, Windows really returns TRUE in this case */
422 pdcattr
= DCDest
->pdcattr
;
424 DestRect
.left
= nXDest
;
425 DestRect
.top
= nYDest
;
426 DestRect
.right
= nXDest
+ nWidth
;
427 DestRect
.bottom
= nYDest
+ nHeight
;
428 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
430 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
431 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
432 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
433 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
435 SourcePoint
.x
= nXSrc
;
436 SourcePoint
.y
= nYSrc
;
440 IntLPtoDP(DCSrc
, (LPPOINT
)&SourcePoint
, 1);
442 SourcePoint
.x
+= DCSrc
->ptlDCOrig
.x
;
443 SourcePoint
.y
+= DCSrc
->ptlDCOrig
.y
;
444 /* Calculate Source Rect */
445 SourceRect
.left
= SourcePoint
.x
;
446 SourceRect
.top
= SourcePoint
.y
;
447 SourceRect
.right
= SourcePoint
.x
+ DestRect
.right
- DestRect
.left
;
448 SourceRect
.bottom
= SourcePoint
.y
+ DestRect
.bottom
- DestRect
.top
;
454 SourceRect
.right
= 0;
455 SourceRect
.bottom
= 0;
459 DC_vPrepareDCsForBlit(DCDest
, &DestRect
, DCSrc
, &SourceRect
);
461 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
462 DC_vUpdateFillBrush(DCDest
);
464 /* Determine surfaces to be used in the bitblt */
465 BitmapDest
= DCDest
->dclevel
.pSurface
;
472 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
478 /* Create the XLATEOBJ. */
481 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
482 XlateObj
= &exlo
.xlo
;
486 /* Perform the bitblt operation */
487 Status
= IntEngBitBlt(&BitmapDest
->SurfObj
,
488 BitmapSrc
? &BitmapSrc
->SurfObj
: NULL
,
489 psurfMask
? &psurfMask
->SurfObj
: NULL
,
495 &DCDest
->eboFill
.BrushObject
,
496 &DCDest
->dclevel
.pbrFill
->ptOrigin
,
500 EXLATEOBJ_vCleanup(&exlo
);
502 DC_vFinishBlit(DCDest
, DCSrc
);
508 if(psurfMask
) SURFACE_ShareUnlockSurface(psurfMask
);
526 IN DWORD crBackColor
)
528 FIXME("NtGdiPlgBlt: unimplemented.\n");
545 IN DWORD dwBackColor
,
556 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
557 SURFACE
*BitmapMask
= NULL
;
563 XLATEOBJ
*XlateObj
= NULL
;
569 UsesSource
= ROP_USES_SOURCE(ROP
);
570 UsesMask
= ROP_USES_MASK(ROP
);
572 if (0 == WidthDest
|| 0 == HeightDest
|| 0 == WidthSrc
|| 0 == HeightSrc
)
574 EngSetLastError(ERROR_INVALID_PARAMETER
);
578 if (!hDCDest
|| (UsesSource
&& !hDCSrc
) || (UsesMask
&& !hDCMask
))
580 EngSetLastError(ERROR_INVALID_PARAMETER
);
585 ahDC
[1] = UsesSource
? hDCSrc
: NULL
;
586 ahDC
[2] = UsesMask
? hDCMask
: NULL
;
587 if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
589 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to GreStretchBltMask\n", hDCDest
, hDCSrc
);
590 EngSetLastError(ERROR_INVALID_HANDLE
);
597 if (DCDest
->dctype
== DC_TYPE_INFO
)
599 if(DCSrc
) GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
600 if(DCMask
) GDIOBJ_vUnlockObject(&DCMask
->BaseObject
);
601 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
602 /* Yes, Windows really returns TRUE in this case */
608 if (DCSrc
->dctype
== DC_TYPE_INFO
)
610 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
611 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
612 if(DCMask
) GDIOBJ_vUnlockObject(&DCMask
->BaseObject
);
613 /* Yes, Windows really returns TRUE in this case */
618 pdcattr
= DCDest
->pdcattr
;
620 DestRect
.left
= XOriginDest
;
621 DestRect
.top
= YOriginDest
;
622 DestRect
.right
= XOriginDest
+WidthDest
;
623 DestRect
.bottom
= YOriginDest
+HeightDest
;
624 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
626 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
627 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
628 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
629 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
631 SourceRect
.left
= XOriginSrc
;
632 SourceRect
.top
= YOriginSrc
;
633 SourceRect
.right
= XOriginSrc
+WidthSrc
;
634 SourceRect
.bottom
= YOriginSrc
+HeightSrc
;
638 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
640 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
641 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
642 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
643 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
649 /* Only prepare Source and Dest, hdcMask represents a DIB */
650 DC_vPrepareDCsForBlit(DCDest
, &DestRect
, DCSrc
, &SourceRect
);
652 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
653 DC_vUpdateFillBrush(DCDest
);
655 /* Determine surfaces to be used in the bitblt */
656 BitmapDest
= DCDest
->dclevel
.pSurface
;
657 if (BitmapDest
== NULL
)
661 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
662 if (BitmapSrc
== NULL
)
665 /* Create the XLATEOBJ. */
666 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
667 XlateObj
= &exlo
.xlo
;
670 /* Offset the brush */
671 BrushOrigin
.x
+= DCDest
->ptlDCOrig
.x
;
672 BrushOrigin
.y
+= DCDest
->ptlDCOrig
.y
;
674 /* Make mask surface for source surface */
675 if (BitmapSrc
&& DCMask
)
677 BitmapMask
= DCMask
->dclevel
.pSurface
;
679 (BitmapMask
->SurfObj
.sizlBitmap
.cx
< WidthSrc
||
680 BitmapMask
->SurfObj
.sizlBitmap
.cy
< HeightSrc
))
682 WARN("%dx%d mask is smaller than %dx%d bitmap\n",
683 BitmapMask
->SurfObj
.sizlBitmap
.cx
, BitmapMask
->SurfObj
.sizlBitmap
.cy
,
684 WidthSrc
, HeightSrc
);
685 EXLATEOBJ_vCleanup(&exlo
);
688 /* Create mask offset point */
689 MaskPoint
.x
= XOriginMask
;
690 MaskPoint
.y
= YOriginMask
;
691 IntLPtoDP(DCMask
, &MaskPoint
, 1);
692 MaskPoint
.x
+= DCMask
->ptlDCOrig
.x
;
693 MaskPoint
.y
+= DCMask
->ptlDCOrig
.y
;
696 /* Perform the bitblt operation */
697 Status
= IntEngStretchBlt(&BitmapDest
->SurfObj
,
698 BitmapSrc
? &BitmapSrc
->SurfObj
: NULL
,
699 BitmapMask
? &BitmapMask
->SurfObj
: NULL
,
705 BitmapMask
? &MaskPoint
: NULL
,
706 &DCDest
->eboFill
.BrushObject
,
711 EXLATEOBJ_vCleanup(&exlo
);
715 DC_vFinishBlit(DCDest
, DCSrc
);
743 IN DWORD dwBackColor
)
745 DWORD dwTRop
= ROP
& ~(NOMIRRORBITMAP
|CAPTUREBLT
);
747 return GreStretchBltMask(
783 pbrush
= pebo
->pbrush
;
788 if (pbrush
->flAttrs
& BR_IS_NULL
)
795 DestRect
.left
= XLeft
;
796 DestRect
.right
= XLeft
+ Width
;
800 DestRect
.left
= XLeft
+ Width
+ 1;
801 DestRect
.right
= XLeft
+ 1;
806 DestRect
.top
= YLeft
;
807 DestRect
.bottom
= YLeft
+ Height
;
811 DestRect
.top
= YLeft
+ Height
+ 1;
812 DestRect
.bottom
= YLeft
+ 1;
815 IntLPtoDP(pdc
, (LPPOINT
)&DestRect
, 2);
817 DestRect
.left
+= pdc
->ptlDCOrig
.x
;
818 DestRect
.top
+= pdc
->ptlDCOrig
.y
;
819 DestRect
.right
+= pdc
->ptlDCOrig
.x
;
820 DestRect
.bottom
+= pdc
->ptlDCOrig
.y
;
822 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
+ XLeft
;
823 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
+ YLeft
;
825 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
;
826 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
;
829 DC_vPrepareDCsForBlit(pdc
, &DestRect
, NULL
, NULL
);
831 psurf
= pdc
->dclevel
.pSurface
;
846 DC_vFinishBlit(pdc
, NULL
);
864 pdc
= DC_LockDc(hDC
);
867 EngSetLastError(ERROR_INVALID_HANDLE
);
871 if (pdc
->dctype
== DC_TYPE_INFO
)
874 /* Yes, Windows really returns TRUE in this case */
878 for (i
= 0; i
< cRects
; i
++)
880 pbrush
= BRUSH_ShareLockBrush(pRects
->hBrush
);
882 /* Check if we could lock the brush */
885 /* Initialize a brush object */
886 EBRUSHOBJ_vInitFromDC(&eboFill
, pbrush
, pdc
);
897 /* Cleanup the brush object and unlock the brush */
898 EBRUSHOBJ_vCleanup(&eboFill
);
899 BRUSH_ShareUnlockBrush(pbrush
);
922 /* Mask away everything except foreground rop index */
923 dwRop
= dwRop
& 0x00FF0000;
926 /* Check if the rop uses a source */
927 if (ROP_USES_SOURCE(dwRop
))
929 /* This is not possible */
934 pdc
= DC_LockDc(hdcDest
);
937 EngSetLastError(ERROR_INVALID_HANDLE
);
941 /* Check if the DC has no surface (empty mem or info DC) */
942 if (pdc
->dclevel
.pSurface
== NULL
)
944 /* Nothing to do, Windows returns TRUE! */
949 /* Update the fill brush, if neccessary */
950 if (pdc
->pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
951 DC_vUpdateFillBrush(pdc
);
953 /* Call the internal function */
954 bResult
= IntPatBlt(pdc
, x
, y
, cx
, cy
, dwRop
, &pdc
->eboFill
);
956 /* Unlock the DC and return the result */
966 IN PPOLYPATBLT pRects
,
971 NTSTATUS Status
= STATUS_SUCCESS
;
976 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, GDITAG_PLGBLT_DATA
);
979 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
985 cRects
* sizeof(PATRECT
),
989 cRects
* sizeof(PATRECT
));
991 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
993 Status
= _SEH2_GetExceptionCode();
997 if (!NT_SUCCESS(Status
))
999 ExFreePoolWithTag(rb
, GDITAG_PLGBLT_DATA
);
1000 SetLastNtError(Status
);
1005 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, rb
, cRects
, Mode
);
1008 ExFreePoolWithTag(rb
, GDITAG_PLGBLT_DATA
);
1020 _In_ COLORREF crColor
)
1023 ULONG iOldColor
, iSolidColor
;
1030 pdc
= DC_LockDc(hdc
);
1033 EngSetLastError(ERROR_INVALID_HANDLE
);
1037 /* Check if the DC has no surface (empty mem or info DC) */
1038 if (pdc
->dclevel
.pSurface
== NULL
)
1045 /* Translate the color to the target format */
1046 iSolidColor
= TranslateCOLORREF(pdc
, crColor
);
1048 /* Use the DC's text brush, which is always a solid brush */
1049 pebo
= &pdc
->eboText
;
1051 /* Save the old solid color and set the one for the pixel */
1052 iOldColor
= EBRUSHOBJ_iSetSolidColor(pebo
, iSolidColor
);
1054 /* Save dirty flags and reset dirty text brush flag */
1055 ulDirty
= pdc
->pdcattr
->ulDirty_
;
1056 pdc
->pdcattr
->ulDirty_
&= ~DIRTY_TEXT
;
1058 /* Call the internal function */
1059 bResult
= IntPatBlt(pdc
, x
, y
, 1, 1, PATCOPY
, pebo
);
1061 /* Restore old text brush color and dirty flags */
1062 EBRUSHOBJ_iSetSolidColor(pebo
, iOldColor
);
1063 pdc
->pdcattr
->ulDirty_
= ulDirty
;
1065 /* Initialize an XLATEOBJ from the target surface to RGB */
1066 EXLATEOBJ_vInitialize(&exlo
,
1067 pdc
->dclevel
.pSurface
->ppal
,
1070 pdc
->pdcattr
->crBackgroundClr
,
1071 pdc
->pdcattr
->crForegroundClr
);
1073 /* Translate the color back to RGB */
1074 crColor
= XLATEOBJ_iXlate(&exlo
.xlo
, iSolidColor
);
1076 /* Cleanup and return the target format color */
1077 EXLATEOBJ_vCleanup(&exlo
);
1082 /* Return the new RGB color or -1 on failure */
1083 return bResult
? crColor
: -1;
1094 ULONG ulRGBColor
= CLR_INVALID
;
1096 PSURFACE psurfSrc
, psurfDest
;
1099 pdc
= DC_LockDc(hdc
);
1102 EngSetLastError(ERROR_INVALID_HANDLE
);
1106 /* Check if the DC has no surface (empty mem or info DC) */
1107 psurfSrc
= pdc
->dclevel
.pSurface
;
1108 if (psurfSrc
== NULL
)
1114 /* Get the logical coordinates */
1118 /* Translate coordinates to device coordinates */
1119 IntLPtoDP(pdc
, &ptlSrc
, 1);
1120 ptlSrc
.x
+= pdc
->ptlDCOrig
.x
;
1121 ptlSrc
.y
+= pdc
->ptlDCOrig
.y
;
1123 /* Check if the pixel is outside the surface */
1124 if ((ptlSrc
.x
>= psurfSrc
->SurfObj
.sizlBitmap
.cx
) ||
1125 (ptlSrc
.y
>= psurfSrc
->SurfObj
.sizlBitmap
.cy
))
1131 /* Allocate a surface */
1132 psurfDest
= SURFACE_AllocSurface(STYPE_BITMAP
,
1141 RECTL rclDest
= {0, 0, 1, 1};
1144 /* Translate from the source palette to RGB color */
1145 EXLATEOBJ_vInitialize(&exlo
,
1149 RGB(0xff,0xff,0xff),
1152 /* Call the copy bits function */
1153 EngCopyBits(&psurfDest
->SurfObj
,
1160 /* Cleanup the XLATEOBJ */
1161 EXLATEOBJ_vCleanup(&exlo
);
1163 /* Delete the surface */
1164 GDIOBJ_vDeleteObject(&psurfDest
->BaseObject
);
1171 /* Return the new RGB color or -1 on failure */