Index: subsystems/win32/win32k/dib/dib.c =================================================================== --- subsystems/win32/win32k/dib/dib.c (revision 39534) +++ 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 39534) +++ 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/dib24bpp.c =================================================================== --- subsystems/win32/win32k/dib/dib24bpp.c (revision 39534) +++ 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/dibXXbpp.c =================================================================== --- subsystems/win32/win32k/dib/dibXXbpp.c (revision 39534) +++ 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 39534) +++ 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) { @@ -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/objects/bitblt.c =================================================================== --- subsystems/win32/win32k/objects/bitblt.c (revision 39534) +++ 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 {