diff --git a/rostests/apitests/gdi32/CombineTransform.c b/rostests/apitests/gdi32/CombineTransform.c new file mode 100644 index 00000000000..91408cb8ac5 --- /dev/null +++ b/rostests/apitests/gdi32/CombineTransform.c @@ -0,0 +1,274 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for CreatePen + * PROGRAMMERS: Timo Kreuzer + */ + +#include +#include +#include +#include +#include +#include + +#define MAX_OFFSET 4294967040.0 + +BOOL +WINAPI +CombineTransform( + LPXFORM pxfResult, + const XFORM *pxf1, + const XFORM *pxf2) +{ + XFORM xformTmp; + + /* Do matrix multiplication */ + xformTmp.eM11 = pxf1->eM11 * pxf2->eM11 + pxf1->eM12 * pxf2->eM21; + xformTmp.eM12 = pxf1->eM11 * pxf2->eM12 + pxf1->eM12 * pxf2->eM22; + xformTmp.eM21 = pxf1->eM21 * pxf2->eM11 + pxf1->eM22 * pxf2->eM21; + xformTmp.eM22 = pxf1->eM21 * pxf2->eM12 + pxf1->eM22 * pxf2->eM22; + xformTmp.eDx = pxf1->eDx * pxf2->eM11 + pxf1->eDy * pxf2->eM21 + pxf2->eDx; + xformTmp.eDy = pxf1->eDx * pxf2->eM12 + pxf1->eDy * pxf2->eM22 + pxf2->eDy; + +#if 0 + ok(pxf1->eM11 * pxf2->eM11 == pxf2->eM11 * pxf1->eM11, "1: %f, %f -> %f, %f\n", + pxf1->eM11, pxf2->eM11, pxf1->eM11 * pxf2->eM11, pxf2->eM11 * pxf1->eM11); + ok(pxf1->eM11 * pxf2->eM12 == pxf2->eM12 * pxf1->eM11, "2: %f, %f -> %f, %f\n", + pxf1->eM11, pxf2->eM12, pxf1->eM11 * pxf2->eM12, pxf2->eM12 * pxf1->eM11); + ok(pxf1->eM21 * pxf2->eM11 == pxf2->eM11 * pxf1->eM21, "3\n"); + ok(pxf1->eM21 * pxf2->eM12 == pxf2->eM12 * pxf1->eM21, "4\n"); + + ok(pxf1->eM12 * pxf2->eM21 == pxf2->eM21 * pxf1->eM12, "5\n"); + ok(pxf1->eM12 * pxf2->eM22 == pxf2->eM22 * pxf1->eM12, "6\n"); + ok(pxf1->eM22 * pxf2->eM21 == pxf2->eM21 * pxf1->eM22, "7\n"); + ok(pxf1->eM22 * pxf2->eM22 == pxf2->eM22 * pxf1->eM22, "8\n"); +#endif + + *pxfResult = xformTmp; + + /* windows compatibility fixups */ + if (_isnan(xformTmp.eM12)) + { + if (pxf1->eM11 == 0 || pxf2->eM12 == 0) pxfResult->eM12 = 0.; + } + + if (_isnan(xformTmp.eM21)) pxfResult->eM21 = 0.; + if (_isnan(xformTmp.eDx)) pxfResult->eDx = 0.; + if (_isnan(xformTmp.eDy)) pxfResult->eDy = 0.; + + /* Check for invalid offset range */ + if (xformTmp.eDx > MAX_OFFSET || xformTmp.eDx < -MAX_OFFSET || + xformTmp.eDy > MAX_OFFSET || xformTmp.eDy < -MAX_OFFSET) + { + return FALSE; + } + + return TRUE; +} + +void +RandXform(XFORM *pxform) +{ + XFORML *pxforml = (XFORML*)pxform; + + pxforml->eM11 ^= (rand() << 16) ^ (rand() << (rand() % 16)) ^ rand(); + pxforml->eM12 ^= (rand() << 16) ^ (rand() << (rand() % 16)) ^ rand(); + pxforml->eM21 ^= (rand() << 16) ^ (rand() << (rand() % 16)) ^ rand(); + pxforml->eM22 ^= (rand() << 16) ^ (rand() << (rand() % 16)) ^ rand(); + pxforml->eDx ^= (rand() << 16) ^ (rand() << (rand() % 16)) ^ rand(); + pxforml->eDy ^= (rand() << 16) ^ (rand() << (rand() % 16)) ^ rand(); + + +} + +void Test_CombineTransform() +{ + XFORM xform1, xform2, xform3; + BOOL ret; + + /* 2 Identity matrices */ + xform1.eM11 = 1.0; + xform1.eM12 = 0; + xform1.eM21 = 0; + xform1.eM22 = 1.0; + xform1.eDx = 0; + xform1.eDy = 0; + xform2 = xform1; + SetLastError(ERROR_SUCCESS); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + ok(xform3.eM11 == 1.0, "eM11: Expected 1.0, got %f\n", xform3.eM11); + ok(xform3.eM12 == 0, "eM11: Expected 0, got %f\n", xform3.eM12); + ok(xform3.eM21 == 0, "eM11: Expected 0, got %f\n", xform3.eM21); + ok(xform3.eM22 == 1.0, "eM11: Expected 1.0, got %f\n", xform3.eM22); + ok(xform3.eDx == 0, "eM11: Expected 0, got %f\n", xform3.eDx); + ok(xform3.eDy == 0, "eM11: Expected 0, got %f\n", xform3.eDy); + ok(GetLastError() == ERROR_SUCCESS, "Exected ERROR_SUCCESS, got %ld\n", GetLastError()); + + /* 2 Identity matrices with offsets */ + xform1.eDx = 20.0; + xform1.eDy = -100; + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + ok(xform3.eM11 == 1.0, "eM11: Expected 1.0, got %f\n", xform3.eM11); + ok(xform3.eM12 == 0, "eM11: Expected 0, got %f\n", xform3.eM12); + ok(xform3.eM21 == 0, "eM11: Expected 0, got %f\n", xform3.eM21); + ok(xform3.eM22 == 1.0, "eM11: Expected 1.0, got %f\n", xform3.eM22); + ok(xform3.eDx == 20.0, "eM11: Expected 20.0, got %f\n", xform3.eDx); + ok(xform3.eDy == -100, "eM11: Expected -100, got %f\n", xform3.eDy); + xform2.eDx = -60.0; + xform2.eDy = -20; + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + ok(xform3.eDx == -40.0, "eM11: Expected 40.0, got %f\n", xform3.eDx); + ok(xform3.eDy == -120.0, "eM11: Expected -120.0, got %f\n", xform3.eDy); + + /* add some stretching */ + xform2.eM11 = 2; + xform2.eM22 = 4; + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + ok(xform3.eM11 == 2.0, "eM11: Expected 2.0, got %f\n", xform3.eM11); + ok(xform3.eM12 == 0, "eM11: Expected 0, got %f\n", xform3.eM12); + ok(xform3.eM21 == 0, "eM11: Expected 0, got %f\n", xform3.eM21); + ok(xform3.eM22 == 4.0, "eM11: Expected 4.0, got %f\n", xform3.eM22); + ok(xform3.eDx == -20.0, "eM11: Expected 20.0, got %f\n", xform3.eDx); + ok(xform3.eDy == -420.0, "eM11: Expected 420.0, got %f\n", xform3.eDy); + + /* add some more stretching */ + xform1.eM11 = -2.5; + xform1.eM22 = 0.5; + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + ok(xform3.eM11 == -5.0, "eM11: Expected -5.0, got %f\n", xform3.eM11); + ok(xform3.eM12 == 0, "eM11: Expected 0, got %f\n", xform3.eM12); + ok(xform3.eM21 == 0, "eM11: Expected 0, got %f\n", xform3.eM21); + ok(xform3.eM22 == 2.0, "eM11: Expected 2.0, got %f\n", xform3.eM22); + ok(xform3.eDx == -20.0, "eM11: Expected 20.0, got %f\n", xform3.eDx); + ok(xform3.eDy == -420.0, "eM11: Expected 420.0, got %f\n", xform3.eDy); + + xform1.eM12 = 2.0; + xform1.eM21 = -0.5; + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + ok(xform3.eM11 == -5.0, "eM11: Expected -5.0, got %f\n", xform3.eM11); + ok(xform3.eM12 == 8.0, "eM11: Expected 8.0, got %f\n", xform3.eM12); + ok(xform3.eM21 == -1.0, "eM11: Expected -1.0, got %f\n", xform3.eM21); + ok(xform3.eM22 == 2.0, "eM11: Expected 2.0, got %f\n", xform3.eM22); + ok(xform3.eDx == -20.0, "eM11: Expected 20.0, got %f\n", xform3.eDx); + ok(xform3.eDy == -420.0, "eM11: Expected 420.0, got %f\n", xform3.eDy); + + xform2.eM12 = 4.0; + xform2.eM21 = 6.5; + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + ok(xform3.eM11 == 8.0, "eM11: Expected 8.0, got %f\n", xform3.eM11); + ok(xform3.eM12 == -2.0, "eM11: Expected -2.0, got %f\n", xform3.eM12); + ok(xform3.eM21 == 2.25, "eM11: Expected 2.25, got %f\n", xform3.eM21); + ok(xform3.eM22 == 0.00, "eM11: Expected 0.00, got %f\n", xform3.eM22); + ok(xform3.eDx == -670.0, "eM11: Expected -670.0, got %f\n", xform3.eDx); + ok(xform3.eDy == -340.0, "eM11: Expected -340.0, got %f\n", xform3.eDy); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + + xform1.eM11 = 1.; + xform1.eM12 = 0; + xform1.eM21 = 0; + xform1.eM22 = 1.; + xform1.eDx = 0; + xform1.eDy = 0; + xform2 = xform1; + + xform1.eDx = 4294967167.999999761; + ok(xform1.eDx == 4294967040.0, "float rounding error.\n"); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + + xform1.eDx = 4294967167.999999762; + ok(xform1.eDx == 4294967296.0, "float rounding error.\n"); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 0, "expected ret = 0, got %d\n", ret); + ok(GetLastError() == ERROR_SUCCESS, "Exected ERROR_SUCCESS, got %ld\n", GetLastError()); + + xform1.eDx = -4294967167.999999761; + ok(xform1.eDx == -4294967040.0, "float rounding error.\n"); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + + xform1.eDx = -4294967167.999999762; + ok(xform1.eDx == -4294967296.0, "float rounding error.\n"); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 0, "expected ret = 0, got %d\n", ret); + ok(GetLastError() == ERROR_SUCCESS, "Exected ERROR_SUCCESS, got %ld\n", GetLastError()); + + xform1.eDx = 0; + xform1.eDy = 4294967167.999999761; + ok(xform1.eDy == 4294967040.0, "float rounding error.\n"); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + + xform1.eDy = 4294967167.999999762; + ok(xform1.eDy == 4294967296.0, "float rounding error.\n"); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 0, "expected ret = 0, got %d\n", ret); + ok(GetLastError() == ERROR_SUCCESS, "Exected ERROR_SUCCESS, got %ld\n", GetLastError()); + + xform1.eDy = -4294967167.999999761; + ok(xform1.eDy == -4294967040.0, "float rounding error.\n"); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + + xform1.eDy = -4294967167.999999762; + ok(xform1.eDy == -4294967296.0, "float rounding error.\n"); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 0, "expected ret = 0, got %d\n", ret); + ok(GetLastError() == ERROR_SUCCESS, "Exected ERROR_SUCCESS, got %ld\n", GetLastError()); + + xform1.eDx = 100000.0; + xform2.eM11 = 100000.0; + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 0, "expected ret = 0, got %d\n", ret); + ok(GetLastError() == ERROR_SUCCESS, "Exected ERROR_SUCCESS, got %ld\n", GetLastError()); + + /* Some undefined values */ + *(DWORD*)&xform1.eM11 = 0xffc00000; // (0.0F/0.0F) + xform1.eM12 = 0; + xform1.eM21 = 0; + *(DWORD*)&xform1.eM22 = 0x7f800000; // (1.0F/0.0F) + xform1.eDx = 0; + xform1.eDy = 0; + xform2 = xform1; + SetLastError(ERROR_SUCCESS); + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + ok(*(DWORD*)&xform3.eM11 == 0xffc00000, "eM11: Expected 0xffc00000, got 0x%lx\n", *(DWORD*)&xform3.eM11); + ok(xform3.eM12 == 0, "eM12: Expected 0, got %f\n", xform3.eM12); + ok(xform3.eM21 == 0, "eM21: Expected 0, got %f\n", xform3.eM21); + ok(*(DWORD*)&xform3.eM22 == 0x7f800000, "eM22: Expected 0x7f800000, got 0x%lx\n", *(DWORD*)&xform3.eM22); + ok(xform3.eDx == 0, "eDx: Expected 0, got %f\n", xform3.eDx); + ok(xform3.eDy == 0, "eDy: Expected 0, got %f\n", xform3.eDy); + ok(GetLastError() == ERROR_SUCCESS, "Exected ERROR_SUCCESS, got %ld\n", GetLastError()); + + /* Some undefined values */ + xform2.eM11 = 1.; + xform2.eM22 = 1.; + xform2.eM12 = 1.; + xform2.eM21 = 1.; + ret = CombineTransform(&xform3, &xform1, &xform2); + ok(ret == 1, "expected ret = 1, got %d\n", ret); + ok(*(DWORD*)&xform3.eM11 == 0xffc00000, "eM11: Expected 0xffc00000, got 0x%lx\n", *(DWORD*)&xform3.eM11); + ok(*(DWORD*)&xform3.eM12 == 0xffc00000, "eM12: Expected 0xffc00000, got 0x%lx\n", *(DWORD*)&xform3.eM12); + ok(*(DWORD*)&xform3.eM21 == 0x7f800000, "eM21: Expected 0x7f800000, got 0x%lx\n", *(DWORD*)&xform3.eM21); + ok(*(DWORD*)&xform3.eM22 == 0x7f800000, "eM22: Expected 0x7f800000, got 0x%lx\n", *(DWORD*)&xform3.eM22); + ok(xform3.eDx == 0, "eDx: Expected 0, got %f\n", xform3.eDx); + ok(xform3.eDy == 0, "eDy: Expected 0, got %f\n", xform3.eDy); + ok(GetLastError() == ERROR_SUCCESS, "Exected ERROR_SUCCESS, got %ld\n", GetLastError()); + +} + +START_TEST(CombineTransform) +{ + Test_CombineTransform(); +} + diff --git a/rostests/apitests/gdi32/MaskBlt.c b/rostests/apitests/gdi32/MaskBlt.c new file mode 100644 index 00000000000..2b85594e921 --- /dev/null +++ b/rostests/apitests/gdi32/MaskBlt.c @@ -0,0 +1,95 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for GdiReleaseLocalDC + * PROGRAMMERS: Timo Kreuzer + */ + +#include +#include +#include + +void Test_MaskBlt_1bpp() +{ + HDC hdcDst, hdcSrc; + BITMAPINFO bmi = {{sizeof(BITMAPINFOHEADER), 8, 1, 1, 1, BI_RGB, 0, 10, 10, 0,0}}; + HBITMAP hbmDst, hbmSrc, hbmMsk; + PUCHAR pjBitsDst, pjBitsSrc, pjBitsMsk; + BOOL ret; + + /* Create a dest dc and bitmap */ + hdcDst = CreateCompatibleDC(NULL); + hbmDst = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, (PVOID*)&pjBitsDst, NULL, 0); + SelectObject(hdcDst, hbmDst); + + /* Create a source dc and bitmap */ + hdcSrc = CreateCompatibleDC(NULL); + hbmSrc = CreateDIBSection(hdcSrc, &bmi, DIB_RGB_COLORS, (PVOID*)&pjBitsSrc, NULL, 0); + SelectObject(hdcSrc, hbmSrc); + + /* Create a 1 bpp mask bitmap */ + hbmMsk = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, (PVOID*)&pjBitsMsk, NULL, 0); + + /* Do the masking */ + pjBitsDst[0] = 0xAA; + pjBitsSrc[0] = 0xCC; + pjBitsMsk[0] = 0xF0; + ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000)); + ok(ret == 1, "MaskBlt failed (%d)\n", ret); + ok (pjBitsDst[0] == 0xCA, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]); + + pjBitsDst[0] = 0x00; + pjBitsSrc[0] = 0xFF; + pjBitsMsk[0] = 0xF0; + ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000)); + ok(ret == 1, "MaskBlt failed (%d)\n", ret); + ok (pjBitsDst[0] == 0xF0, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]); + + + +} + +void Test_MaskBlt_RGBA() +{ + HDC hdcDst, hdcSrc; + BITMAPINFO bmi1 = {{sizeof(BITMAPINFOHEADER), 8, 1, 1, 1, BI_RGB, 0, 10, 10, 0,0}}; + BITMAPINFO bmi32 = {{sizeof(BITMAPINFOHEADER), 8, 1, 1, 32, BI_RGB, 0, 10, 10, 0,0}}; + HBITMAP hbmDst, hbmSrc, hbmMsk; + PUCHAR pjBitsDst, pjBitsSrc, pjBitsMsk; + BOOL ret; + + /* Create a dest dc and bitmap */ + hdcDst = CreateCompatibleDC(NULL); + hbmDst = CreateDIBSection(hdcDst, &bmi32, DIB_RGB_COLORS, (PVOID*)&pjBitsDst, NULL, 0); + SelectObject(hdcDst, hbmDst); + + /* Create a source dc and bitmap */ + hdcSrc = CreateCompatibleDC(NULL); + hbmSrc = CreateDIBSection(hdcSrc, &bmi32, DIB_RGB_COLORS, (PVOID*)&pjBitsSrc, NULL, 0); + SelectObject(hdcSrc, hbmSrc); + + /* Create a 1 bpp mask bitmap */ + hbmMsk = CreateDIBSection(hdcDst, &bmi1, DIB_RGB_COLORS, (PVOID*)&pjBitsMsk, NULL, 0); + + /* Do the masking */ + pjBitsDst[0] = 0xAA; + pjBitsSrc[0] = 0xCC; + pjBitsMsk[0] = 0xF0; + ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000)); + ok(ret == 1, "MaskBlt failed (%d)\n", ret); + ok (pjBitsDst[0] == 0xCA, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]); + + pjBitsDst[0] = 0x00; + pjBitsSrc[0] = 0xFF; + pjBitsMsk[0] = 0xF0; + ret = MaskBlt(hdcDst, 0, 0, 8, 1, hdcSrc, 0, 0, hbmMsk, 0, 0, MAKEROP4(SRCCOPY, 0xAA0000)); + ok(ret == 1, "MaskBlt failed (%d)\n", ret); + ok (pjBitsDst[0] == 0xF0, "pjBitsDst[0] == 0x%x\n", pjBitsDst[0]); + +} + +START_TEST(MaskBlt) +{ + Test_MaskBlt_1bpp(); +} + diff --git a/rostests/apitests/gdi32/gdi32_apitest.rbuild b/rostests/apitests/gdi32/gdi32_apitest.rbuild index 21ef88ba037..2b232afd687 100644 --- a/rostests/apitests/gdi32/gdi32_apitest.rbuild +++ b/rostests/apitests/gdi32/gdi32_apitest.rbuild @@ -12,7 +12,7 @@ AddFontResource.c AddFontResourceEx.c BeginPath.c - + CombineTransform.c CreateBitmapIndirect.c CreateCompatibleDC.c CreateFont.c @@ -43,6 +43,7 @@ GetStockObject.c GetTextExtentExPoint.c GetTextFace.c + MaskBlt.c SelectObject.c SetDCPenColor.c SetMapMode.c diff --git a/rostests/apitests/gdi32/testlist.c b/rostests/apitests/gdi32/testlist.c index ccc00f6457d..a1c3cba31cb 100644 --- a/rostests/apitests/gdi32/testlist.c +++ b/rostests/apitests/gdi32/testlist.c @@ -8,6 +8,7 @@ extern void func_AddFontResource(void); extern void func_AddFontResourceEx(void); extern void func_BeginPath(void); +extern void func_CombineTransform(void); extern void func_CreateBitmapIndirect(void); extern void func_CreateCompatibleDC(void); extern void func_CreateFont(void); @@ -38,6 +39,7 @@ extern void func_GetObject(void); extern void func_GetStockObject(void); extern void func_GetTextExtentExPoint(void); extern void func_GetTextFace(void); +extern void func_MaskBlt(void); extern void func_SelectObject(void); extern void func_SetDCPenColor(void); extern void func_SetMapMode(void); @@ -50,6 +52,7 @@ const struct test winetest_testlist[] = { "AddFontResource", func_AddFontResource }, { "AddFontResourceEx", func_AddFontResourceEx }, { "BeginPath", func_BeginPath }, + { "CombineTransform", func_CombineTransform }, { "CreateBitmapIndirect", func_CreateBitmapIndirect }, { "CreateCompatibleDC", func_CreateCompatibleDC }, { "CreateFont", func_CreateFont }, @@ -80,6 +83,7 @@ const struct test winetest_testlist[] = { "GetStockObject", func_GetStockObject }, { "GetTextExtentExPoint", func_GetTextExtentExPoint }, { "GetTextFace", func_GetTextFace }, + { "MaskBlt", func_MaskBlt }, { "SelectObject", func_SelectObject }, { "SetDCPenColor", func_SetDCPenColor }, { "SetMapMode", func_SetMapMode },