From 81a05c875c8c7507f86f60e0dd81097d245d3e0b Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sat, 3 Apr 2004 21:25:20 +0000 Subject: [PATCH] some more work on TransparentBlt() (EngTransparentBlt() is still unimplemented) svn path=/trunk/; revision=8961 --- reactos/subsys/win32k/eng/transblt.c | 143 +++++++++++++----------- reactos/subsys/win32k/include/intgdi.h | 12 ++ reactos/subsys/win32k/objects/bitmaps.c | 34 ++++-- 3 files changed, 114 insertions(+), 75 deletions(-) diff --git a/reactos/subsys/win32k/eng/transblt.c b/reactos/subsys/win32k/eng/transblt.c index 36809670fd2..fca40f38777 100644 --- a/reactos/subsys/win32k/eng/transblt.c +++ b/reactos/subsys/win32k/eng/transblt.c @@ -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 #include +#include +#include #include "brush.h" #include "clip.h" #include "objects.h" -#include +#define NDEBUG +#include + 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(sxleft, 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 */ diff --git a/reactos/subsys/win32k/include/intgdi.h b/reactos/subsys/win32k/include/intgdi.h index 830b7670e57..3edac2563a8 100644 --- a/reactos/subsys/win32k/include/intgdi.h +++ b/reactos/subsys/win32k/include/intgdi.h @@ -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 */ diff --git a/reactos/subsys/win32k/objects/bitmaps.c b/reactos/subsys/win32k/objects/bitmaps.c index 77a8a77ac63..27d9013cfef 100644 --- a/reactos/subsys/win32k/objects/bitmaps.c +++ b/reactos/subsys/win32k/objects/bitmaps.c @@ -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 #include @@ -28,6 +28,7 @@ //#include #include "../eng/handle.h" #include +#include #include #include #include @@ -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