Index: subsystems/win32/win32k/dib/dib.c =================================================================== --- subsystems/win32/win32k/dib/dib.c (revision 39576) +++ subsystems/win32/win32k/dib/dib.c (working copy) @@ -224,10 +224,12 @@ } BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFOBJ *PatternSurface, RECTL* DestRect, RECTL *SourceRect, POINTL* MaskOrigin, BRUSHOBJ* Brush, - POINTL* BrushOrign, CLIPOBJ *ClipRegion, - XLATEOBJ *ColorTranslation, ROP4 Rop) + POINTL* BrushOrign, + XLATEOBJ *ColorTranslation, + XLATEOBJ *XlatePatternToDest, ROP4 Rop) { return FALSE; } Index: subsystems/win32/win32k/dib/dib.h =================================================================== --- subsystems/win32/win32k/dib/dib.h (revision 39576) +++ subsystems/win32/win32k/dib/dib.h (working copy) @@ -41,7 +41,7 @@ typedef VOID (*PFN_DIB_HLine)(SURFOBJ*,LONG,LONG,LONG,ULONG); typedef VOID (*PFN_DIB_VLine)(SURFOBJ*,LONG,LONG,LONG,ULONG); typedef BOOLEAN (*PFN_DIB_BitBlt)(PBLTINFO); -typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,CLIPOBJ*,XLATEOBJ*,ROP4); +typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); typedef BOOLEAN (*PFN_DIB_TransparentBlt)(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); typedef BOOLEAN (*PFN_DIB_ColorFill)(SURFOBJ*, RECTL*, ULONG); typedef BOOLEAN (*PFN_DIB_AlphaBlend)(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); @@ -67,7 +67,7 @@ VOID Dummy_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG); VOID Dummy_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG); BOOLEAN Dummy_BitBlt(PBLTINFO); -BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,CLIPOBJ*,XLATEOBJ*,ROP4); +BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); BOOLEAN Dummy_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG); BOOLEAN Dummy_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN Dummy_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); @@ -132,7 +132,7 @@ BOOLEAN DIB_32BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); -BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,CLIPOBJ*,XLATEOBJ*,ROP4); +BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4); extern unsigned char notmask[2]; extern unsigned char altnotmask[2]; Index: subsystems/win32/win32k/dib/dib16bpp.c =================================================================== --- subsystems/win32/win32k/dib/dib16bpp.c (revision 39576) +++ subsystems/win32/win32k/dib/dib16bpp.c (working copy) @@ -528,10 +528,10 @@ USHORT us; struct { - USHORT red:5, - green:6, - blue:5; - } col; + USHORT red:5, + green:6, + blue:5; + } col; } NICEPIXEL16; static __inline UCHAR @@ -546,6 +546,12 @@ return (val > 63) ? 63 : val; } +static __inline UCHAR +Clamp8(ULONG val) +{ + return (val > 255) ? 255 : val; +} + BOOLEAN DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, RECTL* SourceRect, CLIPOBJ* ClipRegion, @@ -555,8 +561,9 @@ register PUSHORT Dst; ULONG DstDelta; BLENDFUNCTION BlendFunc; - register NICEPIXEL16 DstPixel; - register NICEPIXEL32 SrcPixel; + register NICEPIXEL16 SrcPixel16; + register NICEPIXEL32 SrcPixel32; + register NICEPIXEL32 DstPixel32; UCHAR Alpha, SrcBpp; DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", @@ -589,6 +596,23 @@ return FALSE; } + if (!ColorTranslation) + { + DPRINT1("Dest Xlate Translation failed\n"); + return FALSE; + } + + XLATEGDI* XlateGDI; + XLATEOBJ* SrcXlateObj; + XlateGDI = ObjToGDI(ColorTranslation, XLATE); + SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal); + + if (!SrcXlateObj) + { + DPRINT1("IntEngCreateXlate failed\n"); + return FALSE; + } + Dst = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + (DestRect->left << 1)); DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 1); @@ -604,52 +628,38 @@ { if (SrcBpp <= 16) { - DstPixel.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); - SrcPixel.col.red = (DstPixel.col.red << 3) | (DstPixel.col.red >> 2); - - SrcPixel.col.green = (DstPixel.col.green << 2) | - (DstPixel.col.green >> 4); - - SrcPixel.col.blue = (DstPixel.col.blue << 3) | (DstPixel.col.blue >> 2); + SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); + SrcPixel32.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2); + SrcPixel32.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4); + SrcPixel32.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2); } else { - SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY); - } - SrcPixel.col.red = SrcPixel.col.red * - BlendFunc.SourceConstantAlpha / 255; + SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY); + } + SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255; + SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255; + SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255; + SrcPixel32.col.alpha = (SrcBpp == 32) ? + (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : + BlendFunc.SourceConstantAlpha; - SrcPixel.col.green = SrcPixel.col.green * - BlendFunc.SourceConstantAlpha / 255; - - SrcPixel.col.blue = SrcPixel.col.blue * - BlendFunc.SourceConstantAlpha / 255; - - SrcPixel.col.alpha = (SrcBpp == 32) ? - (SrcPixel.col.alpha * - BlendFunc.SourceConstantAlpha / 255) : - BlendFunc.SourceConstantAlpha; - Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? - SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha; + SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; - DstPixel.us = *Dst; - DstPixel.col.red = Clamp5(DstPixel.col.red * (255 - Alpha) / 255 + - (SrcPixel.col.red >> 3)); + DstPixel32.ul = XLATEOBJ_iXlate(SrcXlateObj, *Dst); + SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red); + SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green); + SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue); + *Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul); + } + Dst = (PUSHORT)((ULONG_PTR)Dst + DstDelta); + SrcY++; + } - DstPixel.col.green = Clamp6(DstPixel.col.green * (255 - Alpha) / 255 + - (SrcPixel.col.green >> 2)); + if (SrcXlateObj) + EngDeleteXlate(SrcXlateObj); - DstPixel.col.blue = Clamp5(DstPixel.col.blue * (255 - Alpha) / 255 + - (SrcPixel.col.blue >> 3)); - - *Dst++ = DstPixel.us; - } - - Dst = (PUSHORT)((ULONG_PTR)Dst + DstDelta); - SrcY++; - } - return TRUE; } Index: subsystems/win32/win32k/dib/dib24bpp.c =================================================================== --- subsystems/win32/win32k/dib/dib24bpp.c (revision 39576) +++ subsystems/win32/win32k/dib/dib24bpp.c (working copy) @@ -263,7 +263,8 @@ } else { - Pattern = BltInfo->Brush->iSolidColor; + if (BltInfo->Brush) + Pattern = BltInfo->Brush->iSolidColor; } } Index: subsystems/win32/win32k/dib/dib8bpp.c =================================================================== --- subsystems/win32/win32k/dib/dib8bpp.c (revision 39576) +++ subsystems/win32/win32k/dib/dib8bpp.c (working copy) @@ -339,28 +339,28 @@ } typedef union { - ULONG ul; - struct { - UCHAR red; - UCHAR green; - UCHAR blue; - UCHAR alpha; - } col; + ULONG ul; + struct { + UCHAR red; + UCHAR green; + UCHAR blue; + UCHAR alpha; + } col; } NICEPIXEL32; typedef union { - USHORT us; - struct { - USHORT red:5, - green:6, - blue:5; - } col; + USHORT us; + struct { + USHORT red:5, + green:6, + blue:5; + } col; } NICEPIXEL16; static __inline UCHAR Clamp8(ULONG val) { - return (val > 255) ? 255 : val; + return (val > 255) ? 255 : val; } BOOLEAN @@ -368,132 +368,110 @@ RECTL* SourceRect, CLIPOBJ* ClipRegion, XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj) { - INT Rows, Cols, SrcX, SrcY; - register PUCHAR Dst; - ULONG DstDelta; - BLENDFUNCTION BlendFunc; - register NICEPIXEL32 DstPixel; - register NICEPIXEL32 SrcPixel; - register NICEPIXEL16 SrcPixel16; - UCHAR Alpha, SrcBpp; - HPALETTE SrcPalette, DstPalette; - XLATEOBJ *SrcTo32Xlate, *DstTo32Xlate, *DstFrom32Xlate; + INT Rows, Cols, SrcX, SrcY; + register PUCHAR Dst; + ULONG DstDelta; + BLENDFUNCTION BlendFunc; + register NICEPIXEL16 SrcPixel16; + register NICEPIXEL32 SrcPixel32; + register NICEPIXEL32 DstPixel32; + UCHAR Alpha, SrcBpp; - DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", - SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, - DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); + DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", + SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, + DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); - ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top && - DestRect->right - DestRect->left == SourceRect->right - SourceRect->left); + ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top && + DestRect->right - DestRect->left == SourceRect->right - SourceRect->left); - BlendFunc = BlendObj->BlendFunction; - if (BlendFunc.BlendOp != AC_SRC_OVER) - { - DPRINT1("BlendOp != AC_SRC_OVER\n"); + BlendFunc = BlendObj->BlendFunction; + if (BlendFunc.BlendOp != AC_SRC_OVER) + { + DPRINT1("BlendOp != AC_SRC_OVER\n"); + return FALSE; + } + if (BlendFunc.BlendFlags != 0) + { + DPRINT1("BlendFlags != 0\n"); + return FALSE; + } + if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0) + { + DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat); + return FALSE; + } + if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 && + BitsPerFormat(Source->iBitmapFormat) != 32) + { + DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n"); + return FALSE; + } + + if (!ColorTranslation) + { + DPRINT1("Dest Xlate Translation failed\n"); return FALSE; - } - if (BlendFunc.BlendFlags != 0) - { - DPRINT1("BlendFlags != 0\n"); - return FALSE; - } - if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0) - { - DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat); - return FALSE; - } - if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 && - BitsPerFormat(Source->iBitmapFormat) != 32) - { - DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n"); - return FALSE; - } + } - SrcBpp = BitsPerFormat(Source->iBitmapFormat); - SrcPalette = IntEngGetXlatePalette(ColorTranslation, XO_SRCPALETTE); - if (SrcPalette != 0) - { - SrcTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, SrcPalette); - if (SrcTo32Xlate == NULL) - { - DPRINT1("IntEngCreateXlate failed\n"); - return FALSE; - } - } - else - { - SrcTo32Xlate = NULL; - ASSERT(SrcBpp >= 16); - } + XLATEGDI* XlateGDI; + XLATEOBJ* SrcXlateObj; + XlateGDI = ObjToGDI(ColorTranslation, XLATE); + SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal); - DstPalette = IntEngGetXlatePalette(ColorTranslation, XO_DESTPALETTE); - DstTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, DstPalette); - DstFrom32Xlate = IntEngCreateXlate(0, PAL_RGB, DstPalette, NULL); - if (DstTo32Xlate == NULL || DstFrom32Xlate == NULL) - { - if (SrcTo32Xlate != NULL) - EngDeleteXlate(SrcTo32Xlate); - if (DstTo32Xlate != NULL) - EngDeleteXlate(DstTo32Xlate); - if (DstFrom32Xlate != NULL) - EngDeleteXlate(DstFrom32Xlate); + if (!SrcXlateObj) + { DPRINT1("IntEngCreateXlate failed\n"); return FALSE; - } + } - Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + + Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + DestRect->left); - DstDelta = Dest->lDelta - (DestRect->right - DestRect->left); + DstDelta = Dest->lDelta - (DestRect->right - DestRect->left); + SrcBpp = BitsPerFormat(Source->iBitmapFormat); - Rows = DestRect->bottom - DestRect->top; - SrcY = SourceRect->top; - while (--Rows >= 0) - { - Cols = DestRect->right - DestRect->left; - SrcX = SourceRect->left; - while (--Cols >= 0) - { - if (SrcTo32Xlate != NULL) - { - SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, SrcTo32Xlate); - } - else if (SrcBpp <= 16) - { - SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); - SrcPixel.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2); - SrcPixel.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4); - SrcPixel.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2); - } - else - { - SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY); - } - SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255; - SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255; - SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255; - SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha; + Rows = DestRect->bottom - DestRect->top; + SrcY = SourceRect->top; + while (--Rows >= 0) + { + Cols = DestRect->right - DestRect->left; + SrcX = SourceRect->left; + while (--Cols >= 0) + { + if (SrcBpp <= 16) + { + SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); + SrcPixel32.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2); + SrcPixel32.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4); + SrcPixel32.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2); + } + else + { + SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY); + } + SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255; + SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255; + SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255; + SrcPixel32.col.alpha = (SrcBpp == 32) ? + (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : + BlendFunc.SourceConstantAlpha; - Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? - SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha; + Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? + SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; - DstPixel.ul = XLATEOBJ_iXlate(DstTo32Xlate, *Dst); - DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red); - DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green); - DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue); - *Dst++ = XLATEOBJ_iXlate(DstFrom32Xlate, DstPixel.ul); - } - Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta); - SrcY++; - } + DstPixel32.ul = XLATEOBJ_iXlate(SrcXlateObj, *Dst); + SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red); + SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green); + SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue); + *Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul); + } + Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta); + SrcY++; + } - if (SrcTo32Xlate != NULL) - EngDeleteXlate(SrcTo32Xlate); - if (DstTo32Xlate != NULL) - EngDeleteXlate(DstTo32Xlate); - if (DstFrom32Xlate != NULL) - EngDeleteXlate(DstFrom32Xlate); + if (SrcXlateObj) + EngDeleteXlate(SrcXlateObj); - return TRUE; + return TRUE; } /* EOF */ Index: subsystems/win32/win32k/dib/dibXXbpp.c =================================================================== --- subsystems/win32/win32k/dib/dibXXbpp.c (revision 39576) +++ subsystems/win32/win32k/dib/dibXXbpp.c (working copy) @@ -23,42 +23,34 @@ #include BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, + SURFOBJ *PatternSurface, RECTL *DestRect, RECTL *SourceRect, POINTL *MaskOrigin, BRUSHOBJ *Brush, - POINTL *BrushOrigin, CLIPOBJ *ClipRegion, - XLATEOBJ *ColorTranslation, ROP4 ROP) + POINTL *BrushOrigin, + XLATEOBJ *ColorTranslation, + XLATEOBJ *XlatePatternToDest, ROP4 ROP) { - LONG SrcSizeY; - LONG SrcSizeX; - LONG DesSizeY; - LONG DesSizeX; LONG sx = 0; LONG sy = 0; LONG DesX; LONG DesY; - LONG SrcZoomXHight; - LONG SrcZoomXLow; - LONG SrcZoomYHight; - LONG SrcZoomYLow; + LONG dstHight; + LONG dstWidth; + LONG srcHight; + LONG srcWidth; - LONG sy_dec = 0; - LONG sy_max; - - LONG sx_dec = 0; - LONG sx_max; ULONG color; ULONG Dest, Source = 0, Pattern = 0; ULONG xxBPPMask; + BOOL IsDraw = FALSE; PFN_DIB_GetPixel fnSource_GetPixel = NULL; PFN_DIB_GetPixel fnDest_GetPixel = NULL; PFN_DIB_PutPixel fnDest_PutPixel = NULL; + PFN_DIB_GetPixel fnPattern_GetPixel = NULL; - RECT_ENUM RectEnum; - BOOL EnumMore; - unsigned i; - RECTL OutputRect; + ULONG PatternX = 0, PatternY = 0; BOOL UsesSource = ROP4_USES_SOURCE(ROP); BOOL UsesPattern = ROP4_USES_PATTERN(ROP); @@ -76,31 +68,13 @@ BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom); } - /* Calc the Zoom height of Source */ - SrcSizeY = SourceRect->bottom - SourceRect->top; + dstHight = DestRect->bottom - DestRect->top; + dstWidth = DestRect->right - DestRect->left; + srcHight = SourceRect->bottom - SourceRect->top; + srcWidth = SourceRect->right - SourceRect->left; - /* Calc the Zoom Width of Source */ - SrcSizeX = SourceRect->right - SourceRect->left; + /* FIXME : MaskOrigin? */ - /* Calc the Zoom height of Destinations */ - DesSizeY = DestRect->bottom - DestRect->top; - - /* Calc the Zoom width of Destinations */ - DesSizeX = DestRect->right - DestRect->left; - - /* Calc the zoom factor of source height */ - SrcZoomYHight = SrcSizeY / DesSizeY; - SrcZoomYLow = SrcSizeY - (SrcZoomYHight * DesSizeY); - - /* Calc the zoom factor of source width */ - SrcZoomXHight = SrcSizeX / DesSizeX; - SrcZoomXLow = SrcSizeX - (SrcZoomXHight * DesSizeX); - - sx_max = DesSizeX; - sy_max = DesSizeY; - - /* FIXME : MaskOrigin, BrushOrigin? */ - switch(DestSurf->iBitmapFormat) { case BMF_1BPP: xxBPPMask = 0x1; break; @@ -114,73 +88,76 @@ if (UsesPattern) { - DPRINT1("StretchBlt does not support pattern ROPs yet\n"); - return TRUE; + if (PatternSurface) + { + PatternY = (DestRect->top - BrushOrigin->y) % PatternSurface->sizlBitmap.cy; + if (PatternY < 0) + { + PatternY += PatternSurface->sizlBitmap.cy; + } + fnPattern_GetPixel = DibFunctionsForBitmapFormat[PatternSurface->iBitmapFormat].DIB_GetPixel; + } + else + { + if (Brush) + Pattern = Brush->iSolidColor; + } } - - CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0); - do - { - EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum); - for (i = 0; i < RectEnum.c; i++) + + for (DesY=DestRect->top; DesYbottom; DesY++) + { + if (PatternSurface) { - OutputRect.left = RectEnum.arcl[i].left; - OutputRect.right = RectEnum.arcl[i].right; - OutputRect.top = RectEnum.arcl[i].top; - OutputRect.bottom = RectEnum.arcl[i].bottom; - - sy = SourceRect->top; - sy_dec = 0; - for (DesY=DestRect->top; DesYbottom; DesY++) + PatternX = (DestRect->left - BrushOrigin->x) % PatternSurface->sizlBitmap.cx; + if (PatternX < 0) { - sx = SourceRect->left; - sx_dec = 0; + PatternX += PatternSurface->sizlBitmap.cx; + } + } + if (UsesSource) + sy = SourceRect->top+(DesY - DestRect->top) * srcHight / dstHight; - for (DesX=DestRect->left; DesXright; DesX++) + for (DesX=DestRect->left; DesXright; DesX++) + { + IsDraw = TRUE; + if (UsesSource) + { + sx = SourceRect->left+(DesX - DestRect->left) * srcWidth / dstWidth; + if (sx >= 0 && sy >= 0 && + SourceSurf->sizlBitmap.cx > sx && SourceSurf->sizlBitmap.cy > sy) { - /* Check if inside clip region */ - if (DesX >= OutputRect.left && - DesX < OutputRect.right && - DesY >= OutputRect.top && - DesY < OutputRect.bottom) - { - if (UsesSource) - { - Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy)); - } - - if (UsesPattern) - { - /* TBD as soon as BRUSHOBJ is available */ - } - - Dest = fnDest_GetPixel(DestSurf, DesX, DesY); - color = DIB_DoRop(ROP, Dest, Source, Pattern) & xxBPPMask; - - fnDest_PutPixel(DestSurf, DesX, DesY, color); - - } - sx += SrcZoomXHight; - sx_dec += SrcZoomXLow; - if (sx_dec >= sx_max) - { - sx++; - sx_dec -= sx_max; - } + Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy)); } + else + { + Source = 0; + IsDraw = (ROP3_TO_ROP4(SRCCOPY) != ROP); + } + } - sy += SrcZoomYHight; - sy_dec += SrcZoomYLow; - if (sy_dec >= sy_max) + if (IsDraw) + { + if (PatternSurface) { - sy++; - sy_dec -= sy_max; + Pattern = XLATEOBJ_iXlate(XlatePatternToDest, fnPattern_GetPixel(PatternSurface, PatternX, PatternY)); + PatternX++; + PatternX %= PatternSurface->sizlBitmap.cx; } + + Dest = fnDest_GetPixel(DestSurf, DesX, DesY); + color = DIB_DoRop(ROP, Dest, Source, Pattern) & xxBPPMask; + + fnDest_PutPixel(DestSurf, DesX, DesY, color); } } + + if (PatternSurface) + { + PatternY++; + PatternY %= PatternSurface->sizlBitmap.cy; + } } - while (EnumMore); return TRUE; } Index: subsystems/win32/win32k/eng/bitblt.c =================================================================== --- subsystems/win32/win32k/eng/bitblt.c (revision 39576) +++ subsystems/win32/win32k/eng/bitblt.c (working copy) @@ -45,7 +45,6 @@ typedef BOOLEAN (APIENTRY *PSTRETCHRECTFUNC)(SURFOBJ* OutputObj, SURFOBJ* InputObj, SURFOBJ* Mask, - CLIPOBJ* ClipRegion, XLATEOBJ* ColorTranslation, RECTL* OutputRect, RECTL* InputRect, @@ -106,7 +105,7 @@ dx = DestRect->right - DestRect->left; dy = DestRect->bottom - DestRect->top; - if (Brush->iSolidColor == 0xFFFFFFFF) + if (Brush && Brush->iSolidColor == 0xFFFFFFFF) { GdiBrush = CONTAINING_RECORD( Brush, @@ -140,13 +139,13 @@ if (psurfPattern == NULL) { DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel( - Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor); + Dest, DestRect->left + i, DestRect->top + j, Brush ? Brush->iSolidColor : 0); } else { DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel( Dest, DestRect->left + i, DestRect->top + j, - DIB_GetSource(psoPattern, (DestRect->left + i) % PatternWidth, PatternY, GdiBrush->XlateObject)); + DIB_GetSource(psoPattern, (DestRect->left + i) % PatternWidth, PatternY, GdiBrush ? GdiBrush->XlateObject : NULL)); } } c8++; @@ -180,7 +179,7 @@ // These functions are assigned if we're working with a DIB // The assigned functions depend on the bitsPerPixel of the DIB - DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_ColorFill(Dest, DestRect, Brush->iSolidColor); + DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_ColorFill(Dest, DestRect, Brush ? Brush->iSolidColor : 0); return TRUE; } @@ -218,7 +217,7 @@ BltInfo.Rop4 = Rop4; /* Pattern brush */ - if (ROP4_USES_PATTERN(Rop4) && Brush->iSolidColor == 0xFFFFFFFF) + if (ROP4_USES_PATTERN(Rop4) && Brush && Brush->iSolidColor == 0xFFFFFFFF) { GdiBrush = CONTAINING_RECORD(Brush, GDIBRUSHINST, BrushObject); if ((psurfPattern = SURFACE_LockSurface(GdiBrush->GdiBrushObject->hbmPattern))) @@ -488,7 +487,7 @@ } else if (ROP3_TO_ROP4(PATCOPY) == Rop4) { - if (Brush->iSolidColor == 0xFFFFFFFF) + if (Brush && Brush->iSolidColor == 0xFFFFFFFF) BltRectFunc = CallDibBitBlt; else BltRectFunc = BltPatCopy; @@ -737,7 +736,6 @@ CallDibStretchBlt(SURFOBJ* psoDest, SURFOBJ* psoSource, SURFOBJ* Mask, - CLIPOBJ* ClipRegion, XLATEOBJ* ColorTranslation, RECTL* OutputRect, RECTL* InputRect, @@ -747,6 +745,11 @@ ROP4 Rop4) { POINTL RealBrushOrigin; + SURFACE* psurfPattern; + PGDIBRUSHINST GdiBrush = NULL; + SURFOBJ* PatternSurface = NULL; + XLATEOBJ* XlatePatternToDest = NULL; + if (BrushOrigin == NULL) { RealBrushOrigin.x = RealBrushOrigin.y = 0; @@ -754,9 +757,38 @@ else { RealBrushOrigin = *BrushOrigin; + } + + /* Pattern brush */ + if (ROP4_USES_PATTERN(Rop4) && Brush && Brush->iSolidColor == 0xFFFFFFFF) + { + GdiBrush = CONTAINING_RECORD(Brush, GDIBRUSHINST, BrushObject); + psurfPattern = SURFACE_LockSurface(GdiBrush->GdiBrushObject->hbmPattern); + if (psurfPattern) + { + PatternSurface = &psurfPattern->SurfObj; + } + else + { + /* FIXME - What to do here? */ + } + XlatePatternToDest = GdiBrush->XlateObject; } + else + { + psurfPattern = NULL; + } + return DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_StretchBlt( - psoDest, psoSource, OutputRect, InputRect, MaskOrigin, Brush, &RealBrushOrigin, ClipRegion, ColorTranslation, Rop4); + psoDest, psoSource, PatternSurface, + OutputRect, InputRect, MaskOrigin, Brush, &RealBrushOrigin, + ColorTranslation, XlatePatternToDest, Rop4); + + /* Pattern brush */ + if (psurfPattern) + { + SURFACE_UnlockSurface(psurfPattern); + } } @@ -836,10 +868,34 @@ SURFOBJ* psoInput; SURFOBJ* psoOutput; PSTRETCHRECTFUNC BltRectFunc; - BOOLEAN Ret; + BOOLEAN Ret = TRUE; POINTL AdjustedBrushOrigin; BOOL UsesSource = ROP4_USES_SOURCE(ROP4); + BYTE clippingType; + RECTL ClipRect; + RECT_ENUM RectEnum; + BOOL EnumMore; + ULONG Direction; + RECTL CombinedRect; + RECTL InputToCombinedRect; + unsigned i; + + LONG dstHight; + LONG dstWidth; + LONG srcHight; + LONG srcWidth; + + /* Determine clipping type */ + if (ClipRegion == (CLIPOBJ *) NULL) + { + clippingType = DC_TRIVIAL; + } + else + { + clippingType = ClipRegion->iDComplexity; + } + if (ROP4 == R4_NOOP) { /* Copy destination onto itself: nop */ @@ -866,18 +922,6 @@ return FALSE; } - /* Make sure we don't try to copy anything outside the valid source region */ - if (InputRect.left < 0) - { - OutputRect.left -= InputRect.left; - InputRect.left = 0; - } - if (InputRect.top < 0) - { - OutputRect.top -= InputRect.top; - InputRect.top = 0; - } - if (! IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &psoInput)) { @@ -965,10 +1009,90 @@ BltRectFunc = CallDibStretchBlt; } - Ret = (*BltRectFunc)(psoOutput, psoInput, Mask, ClipRegion, + dstHight = OutputRect.bottom - OutputRect.top; + dstWidth = OutputRect.right - OutputRect.left; + srcHight = InputRect.bottom - InputRect.top; + srcWidth = InputRect.right - InputRect.left; + switch (clippingType) + { + case DC_TRIVIAL: + Ret = (*BltRectFunc)(psoOutput, psoInput, Mask, ColorTranslation, &OutputRect, &InputRect, MaskOrigin, Brush, &AdjustedBrushOrigin, ROP4); + break; + case DC_RECT: + // Clip the blt to the clip rectangle + ClipRect.left = ClipRegion->rclBounds.left + Translate.x; + ClipRect.right = ClipRegion->rclBounds.right + Translate.x; + ClipRect.top = ClipRegion->rclBounds.top + Translate.y; + ClipRect.bottom = ClipRegion->rclBounds.bottom + Translate.y; + if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect)) + { + InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * srcHight / dstHight; + InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * srcHight / dstHight; + InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * srcWidth / dstWidth; + InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * srcWidth / dstWidth; + Ret = (*BltRectFunc)(psoOutput, psoInput, Mask, + ColorTranslation, + &CombinedRect, + &InputToCombinedRect, + MaskOrigin, + Brush, + &AdjustedBrushOrigin, + ROP4); + } + break; + case DC_COMPLEX: + if (psoOutput == psoInput) + { + if (OutputRect.top < InputRect.top) + { + Direction = OutputRect.left < InputRect.left ? + CD_RIGHTDOWN : CD_LEFTDOWN; + } + else + { + Direction = OutputRect.left < InputRect.left ? + CD_RIGHTUP : CD_LEFTUP; + } + } + else + { + Direction = CD_ANY; + } + CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, Direction, 0); + do + { + EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), + (PVOID) &RectEnum); + for (i = 0; i < RectEnum.c; i++) + { + ClipRect.left = RectEnum.arcl[i].left + Translate.x; + ClipRect.right = RectEnum.arcl[i].right + Translate.x; + ClipRect.top = RectEnum.arcl[i].top + Translate.y; + ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y; + if (EngIntersectRect(&CombinedRect, &OutputRect, &ClipRect)) + { + InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * srcHight / dstHight; + InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * srcHight / dstHight; + InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * srcWidth / dstWidth; + InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * srcWidth / dstWidth; + Ret = (*BltRectFunc)(psoOutput, psoInput, Mask, + ColorTranslation, + &CombinedRect, + &InputToCombinedRect, + MaskOrigin, + Brush, + &AdjustedBrushOrigin, + ROP4); + } + } + } + while (EnumMore); + break; + } + IntEngLeave(&EnterLeaveDest); if (UsesSource) { @@ -1009,7 +1133,7 @@ MaskOrigin, Mode, NULL, - SRCCOPY); + ROP3_TO_ROP4(SRCCOPY)); } BOOL APIENTRY @@ -1061,18 +1185,6 @@ } InputRect = *SourceRect; - /* Make sure we don't try to copy anything outside the valid source region */ - if (InputRect.left < 0) - { - InputClippedRect.left -= InputRect.left; - InputRect.left = 0; - } - if (InputRect.top < 0) - { - InputClippedRect.top -= InputRect.top; - InputRect.top = 0; - } - if (InputClippedRect.right < InputClippedRect.left || InputClippedRect.bottom < InputClippedRect.top) { @@ -1547,7 +1659,7 @@ if (Mask != NULL) { - BrushColor = XLATEOBJ_iXlate(SrcColorTranslation, Brush->iSolidColor); + BrushColor = XLATEOBJ_iXlate(SrcColorTranslation, Brush ? Brush->iSolidColor : 0); r = (int)GetRValue(BrushColor); g = (int)GetGValue(BrushColor); b = (int)GetBValue(BrushColor); @@ -1563,7 +1675,7 @@ if (*lMask == 0xff) { DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_PutPixel( - psoDest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor); + psoDest, DestRect->left + i, DestRect->top + j, Brush ? Brush->iSolidColor : 0); } else { Index: subsystems/win32/win32k/ntuser/cursoricon.c =================================================================== --- subsystems/win32/win32k/ntuser/cursoricon.c (revision 39576) +++ subsystems/win32/win32k/ntuser/cursoricon.c (working copy) @@ -1389,82 +1389,6 @@ } -#define STRETCH_CAN_SRCCOPY_ONLY - -#ifdef STRETCH_CAN_SRCCOPY_ONLY -void -FASTCALL -DoStretchBlt(HDC DcDest, int XDest, int YDest, int WidthDest, int HeightDest, - HDC DcSrc, int XSrc, int YSrc, int WidthSrc, int HeightSrc, - DWORD Rop3, BOOL Color) -{ - HDC DcStretched; - HBITMAP BitmapStretched; - HBITMAP OldBitmap; - - if (WidthDest == WidthSrc && HeightDest == HeightSrc) - { - NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest, - DcSrc, XSrc, YSrc, Rop3, 0, 0); - } - else if (SRCCOPY == Rop3) - { - NtGdiStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest, - DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, - Rop3, 0); - } - else - { - DcStretched = NtGdiCreateCompatibleDC(DcSrc); - if (NULL == DcStretched) - { - DPRINT1("Failed to create compatible DC\n"); - return; - } - if (Color) - { - BitmapStretched = NtGdiCreateCompatibleBitmap(DcDest, WidthDest, - HeightDest); - } - else - { - BitmapStretched = IntGdiCreateBitmap(WidthDest, HeightDest, 1, 1, NULL); - } - if (NULL == BitmapStretched) - { - NtGdiDeleteObjectApp(DcStretched); - DPRINT1("Failed to create temporary bitmap\n"); - return; - } - OldBitmap = NtGdiSelectBitmap(DcStretched, BitmapStretched); - if (NULL == OldBitmap) - { - NtGdiDeleteObject(BitmapStretched); - NtGdiDeleteObjectApp(DcStretched); - DPRINT1("Failed to create temporary bitmap\n"); - return; - } - if (! NtGdiStretchBlt(DcStretched, 0, 0, WidthDest, HeightDest, - DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, - SRCCOPY, 0) || - ! NtGdiBitBlt(DcDest, XDest, YDest, WidthDest, HeightDest, - DcStretched, 0, 0, Rop3, 0, 0)) - { - DPRINT1("Failed to blt\n"); - } - NtGdiSelectBitmap(DcStretched, OldBitmap); - NtGdiDeleteObject(BitmapStretched); - NtGdiDeleteObjectApp(DcStretched); - } -} -#else -#define DoStretchBlt(DcDest, XDest, YDest, WidthDest, HeightDest, \ - DcSrc, XSrc, YSrc, WidthSrc, HeightSrc, Rop3, Color) \ - NtGdiStretchBlt((DcDest), (XDest), (YDest), (WidthDest), (HeightDest), \ - (DcSrc), (XSrc), (YSrc), (WidthSrc), (HeightSrc), \ - (Rop3), 0) -#endif /* STRETCH_CAN_SRCCOPY_ONLY */ - BOOL UserDrawIconEx( HDC hDc, @@ -1524,9 +1448,32 @@ when cxWidth or cyHeight is 0 */ if ((bmpColor.bmBitsPixel == 32) && (cxWidth != 0) && (cyHeight != 0)) { - bAlpha = TRUE; - } + SURFACE *psurfOff = NULL; + PFN_DIB_GetPixel fnSource_GetPixel = NULL; + INT x, y; + psurfOff = SURFACE_LockSurface(hbmColor); + if (psurfOff) + { + fnSource_GetPixel = DibFunctionsForBitmapFormat[psurfOff->SurfObj.iBitmapFormat].DIB_GetPixel; + if (fnSource_GetPixel) + { + for (x = 0; x < psurfOff->SurfObj.sizlBitmap.cx; x++) + { + for (y = 0; y < psurfOff->SurfObj.sizlBitmap.cx; y++) + { + bAlpha = ((BYTE)(fnSource_GetPixel(&psurfOff->SurfObj, x, y) >> 24) & 0xff); + if (bAlpha) + break; + } + if (bAlpha) + break; + } + } + SURFACE_UnlockSurface(psurfOff); + } + } + if (!diFlags) diFlags = DI_NORMAL; @@ -1541,209 +1488,196 @@ DoFlickerFree = (hbrFlickerFreeDraw && (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH)); - if (DoFlickerFree || bAlpha) - { - RECT r; - BITMAP bm; - SURFACE *psurfOff = NULL; + if (DoFlickerFree || bAlpha) + { + RECT r; + BITMAP bm; + SURFACE *psurfOff = NULL; - r.right = cxWidth; - r.bottom = cyHeight; + r.right = cxWidth; + r.bottom = cyHeight; - hdcOff = NtGdiCreateCompatibleDC(hDc); - if (!hdcOff) - { - DPRINT1("NtGdiCreateCompatibleDC() failed!\n"); - return FALSE; - } + hdcOff = NtGdiCreateCompatibleDC(hDc); + if (!hdcOff) + { + DPRINT1("NtGdiCreateCompatibleDC() failed!\n"); + return FALSE; + } - hbmOff = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight); - if (!hbmOff) - { - DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n"); - goto cleanup; - } + hbmOff = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight); + if (!hbmOff) + { + DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n"); + goto cleanup; + } - /* make sure we have a 32 bit offscreen bitmap - otherwise we can't do alpha blending */ - psurfOff = SURFACE_LockSurface(hbmOff); - if (psurfOff == NULL) - { - DPRINT1("BITMAPOBJ_LockBitmap() failed!\n"); - goto cleanup; - } - BITMAP_GetObject(psurfOff, sizeof(BITMAP), (PVOID)&bm); + /* make sure we have a 32 bit offscreen bitmap + otherwise we can't do alpha blending */ + psurfOff = SURFACE_LockSurface(hbmOff); + if (psurfOff == NULL) + { + DPRINT1("BITMAPOBJ_LockBitmap() failed!\n"); + goto cleanup; + } + BITMAP_GetObject(psurfOff, sizeof(BITMAP), (PVOID)&bm); - if (bm.bmBitsPixel != 32) - bAlpha = FALSE; + if (bm.bmBitsPixel != 32) + bAlpha = FALSE; - SURFACE_UnlockSurface(psurfOff); + SURFACE_UnlockSurface(psurfOff); - hOldOffBmp = NtGdiSelectBitmap(hdcOff, hbmOff); - if (!hOldOffBmp) - { - DPRINT1("NtGdiSelectBitmap() failed!\n"); - goto cleanup; - } + hOldOffBmp = NtGdiSelectBitmap(hdcOff, hbmOff); + if (!hOldOffBmp) + { + DPRINT1("NtGdiSelectBitmap() failed!\n"); + goto cleanup; + } - if (DoFlickerFree) - { - hOldOffBrush = NtGdiSelectBrush(hdcOff, hbrFlickerFreeDraw); - if (!hOldOffBrush) - { - DPRINT1("NtGdiSelectBrush() failed!\n"); - goto cleanup; - } + if (DoFlickerFree) + { + hOldOffBrush = NtGdiSelectBrush(hdcOff, hbrFlickerFreeDraw); + if (!hOldOffBrush) + { + DPRINT1("NtGdiSelectBrush() failed!\n"); + goto cleanup; + } - NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY); - } - } - else - hdcOff = hDc; + NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY); + } + } + else + hdcOff = hDc; - hdcMem = NtGdiCreateCompatibleDC(hDc); - if (!hdcMem) - { - DPRINT1("NtGdiCreateCompatibleDC() failed!\n"); - goto cleanup; - } + hdcMem = NtGdiCreateCompatibleDC(hDc); + if (!hdcMem) + { + DPRINT1("NtGdiCreateCompatibleDC() failed!\n"); + goto cleanup; + } - nStretchMode = IntGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS); + nStretchMode = IntGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS); - oldFg = IntGdiSetTextColor(hdcOff, RGB(0, 0, 0)); - oldBg = IntGdiSetBkColor(hdcOff, RGB(255, 255, 255)); + oldFg = IntGdiSetTextColor(hdcOff, RGB(0, 0, 0)); + oldBg = IntGdiSetBkColor(hdcOff, RGB(255, 255, 255)); - if (diFlags & DI_MASK) - { - hOldMem = NtGdiSelectBitmap(hdcMem, hbmMask); - if (!hOldMem) - { - DPRINT("NtGdiSelectBitmap() failed!\n"); - goto cleanup; - } - DoStretchBlt(hdcOff, - (DoFlickerFree || bAlpha ? 0 : xLeft), - (DoFlickerFree || bAlpha ? 0 : yTop), - cxWidth, - cyHeight, - hdcMem, - 0, - 0, - IconSize.cx, - IconSize.cy, - ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), - FALSE); + if (bAlpha) + { + BLENDFUNCTION BlendFunc; - NtGdiSelectBitmap(hdcMem, hOldMem); - } + BlendFunc.BlendOp = AC_SRC_OVER; + BlendFunc.BlendFlags = 0; + BlendFunc.SourceConstantAlpha = 255; + BlendFunc.AlphaFormat = AC_SRC_ALPHA; - if(diFlags & DI_IMAGE) - { - hOldMem = NtGdiSelectBitmap(hdcMem, (hbmColor ? hbmColor : hbmMask)); + if (DoFlickerFree) + { + hOldMem = NtGdiSelectBitmap(hdcMem, (hbmColor ? hbmColor : hbmMask)); - DoStretchBlt(hdcOff, - (DoFlickerFree || bAlpha ? 0 : xLeft), - (DoFlickerFree || bAlpha ? 0 : yTop), - cxWidth, - cyHeight, - hdcMem, - 0, - (hbmColor ? 0 : IconSize.cy), - IconSize.cx, - IconSize.cy, - ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY), - NULL != hbmColor); + NtGdiStretchBlt(hdcOff, + (DoFlickerFree || bAlpha ? 0 : xLeft), + (DoFlickerFree || bAlpha ? 0 : yTop), + cxWidth, + cyHeight, + hdcMem, + 0, + (hbmColor ? 0 : IconSize.cy), + IconSize.cx, + IconSize.cy, + SRCCOPY, + 0); - NtGdiSelectBitmap(hdcMem, hOldMem); - } + NtGdiSelectBitmap(hdcMem, hOldMem); + NtGdiAlphaBlend(hDc, xLeft, yTop, cxWidth, cyHeight, + hdcOff, 0, 0, cxWidth, cyHeight, BlendFunc, 0); - if (bAlpha) - { - BITMAP bm; - SURFACE *psurfOff = NULL; - PBYTE pBits = NULL; - BLENDFUNCTION BlendFunc; - DWORD Pixel; - BYTE Red, Green, Blue, Alpha; - DWORD Count = 0; - INT i, j; - - psurfOff = SURFACE_LockSurface(hbmOff); - if (psurfOff == NULL) + } + else { - DPRINT1("BITMAPOBJ_LockBitmap() failed!\n"); - goto cleanup; + hOldMem = NtGdiSelectBitmap(hdcMem, (hbmColor ? hbmColor : hbmMask)); + NtGdiAlphaBlend(hDc, xLeft, yTop, cxWidth, cyHeight, + hdcMem, 0, 0, IconSize.cx, IconSize.cy, BlendFunc, 0); + NtGdiSelectBitmap(hdcMem, hOldMem); } - BITMAP_GetObject(psurfOff, sizeof(BITMAP), (PVOID)&bm); - pBits = ExAllocatePoolWithTag(PagedPool, bm.bmWidthBytes * abs(bm.bmHeight), TAG_BITMAP); - if (pBits == NULL) + } + else + { + if (DoFlickerFree) { - DPRINT1("ExAllocatePoolWithTag() failed!\n"); - SURFACE_UnlockSurface(psurfOff); - goto cleanup; + RECT r; + r.right = cxWidth; + r.bottom = cyHeight; + NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY); } - - /* get icon bits */ - IntGetBitmapBits(psurfOff, bm.bmWidthBytes * abs(bm.bmHeight), pBits); - - /* premultiply with the alpha channel value */ - for (i = 0; i < cyHeight; i++) + if (diFlags & DI_MASK) { - for (j = 0; j < cxWidth; j++) + hOldMem = NtGdiSelectBitmap(hdcMem, hbmMask); + if (!hOldMem) { - Pixel = *(DWORD *)(pBits + Count); + DPRINT("NtGdiSelectBitmap() failed!\n"); + goto cleanup; + } - Alpha = ((BYTE)(Pixel >> 24) & 0xff); + NtGdiStretchBlt(hdcOff, + (DoFlickerFree || bAlpha ? 0 : xLeft), + (DoFlickerFree || bAlpha ? 0 : yTop), + cxWidth, + cyHeight, + hdcMem, + 0, + 0, + IconSize.cx, + IconSize.cy, + ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), + 0); - Red = (((BYTE)(Pixel >> 0)) * Alpha) / 0xff; - Green = (((BYTE)(Pixel >> 8)) * Alpha) / 0xff; - Blue = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff; - - *(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24)); - - Count += sizeof (DWORD); - } + NtGdiSelectBitmap(hdcMem, hOldMem); } - /* set icon bits */ - IntSetBitmapBits(psurfOff, bm.bmWidthBytes * abs(bm.bmHeight), pBits); - ExFreePoolWithTag(pBits, TAG_BITMAP); + if(diFlags & DI_IMAGE) + { + hOldMem = NtGdiSelectBitmap(hdcMem, (hbmColor ? hbmColor : hbmMask)); - SURFACE_UnlockSurface(psurfOff); + NtGdiStretchBlt(hdcOff, + (DoFlickerFree || bAlpha ? 0 : xLeft), + (DoFlickerFree || bAlpha ? 0 : yTop), + cxWidth, + cyHeight, + hdcMem, + 0, + (hbmColor ? 0 : IconSize.cy), + IconSize.cx, + IconSize.cy, + ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY), + 0); - BlendFunc.BlendOp = AC_SRC_OVER; - BlendFunc.BlendFlags = 0; - BlendFunc.SourceConstantAlpha = 255; - BlendFunc.AlphaFormat = AC_SRC_ALPHA; + NtGdiSelectBitmap(hdcMem, hOldMem); + } - NtGdiAlphaBlend(hDc, xLeft, yTop, cxWidth, cyHeight, - hdcOff, 0, 0, cxWidth, cyHeight, BlendFunc, 0); + if (DoFlickerFree) + { + NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0); + } } - else if (DoFlickerFree) - { - NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, - cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0); - } - IntGdiSetTextColor(hdcOff, oldFg); - IntGdiSetBkColor(hdcOff, oldBg); - IntGdiSetStretchBltMode(hdcOff, nStretchMode); + IntGdiSetTextColor(hdcOff, oldFg); + IntGdiSetBkColor(hdcOff, oldBg); + IntGdiSetStretchBltMode(hdcOff, nStretchMode); - Ret = TRUE; + Ret = TRUE; cleanup: - if(DoFlickerFree || bAlpha) - { - if(hOldOffBmp) NtGdiSelectBitmap(hdcOff, hOldOffBmp); - if(hOldOffBrush) NtGdiSelectBrush(hdcOff, hOldOffBrush); - if(hbmOff) NtGdiDeleteObject(hbmOff); - if(hdcOff) NtGdiDeleteObjectApp(hdcOff); - } + if(DoFlickerFree || bAlpha) + { + if(hOldOffBmp) NtGdiSelectBitmap(hdcOff, hOldOffBmp); + if(hOldOffBrush) NtGdiSelectBrush(hdcOff, hOldOffBrush); + if(hbmOff) NtGdiDeleteObject(hbmOff); + if(hdcOff) NtGdiDeleteObjectApp(hdcOff); + } - if(hdcMem) NtGdiDeleteObjectApp(hdcMem); - return Ret; + if(hdcMem) NtGdiDeleteObjectApp(hdcMem); + return Ret; } /* @@ -1752,45 +1686,38 @@ BOOL APIENTRY NtUserDrawIconEx( - HDC hdc, - int xLeft, - int yTop, - HICON hIcon, - int cxWidth, - int cyHeight, - UINT istepIfAniCur, - HBRUSH hbrFlickerFreeDraw, - UINT diFlags, - DWORD Unknown0, - DWORD Unknown1) + HDC hdc, + int xLeft, + int yTop, + HICON hIcon, + int cxWidth, + int cyHeight, + UINT istepIfAniCur, + HBRUSH hbrFlickerFreeDraw, + UINT diFlags, + DWORD Unknown0, + DWORD Unknown1) { - PCURICON_OBJECT pIcon; - BOOL Ret; + PCURICON_OBJECT pIcon; + BOOL Ret; - DPRINT("Enter NtUserDrawIconEx\n"); - UserEnterExclusive(); + DPRINT("Enter NtUserDrawIconEx\n"); + UserEnterExclusive(); - if(!(pIcon = UserGetCurIconObject(hIcon))) - { - DPRINT1("UserGetCurIconObject() failed!\n"); - UserLeave(); - return FALSE; - } + if(!(pIcon = UserGetCurIconObject(hIcon))) + { + DPRINT1("UserGetCurIconObject() failed!\n"); + UserLeave(); + return FALSE; + } - Ret = UserDrawIconEx(hdc, - xLeft, - yTop, - pIcon, - cxWidth, - cyHeight, - istepIfAniCur, - hbrFlickerFreeDraw, - diFlags); + Ret = UserDrawIconEx(hdc, xLeft, yTop, pIcon, cxWidth, cyHeight, + istepIfAniCur, hbrFlickerFreeDraw, diFlags); - UserDereferenceObject(pIcon); + UserDereferenceObject(pIcon); - UserLeave(); - return Ret; + UserLeave(); + return Ret; } /* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR Index: subsystems/win32/win32k/objects/bitblt.c =================================================================== --- subsystems/win32/win32k/objects/bitblt.c (revision 39576) +++ subsystems/win32/win32k/objects/bitblt.c (working copy) @@ -751,7 +751,7 @@ PDC DCDest; PDC DCSrc = NULL; PDC_ATTR Dc_Attr; - SURFACE *BitmapDest, *BitmapSrc = NULL; + SURFACE *BitmapDest = NULL, *BitmapSrc = NULL; RECTL DestRect; RECTL SourceRect; BOOL Status = FALSE; @@ -842,8 +842,9 @@ /* Determine surfaces to be used in the bitblt */ BitmapDest = SURFACE_LockSurface(DCDest->w.hBitmap); - if (BitmapDest == NULL) + if (!BitmapDest) goto failed; + if (UsesSource) { if (DCSrc->w.hBitmap == DCDest->w.hBitmap) @@ -878,6 +879,8 @@ BrushOrigin = *((PPOINTL)&BrushObj->ptOrigin); IntGdiInitBrushInstance(&BrushInst, BrushObj, DCDest->XlateBrush); } + BrushOrigin.x += DCDest->ptlDCOrig.x; + BrushOrigin.y += DCDest->ptlDCOrig.y; /* Perform the bitblt operation */ Status = IntEngStretchBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, @@ -937,7 +940,7 @@ return FALSE; } - if (!(BrushObj->flAttrs & GDIBRUSH_IS_NULL)) + if (BrushObj && !(BrushObj->flAttrs & GDIBRUSH_IS_NULL)) { if (Width > 0) { Index: tools/gendib/gendib.c =================================================================== --- tools/gendib/gendib.c (revision 39534) +++ tools/gendib/gendib.c (working copy) @@ -877,6 +877,12 @@ { if (0 == Partial) { + Output(Out, "if (!BltInfo->Brush)\n"); + Output(Out, "{\n"); + Output(Out, "Pattern = 0;\n"); + Output(Out, "}\n"); + Output(Out, "else\n"); + Output(Out, "{\n"); Output(Out, "Pattern = BltInfo->Brush->iSolidColor"); } else @@ -887,6 +893,7 @@ if (32 / Bpp <= Partial + 1) { Output(Out, ";\n"); + Output(Out, "}\n"); } else {