From 9f458df88c719f095deb859e163f3c2296df3f43 Mon Sep 17 00:00:00 2001 From: Akihiro Sagawa Date: Sat, 13 Oct 2018 22:31:02 +0900 Subject: [PATCH] gdi32: Adjust destination coordinates in some special cases. When the source rectangle needs to flip and it doesn't fit in the source device area, the destination image is flipped but the destination area isn't flipped. GdiAlphaBlend doesn't support mirroring, the above isn't applicable. 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 | 6 +++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c index 6f5af649c6c..abca82245a4 100644 --- a/dlls/gdi32/bitblt.c +++ b/dlls/gdi32/bitblt.c @@ -60,12 +60,30 @@ BOOL intersect_vis_rectangles( struct bitblt_coords *dst, struct bitblt_coords * 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; + rect.left = rect.left * dst->width / src->width; + rect.top = rect.top * dst->height / src->height; + rect.right = rect.right * dst->width / src->width; + rect.bottom = rect.bottom * dst->height / src->height; order_rect( &rect ); + /* when the source rectangle needs to flip and it doesn't fit in the source device + area, the destination area isn't flipped. So, adjust destination coordinates */ + if (src->width < 0 && dst->width > 0 && + (src->x + src->width + 1 < src->visrect.left || src->x > src->visrect.right)) + dst->x += (dst->width - rect.right) - rect.left; + else if (src->width > 0 && dst->width < 0 && + (src->x < src->visrect.left || src->x + src->width > src->visrect.right)) + dst->x -= rect.right - (dst->width - rect.left); + + if (src->height < 0 && dst->height > 0 && + (src->y + src->height + 1 < src->visrect.top || src->y > src->visrect.bottom)) + dst->y += (dst->height - rect.bottom) - rect.top; + else if (src->height > 0 && dst->height < 0 && + (src->y < src->visrect.top || src->y + src->height > src->visrect.bottom)) + dst->y -= rect.bottom - (dst->height - rect.top); + + offset_rect( &rect, dst->x, dst->y ); + /* avoid rounding errors */ rect.left--; rect.top--; diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c index a902edcfb4f..4622de9c937 100644 --- a/dlls/gdi32/tests/bitmap.c +++ b/dlls/gdi32/tests/bitmap.c @@ -3263,13 +3263,13 @@ static void test_StretchBlt(void) memset( expected, 0, get_dib_image_size( &biDst ) ); expected[102] = 0x76543210, expected[103] = 0xfedcba98; expected[117] = 0x0000cccc, expected[118] = 0x0000f0f0, expected[119] = 0x0000ff00; - todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, + check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 0, 0, 8, 8, 2, 2, -8, -8, expected, __LINE__); memset( expected, 0, get_dib_image_size( &biDst ) ); expected[85] = 0x76543210, expected[86] = 0xfedcba98; expected[99] = 0x0000aaaa, expected[100] = 0x0000cccc, expected[101] = 0x0000f0f0, expected[102] = 0x0000ff00; - todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, + check_StretchBlt_stretch(hdcDst, hdcSrc, &biDst, dstBuffer, srcBuffer, 8, 8, -18, -18, 0, 0, 18, 18, expected, __LINE__); SelectObject(hdcDst, oldDst); @@ -3595,7 +3595,7 @@ static void test_StretchDIBits(void) expected[0] = 0x00000000, expected[1] = 0x00000000; expected[2] = 0xFEEDFACE, expected[3] = 0x00000000; - todo_wine ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, 1, 1, -2, -2, 1, 1, 2, 2, expected, __LINE__); ok( ret == 2, "got ret %d\n", ret );