From bcc21c9b79369634667ee22b2711a0834a32cf8d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 1 Sep 2011 13:00:14 +0200 Subject: [PATCH] winex11: Fix SetDIBitsToDevice coordinate mapping for negative values. --- dlls/gdi32/tests/bitmap.c | 41 +++++++++++++++++++++++++++++++++++++++ dlls/winex11.drv/dib.c | 9 ++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c index e7b7d2d7b0a..6a80232aa1c 100644 --- a/dlls/gdi32/tests/bitmap.c +++ b/dlls/gdi32/tests/bitmap.c @@ -4364,6 +4364,15 @@ static void test_SetDIBitsToDevice(void) for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); memset( dib_bits, 0xaa, 64 * 4 ); + ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -2, -4, 0, 12, data, info, DIB_RGB_COLORS ); + ok( ret == 12, "got %d\n", ret ); + for (i = 0; i < 64; i++) + if (i == 31 || i == 39 || i == 47 || i == 55 || i == 63) + ok( dib_bits[i] == inverted_data[i + 1], "%d: got %08x\n", i, dib_bits[i] ); + else + ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); + memset( dib_bits, 0xaa, 64 * 4 ); + info->bmiHeader.biHeight = -5; ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS ); ok( ret == 2, "got %d\n", ret ); @@ -4420,6 +4429,15 @@ static void test_SetDIBitsToDevice(void) for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); memset( dib_bits, 0xaa, 64 * 4 ); + ret = SetDIBitsToDevice( hdc, 5, -7, 8, 16, -1, -8, 0, 12, data, info, DIB_RGB_COLORS ); + ok( ret == 12, "got %d\n", ret ); + for (i = 0; i < 64; i++) + if (i == 6 || i == 7) + ok( dib_bits[i] == data[i + 82], "%d: got %08x\n", i, dib_bits[i] ); + else + ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); + memset( dib_bits, 0xaa, 64 * 4 ); + info->bmiHeader.biHeight = -5; ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS ); ok( ret == 2, "got %d\n", ret ); @@ -4464,6 +4482,29 @@ static void test_SetDIBitsToDevice(void) for (i = 56; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); memset( dib_bits, 0xaa, 64 * 4 ); + ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, 0, -4, 1, 12, data, info, DIB_RGB_COLORS ); + ok( ret == 3, "got %d\n", ret ); + for (i = 0; i < 64; i++) + if ((i >= 36 && i <= 39) || (i >= 44 && i <= 47) || (i >= 52 && i <= 55)) + ok( dib_bits[i] == inverted_data[i + 68], "%d: got %08x\n", i, dib_bits[i] ); + else + ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); + memset( dib_bits, 0xaa, 64 * 4 ); + + ret = SetDIBitsToDevice( hdc, 4, 4, 8, 8, -30, -30, 1, 12, data, info, DIB_RGB_COLORS ); + ok( ret == 0, "got %d\n", ret ); + for (i = 0; i < 64; i++) ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); + memset( dib_bits, 0xaa, 64 * 4 ); + + ret = SetDIBitsToDevice( hdc, 5, -5, 8, 16, -2, -4, 4, 12, data, info, DIB_RGB_COLORS ); + ok( ret == 8, "got %d\n", ret ); + for (i = 0; i < 64; i++) + if (i == 7 || i == 15 || i == 23) + ok( dib_bits[i] == inverted_data[i + 97], "%d: got %08x\n", i, dib_bits[i] ); + else + ok( dib_bits[i] == 0xaaaaaaaa, "%d: got %08x\n", i, dib_bits[i] ); + memset( dib_bits, 0xaa, 64 * 4 ); + info->bmiHeader.biHeight = 5; ret = SetDIBitsToDevice( hdc, 0, 0, 8, 8, 0, 0, 1, 2, data, info, DIB_RGB_COLORS ); ok( ret == 2, "got %d\n", ret ); diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c index d5668e31cdf..3f68e287f36 100644 --- a/dlls/winex11.drv/dib.c +++ b/dlls/winex11.drv/dib.c @@ -3764,14 +3764,21 @@ INT X11DRV_SetDIBitsToDevice( PHYSDEV dev, INT xDest, INT yDest, DWORD cx, DWORD } else { - if (ySrc >= startscan + lines) return lines; + if (ySrc >= startscan + lines) return 0; pt.y += ySrc + cy - (startscan + lines); cy = startscan + lines - ySrc; ySrc = 0; if (cy > lines) cy = lines; } if (xSrc >= info->bmiHeader.biWidth) return lines; + if (xSrc + cx <= 0) return lines; if (xSrc + cx >= info->bmiHeader.biWidth) cx = info->bmiHeader.biWidth - xSrc; + if (xSrc < 0) + { + pt.x -= xSrc; + cx += xSrc; + xSrc = 0; + } if (!cx || !cy) return lines; /* Update the pixmap from the DIB section */