From 566b92320cef43d5938f955e7112bae90a676f1d Mon Sep 17 00:00:00 2001 From: Akihiro Sagawa Date: Sat, 13 Oct 2018 22:31:00 +0900 Subject: [PATCH] gdi32: Fix negative width/height handling in stretch bitblt family. Signed-off-by: Akihiro Sagawa Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/bitblt.c | 26 ++++++++++++++------------ dlls/gdi32/tests/bitmap.c | 3 +-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c index c8d67cbadab..6f5af649c6c 100644 --- a/dlls/gdi32/bitblt.c +++ b/dlls/gdi32/bitblt.c @@ -57,12 +57,13 @@ BOOL intersect_vis_rectangles( struct bitblt_coords *dst, struct bitblt_coords * { /* map source rectangle into destination coordinates */ rect = src->visrect; - offset_rect( &rect, -min( src->x, src->x + src->width + 1), - -min( src->y, src->y + src->height + 1) ); - rect.left = dst->x + rect.left * dst->width / abs(src->width); - rect.top = dst->y + rect.top * dst->height / abs(src->height); - rect.right = dst->x + rect.right * dst->width / abs(src->width); - rect.bottom = dst->y + rect.bottom * dst->height / abs(src->height); + offset_rect( &rect, + -src->x - (src->width < 0 ? 1 : 0), + -src->y - (src->height < 0 ? 1 : 0)); + rect.left = dst->x + rect.left * dst->width / src->width; + rect.top = dst->y + rect.top * dst->height / src->height; + rect.right = dst->x + rect.right * dst->width / src->width; + rect.bottom = dst->y + rect.bottom * dst->height / src->height; order_rect( &rect ); /* avoid rounding errors */ @@ -74,12 +75,13 @@ BOOL intersect_vis_rectangles( struct bitblt_coords *dst, struct bitblt_coords * /* map destination rectangle back to source coordinates */ rect = dst->visrect; - offset_rect( &rect, -min( dst->x, dst->x + dst->width + 1), - -min( dst->y, dst->y + dst->height + 1) ); - rect.left = src->x + rect.left * src->width / abs(dst->width); - rect.top = src->y + rect.top * src->height / abs(dst->height); - rect.right = src->x + rect.right * src->width / abs(dst->width); - rect.bottom = src->y + rect.bottom * src->height / abs(dst->height); + offset_rect( &rect, + -dst->x - (dst->width < 0 ? 1 : 0), + -dst->y - (dst->height < 0 ? 1 : 0)); + rect.left = src->x + rect.left * src->width / dst->width; + rect.top = src->y + rect.top * src->height / dst->height; + rect.right = src->x + rect.right * src->width / dst->width; + rect.bottom = src->y + rect.bottom * src->height / dst->height; order_rect( &rect ); /* avoid rounding errors */ diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c index d8a6fb016d9..a902edcfb4f 100644 --- a/dlls/gdi32/tests/bitmap.c +++ b/dlls/gdi32/tests/bitmap.c @@ -3256,7 +3256,7 @@ static void test_StretchBlt(void) memset( expected, 0, get_dib_image_size( &biDst ) ); expected[17] = 0x76543210, expected[18] = 0xfedcba98; expected[32] = 0x0000cccc, expected[33] = 0x0000f0f0, expected[34] = 0x0000ff00; - todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, + check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 2, 2, -8, -8, 0, 0, 8, 8, expected, __LINE__); /* the source rectangle doesn't fit in the device area */ @@ -3701,7 +3701,6 @@ static void test_GdiAlphaBlend(void) SetViewportExtEx(hdcDst, -1, -1, NULL); SetLastError(0xdeadbeef); ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend); - todo_wine ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); SetLastError(0xdeadbeef); ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend);