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 <sagawa.aki@gmail.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Akihiro Sagawa 2018-10-13 22:31:02 +09:00 committed by Alexandre Julliard
parent 566b92320c
commit 9f458df88c
2 changed files with 25 additions and 7 deletions

View File

@ -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--;

View File

@ -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 );