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
,
158 /* Forward to NtGdiMaskBlt */
159 // TODO: What's fl for?
160 return NtGdiMaskBlt(hDCDest
,
193 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
194 ULONG TransparentColor
= 0;
198 TRACE("Locking DCs\n");
201 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
203 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDst
, hdcSrc
);
204 EngSetLastError(ERROR_INVALID_HANDLE
);
210 if (DCDest
->dctype
== DC_TYPE_INFO
|| DCDest
->dctype
== DCTYPE_INFO
)
212 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
213 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
214 /* Yes, Windows really returns TRUE in this case */
220 rcDest
.right
= rcDest
.left
+ cxDst
;
221 rcDest
.bottom
= rcDest
.top
+ cyDst
;
222 IntLPtoDP(DCDest
, (LPPOINT
)&rcDest
, 2);
224 rcDest
.left
+= DCDest
->ptlDCOrig
.x
;
225 rcDest
.top
+= DCDest
->ptlDCOrig
.y
;
226 rcDest
.right
+= DCDest
->ptlDCOrig
.x
;
227 rcDest
.bottom
+= DCDest
->ptlDCOrig
.y
;
231 rcSrc
.right
= rcSrc
.left
+ cxSrc
;
232 rcSrc
.bottom
= rcSrc
.top
+ cySrc
;
233 IntLPtoDP(DCSrc
, (LPPOINT
)&rcSrc
, 2);
235 rcSrc
.left
+= DCSrc
->ptlDCOrig
.x
;
236 rcSrc
.top
+= DCSrc
->ptlDCOrig
.y
;
237 rcSrc
.right
+= DCSrc
->ptlDCOrig
.x
;
238 rcSrc
.bottom
+= DCSrc
->ptlDCOrig
.y
;
240 /* Prepare for blit */
241 DC_vPrepareDCsForBlit(DCDest
, rcDest
, DCSrc
, rcSrc
);
243 BitmapDest
= DCDest
->dclevel
.pSurface
;
249 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
255 /* Translate Transparent (RGB) Color to the source palette */
256 EXLATEOBJ_vInitialize(&exlo
, &gpalRGB
, BitmapSrc
->ppal
, 0, 0, 0);
257 TransparentColor
= XLATEOBJ_iXlate(&exlo
.xlo
, (ULONG
)TransColor
);
258 EXLATEOBJ_vCleanup(&exlo
);
260 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
262 Ret
= IntEngTransparentBlt(&BitmapDest
->SurfObj
, &BitmapSrc
->SurfObj
,
263 DCDest
->rosdc
.CombinedClip
, &exlo
.xlo
, &rcDest
, &rcSrc
,
264 TransparentColor
, 0);
266 EXLATEOBJ_vCleanup(&exlo
);
269 DC_vFinishBlit(DCDest
, DCSrc
);
270 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
271 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
290 IN DWORD crBackColor
)
296 PDC_ATTR pdcattr
= NULL
;
297 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
, *psurfMask
= NULL
;
298 RECTL DestRect
, SourceRect
;
299 POINTL SourcePoint
, MaskPoint
;
302 XLATEOBJ
*XlateObj
= NULL
;
303 BOOL UsesSource
= ROP_USES_SOURCE(dwRop
);
308 UsesMask
= ROP_USES_MASK(dwRop
);
310 //DPRINT1("dwRop : 0x%08x\n", dwRop);
311 if (!hdcDest
|| (UsesSource
&& !hdcSrc
))
313 EngSetLastError(ERROR_INVALID_PARAMETER
);
317 /* Take care of mask bitmap */
320 psurfMask
= SURFACE_ShareLockSurface(hbmMask
);
323 EngSetLastError(ERROR_INVALID_HANDLE
);
332 EngSetLastError(ERROR_INVALID_PARAMETER
);
335 if(gajBitsPerFormat
[psurfMask
->SurfObj
.iBitmapFormat
] != 1)
337 EngSetLastError(ERROR_INVALID_PARAMETER
);
338 SURFACE_ShareUnlockSurface(psurfMask
);
344 WARN("Getting Mask bitmap without needing it?\n");
345 SURFACE_ShareUnlockSurface(psurfMask
);
351 /* Take care of source and destination bitmap */
352 TRACE("Locking DCs\n");
354 ahDC
[1] = UsesSource
? hdcSrc
: NULL
;
355 if (!GDIOBJ_bLockMultipleObjects(2, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
357 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to NtGdiAlphaBlend\n", hdcDest
, hdcSrc
);
358 EngSetLastError(ERROR_INVALID_HANDLE
);
367 if(DCSrc
) DC_UnlockDc(DCSrc
);
368 WARN("Invalid destination dc handle (0x%p) passed to NtGdiBitBlt\n", hdcDest
);
372 if (DCDest
->dctype
== DC_TYPE_INFO
)
374 if(DCSrc
) DC_UnlockDc(DCSrc
);
376 /* Yes, Windows really returns TRUE in this case */
383 if (DCSrc
->dctype
== DC_TYPE_INFO
)
387 /* Yes, Windows really returns TRUE in this case */
392 pdcattr
= DCDest
->pdcattr
;
394 DestRect
.left
= nXDest
;
395 DestRect
.top
= nYDest
;
396 DestRect
.right
= nXDest
+ nWidth
;
397 DestRect
.bottom
= nYDest
+ nHeight
;
398 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
400 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
401 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
402 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
403 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
405 SourcePoint
.x
= nXSrc
;
406 SourcePoint
.y
= nYSrc
;
410 IntLPtoDP(DCSrc
, (LPPOINT
)&SourcePoint
, 1);
412 SourcePoint
.x
+= DCSrc
->ptlDCOrig
.x
;
413 SourcePoint
.y
+= DCSrc
->ptlDCOrig
.y
;
414 /* Calculate Source Rect */
415 SourceRect
.left
= SourcePoint
.x
;
416 SourceRect
.top
= SourcePoint
.y
;
417 SourceRect
.right
= SourcePoint
.x
+ DestRect
.right
- DestRect
.left
;
418 SourceRect
.bottom
= SourcePoint
.y
+ DestRect
.bottom
- DestRect
.top
;
424 SourceRect
.right
= 0;
425 SourceRect
.bottom
= 0;
429 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
431 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
432 DC_vUpdateFillBrush(DCDest
);
434 /* Determine surfaces to be used in the bitblt */
435 BitmapDest
= DCDest
->dclevel
.pSurface
;
442 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
448 /* Create the XLATEOBJ. */
451 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
452 XlateObj
= &exlo
.xlo
;
456 /* Perform the bitblt operation */
457 Status
= IntEngBitBlt(&BitmapDest
->SurfObj
,
458 BitmapSrc
? &BitmapSrc
->SurfObj
: NULL
,
459 psurfMask
? &psurfMask
->SurfObj
: NULL
,
460 DCDest
->rosdc
.CombinedClip
,
465 &DCDest
->eboFill
.BrushObject
,
466 &DCDest
->dclevel
.pbrFill
->ptOrigin
,
470 EXLATEOBJ_vCleanup(&exlo
);
472 DC_vFinishBlit(DCDest
, DCSrc
);
478 if(psurfMask
) SURFACE_ShareUnlockSurface(psurfMask
);
496 IN DWORD crBackColor
)
498 FIXME("NtGdiPlgBlt: unimplemented.\n");
515 IN DWORD dwBackColor
,
526 SURFACE
*BitmapDest
, *BitmapSrc
= NULL
;
527 SURFACE
*BitmapMask
= NULL
;
533 XLATEOBJ
*XlateObj
= NULL
;
539 UsesSource
= ROP_USES_SOURCE(ROP
);
540 UsesMask
= ROP_USES_MASK(ROP
);
542 if (0 == WidthDest
|| 0 == HeightDest
|| 0 == WidthSrc
|| 0 == HeightSrc
)
544 EngSetLastError(ERROR_INVALID_PARAMETER
);
548 if (!hDCDest
|| (UsesSource
&& !hDCSrc
) || (UsesMask
&& !hDCMask
))
550 EngSetLastError(ERROR_INVALID_PARAMETER
);
555 ahDC
[1] = UsesSource
? hDCSrc
: NULL
;
556 ahDC
[2] = UsesMask
? hDCMask
: NULL
;
557 if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ
*)ahDC
, apObj
, GDIObjType_DC_TYPE
))
559 WARN("Invalid dc handle (dest=0x%p, src=0x%p) passed to GreStretchBltMask\n", hDCDest
, hDCSrc
);
560 EngSetLastError(ERROR_INVALID_HANDLE
);
567 if (DCDest
->dctype
== DC_TYPE_INFO
)
569 if(DCSrc
) GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
570 if(DCMask
) GDIOBJ_vUnlockObject(&DCMask
->BaseObject
);
571 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
572 /* Yes, Windows really returns TRUE in this case */
578 if (DCSrc
->dctype
== DC_TYPE_INFO
)
580 GDIOBJ_vUnlockObject(&DCDest
->BaseObject
);
581 GDIOBJ_vUnlockObject(&DCSrc
->BaseObject
);
582 if(DCMask
) GDIOBJ_vUnlockObject(&DCMask
->BaseObject
);
583 /* Yes, Windows really returns TRUE in this case */
588 pdcattr
= DCDest
->pdcattr
;
590 DestRect
.left
= XOriginDest
;
591 DestRect
.top
= YOriginDest
;
592 DestRect
.right
= XOriginDest
+WidthDest
;
593 DestRect
.bottom
= YOriginDest
+HeightDest
;
594 IntLPtoDP(DCDest
, (LPPOINT
)&DestRect
, 2);
596 DestRect
.left
+= DCDest
->ptlDCOrig
.x
;
597 DestRect
.top
+= DCDest
->ptlDCOrig
.y
;
598 DestRect
.right
+= DCDest
->ptlDCOrig
.x
;
599 DestRect
.bottom
+= DCDest
->ptlDCOrig
.y
;
601 SourceRect
.left
= XOriginSrc
;
602 SourceRect
.top
= YOriginSrc
;
603 SourceRect
.right
= XOriginSrc
+WidthSrc
;
604 SourceRect
.bottom
= YOriginSrc
+HeightSrc
;
608 IntLPtoDP(DCSrc
, (LPPOINT
)&SourceRect
, 2);
610 SourceRect
.left
+= DCSrc
->ptlDCOrig
.x
;
611 SourceRect
.top
+= DCSrc
->ptlDCOrig
.y
;
612 SourceRect
.right
+= DCSrc
->ptlDCOrig
.x
;
613 SourceRect
.bottom
+= DCSrc
->ptlDCOrig
.y
;
619 /* Only prepare Source and Dest, hdcMask represents a DIB */
620 DC_vPrepareDCsForBlit(DCDest
, DestRect
, DCSrc
, SourceRect
);
622 if (pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
623 DC_vUpdateFillBrush(DCDest
);
625 /* Determine surfaces to be used in the bitblt */
626 BitmapDest
= DCDest
->dclevel
.pSurface
;
627 if (BitmapDest
== NULL
)
631 BitmapSrc
= DCSrc
->dclevel
.pSurface
;
632 if (BitmapSrc
== NULL
)
635 /* Create the XLATEOBJ. */
636 EXLATEOBJ_vInitXlateFromDCs(&exlo
, DCSrc
, DCDest
);
637 XlateObj
= &exlo
.xlo
;
640 /* Offset the brush */
641 BrushOrigin
.x
+= DCDest
->ptlDCOrig
.x
;
642 BrushOrigin
.y
+= DCDest
->ptlDCOrig
.y
;
644 /* Make mask surface for source surface */
645 if (BitmapSrc
&& DCMask
)
647 BitmapMask
= DCMask
->dclevel
.pSurface
;
649 (BitmapMask
->SurfObj
.sizlBitmap
.cx
< WidthSrc
||
650 BitmapMask
->SurfObj
.sizlBitmap
.cy
< HeightSrc
))
652 WARN("%dx%d mask is smaller than %dx%d bitmap\n",
653 BitmapMask
->SurfObj
.sizlBitmap
.cx
, BitmapMask
->SurfObj
.sizlBitmap
.cy
,
654 WidthSrc
, HeightSrc
);
655 EXLATEOBJ_vCleanup(&exlo
);
658 /* Create mask offset point */
659 MaskPoint
.x
= XOriginMask
;
660 MaskPoint
.y
= YOriginMask
;
661 IntLPtoDP(DCMask
, &MaskPoint
, 1);
662 MaskPoint
.x
+= DCMask
->ptlDCOrig
.x
;
663 MaskPoint
.y
+= DCMask
->ptlDCOrig
.y
;
666 /* Perform the bitblt operation */
667 Status
= IntEngStretchBlt(&BitmapDest
->SurfObj
,
668 BitmapSrc
? &BitmapSrc
->SurfObj
: NULL
,
669 BitmapMask
? &BitmapMask
->SurfObj
: NULL
,
670 DCDest
->rosdc
.CombinedClip
,
675 BitmapMask
? &MaskPoint
: NULL
,
676 &DCDest
->eboFill
.BrushObject
,
681 EXLATEOBJ_vCleanup(&exlo
);
685 DC_vFinishBlit(DCDest
, DCSrc
);
713 IN DWORD dwBackColor
)
715 return GreStretchBltMask(
751 pbrush
= pebo
->pbrush
;
756 if (pbrush
->flAttrs
& BR_IS_NULL
)
763 DestRect
.left
= XLeft
;
764 DestRect
.right
= XLeft
+ Width
;
768 DestRect
.left
= XLeft
+ Width
+ 1;
769 DestRect
.right
= XLeft
+ 1;
774 DestRect
.top
= YLeft
;
775 DestRect
.bottom
= YLeft
+ Height
;
779 DestRect
.top
= YLeft
+ Height
+ 1;
780 DestRect
.bottom
= YLeft
+ 1;
783 IntLPtoDP(pdc
, (LPPOINT
)&DestRect
, 2);
785 DestRect
.left
+= pdc
->ptlDCOrig
.x
;
786 DestRect
.top
+= pdc
->ptlDCOrig
.y
;
787 DestRect
.right
+= pdc
->ptlDCOrig
.x
;
788 DestRect
.bottom
+= pdc
->ptlDCOrig
.y
;
790 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
+ XLeft
;
791 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
+ YLeft
;
793 BrushOrigin
.x
= pbrush
->ptOrigin
.x
+ pdc
->ptlDCOrig
.x
;
794 BrushOrigin
.y
= pbrush
->ptOrigin
.y
+ pdc
->ptlDCOrig
.y
;
797 DC_vPrepareDCsForBlit(pdc
, DestRect
, NULL
, DestRect
);
799 psurf
= pdc
->dclevel
.pSurface
;
805 pdc
->rosdc
.CombinedClip
,
814 DC_vFinishBlit(pdc
, NULL
);
832 pdc
= DC_LockDc(hDC
);
835 EngSetLastError(ERROR_INVALID_HANDLE
);
839 if (pdc
->dctype
== DC_TYPE_INFO
)
842 /* Yes, Windows really returns TRUE in this case */
846 for (i
= 0; i
< cRects
; i
++)
848 pbrush
= BRUSH_ShareLockBrush(pRects
->hBrush
);
850 /* Check if we could lock the brush */
853 /* Initialize a brush object */
854 EBRUSHOBJ_vInitFromDC(&eboFill
, pbrush
, pdc
);
865 /* Cleanup the brush object and unlock the brush */
866 EBRUSHOBJ_vCleanup(&eboFill
);
867 BRUSH_ShareUnlockBrush(pbrush
);
890 /* Mask away everything except foreground rop index */
891 dwRop
= dwRop
& 0x00FF0000;
894 /* Check if the rop uses a source */
895 if (ROP_USES_SOURCE(dwRop
))
897 /* This is not possible */
902 pdc
= DC_LockDc(hdcDest
);
905 EngSetLastError(ERROR_INVALID_HANDLE
);
909 /* Check if the DC has no surface (empty mem or info DC) */
910 if (pdc
->dclevel
.pSurface
== NULL
)
912 /* Nothing to do, Windows returns TRUE! */
917 /* Update the fill brush, if neccessary */
918 if (pdc
->pdcattr
->ulDirty_
& (DIRTY_FILL
| DC_BRUSH_DIRTY
))
919 DC_vUpdateFillBrush(pdc
);
921 /* Call the internal function */
922 bResult
= IntPatBlt(pdc
, x
, y
, cx
, cy
, dwRop
, &pdc
->eboFill
);
924 /* Unlock the DC and return the result */
934 IN PPOLYPATBLT pRects
,
939 NTSTATUS Status
= STATUS_SUCCESS
;
944 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, GDITAG_PLGBLT_DATA
);
947 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY
);
953 cRects
* sizeof(PATRECT
),
957 cRects
* sizeof(PATRECT
));
959 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
961 Status
= _SEH2_GetExceptionCode();
965 if (!NT_SUCCESS(Status
))
967 ExFreePoolWithTag(rb
, GDITAG_PLGBLT_DATA
);
968 SetLastNtError(Status
);
973 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, rb
, cRects
, Mode
);
976 ExFreePoolWithTag(rb
, GDITAG_PLGBLT_DATA
);
988 _In_ COLORREF crColor
)
991 ULONG iOldColor
, iSolidColor
;
998 pdc
= DC_LockDc(hdc
);
1001 EngSetLastError(ERROR_INVALID_HANDLE
);
1005 /* Check if the DC has no surface (empty mem or info DC) */
1006 if (pdc
->dclevel
.pSurface
== NULL
)
1013 /* Translate the color to the target format */
1014 iSolidColor
= TranslateCOLORREF(pdc
, crColor
);
1016 /* Use the DC's text brush, which is always a solid brush */
1017 pebo
= &pdc
->eboText
;
1019 /* Save the old solid color and set the one for the pixel */
1020 iOldColor
= EBRUSHOBJ_iSetSolidColor(pebo
, iSolidColor
);
1022 /* Save dirty flags and reset dirty text brush flag */
1023 ulDirty
= pdc
->pdcattr
->ulDirty_
;
1024 pdc
->pdcattr
->ulDirty_
&= ~DIRTY_TEXT
;
1026 /* Call the internal function */
1027 bResult
= IntPatBlt(pdc
, x
, y
, 1, 1, PATCOPY
, pebo
);
1029 /* Restore old text brush color and dirty flags */
1030 EBRUSHOBJ_iSetSolidColor(pebo
, iOldColor
);
1031 pdc
->pdcattr
->ulDirty_
= ulDirty
;
1033 /* Initialize an XLATEOBJ from the target surface to RGB */
1034 EXLATEOBJ_vInitialize(&exlo
,
1035 pdc
->dclevel
.pSurface
->ppal
,
1038 pdc
->pdcattr
->crBackgroundClr
,
1039 pdc
->pdcattr
->crForegroundClr
);
1041 /* Translate the color back to RGB */
1042 crColor
= XLATEOBJ_iXlate(&exlo
.xlo
, iSolidColor
);
1044 /* Cleanup and return the target format color */
1045 EXLATEOBJ_vCleanup(&exlo
);
1050 /* Return the new RGB color or -1 on failure */
1051 return bResult
? crColor
: -1;
1062 ULONG ulRGBColor
= CLR_INVALID
;
1064 PSURFACE psurfSrc
, psurfDest
;
1067 pdc
= DC_LockDc(hdc
);
1070 EngSetLastError(ERROR_INVALID_HANDLE
);
1074 /* Check if the DC has no surface (empty mem or info DC) */
1075 psurfSrc
= pdc
->dclevel
.pSurface
;
1076 if (psurfSrc
== NULL
)
1082 /* Get the logical coordinates */
1086 /* Translate coordinates to device coordinates */
1087 IntLPtoDP(pdc
, &ptlSrc
, 1);
1088 ptlSrc
.x
+= pdc
->ptlDCOrig
.x
;
1089 ptlSrc
.y
+= pdc
->ptlDCOrig
.y
;
1091 /* Check if the pixel is outside the surface */
1092 if ((ptlSrc
.x
>= psurfSrc
->SurfObj
.sizlBitmap
.cx
) ||
1093 (ptlSrc
.y
>= psurfSrc
->SurfObj
.sizlBitmap
.cy
))
1099 /* Allocate a surface */
1100 psurfDest
= SURFACE_AllocSurface(STYPE_BITMAP
,
1109 RECTL rclDest
= {0, 0, 1, 1};
1112 /* Translate from the source palette to RGB color */
1113 EXLATEOBJ_vInitialize(&exlo
,
1117 RGB(0xff,0xff,0xff),
1120 /* Call the copy bits function */
1121 EngCopyBits(&psurfDest
->SurfObj
,
1128 /* Cleanup the XLATEOBJ */
1129 EXLATEOBJ_vCleanup(&exlo
);
1131 /* Delete the surface */
1132 GDIOBJ_vDeleteObject(&psurfDest
->BaseObject
);
1139 /* Return the new RGB color or -1 on failure */