mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
some more work on TransparentBlt() (EngTransparentBlt() is still unimplemented)
svn path=/trunk/; revision=8961
This commit is contained in:
parent
06ed71caec
commit
81a05c875c
3 changed files with 114 additions and 75 deletions
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: transblt.c,v 1.12 2004/03/05 09:02:42 hbirr Exp $
|
/* $Id: transblt.c,v 1.13 2004/04/03 21:25:20 weiden Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -35,12 +35,16 @@
|
||||||
#include <include/eng.h>
|
#include <include/eng.h>
|
||||||
#include <include/object.h>
|
#include <include/object.h>
|
||||||
#include <include/surface.h>
|
#include <include/surface.h>
|
||||||
|
#include <include/mouse.h>
|
||||||
|
#include <include/inteng.h>
|
||||||
|
|
||||||
#include "brush.h"
|
#include "brush.h"
|
||||||
#include "clip.h"
|
#include "clip.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
|
|
||||||
#include <include/mouse.h>
|
#define NDEBUG
|
||||||
|
#include <win32k/debug1.h>
|
||||||
|
|
||||||
|
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
EngTransparentBlt(PSURFOBJ Dest,
|
EngTransparentBlt(PSURFOBJ Dest,
|
||||||
|
@ -52,73 +56,84 @@ EngTransparentBlt(PSURFOBJ Dest,
|
||||||
ULONG TransparentColor,
|
ULONG TransparentColor,
|
||||||
ULONG Reserved)
|
ULONG Reserved)
|
||||||
{
|
{
|
||||||
PSURFGDI DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest),
|
DPRINT1("EngTransparentBlt() unimplemented!\n");
|
||||||
SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
|
return FALSE;
|
||||||
HSURF hTemp;
|
}
|
||||||
PSURFOBJ TempSurf;
|
|
||||||
POINTL TempPoint, SourcePoint;
|
|
||||||
RECTL TempRect;
|
|
||||||
SIZEL TempSize;
|
|
||||||
BOOLEAN ret;
|
|
||||||
LONG dx, dy, sx, sy;
|
|
||||||
|
|
||||||
dx = abs(DestRect->right - DestRect->left);
|
BOOL FASTCALL
|
||||||
dy = abs(DestRect->bottom - DestRect->top);
|
IntTransparentBlt(PSURFOBJ Dest,
|
||||||
|
PSURFOBJ Source,
|
||||||
sx = abs(SourceRect->right - SourceRect->left);
|
PCLIPOBJ Clip,
|
||||||
sy = abs(SourceRect->bottom - SourceRect->top);
|
PXLATEOBJ ColorTranslation,
|
||||||
|
PRECTL DestRect,
|
||||||
if(sx<dx) dx = sx;
|
PRECTL SourceRect,
|
||||||
if(sy<dy) dy = sy;
|
ULONG TransparentColor,
|
||||||
|
ULONG Reserved)
|
||||||
MouseSafetyOnDrawStart(Source, SourceGDI, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
|
{
|
||||||
MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
|
BOOL Ret;
|
||||||
|
RECTL OutputRect, InputClippedRect;
|
||||||
if(DestGDI->TransparentBlt != NULL)
|
PSURFGDI SurfGDIDest, SurfGDISrc;
|
||||||
|
|
||||||
|
InputClippedRect = *DestRect;
|
||||||
|
if(InputClippedRect.right < InputClippedRect.left)
|
||||||
{
|
{
|
||||||
// The destination is device managed, therefore get the source into a format compatible surface
|
InputClippedRect.left = DestRect->right;
|
||||||
TempPoint.x = 0;
|
InputClippedRect.right = DestRect->left;
|
||||||
TempPoint.y = 0;
|
}
|
||||||
TempRect.top = 0;
|
if(InputClippedRect.bottom < InputClippedRect.top)
|
||||||
TempRect.left = 0;
|
{
|
||||||
TempRect.bottom = dy;
|
InputClippedRect.top = DestRect->bottom;
|
||||||
TempRect.right = dx;
|
InputClippedRect.bottom = DestRect->top;
|
||||||
TempSize.cx = TempRect.right;
|
}
|
||||||
TempSize.cy = TempRect.bottom;
|
|
||||||
|
/* Clip against the bounds of the clipping region so we won't try to write
|
||||||
hTemp = EngCreateBitmap(TempSize,
|
* outside the surface */
|
||||||
DIB_GetDIBWidthBytes(dx, BitsPerFormat(Dest->iBitmapFormat)),
|
if(Clip)
|
||||||
Dest->iBitmapFormat, 0, NULL);
|
{
|
||||||
TempSurf = (PSURFOBJ)AccessUserObject((ULONG)hTemp);
|
if(!EngIntersectRect(&OutputRect, &InputClippedRect, &Clip->rclBounds))
|
||||||
|
|
||||||
SourcePoint.x = SourceRect->left;
|
|
||||||
SourcePoint.y = SourceRect->top;
|
|
||||||
|
|
||||||
// FIXME: Skip creating a TempSurf if we have the same BPP and palette
|
|
||||||
EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, &SourcePoint, NULL, NULL, NULL, 0);
|
|
||||||
|
|
||||||
IntLockGDIDriver(DestGDI);
|
|
||||||
ret = DestGDI->TransparentBlt(Dest, TempSurf, Clip, NULL, DestRect, SourceRect,
|
|
||||||
TransparentColor, Reserved);
|
|
||||||
IntUnLockGDIDriver(DestGDI);
|
|
||||||
|
|
||||||
MouseSafetyOnDrawEnd(Dest, DestGDI);
|
|
||||||
MouseSafetyOnDrawEnd(Source, SourceGDI);
|
|
||||||
|
|
||||||
if(EngDeleteSurface(hTemp) == FALSE)
|
|
||||||
{
|
{
|
||||||
DbgPrint("Win32k: Failed to delete surface: %d\n", hTemp);
|
return TRUE;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return ret;
|
else
|
||||||
|
{
|
||||||
|
OutputRect = *DestRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Source != Dest)
|
||||||
|
{
|
||||||
|
SurfGDISrc = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
|
||||||
|
ASSERT(SurfGDISrc);
|
||||||
|
MouseSafetyOnDrawStart(Source, SurfGDISrc, SourceRect->left, SourceRect->top,
|
||||||
|
(SourceRect->left + abs(SourceRect->right - SourceRect->left)),
|
||||||
|
(SourceRect->top + abs(SourceRect->bottom - SourceRect->top)));
|
||||||
|
}
|
||||||
|
SurfGDIDest = (PSURFGDI)AccessInternalObjectFromUserObject(Dest);
|
||||||
|
ASSERT(SurfGDIDest);
|
||||||
|
MouseSafetyOnDrawStart(Dest, SurfGDIDest, OutputRect.left, OutputRect.top,
|
||||||
|
OutputRect.right, OutputRect.bottom);
|
||||||
|
|
||||||
|
if(SurfGDIDest->TransparentBlt)
|
||||||
|
{
|
||||||
|
Ret = SurfGDIDest->TransparentBlt(Dest, Source, Clip, ColorTranslation, &OutputRect,
|
||||||
|
SourceRect, TransparentColor, Reserved);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Ret = FALSE;
|
||||||
|
|
||||||
|
if(!Ret)
|
||||||
|
{
|
||||||
|
Ret = EngTransparentBlt(Dest, Source, Clip, ColorTranslation, &OutputRect,
|
||||||
|
SourceRect, TransparentColor, Reserved);
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseSafetyOnDrawEnd(Dest, SurfGDIDest);
|
||||||
|
if(Source != Dest)
|
||||||
|
{
|
||||||
|
MouseSafetyOnDrawEnd(Source, SurfGDISrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulate a transparent blt
|
return Ret;
|
||||||
|
|
||||||
MouseSafetyOnDrawEnd(Dest, DestGDI);
|
|
||||||
MouseSafetyOnDrawEnd(Source, SourceGDI);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -121,5 +121,17 @@ IntGdiCombineTransform(LPXFORM XFormResult,
|
||||||
LPXFORM xform1,
|
LPXFORM xform1,
|
||||||
LPXFORM xform2);
|
LPXFORM xform2);
|
||||||
|
|
||||||
|
/* Bitmap functions */
|
||||||
|
|
||||||
|
BOOL FASTCALL
|
||||||
|
IntTransparentBlt(PSURFOBJ Dest,
|
||||||
|
PSURFOBJ Source,
|
||||||
|
PCLIPOBJ Clip,
|
||||||
|
PXLATEOBJ ColorTranslation,
|
||||||
|
PRECTL DestRect,
|
||||||
|
PRECTL SourceRect,
|
||||||
|
ULONG TransparentColor,
|
||||||
|
ULONG Reserved);
|
||||||
|
|
||||||
#endif /* _WIN32K_INTGDI_H */
|
#endif /* _WIN32K_INTGDI_H */
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: bitmaps.c,v 1.65 2004/03/28 21:46:26 weiden Exp $ */
|
/* $Id: bitmaps.c,v 1.66 2004/04/03 21:25:20 weiden Exp $ */
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
//#include <win32k/debug.h>
|
//#include <win32k/debug.h>
|
||||||
#include "../eng/handle.h"
|
#include "../eng/handle.h"
|
||||||
#include <include/inteng.h>
|
#include <include/inteng.h>
|
||||||
|
#include <include/intgdi.h>
|
||||||
#include <include/eng.h>
|
#include <include/eng.h>
|
||||||
#include <include/error.h>
|
#include <include/error.h>
|
||||||
#include <include/surface.h>
|
#include <include/surface.h>
|
||||||
|
@ -280,11 +281,12 @@ NtGdiTransparentBlt(
|
||||||
PDC DCDest, DCSrc;
|
PDC DCDest, DCSrc;
|
||||||
RECT rcDest, rcSrc;
|
RECT rcDest, rcSrc;
|
||||||
PSURFOBJ SurfDest, SurfSrc;
|
PSURFOBJ SurfDest, SurfSrc;
|
||||||
PSURFGDI SurfGDIDest, SurfGDISrc;
|
|
||||||
PXLATEOBJ XlateObj;
|
PXLATEOBJ XlateObj;
|
||||||
HPALETTE SourcePalette, DestPalette;
|
HPALETTE SourcePalette, DestPalette;
|
||||||
PPALGDI PalDestGDI, PalSourceGDI;
|
PPALGDI PalDestGDI, PalSourceGDI;
|
||||||
USHORT PalDestMode, PalSrcMode;
|
USHORT PalDestMode, PalSrcMode;
|
||||||
|
ULONG TransparentColor;
|
||||||
|
BOOL Ret;
|
||||||
|
|
||||||
if(!(DCDest = DC_LockDc(hdcDst)))
|
if(!(DCDest = DC_LockDc(hdcDst)))
|
||||||
{
|
{
|
||||||
|
@ -342,32 +344,42 @@ NtGdiTransparentBlt(
|
||||||
}
|
}
|
||||||
PALETTE_UnlockPalette(SourcePalette);
|
PALETTE_UnlockPalette(SourcePalette);
|
||||||
|
|
||||||
XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalDestMode, PalSrcMode, DestPalette, SourcePalette);
|
if((XlateObj = (PXLATEOBJ)IntEngCreateXlate(PalDestMode, PalSrcMode, DestPalette, SourcePalette)))
|
||||||
|
{
|
||||||
|
/* FIXME - is color translation right? */
|
||||||
|
TransparentColor = XLATEOBJ_iXlate(XlateObj, (ULONG)TransColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME - what should be done here? */
|
||||||
|
TransparentColor = (ULONG)TransColor;
|
||||||
|
}
|
||||||
|
|
||||||
SurfDest = (PSURFOBJ)AccessUserObject((ULONG)DCDest->Surface);
|
SurfDest = (PSURFOBJ)AccessUserObject((ULONG)DCDest->Surface);
|
||||||
ASSERT(SurfDest);
|
ASSERT(SurfDest);
|
||||||
SurfGDIDest = (PSURFGDI)AccessInternalObjectFromUserObject(SurfDest);
|
|
||||||
ASSERT(SurfGDIDest);
|
|
||||||
SurfSrc = (PSURFOBJ)AccessUserObject((ULONG)DCSrc->Surface);
|
SurfSrc = (PSURFOBJ)AccessUserObject((ULONG)DCSrc->Surface);
|
||||||
ASSERT(SurfSrc);
|
ASSERT(SurfSrc);
|
||||||
SurfGDISrc = (PSURFGDI)AccessInternalObjectFromUserObject(SurfSrc);
|
|
||||||
ASSERT(SurfGDISrc);
|
|
||||||
|
|
||||||
rcDest.left = xDst;
|
rcDest.left = xDst;
|
||||||
rcDest.top = yDst;
|
rcDest.top = yDst;
|
||||||
rcDest.right = rcDest.left + cxDst;
|
rcDest.right = rcDest.left + cxDst;
|
||||||
rcDest.bottom = rcDest.bottom + cyDst;
|
rcDest.bottom = rcDest.top + cyDst;
|
||||||
rcSrc.left = xSrc;
|
rcSrc.left = xSrc;
|
||||||
rcSrc.top = ySrc;
|
rcSrc.top = ySrc;
|
||||||
rcSrc.right = rcDest.left + cxSrc;
|
rcSrc.right = rcSrc.left + cxSrc;
|
||||||
rcSrc.bottom = rcDest.bottom + cySrc;
|
rcSrc.bottom = rcSrc.top + cySrc;
|
||||||
|
|
||||||
if((cxDst != cxSrc) || (cyDst != cySrc))
|
if((cxDst != cxSrc) || (cyDst != cySrc))
|
||||||
{
|
{
|
||||||
/* FIXME - Create a temporary bitmap and stretchblt it */
|
/* FIXME - Create a temporary bitmap and stretchblt it */
|
||||||
|
DPRINT1("TransparentBlt() does not support stretching!\n");
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ret = IntTransparentBlt(SurfDest, SurfSrc, DCDest->CombinedClip, XlateObj, &rcDest, &rcSrc,
|
||||||
|
TransparentColor, 0);
|
||||||
|
|
||||||
|
done:
|
||||||
DC_UnlockDc(hdcSrc);
|
DC_UnlockDc(hdcSrc);
|
||||||
if(hdcDst != hdcSrc)
|
if(hdcDst != hdcSrc)
|
||||||
{
|
{
|
||||||
|
@ -377,7 +389,7 @@ NtGdiTransparentBlt(
|
||||||
{
|
{
|
||||||
EngDeleteXlate(XlateObj);
|
EngDeleteXlate(XlateObj);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
HBITMAP STDCALL
|
HBITMAP STDCALL
|
||||||
|
|
Loading…
Reference in a new issue