From 95057e2cf74acf51c9bbc2ad222079a3b4edefdd Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Tue, 6 Apr 2004 21:53:48 +0000 Subject: [PATCH] implemented TransparentBlt() on 16bpp and 24bpp surfaces svn path=/trunk/; revision=8993 --- reactos/subsys/win32k/dib/dib.c | 4 +- reactos/subsys/win32k/dib/dib.h | 2 +- reactos/subsys/win32k/dib/dib16bpp.c | 62 +++++++++++++++++++++++--- reactos/subsys/win32k/dib/dib24bpp.c | 31 ++++++++++++- reactos/subsys/win32k/dib/dib32bpp.c | 23 ++++------ reactos/subsys/win32k/eng/bitblt.c | 4 +- reactos/subsys/win32k/eng/gradient.c | 7 +-- reactos/subsys/win32k/eng/transblt.c | 20 ++++++++- reactos/subsys/win32k/include/inteng.h | 2 + 9 files changed, 120 insertions(+), 35 deletions(-) diff --git a/reactos/subsys/win32k/dib/dib.c b/reactos/subsys/win32k/dib/dib.c index 3825379d54f..5023165be5a 100644 --- a/reactos/subsys/win32k/dib/dib.c +++ b/reactos/subsys/win32k/dib/dib.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: dib.c,v 1.8 2004/04/06 17:54:32 weiden Exp $ */ +/* $Id: dib.c,v 1.9 2004/04/06 21:53:48 weiden Exp $ */ #include #include @@ -68,7 +68,7 @@ DIB_GetSource(SURFOBJ* SourceSurf, SURFGDI* SourceGDI, ULONG sx, ULONG sy, XLATE } ULONG -DIB_GetOriginalSource(SURFOBJ* SourceSurf, SURFGDI* SourceGDI, ULONG sx, ULONG sy) +DIB_GetSourceIndex(SURFOBJ* SourceSurf, SURFGDI* SourceGDI, ULONG sx, ULONG sy) { switch (SourceGDI->BitsPerPixel) { diff --git a/reactos/subsys/win32k/dib/dib.h b/reactos/subsys/win32k/dib/dib.h index fd71097f82e..2c3dac2e035 100644 --- a/reactos/subsys/win32k/dib/dib.h +++ b/reactos/subsys/win32k/dib/dib.h @@ -3,7 +3,7 @@ extern unsigned char altnotmask[2]; #define MASK1BPP(x) (1<<(7-((x)&7))) ULONG DIB_DoRop(ULONG Rop, ULONG Dest, ULONG Source, ULONG Pattern); ULONG DIB_GetSource(SURFOBJ* SourceSurf, SURFGDI* SourceGDI, ULONG sx, ULONG sy, XLATEOBJ* ColorTranslation); -ULONG DIB_GetOriginalSource(SURFOBJ* SourceSurf, SURFGDI* SourceGDI, ULONG sx, ULONG sy); +ULONG DIB_GetSourceIndex(SURFOBJ* SourceSurf, SURFGDI* SourceGDI, ULONG sx, ULONG sy); VOID DIB_1BPP_PutPixel(SURFOBJ* SurfObj, LONG x, LONG y, ULONG c); ULONG DIB_1BPP_GetPixel(SURFOBJ* SurfObj, LONG x, LONG y); diff --git a/reactos/subsys/win32k/dib/dib16bpp.c b/reactos/subsys/win32k/dib/dib16bpp.c index 3b6b002b69b..60849250f4c 100644 --- a/reactos/subsys/win32k/dib/dib16bpp.c +++ b/reactos/subsys/win32k/dib/dib16bpp.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: dib16bpp.c,v 1.23 2004/04/06 17:54:32 weiden Exp $ */ +/* $Id: dib16bpp.c,v 1.24 2004/04/06 21:53:48 weiden Exp $ */ #undef WIN32_LEAN_AND_MEAN #include #include @@ -283,7 +283,7 @@ DIB_16BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, { ULONG X, Y; ULONG SourceX, SourceY; - ULONG Dest, Source, Pattern = 0; + ULONG wd, Dest, Source, Pattern = 0; PULONG DestBits; BOOL UsesSource; BOOL UsesPattern; @@ -333,7 +333,8 @@ DIB_16BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, PatternHeight = PatternObj->sizlBitmap.cy; } } - + + wd = ((DestRect->right - DestRect->left) << 1) - DestSurf->lDelta; RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x1); SourceY = SourcePoint->y; DestBits = (PULONG)( @@ -394,9 +395,7 @@ DIB_16BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SourceY++; DestBits = (PULONG)( - (ULONG_PTR)DestBits - - ((DestRect->right - DestRect->left) << 1) + - DestSurf->lDelta); + (ULONG_PTR)DestBits - wd); } if (PatternSurface != NULL) @@ -608,7 +607,56 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, RECTL* DestRect, POINTL *SourcePoint, XLATEOBJ *ColorTranslation, ULONG iTransColor) { - return FALSE; + ULONG X, Y, SourceX, SourceY, Source, wd, Dest; + LONG RoundedRight; + ULONG *DestBits; + + RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x1); + SourceY = SourcePoint->y; + DestBits = (ULONG*)(DestSurf->pvScan0 + + (DestRect->left << 1) + + DestRect->top * DestSurf->lDelta); + wd = ((DestRect->right - DestRect->left) << 1) - DestSurf->lDelta; + + for(Y = DestRect->top; Y < DestRect->bottom; Y++) + { + SourceX = SourcePoint->x; + for(X = DestRect->left; X < RoundedRight; X += 2, DestBits++, SourceX += 2) + { + Dest = *DestBits; + + Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX, SourceY); + if(Source != iTransColor) + { + Dest &= 0xFFFF0000; + Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFF); + } + + Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX + 1, SourceY); + if(Source != iTransColor) + { + Dest &= 0xFFFF; + Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) << 16); + } + + *DestBits = Dest; + } + + if(X < DestRect->right) + { + Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX, SourceY); + if(Source != iTransColor) + { + *((USHORT*)DestBits) = (USHORT)(XLATEOBJ_iXlate(ColorTranslation, Source) << 16); + } + + DestBits = (PULONG)((ULONG_PTR)DestBits + 2); + } + SourceY++; + DestBits = (ULONG*)((ULONG_PTR)DestBits - wd); + } + + return TRUE; } /* EOF */ diff --git a/reactos/subsys/win32k/dib/dib24bpp.c b/reactos/subsys/win32k/dib/dib24bpp.c index 36911add3fa..e696ad73ed8 100644 --- a/reactos/subsys/win32k/dib/dib24bpp.c +++ b/reactos/subsys/win32k/dib/dib24bpp.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: dib24bpp.c,v 1.19 2004/04/06 17:54:32 weiden Exp $ */ +/* $Id: dib24bpp.c,v 1.20 2004/04/06 21:53:48 weiden Exp $ */ #undef WIN32_LEAN_AND_MEAN #include #include @@ -367,7 +367,34 @@ DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, RECTL* DestRect, POINTL *SourcePoint, XLATEOBJ *ColorTranslation, ULONG iTransColor) { - return FALSE; + ULONG X, Y, SourceX, SourceY, Source, wd, Dest; + BYTE *DestBits; + + SourceY = SourcePoint->y; + DestBits = (BYTE*)(DestSurf->pvScan0 + + (DestRect->left << 2) + + DestRect->top * DestSurf->lDelta); + wd = ((DestRect->right - DestRect->left) << 2) - DestSurf->lDelta; + + for(Y = DestRect->top; Y < DestRect->bottom; Y++) + { + SourceX = SourcePoint->x; + for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++) + { + Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX, SourceY); + if(Source != iTransColor) + { + Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF; + *(PUSHORT)(DestBits) = Dest & 0xFFFF; + *(DestBits + 2) = Dest >> 16; + } + } + + SourceY++; + DestBits = (BYTE*)((ULONG_PTR)DestBits - wd); + } + + return TRUE; } /* EOF */ diff --git a/reactos/subsys/win32k/dib/dib32bpp.c b/reactos/subsys/win32k/dib/dib32bpp.c index 09369cb5edb..4206bed8df8 100644 --- a/reactos/subsys/win32k/dib/dib32bpp.c +++ b/reactos/subsys/win32k/dib/dib32bpp.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: dib32bpp.c,v 1.19 2004/04/06 17:54:32 weiden Exp $ */ +/* $Id: dib32bpp.c,v 1.20 2004/04/06 21:53:48 weiden Exp $ */ #undef WIN32_LEAN_AND_MEAN #include #include @@ -572,12 +572,11 @@ DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, RECTL* DestRect, POINTL *SourcePoint, XLATEOBJ *ColorTranslation, ULONG iTransColor) { - ULONG X, Y; - ULONG SourceX, SourceY, Source, wd; - PULONG DestBits; + ULONG X, Y, SourceX, SourceY, Source, wd; + ULONG *DestBits; SourceY = SourcePoint->y; - DestBits = (PULONG)(DestSurf->pvScan0 + + DestBits = (ULONG*)(DestSurf->pvScan0 + (DestRect->left << 2) + DestRect->top * DestSurf->lDelta); wd = ((DestRect->right - DestRect->left) << 2) - DestSurf->lDelta; @@ -587,21 +586,15 @@ DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SourceX = SourcePoint->x; for(X = DestRect->left; X < DestRect->right; X++, DestBits++, SourceX++) { - Source = DIB_GetOriginalSource(SourceSurf, SourceGDI, SourceX, SourceY); - if(Source == iTransColor) + Source = DIB_GetSourceIndex(SourceSurf, SourceGDI, SourceX, SourceY); + if(Source != iTransColor) { - /* Skip transparent pixels */ - continue; - } - - if(ColorTranslation) *DestBits = XLATEOBJ_iXlate(ColorTranslation, Source); - else - *DestBits = Source; + } } SourceY++; - DestBits = (PULONG)((ULONG_PTR)DestBits - wd); + DestBits = (ULONG*)((ULONG_PTR)DestBits - wd); } return TRUE; diff --git a/reactos/subsys/win32k/eng/bitblt.c b/reactos/subsys/win32k/eng/bitblt.c index bc094eefc3a..7e7d54a78de 100644 --- a/reactos/subsys/win32k/eng/bitblt.c +++ b/reactos/subsys/win32k/eng/bitblt.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: bitblt.c,v 1.44 2004/04/05 21:26:24 navaraf Exp $ +/* $Id: bitblt.c,v 1.45 2004/04/06 21:53:48 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -46,8 +46,6 @@ #define NDEBUG #include -#define ROP_NOOP 0x00AA0029 - typedef BOOLEAN STDCALL (*PBLTRECTFUNC)(SURFOBJ* OutputObj, SURFGDI* OutputGDI, SURFOBJ* InputObj, diff --git a/reactos/subsys/win32k/eng/gradient.c b/reactos/subsys/win32k/eng/gradient.c index 063606170ec..fb8902170b5 100644 --- a/reactos/subsys/win32k/eng/gradient.c +++ b/reactos/subsys/win32k/eng/gradient.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: gradient.c,v 1.6 2004/03/21 10:18:33 weiden Exp $ +/* $Id: gradient.c,v 1.7 2004/04/06 21:53:48 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -570,13 +571,13 @@ IntEngGradientFill( { IntLockGDIDriver(SurfGDI); SurfGDI->BitBlt(psoDest, NULL, NULL, pco, pxlo, - prclExtents, pptlDitherOrg, NULL, NULL, NULL, 0x00AA0029); + prclExtents, pptlDitherOrg, NULL, NULL, NULL, ROP_NOOP); IntUnLockGDIDriver(SurfGDI); MouseSafetyOnDrawEnd(psoDest, SurfGDI); return TRUE; } EngBitBlt(psoDest, NULL, NULL, pco, pxlo, - prclExtents, pptlDitherOrg, NULL, NULL, NULL, 0x00AA0029); + prclExtents, pptlDitherOrg, NULL, NULL, NULL, ROP_NOOP); } MouseSafetyOnDrawEnd(psoDest, SurfGDI); return Ret; diff --git a/reactos/subsys/win32k/eng/transblt.c b/reactos/subsys/win32k/eng/transblt.c index 290317068c9..1fb12e1c772 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.14 2004/04/06 17:54:32 weiden Exp $ +/* $Id: transblt.c,v 1.15 2004/04/06 21:53:48 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -152,7 +152,7 @@ EngTransparentBlt(PSURFOBJ Dest, Pt.x = InputPoint.x + CombinedRect.left - OutputRect.left; Pt.y = InputPoint.y + CombinedRect.top - OutputRect.top; Ret = OutputGDI->DIB_TransparentBlt(OutputObj, InputObj, OutputGDI, InputGDI, &CombinedRect, - &Pt, ColorTranslation, iTransColor); + &Pt, ColorTranslation, iTransColor); break; } case DC_COMPLEX: @@ -285,6 +285,22 @@ IntEngTransparentBlt(PSURFOBJ Dest, SourceRect, iTransColor, Reserved); } + if(Ret) + { + /* Dummy BitBlt to let driver know that something has changed. + 0x00AA0029 is the Rop for D (no-op) */ + if(SurfGDIDest->BitBlt) + { + IntLockGDIDriver(SurfGDIDest); + SurfGDIDest->BitBlt(Dest, NULL, NULL, Clip, ColorTranslation, + &OutputRect, NULL, NULL, NULL, NULL, ROP_NOOP); + IntUnLockGDIDriver(SurfGDIDest); + } + else + EngBitBlt(Dest, NULL, NULL, Clip, ColorTranslation, + &OutputRect, NULL, NULL, NULL, NULL, ROP_NOOP); + } + MouseSafetyOnDrawEnd(Dest, SurfGDIDest); if(Source != Dest) { diff --git a/reactos/subsys/win32k/include/inteng.h b/reactos/subsys/win32k/include/inteng.h index 19e8ad70984..f3211d81a73 100644 --- a/reactos/subsys/win32k/include/inteng.h +++ b/reactos/subsys/win32k/include/inteng.h @@ -1,6 +1,8 @@ #ifndef _WIN32K_INTENG_H #define _WIN32K_INTENG_H +#define ROP_NOOP 0x00AA0029 + /* Definitions of IntEngXxx functions */ BOOL STDCALL IntEngLineTo(SURFOBJ *Surface,