some more work on TransparentBlt() (EngTransparentBlt() is still unimplemented)

svn path=/trunk/; revision=8961
This commit is contained in:
Thomas Bluemel 2004-04-03 21:25:20 +00:00
parent 06ed71caec
commit 81a05c875c
3 changed files with 114 additions and 75 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* PROJECT: ReactOS kernel
@ -35,12 +35,16 @@
#include <include/eng.h>
#include <include/object.h>
#include <include/surface.h>
#include <include/mouse.h>
#include <include/inteng.h>
#include "brush.h"
#include "clip.h"
#include "objects.h"
#include <include/mouse.h>
#define NDEBUG
#include <win32k/debug1.h>
BOOL STDCALL
EngTransparentBlt(PSURFOBJ Dest,
@ -52,73 +56,84 @@ EngTransparentBlt(PSURFOBJ Dest,
ULONG TransparentColor,
ULONG Reserved)
{
PSURFGDI DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest),
SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source);
HSURF hTemp;
PSURFOBJ TempSurf;
POINTL TempPoint, SourcePoint;
RECTL TempRect;
SIZEL TempSize;
BOOLEAN ret;
LONG dx, dy, sx, sy;
DPRINT1("EngTransparentBlt() unimplemented!\n");
return FALSE;
}
dx = abs(DestRect->right - DestRect->left);
dy = abs(DestRect->bottom - DestRect->top);
sx = abs(SourceRect->right - SourceRect->left);
sy = abs(SourceRect->bottom - SourceRect->top);
if(sx<dx) dx = sx;
if(sy<dy) dy = sy;
MouseSafetyOnDrawStart(Source, SourceGDI, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
if(DestGDI->TransparentBlt != NULL)
BOOL FASTCALL
IntTransparentBlt(PSURFOBJ Dest,
PSURFOBJ Source,
PCLIPOBJ Clip,
PXLATEOBJ ColorTranslation,
PRECTL DestRect,
PRECTL SourceRect,
ULONG TransparentColor,
ULONG Reserved)
{
BOOL Ret;
RECTL OutputRect, InputClippedRect;
PSURFGDI SurfGDIDest, SurfGDISrc;
InputClippedRect = *DestRect;
if(InputClippedRect.right < InputClippedRect.left)
{
// The destination is device managed, therefore get the source into a format compatible surface
TempPoint.x = 0;
TempPoint.y = 0;
TempRect.top = 0;
TempRect.left = 0;
TempRect.bottom = dy;
TempRect.right = dx;
TempSize.cx = TempRect.right;
TempSize.cy = TempRect.bottom;
hTemp = EngCreateBitmap(TempSize,
DIB_GetDIBWidthBytes(dx, BitsPerFormat(Dest->iBitmapFormat)),
Dest->iBitmapFormat, 0, NULL);
TempSurf = (PSURFOBJ)AccessUserObject((ULONG)hTemp);
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)
InputClippedRect.left = DestRect->right;
InputClippedRect.right = DestRect->left;
}
if(InputClippedRect.bottom < InputClippedRect.top)
{
InputClippedRect.top = DestRect->bottom;
InputClippedRect.bottom = DestRect->top;
}
/* Clip against the bounds of the clipping region so we won't try to write
* outside the surface */
if(Clip)
{
if(!EngIntersectRect(&OutputRect, &InputClippedRect, &Clip->rclBounds))
{
DbgPrint("Win32k: Failed to delete surface: %d\n", hTemp);
return FALSE;
return TRUE;
}
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
MouseSafetyOnDrawEnd(Dest, DestGDI);
MouseSafetyOnDrawEnd(Source, SourceGDI);
return TRUE;
return Ret;
}
/* EOF */

View file

@ -121,5 +121,17 @@ IntGdiCombineTransform(LPXFORM XFormResult,
LPXFORM xform1,
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 */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
#include <windows.h>
#include <stdlib.h>
@ -28,6 +28,7 @@
//#include <win32k/debug.h>
#include "../eng/handle.h"
#include <include/inteng.h>
#include <include/intgdi.h>
#include <include/eng.h>
#include <include/error.h>
#include <include/surface.h>
@ -280,11 +281,12 @@ NtGdiTransparentBlt(
PDC DCDest, DCSrc;
RECT rcDest, rcSrc;
PSURFOBJ SurfDest, SurfSrc;
PSURFGDI SurfGDIDest, SurfGDISrc;
PXLATEOBJ XlateObj;
HPALETTE SourcePalette, DestPalette;
PPALGDI PalDestGDI, PalSourceGDI;
USHORT PalDestMode, PalSrcMode;
ULONG TransparentColor;
BOOL Ret;
if(!(DCDest = DC_LockDc(hdcDst)))
{
@ -342,32 +344,42 @@ NtGdiTransparentBlt(
}
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);
ASSERT(SurfDest);
SurfGDIDest = (PSURFGDI)AccessInternalObjectFromUserObject(SurfDest);
ASSERT(SurfGDIDest);
SurfSrc = (PSURFOBJ)AccessUserObject((ULONG)DCSrc->Surface);
ASSERT(SurfSrc);
SurfGDISrc = (PSURFGDI)AccessInternalObjectFromUserObject(SurfSrc);
ASSERT(SurfGDISrc);
rcDest.left = xDst;
rcDest.top = yDst;
rcDest.right = rcDest.left + cxDst;
rcDest.bottom = rcDest.bottom + cyDst;
rcDest.bottom = rcDest.top + cyDst;
rcSrc.left = xSrc;
rcSrc.top = ySrc;
rcSrc.right = rcDest.left + cxSrc;
rcSrc.bottom = rcDest.bottom + cySrc;
rcSrc.right = rcSrc.left + cxSrc;
rcSrc.bottom = rcSrc.top + cySrc;
if((cxDst != cxSrc) || (cyDst != cySrc))
{
/* 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);
if(hdcDst != hdcSrc)
{
@ -377,7 +389,7 @@ NtGdiTransparentBlt(
{
EngDeleteXlate(XlateObj);
}
return TRUE;
return Ret;
}
HBITMAP STDCALL