mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
Update gdi32 winetests, so we don't run out of things to fix.
svn path=/trunk/; revision=37695
This commit is contained in:
parent
1301bd7eb6
commit
f9e772b2a2
10 changed files with 1138 additions and 146 deletions
|
@ -70,13 +70,15 @@ static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
|
|||
static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
|
||||
{
|
||||
BITMAP bm;
|
||||
BITMAP bma[2];
|
||||
INT ret, width_bytes;
|
||||
char buf[512], buf_cmp[512];
|
||||
DWORD gle;
|
||||
|
||||
ret = GetObject(hbm, sizeof(bm), &bm);
|
||||
ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
|
||||
|
||||
ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
|
||||
ok(bm.bmType == 0 || broken(bm.bmType == 21072 /* Win9x */), "wrong bm.bmType %d\n", bm.bmType);
|
||||
ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
|
||||
ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
|
||||
width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
|
||||
|
@ -88,8 +90,10 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE
|
|||
assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
|
||||
assert(sizeof(buf) == sizeof(buf_cmp));
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetBitmapBits(hbm, 0, NULL);
|
||||
ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
|
||||
gle=GetLastError();
|
||||
ok(ret == bm.bmWidthBytes * bm.bmHeight || (ret == 0 && gle == ERROR_INVALID_PARAMETER /* Win9x */), "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
|
||||
|
||||
memset(buf_cmp, 0xAA, sizeof(buf_cmp));
|
||||
memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
|
||||
|
@ -100,20 +104,24 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE
|
|||
ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
|
||||
|
||||
/* test various buffer sizes for GetObject */
|
||||
ret = GetObject(hbm, 0, NULL);
|
||||
ok(ret == sizeof(bm), "wrong size %d\n", ret);
|
||||
|
||||
ret = GetObject(hbm, sizeof(bm) * 2, &bm);
|
||||
ok(ret == sizeof(bm), "wrong size %d\n", ret);
|
||||
ret = GetObject(hbm, sizeof(*bma) * 2, bma);
|
||||
ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
|
||||
|
||||
ret = GetObject(hbm, sizeof(bm) / 2, &bm);
|
||||
ok(ret == 0, "%d != 0\n", ret);
|
||||
ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
|
||||
|
||||
ret = GetObject(hbm, 0, &bm);
|
||||
ok(ret == 0, "%d != 0\n", ret);
|
||||
|
||||
ret = GetObject(hbm, 1, &bm);
|
||||
ok(ret == 0, "%d != 0\n", ret);
|
||||
ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
|
||||
|
||||
/* Don't trust Win9x not to try to write to NULL */
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = GetObject(hbm, 0, NULL);
|
||||
ok(ret == sizeof(bm), "wrong size %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_createdibitmap(void)
|
||||
|
@ -275,7 +283,9 @@ static INT DIB_GetWidthBytes( int width, int bpp )
|
|||
static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
|
||||
{
|
||||
BITMAP bm;
|
||||
BITMAP bma[2];
|
||||
DIBSECTION ds;
|
||||
DIBSECTION dsa[2];
|
||||
INT ret, bm_width_bytes, dib_width_bytes;
|
||||
BYTE *buf;
|
||||
|
||||
|
@ -298,8 +308,11 @@ static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER
|
|||
buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
|
||||
|
||||
/* GetBitmapBits returns not 32-bit aligned data */
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetBitmapBits(hbm, 0, NULL);
|
||||
ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
|
||||
ok(ret == bm_width_bytes * bm.bmHeight ||
|
||||
broken(ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
|
||||
"%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
|
||||
|
||||
memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
|
||||
ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
|
||||
|
@ -309,27 +322,30 @@ static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER
|
|||
|
||||
/* test various buffer sizes for GetObject */
|
||||
memset(&ds, 0xAA, sizeof(ds));
|
||||
ret = GetObject(hbm, sizeof(bm) * 2, &bm);
|
||||
ok(ret == sizeof(bm), "wrong size %d\n", ret);
|
||||
ret = GetObject(hbm, sizeof(*bma) * 2, bma);
|
||||
ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
|
||||
ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
|
||||
ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
|
||||
ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
|
||||
|
||||
ret = GetObject(hbm, sizeof(bm) / 2, &bm);
|
||||
ok(ret == 0, "%d != 0\n", ret);
|
||||
ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
|
||||
|
||||
ret = GetObject(hbm, 0, &bm);
|
||||
ok(ret == 0, "%d != 0\n", ret);
|
||||
|
||||
ret = GetObject(hbm, 1, &bm);
|
||||
ok(ret == 0, "%d != 0\n", ret);
|
||||
ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
|
||||
|
||||
/* test various buffer sizes for GetObject */
|
||||
ret = GetObject(hbm, 0, NULL);
|
||||
ok(ret == sizeof(bm), "wrong size %d\n", ret);
|
||||
|
||||
ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
|
||||
ok(ret == sizeof(*dsa) || broken(ret == sizeof(*dsa) * 2 /* Win9x */), "wrong size %d\n", ret);
|
||||
|
||||
memset(&ds, 0xAA, sizeof(ds));
|
||||
ret = GetObject(hbm, sizeof(ds) * 2, &ds);
|
||||
ret = GetObject(hbm, sizeof(ds), &ds);
|
||||
ok(ret == sizeof(ds), "wrong size %d\n", ret);
|
||||
|
||||
ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
|
||||
|
@ -416,6 +432,13 @@ static void test_dibsections(void)
|
|||
pbmi->bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
|
||||
/* invalid pointer for BITMAPINFO
|
||||
(*bits should be NULL on error) */
|
||||
bits = (BYTE*)0xdeadbeef;
|
||||
hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
||||
ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
|
||||
|
||||
hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
||||
ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
|
||||
ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
|
||||
|
@ -965,6 +988,7 @@ static void test_bitmap(void)
|
|||
HBITMAP hbmp, hbmp_old;
|
||||
HDC hdc;
|
||||
BITMAP bm;
|
||||
BITMAP bma[2];
|
||||
INT ret;
|
||||
|
||||
hdc = CreateCompatibleDC(0);
|
||||
|
@ -974,7 +998,8 @@ static void test_bitmap(void)
|
|||
hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
|
||||
if (!hbmp)
|
||||
{
|
||||
ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY,
|
||||
ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
|
||||
GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
|
||||
"expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
|
||||
}
|
||||
else
|
||||
|
@ -1047,17 +1072,17 @@ static void test_bitmap(void)
|
|||
ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
|
||||
|
||||
/* test various buffer sizes for GetObject */
|
||||
ret = GetObject(hbmp, sizeof(bm) * 2, &bm);
|
||||
ok(ret == sizeof(bm), "wrong size %d\n", ret);
|
||||
ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
|
||||
ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
|
||||
|
||||
ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
|
||||
ok(ret == 0, "%d != 0\n", ret);
|
||||
ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
|
||||
|
||||
ret = GetObject(hbmp, 0, &bm);
|
||||
ok(ret == 0, "%d != 0\n", ret);
|
||||
|
||||
ret = GetObject(hbmp, 1, &bm);
|
||||
ok(ret == 0, "%d != 0\n", ret);
|
||||
ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
|
||||
|
||||
DeleteObject(hbmp);
|
||||
DeleteDC(hdc);
|
||||
|
@ -1133,7 +1158,7 @@ static void test_GetDIBits_selected_DIB(UINT bpp)
|
|||
|
||||
/* Select the DIB into a DC */
|
||||
dib_dc = CreateCompatibleDC(NULL);
|
||||
old_bmp = (HBITMAP) SelectObject(dib_dc, dib);
|
||||
old_bmp = SelectObject(dib_dc, dib);
|
||||
dc = CreateCompatibleDC(NULL);
|
||||
bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
|
||||
assert(bits2);
|
||||
|
@ -1168,10 +1193,7 @@ static void test_GetDIBits_selected_DIB(UINT bpp)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (bpp != 1)
|
||||
ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
|
||||
else
|
||||
todo_wine ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
|
||||
ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, bits2);
|
||||
DeleteDC(dc);
|
||||
|
@ -1217,7 +1239,7 @@ static void test_GetDIBits_selected_DDB(BOOL monochrome)
|
|||
|
||||
/* Set the pixels */
|
||||
ddb_dc = CreateCompatibleDC(NULL);
|
||||
old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
|
||||
old_bmp = SelectObject(ddb_dc, ddb);
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
for (j=0; j < height; j++)
|
||||
|
@ -1259,7 +1281,7 @@ static void test_GetDIBits_selected_DDB(BOOL monochrome)
|
|||
memcpy(info2, info, sizeof(BITMAPINFOHEADER));
|
||||
|
||||
/* Select the DDB into another DC */
|
||||
old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
|
||||
old_bmp = SelectObject(ddb_dc, ddb);
|
||||
|
||||
/* Get the bits */
|
||||
res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
|
||||
|
@ -1293,6 +1315,28 @@ static void test_GetDIBits_selected_DDB(BOOL monochrome)
|
|||
}
|
||||
ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
|
||||
|
||||
/* Test the palette */
|
||||
equalContents = TRUE;
|
||||
if (info2->bmiHeader.biBitCount <= 8)
|
||||
{
|
||||
WORD *colors = (WORD*)info2->bmiColors;
|
||||
|
||||
/* Get the palette indices */
|
||||
res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
|
||||
ok(res, "GetDIBits failed\n");
|
||||
|
||||
for (i=0;i < 1 << info->bmiHeader.biSizeImage; i++)
|
||||
{
|
||||
if (colors[i] != i)
|
||||
{
|
||||
equalContents = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok(equalContents, "GetDIBits with DDB selected in DC: non 1:1 palette indices\n");
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, bits2);
|
||||
HeapFree(GetProcessHeap(), 0, bits);
|
||||
DeleteDC(dc);
|
||||
|
@ -1455,7 +1499,6 @@ static void test_GetDIBits(void)
|
|||
"expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
|
||||
bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
|
||||
bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
|
||||
todo_wine
|
||||
ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
|
||||
bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
|
||||
"expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
|
||||
|
@ -1474,6 +1517,16 @@ todo_wine
|
|||
todo_wine
|
||||
ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
|
||||
|
||||
/* Test the palette indices */
|
||||
memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
|
||||
SetLastError(0xdeadbeef);
|
||||
lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
|
||||
|
||||
ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
|
||||
ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
|
||||
for (i = 2; i < 256; i++)
|
||||
ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
|
||||
|
||||
/* retrieve 24-bit DIB data */
|
||||
memset(bi, 0, sizeof(*bi));
|
||||
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
|
@ -1502,7 +1555,6 @@ todo_wine
|
|||
}
|
||||
|
||||
/* returned bits are DWORD aligned and upside down */
|
||||
todo_wine
|
||||
ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
|
||||
DeleteObject(hbmp);
|
||||
|
||||
|
@ -1574,6 +1626,16 @@ todo_wine
|
|||
todo_wine
|
||||
ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
|
||||
|
||||
/* Test the palette indices */
|
||||
memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
|
||||
SetLastError(0xdeadbeef);
|
||||
lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
|
||||
|
||||
ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
|
||||
ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
|
||||
for (i = 2; i < 256; i++)
|
||||
ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
|
||||
|
||||
/* retrieve 24-bit DIB data */
|
||||
memset(bi, 0, sizeof(*bi));
|
||||
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
|
@ -1675,22 +1737,29 @@ static void test_GetDIBits_BI_BITFIELDS(void)
|
|||
memset(dibinfo, 0, sizeof(dibinfo_buf));
|
||||
dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
|
||||
if (ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
|
||||
win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n");
|
||||
else
|
||||
{
|
||||
ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
|
||||
|
||||
ok( !bitmasks[0], "red mask is set\n" );
|
||||
ok( !bitmasks[1], "green mask is set\n" );
|
||||
ok( !bitmasks[2], "blue mask is set\n" );
|
||||
ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
|
||||
ok( !bitmasks[0], "red mask is set\n" );
|
||||
ok( !bitmasks[1], "green mask is set\n" );
|
||||
ok( !bitmasks[2], "blue mask is set\n" );
|
||||
ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
|
||||
|
||||
memset(bitmasks, 0, 3*sizeof(DWORD));
|
||||
dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
|
||||
ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
|
||||
ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
|
||||
memset(bitmasks, 0, 3*sizeof(DWORD));
|
||||
dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
|
||||
ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
|
||||
ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
|
||||
|
||||
ok( bitmasks[0] != 0, "red mask is not set\n" );
|
||||
ok( bitmasks[1] != 0, "green mask is not set\n" );
|
||||
ok( bitmasks[2] != 0, "blue mask is not set\n" );
|
||||
ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
|
||||
ok( bitmasks[0] != 0, "red mask is not set\n" );
|
||||
ok( bitmasks[1] != 0, "green mask is not set\n" );
|
||||
ok( bitmasks[2] != 0, "blue mask is not set\n" );
|
||||
ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
|
||||
}
|
||||
}
|
||||
else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
|
||||
|
||||
|
@ -1825,15 +1894,15 @@ static void test_CreateBitmap(void)
|
|||
HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
|
||||
HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
|
||||
HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
|
||||
HBITMAP curObj1 = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
|
||||
HBITMAP curObj2 = (HBITMAP)GetCurrentObject(screenDC, OBJ_BITMAP);
|
||||
HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
|
||||
HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
|
||||
|
||||
/* these 2 are not the stock monochrome bitmap */
|
||||
HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
|
||||
HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
|
||||
|
||||
HBITMAP old1 = (HBITMAP)SelectObject(hdc, bm2);
|
||||
HBITMAP old2 = (HBITMAP)SelectObject(screenDC, bm3);
|
||||
HBITMAP old1 = SelectObject(hdc, bm2);
|
||||
HBITMAP old2 = SelectObject(screenDC, bm3);
|
||||
SelectObject(hdc, old1);
|
||||
SelectObject(screenDC, old2);
|
||||
|
||||
|
@ -2084,8 +2153,8 @@ void test_GdiAlphaBlend()
|
|||
bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
|
||||
ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
|
||||
|
||||
oldDst = (HBITMAP)SelectObject(hdcDst, bmpDst);
|
||||
oldSrc = (HBITMAP)SelectObject(hdcSrc, bmpSrc);
|
||||
oldDst = SelectObject(hdcDst, bmpDst);
|
||||
oldSrc = SelectObject(hdcSrc, bmpSrc);
|
||||
|
||||
blend.BlendOp = AC_SRC_OVER;
|
||||
blend.BlendFlags = 0;
|
||||
|
@ -2120,6 +2189,51 @@ void test_GdiAlphaBlend()
|
|||
|
||||
}
|
||||
|
||||
static void test_clipping(void)
|
||||
{
|
||||
HBITMAP bmpDst;
|
||||
HBITMAP oldDst;
|
||||
HBITMAP bmpSrc;
|
||||
HBITMAP oldSrc;
|
||||
HRGN hRgn;
|
||||
LPVOID bits;
|
||||
BOOL result;
|
||||
|
||||
HDC hdcDst = CreateCompatibleDC( NULL );
|
||||
HDC hdcSrc = CreateCompatibleDC( NULL );
|
||||
|
||||
BITMAPINFO bmpinfo={{0}};
|
||||
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmpinfo.bmiHeader.biWidth = 100;
|
||||
bmpinfo.bmiHeader.biHeight = 100;
|
||||
bmpinfo.bmiHeader.biPlanes = 1;
|
||||
bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
|
||||
bmpinfo.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
|
||||
ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
|
||||
oldDst = SelectObject( hdcDst, bmpDst );
|
||||
|
||||
bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
|
||||
ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
|
||||
oldSrc = SelectObject( hdcSrc, bmpSrc );
|
||||
|
||||
result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
|
||||
ok(result, "BitBlt failed\n");
|
||||
|
||||
hRgn = CreateRectRgn( 0,0,0,0 );
|
||||
SelectClipRgn( hdcDst, hRgn );
|
||||
|
||||
result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
|
||||
ok(result, "BitBlt failed\n");
|
||||
|
||||
DeleteObject( bmpDst );
|
||||
DeleteObject( bmpSrc );
|
||||
DeleteObject( hRgn );
|
||||
DeleteDC( hdcDst );
|
||||
DeleteDC( hdcSrc );
|
||||
}
|
||||
|
||||
START_TEST(bitmap)
|
||||
{
|
||||
HMODULE hdll;
|
||||
|
@ -2145,4 +2259,5 @@ START_TEST(bitmap)
|
|||
test_GdiAlphaBlend();
|
||||
test_bitmapinfoheadersize();
|
||||
test_get16dibits();
|
||||
test_clipping();
|
||||
}
|
||||
|
|
|
@ -51,8 +51,10 @@ static void test_solidbrush(void)
|
|||
solidBrush = CreateSolidBrush(stock[i].color);
|
||||
|
||||
if(stock[i].stockobj != -1) {
|
||||
stockBrush = (HBRUSH)GetStockObject(stock[i].stockobj);
|
||||
ok(stockBrush!=solidBrush, "Stock %s brush equals solid %s brush\n", stock[i].name, stock[i].name);
|
||||
stockBrush = GetStockObject(stock[i].stockobj);
|
||||
ok(stockBrush!=solidBrush ||
|
||||
broken(stockBrush==solidBrush), /* win9x does return stock object */
|
||||
"Stock %s brush equals solid %s brush\n", stock[i].name, stock[i].name);
|
||||
}
|
||||
else
|
||||
stockBrush = NULL;
|
||||
|
@ -70,7 +72,10 @@ static void test_solidbrush(void)
|
|||
}
|
||||
|
||||
DeleteObject(solidBrush);
|
||||
ok(GetObject(solidBrush, sizeof(br), &br)==0, "GetObject succeeded on a deleted %s brush\n", stock[i].name);
|
||||
ret = GetObject(solidBrush, sizeof(br), &br);
|
||||
ok(ret==0 ||
|
||||
broken(ret!=0), /* win9x */
|
||||
"GetObject succeeded on a deleted %s brush\n", stock[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -111,7 +111,9 @@ static void test_GetRandomRgn(void)
|
|||
GetRgnBox(hrgn, &ret_rc);
|
||||
if(GetVersion() & 0x80000000)
|
||||
OffsetRect(&window_rc, -window_rc.left, -window_rc.top);
|
||||
ok(EqualRect(&window_rc, &ret_rc), "GetRandomRgn %d,%d - %d,%d\n",
|
||||
ok(EqualRect(&window_rc, &ret_rc) ||
|
||||
broken(IsRectEmpty(&ret_rc)), /* win95 */
|
||||
"GetRandomRgn %d,%d - %d,%d\n",
|
||||
ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom);
|
||||
|
||||
DeleteObject(hrgn);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
|
||||
#define near_match(a, b) (abs((a) - (b)) <= 6)
|
||||
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
|
||||
|
||||
LONG (WINAPI *pGdiGetCharDimensions)(HDC hdc, LPTEXTMETRICW lptm, LONG *height);
|
||||
|
@ -105,7 +106,7 @@ static void check_font(const char* test, const LOGFONTA* lf, HFONT hfont)
|
|||
minlen++;
|
||||
minlen += FIELD_OFFSET(LOGFONTA, lfFaceName) + 1;
|
||||
ok(ret == sizeof(LOGFONTA) || ret == minlen, "%s: GetObject returned %d\n", test, ret);
|
||||
ok(!memcmp(&lf, &lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "%s: fonts don't match\n", test);
|
||||
ok(!memcmp(lf, &getobj_lf, FIELD_OFFSET(LOGFONTA, lfFaceName)), "%s: fonts don't match\n", test);
|
||||
ok(!lstrcmpA(lf->lfFaceName, getobj_lf.lfFaceName),
|
||||
"%s: font names don't match: %s != %s\n", test, lf->lfFaceName, getobj_lf.lfFaceName);
|
||||
}
|
||||
|
@ -158,56 +159,119 @@ static INT CALLBACK font_enum_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DW
|
|||
return 1; /* continue enumeration */
|
||||
}
|
||||
|
||||
static void compare_tm(const TEXTMETRICA *tm, const TEXTMETRICA *otm)
|
||||
{
|
||||
ok(tm->tmHeight == otm->tmHeight, "tmHeight %d != %d\n", tm->tmHeight, otm->tmHeight);
|
||||
ok(tm->tmAscent == otm->tmAscent, "tmAscent %d != %d\n", tm->tmAscent, otm->tmAscent);
|
||||
ok(tm->tmDescent == otm->tmDescent, "tmDescent %d != %d\n", tm->tmDescent, otm->tmDescent);
|
||||
ok(tm->tmInternalLeading == otm->tmInternalLeading, "tmInternalLeading %d != %d\n", tm->tmInternalLeading, otm->tmInternalLeading);
|
||||
ok(tm->tmExternalLeading == otm->tmExternalLeading, "tmExternalLeading %d != %d\n", tm->tmExternalLeading, otm->tmExternalLeading);
|
||||
ok(tm->tmAveCharWidth == otm->tmAveCharWidth, "tmAveCharWidth %d != %d\n", tm->tmAveCharWidth, otm->tmAveCharWidth);
|
||||
ok(tm->tmMaxCharWidth == otm->tmMaxCharWidth, "tmMaxCharWidth %d != %d\n", tm->tmMaxCharWidth, otm->tmMaxCharWidth);
|
||||
ok(tm->tmWeight == otm->tmWeight, "tmWeight %d != %d\n", tm->tmWeight, otm->tmWeight);
|
||||
ok(tm->tmOverhang == otm->tmOverhang, "tmOverhang %d != %d\n", tm->tmOverhang, otm->tmOverhang);
|
||||
ok(tm->tmDigitizedAspectX == otm->tmDigitizedAspectX, "tmDigitizedAspectX %d != %d\n", tm->tmDigitizedAspectX, otm->tmDigitizedAspectX);
|
||||
ok(tm->tmDigitizedAspectY == otm->tmDigitizedAspectY, "tmDigitizedAspectY %d != %d\n", tm->tmDigitizedAspectY, otm->tmDigitizedAspectY);
|
||||
ok(tm->tmFirstChar == otm->tmFirstChar, "tmFirstChar %d != %d\n", tm->tmFirstChar, otm->tmFirstChar);
|
||||
ok(tm->tmLastChar == otm->tmLastChar, "tmLastChar %d != %d\n", tm->tmLastChar, otm->tmLastChar);
|
||||
ok(tm->tmDefaultChar == otm->tmDefaultChar, "tmDefaultChar %d != %d\n", tm->tmDefaultChar, otm->tmDefaultChar);
|
||||
ok(tm->tmBreakChar == otm->tmBreakChar, "tmBreakChar %d != %d\n", tm->tmBreakChar, otm->tmBreakChar);
|
||||
ok(tm->tmItalic == otm->tmItalic, "tmItalic %d != %d\n", tm->tmItalic, otm->tmItalic);
|
||||
ok(tm->tmUnderlined == otm->tmUnderlined, "tmUnderlined %d != %d\n", tm->tmUnderlined, otm->tmUnderlined);
|
||||
ok(tm->tmStruckOut == otm->tmStruckOut, "tmStruckOut %d != %d\n", tm->tmStruckOut, otm->tmStruckOut);
|
||||
ok(tm->tmPitchAndFamily == otm->tmPitchAndFamily, "tmPitchAndFamily %d != %d\n", tm->tmPitchAndFamily, otm->tmPitchAndFamily);
|
||||
ok(tm->tmCharSet == otm->tmCharSet, "tmCharSet %d != %d\n", tm->tmCharSet, otm->tmCharSet);
|
||||
}
|
||||
|
||||
static void test_font_metrics(HDC hdc, HFONT hfont, LONG lfHeight,
|
||||
LONG lfWidth, const char *test_str,
|
||||
INT test_str_len, const TEXTMETRICA *tm_orig,
|
||||
const SIZE *size_orig, INT width_of_A_orig,
|
||||
INT scale_x, INT scale_y)
|
||||
{
|
||||
HFONT old_hfont;
|
||||
LOGFONTA lf;
|
||||
OUTLINETEXTMETRIC otm;
|
||||
TEXTMETRICA tm;
|
||||
SIZE size;
|
||||
INT width_of_A, cx, cy;
|
||||
UINT ret;
|
||||
|
||||
if (!hfont)
|
||||
return;
|
||||
|
||||
ok(GetCurrentObject(hdc, OBJ_FONT) == hfont, "hfont should be selected\n");
|
||||
|
||||
GetObjectA(hfont, sizeof(lf), &lf);
|
||||
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
if (GetOutlineTextMetricsA(hdc, 0, NULL))
|
||||
{
|
||||
otm.otmSize = sizeof(otm) / 2;
|
||||
ret = GetOutlineTextMetricsA(hdc, otm.otmSize, &otm);
|
||||
ok(ret == sizeof(otm)/2 /* XP */ ||
|
||||
ret == 1 /* Win9x */, "expected sizeof(otm)/2, got %u\n", ret);
|
||||
|
||||
GetTextMetricsA(hdc, &tm);
|
||||
memset(&otm, 0x1, sizeof(otm));
|
||||
otm.otmSize = sizeof(otm);
|
||||
ret = GetOutlineTextMetricsA(hdc, otm.otmSize, &otm);
|
||||
ok(ret == sizeof(otm) /* XP */ ||
|
||||
ret == 1 /* Win9x */, "expected sizeof(otm), got %u\n", ret);
|
||||
|
||||
memset(&tm, 0x2, sizeof(tm));
|
||||
ret = GetTextMetricsA(hdc, &tm);
|
||||
ok(ret, "GetTextMetricsA failed\n");
|
||||
/* the structure size is aligned */
|
||||
if (memcmp(&tm, &otm.otmTextMetrics, FIELD_OFFSET(TEXTMETRICA, tmCharSet) + 1))
|
||||
{
|
||||
ok(0, "tm != otm\n");
|
||||
compare_tm(&tm, &otm.otmTextMetrics);
|
||||
}
|
||||
|
||||
tm = otm.otmTextMetrics;
|
||||
if (0) /* these metrics are scaled too, but with rounding errors */
|
||||
{
|
||||
ok(otm.otmAscent == tm.tmAscent, "ascent %d != %d\n", otm.otmAscent, tm.tmAscent);
|
||||
ok(otm.otmDescent == -tm.tmDescent, "descent %d != %d\n", otm.otmDescent, -tm.tmDescent);
|
||||
}
|
||||
ok(otm.otmMacAscent == tm.tmAscent, "ascent %d != %d\n", otm.otmMacAscent, tm.tmAscent);
|
||||
ok(otm.otmDescent < 0, "otm.otmDescent should be < 0\n");
|
||||
ok(otm.otmMacDescent < 0, "otm.otmMacDescent should be < 0\n");
|
||||
ok(tm.tmDescent > 0, "tm.tmDescent should be > 0\n");
|
||||
ok(otm.otmMacDescent == -tm.tmDescent, "descent %d != %d\n", otm.otmMacDescent, -tm.tmDescent);
|
||||
ok(otm.otmEMSquare == 2048, "expected 2048, got %d\n", otm.otmEMSquare);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = GetTextMetricsA(hdc, &tm);
|
||||
ok(ret, "GetTextMetricsA failed\n");
|
||||
}
|
||||
|
||||
cx = tm.tmAveCharWidth / tm_orig->tmAveCharWidth;
|
||||
cy = tm.tmHeight / tm_orig->tmHeight;
|
||||
ok(cx == scale_x && cy == scale_y, "expected scale_x %d, scale_y %d, got cx %d, cy %d\n",
|
||||
scale_x, scale_y, cx, cy);
|
||||
ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "%d != %d\n", tm.tmHeight, tm_orig->tmHeight * scale_y);
|
||||
ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "%d != %d\n", tm.tmAscent, tm_orig->tmAscent * scale_y);
|
||||
ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "%d != %d\n", tm.tmDescent, tm_orig->tmDescent * scale_y);
|
||||
ok(tm.tmAveCharWidth == tm_orig->tmAveCharWidth * scale_x, "%d != %d\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x);
|
||||
ok(tm.tmMaxCharWidth == tm_orig->tmMaxCharWidth * scale_x, "%d != %d\n", tm.tmAveCharWidth, tm_orig->tmMaxCharWidth * scale_x);
|
||||
ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "height %d != %d\n", tm.tmHeight, tm_orig->tmHeight * scale_y);
|
||||
ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "ascent %d != %d\n", tm.tmAscent, tm_orig->tmAscent * scale_y);
|
||||
ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "descent %d != %d\n", tm.tmDescent, tm_orig->tmDescent * scale_y);
|
||||
ok(near_match(tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x), "ave width %d != %d\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x);
|
||||
ok(near_match(tm.tmMaxCharWidth, tm_orig->tmMaxCharWidth * scale_x), "max width %d != %d\n", tm.tmMaxCharWidth, tm_orig->tmMaxCharWidth * scale_x);
|
||||
|
||||
ok(lf.lfHeight == lfHeight, "lf %d != %d\n", lf.lfHeight, lfHeight);
|
||||
ok(lf.lfHeight == lfHeight, "lfHeight %d != %d\n", lf.lfHeight, lfHeight);
|
||||
if (lf.lfHeight)
|
||||
{
|
||||
if (lf.lfWidth)
|
||||
ok(lf.lfWidth == tm.tmAveCharWidth, "lf %d != tm %d\n", lf.lfWidth, tm.tmAveCharWidth);
|
||||
ok(lf.lfWidth == tm.tmAveCharWidth, "lfWidth %d != tm %d\n", lf.lfWidth, tm.tmAveCharWidth);
|
||||
}
|
||||
else
|
||||
ok(lf.lfWidth == lfWidth, "lf %d != %d\n", lf.lfWidth, lfWidth);
|
||||
ok(lf.lfWidth == lfWidth, "lfWidth %d != %d\n", lf.lfWidth, lfWidth);
|
||||
|
||||
GetTextExtentPoint32A(hdc, test_str, test_str_len, &size);
|
||||
|
||||
ok(size.cx == size_orig->cx * scale_x, "%d != %d\n", size.cx, size_orig->cx * scale_x);
|
||||
ok(size.cy == size_orig->cy * scale_y, "%d != %d\n", size.cy, size_orig->cy * scale_y);
|
||||
ok(near_match(size.cx, size_orig->cx * scale_x), "cx %d != %d\n", size.cx, size_orig->cx * scale_x);
|
||||
ok(size.cy == size_orig->cy * scale_y, "cy %d != %d\n", size.cy, size_orig->cy * scale_y);
|
||||
|
||||
GetCharWidthA(hdc, 'A', 'A', &width_of_A);
|
||||
|
||||
ok(width_of_A == width_of_A_orig * scale_x, "%d != %d\n", width_of_A, width_of_A_orig * scale_x);
|
||||
|
||||
SelectObject(hdc, old_hfont);
|
||||
ok(near_match(width_of_A, width_of_A_orig * scale_x), "width A %d != %d\n", width_of_A, width_of_A_orig * scale_x);
|
||||
}
|
||||
|
||||
/* Test how GDI scales bitmap font metrics */
|
||||
|
@ -248,7 +312,9 @@ static void test_bitmap_font(void)
|
|||
bitmap_lf.lfHeight = 0;
|
||||
bitmap_lf.lfWidth = 4;
|
||||
hfont = create_font("bitmap", &bitmap_lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
test_font_metrics(hdc, hfont, 0, 4, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, 1);
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
bitmap_lf.lfHeight = height_orig;
|
||||
|
@ -265,27 +331,285 @@ static void test_bitmap_font(void)
|
|||
nearest_height = scale * height_orig;
|
||||
/* XP allows not more than 10% deviation */
|
||||
if (scale > 1 && nearest_height - i > nearest_height / 10) scale--;
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
test_font_metrics(hdc, hfont, bitmap_lf.lfHeight, 0, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, scale);
|
||||
DeleteObject(hfont);
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
}
|
||||
|
||||
/* test integer scaling 3x2 */
|
||||
bitmap_lf.lfHeight = height_orig * 2;
|
||||
bitmap_lf.lfWidth *= 3;
|
||||
hfont = create_font("3x2", &bitmap_lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
test_font_metrics(hdc, hfont, bitmap_lf.lfHeight, 0, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2);
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
/* test integer scaling 3x3 */
|
||||
bitmap_lf.lfHeight = height_orig * 3;
|
||||
bitmap_lf.lfWidth = 0;
|
||||
hfont = create_font("3x3", &bitmap_lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
test_font_metrics(hdc, hfont, bitmap_lf.lfHeight, 0, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3);
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
ReleaseDC(0, hdc);
|
||||
}
|
||||
|
||||
/* Test how GDI scales outline font metrics */
|
||||
static void test_outline_font(void)
|
||||
{
|
||||
static const char test_str[11] = "Test String";
|
||||
HDC hdc, hdc_2;
|
||||
LOGFONTA lf;
|
||||
HFONT hfont, old_hfont, old_hfont_2;
|
||||
OUTLINETEXTMETRICA otm;
|
||||
SIZE size_orig;
|
||||
INT width_orig, height_orig, lfWidth;
|
||||
XFORM xform;
|
||||
GLYPHMETRICS gm;
|
||||
MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} };
|
||||
MAT2 mat2 = { {0x8000,0}, {0,0}, {0,0}, {0x8000,0} };
|
||||
POINT pt;
|
||||
INT ret;
|
||||
|
||||
if (!is_truetype_font_installed("Arial"))
|
||||
{
|
||||
skip("Arial is not installed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hdc = CreateCompatibleDC(0);
|
||||
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
strcpy(lf.lfFaceName, "Arial");
|
||||
lf.lfHeight = 72;
|
||||
hfont = create_font("outline", &lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
otm.otmSize = sizeof(otm);
|
||||
ok(GetOutlineTextMetricsA(hdc, sizeof(otm), &otm), "GetTextMetricsA failed\n");
|
||||
ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n");
|
||||
ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n");
|
||||
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, otm.otmTextMetrics.tmAveCharWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
/* font of otmEMSquare height helps to avoid a lot of rounding errors */
|
||||
lf.lfHeight = otm.otmEMSquare;
|
||||
lf.lfHeight = -lf.lfHeight;
|
||||
hfont = create_font("outline", &lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
otm.otmSize = sizeof(otm);
|
||||
ok(GetOutlineTextMetricsA(hdc, sizeof(otm), &otm), "GetTextMetricsA failed\n");
|
||||
ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n");
|
||||
ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n");
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
height_orig = otm.otmTextMetrics.tmHeight;
|
||||
lfWidth = otm.otmTextMetrics.tmAveCharWidth;
|
||||
|
||||
/* test integer scaling 3x2 */
|
||||
lf.lfHeight = height_orig * 2;
|
||||
lf.lfWidth = lfWidth * 3;
|
||||
hfont = create_font("3x2", &lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 3, 2);
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
/* test integer scaling 3x3 */
|
||||
lf.lfHeight = height_orig * 3;
|
||||
lf.lfWidth = lfWidth * 3;
|
||||
hfont = create_font("3x3", &lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 3, 3);
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
/* test integer scaling 1x1 */
|
||||
lf.lfHeight = height_orig * 1;
|
||||
lf.lfWidth = lfWidth * 1;
|
||||
hfont = create_font("1x1", &lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
|
||||
/* test integer scaling 1x1 */
|
||||
lf.lfHeight = height_orig;
|
||||
lf.lfWidth = 0;
|
||||
hfont = create_font("1x1", &lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
|
||||
/* with an identity matrix */
|
||||
memset(&gm, 0, sizeof(gm));
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
|
||||
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||
ok(gm.gmCellIncX == width_orig, "incX %d != %d\n", gm.gmCellIncX, width_orig);
|
||||
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||
/* with a custom matrix */
|
||||
memset(&gm, 0, sizeof(gm));
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
|
||||
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||
ok(gm.gmCellIncX == width_orig/2, "incX %d != %d\n", gm.gmCellIncX, width_orig/2);
|
||||
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||
|
||||
/* Test that changing the DC transformation affects only the font
|
||||
* selected on this DC and doesn't affect the same font selected on
|
||||
* another DC.
|
||||
*/
|
||||
hdc_2 = CreateCompatibleDC(0);
|
||||
old_hfont_2 = SelectObject(hdc_2, hfont);
|
||||
test_font_metrics(hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
|
||||
SetMapMode(hdc, MM_ANISOTROPIC);
|
||||
|
||||
/* font metrics on another DC should be unchanged */
|
||||
test_font_metrics(hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
|
||||
/* test restrictions of compatibility mode GM_COMPATIBLE */
|
||||
/* part 1: rescaling only X should not change font scaling on screen.
|
||||
So compressing the X axis by 2 is not done, and this
|
||||
appears as X scaling of 2 that no one requested. */
|
||||
SetWindowExtEx(hdc, 100, 100, NULL);
|
||||
SetViewportExtEx(hdc, 50, 100, NULL);
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 2, 1);
|
||||
/* font metrics on another DC should be unchanged */
|
||||
test_font_metrics(hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
|
||||
/* part 2: rescaling only Y should change font scaling.
|
||||
As also X is scaled by a factor of 2, but this is not
|
||||
requested by the DC transformation, we get a scaling factor
|
||||
of 2 in the X coordinate. */
|
||||
SetViewportExtEx(hdc, 100, 200, NULL);
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 2, 1);
|
||||
/* font metrics on another DC should be unchanged */
|
||||
test_font_metrics(hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
|
||||
/* restore scaling */
|
||||
SetMapMode(hdc, MM_TEXT);
|
||||
|
||||
/* font metrics on another DC should be unchanged */
|
||||
test_font_metrics(hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
|
||||
SelectObject(hdc_2, old_hfont_2);
|
||||
DeleteDC(hdc_2);
|
||||
|
||||
if (!SetGraphicsMode(hdc, GM_ADVANCED))
|
||||
{
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
DeleteDC(hdc);
|
||||
skip("GM_ADVANCED is not supported on this platform\n");
|
||||
return;
|
||||
}
|
||||
|
||||
xform.eM11 = 20.0f;
|
||||
xform.eM12 = 0.0f;
|
||||
xform.eM21 = 0.0f;
|
||||
xform.eM22 = 20.0f;
|
||||
xform.eDx = 0.0f;
|
||||
xform.eDy = 0.0f;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetWorldTransform(hdc, &xform);
|
||||
ok(ret, "SetWorldTransform error %u\n", GetLastError());
|
||||
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
|
||||
/* with an identity matrix */
|
||||
memset(&gm, 0, sizeof(gm));
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
|
||||
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||
pt.x = width_orig; pt.y = 0;
|
||||
LPtoDP(hdc, &pt, 1);
|
||||
ok(gm.gmCellIncX == pt.x, "incX %d != %d\n", gm.gmCellIncX, pt.x);
|
||||
ok(gm.gmCellIncX == 20 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 20 * width_orig);
|
||||
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||
/* with a custom matrix */
|
||||
memset(&gm, 0, sizeof(gm));
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
|
||||
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||
pt.x = width_orig; pt.y = 0;
|
||||
LPtoDP(hdc, &pt, 1);
|
||||
ok(gm.gmCellIncX == pt.x/2, "incX %d != %d\n", gm.gmCellIncX, pt.x/2);
|
||||
ok(near_match(gm.gmCellIncX, 10 * width_orig), "incX %d != %d\n", gm.gmCellIncX, 10 * width_orig);
|
||||
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetMapMode(hdc, MM_LOMETRIC);
|
||||
ok(ret == MM_TEXT, "expected MM_TEXT, got %d, error %u\n", ret, GetLastError());
|
||||
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
|
||||
/* with an identity matrix */
|
||||
memset(&gm, 0, sizeof(gm));
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
|
||||
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||
pt.x = width_orig; pt.y = 0;
|
||||
LPtoDP(hdc, &pt, 1);
|
||||
ok(near_match(gm.gmCellIncX, pt.x), "incX %d != %d\n", gm.gmCellIncX, pt.x);
|
||||
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||
/* with a custom matrix */
|
||||
memset(&gm, 0, sizeof(gm));
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
|
||||
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||
pt.x = width_orig; pt.y = 0;
|
||||
LPtoDP(hdc, &pt, 1);
|
||||
ok(near_match(gm.gmCellIncX, (pt.x + 1)/2), "incX %d != %d\n", gm.gmCellIncX, (pt.x + 1)/2);
|
||||
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetMapMode(hdc, MM_TEXT);
|
||||
ok(ret == MM_LOMETRIC, "expected MM_LOMETRIC, got %d, error %u\n", ret, GetLastError());
|
||||
|
||||
test_font_metrics(hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
|
||||
|
||||
/* with an identity matrix */
|
||||
memset(&gm, 0, sizeof(gm));
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
|
||||
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||
pt.x = width_orig; pt.y = 0;
|
||||
LPtoDP(hdc, &pt, 1);
|
||||
ok(gm.gmCellIncX == pt.x, "incX %d != %d\n", gm.gmCellIncX, pt.x);
|
||||
ok(gm.gmCellIncX == 20 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 20 * width_orig);
|
||||
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||
/* with a custom matrix */
|
||||
memset(&gm, 0, sizeof(gm));
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
|
||||
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %d\n", GetLastError());
|
||||
trace("gm.gmCellIncX %d, width_orig %d\n", gm.gmCellIncX, width_orig);
|
||||
pt.x = width_orig; pt.y = 0;
|
||||
LPtoDP(hdc, &pt, 1);
|
||||
ok(gm.gmCellIncX == pt.x/2, "incX %d != %d\n", gm.gmCellIncX, pt.x/2);
|
||||
ok(gm.gmCellIncX == 10 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 10 * width_orig);
|
||||
ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
|
||||
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
|
||||
static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
|
||||
{
|
||||
LOGFONT *lf = (LOGFONT *)lParam;
|
||||
|
@ -781,6 +1105,8 @@ static void test_GetKerningPairs(void)
|
|||
kd[i].otmDescent, otm.otmDescent);
|
||||
ok(kd[i].otmLineGap == otm.otmLineGap, "expected %u, got %u\n",
|
||||
kd[i].otmLineGap, otm.otmLineGap);
|
||||
ok(near_match(kd[i].otmMacDescent, otm.otmMacDescent), "expected %d, got %d\n",
|
||||
kd[i].otmMacDescent, otm.otmMacDescent);
|
||||
todo_wine {
|
||||
ok(kd[i].otmsCapEmHeight == otm.otmsCapEmHeight, "expected %u, got %u\n",
|
||||
kd[i].otmsCapEmHeight, otm.otmsCapEmHeight);
|
||||
|
@ -788,8 +1114,6 @@ todo_wine {
|
|||
kd[i].otmsXHeight, otm.otmsXHeight);
|
||||
ok(kd[i].otmMacAscent == otm.otmMacAscent, "expected %d, got %d\n",
|
||||
kd[i].otmMacAscent, otm.otmMacAscent);
|
||||
ok(kd[i].otmMacDescent == otm.otmMacDescent, "expected %d, got %d\n",
|
||||
kd[i].otmMacDescent, otm.otmMacDescent);
|
||||
/* FIXME: this one sometimes succeeds due to expected 0, enable it when removing todo */
|
||||
if (0) ok(kd[i].otmMacLineGap == otm.otmMacLineGap, "expected %u, got %u\n",
|
||||
kd[i].otmMacLineGap, otm.otmMacLineGap);
|
||||
|
@ -1020,7 +1344,7 @@ static void testJustification(HDC hdc, PSTR str, RECT *clientArea)
|
|||
|
||||
for (e = 0; e < nErrors; e++)
|
||||
{
|
||||
ok(error[e].TabbedTextOutWidth == areaWidth,
|
||||
ok(near_match(error[e].TabbedTextOutWidth, areaWidth),
|
||||
"The output text (\"%s\") width should be %d, not %d.\n",
|
||||
error[e].extent, areaWidth, error[e].TabbedTextOutWidth);
|
||||
/* The width returned by GetTextExtentPoint32() is exactly the same
|
||||
|
@ -1097,8 +1421,8 @@ static BOOL get_glyph_indices(INT charset, UINT code_page, WORD *idx, UINT count
|
|||
ok(cs == charset, "expected %d, got %d\n", charset, cs);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetTextFace(hdc, sizeof(name), name);
|
||||
ok(ret, "GetTextFace error %u\n", GetLastError());
|
||||
ret = GetTextFaceA(hdc, sizeof(name), name);
|
||||
ok(ret, "GetTextFaceA error %u\n", GetLastError());
|
||||
|
||||
if (charset == SYMBOL_CHARSET)
|
||||
{
|
||||
|
@ -1247,7 +1571,7 @@ static void test_GetFontUnicodeRanges(void)
|
|||
ReleaseDC(NULL, hdc);
|
||||
}
|
||||
|
||||
#define MAX_ENUM_FONTS 256
|
||||
#define MAX_ENUM_FONTS 4096
|
||||
|
||||
struct enum_font_data
|
||||
{
|
||||
|
@ -1255,17 +1579,46 @@ struct enum_font_data
|
|||
LOGFONT lf[MAX_ENUM_FONTS];
|
||||
};
|
||||
|
||||
struct enum_font_dataW
|
||||
{
|
||||
int total;
|
||||
LOGFONTW lf[MAX_ENUM_FONTS];
|
||||
};
|
||||
|
||||
static INT CALLBACK arial_enum_proc(const LOGFONT *lf, const TEXTMETRIC *tm, DWORD type, LPARAM lParam)
|
||||
{
|
||||
struct enum_font_data *efd = (struct enum_font_data *)lParam;
|
||||
|
||||
ok(lf->lfHeight == tm->tmHeight, "lfHeight %d != tmHeight %d\n", lf->lfHeight, tm->tmHeight);
|
||||
|
||||
if (type != TRUETYPE_FONTTYPE) return 1;
|
||||
#if 0
|
||||
trace("enumed font \"%s\", charset %d, weight %d, italic %d\n",
|
||||
lf->lfFaceName, lf->lfCharSet, lf->lfWeight, lf->lfItalic);
|
||||
trace("enumed font \"%s\", charset %d, height %d, weight %d, italic %d\n",
|
||||
lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
|
||||
#endif
|
||||
if (efd->total < MAX_ENUM_FONTS)
|
||||
efd->lf[efd->total++] = *lf;
|
||||
else
|
||||
trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static INT CALLBACK arial_enum_procw(const LOGFONTW *lf, const TEXTMETRICW *tm, DWORD type, LPARAM lParam)
|
||||
{
|
||||
struct enum_font_dataW *efd = (struct enum_font_dataW *)lParam;
|
||||
|
||||
ok(lf->lfHeight == tm->tmHeight, "lfHeight %d != tmHeight %d\n", lf->lfHeight, tm->tmHeight);
|
||||
|
||||
if (type != TRUETYPE_FONTTYPE) return 1;
|
||||
#if 0
|
||||
trace("enumed font \"%s\", charset %d, height %d, weight %d, italic %d\n",
|
||||
lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
|
||||
#endif
|
||||
if (efd->total < MAX_ENUM_FONTS)
|
||||
efd->lf[efd->total++] = *lf;
|
||||
else
|
||||
trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1297,9 +1650,37 @@ static void get_charset_stats(struct enum_font_data *efd,
|
|||
}
|
||||
}
|
||||
|
||||
static void get_charset_statsW(struct enum_font_dataW *efd,
|
||||
int *ansi_charset, int *symbol_charset,
|
||||
int *russian_charset)
|
||||
{
|
||||
int i;
|
||||
|
||||
*ansi_charset = 0;
|
||||
*symbol_charset = 0;
|
||||
*russian_charset = 0;
|
||||
|
||||
for (i = 0; i < efd->total; i++)
|
||||
{
|
||||
switch (efd->lf[i].lfCharSet)
|
||||
{
|
||||
case ANSI_CHARSET:
|
||||
(*ansi_charset)++;
|
||||
break;
|
||||
case SYMBOL_CHARSET:
|
||||
(*symbol_charset)++;
|
||||
break;
|
||||
case RUSSIAN_CHARSET:
|
||||
(*russian_charset)++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_EnumFontFamilies(const char *font_name, INT font_charset)
|
||||
{
|
||||
struct enum_font_data efd;
|
||||
struct enum_font_dataW efdw;
|
||||
LOGFONT lf;
|
||||
HDC hdc;
|
||||
int i, ret, ansi_charset, symbol_charset, russian_charset;
|
||||
|
@ -1319,29 +1700,39 @@ static void test_EnumFontFamilies(const char *font_name, INT font_charset)
|
|||
*/
|
||||
if (!*font_name && font_charset == DEFAULT_CHARSET) /* do it only once */
|
||||
{
|
||||
efd.total = 0;
|
||||
/*
|
||||
* Use EnumFontFamiliesW since win98 crashes when the
|
||||
* second parameter is NULL using EnumFontFamilies
|
||||
*/
|
||||
efdw.total = 0;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = EnumFontFamilies(hdc, NULL, arial_enum_proc, (LPARAM)&efd);
|
||||
ok(ret, "EnumFontFamilies error %u\n", GetLastError());
|
||||
get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
|
||||
trace("enumerated ansi %d, symbol %d, russian %d fonts for NULL\n",
|
||||
ansi_charset, symbol_charset, russian_charset);
|
||||
ok(efd.total > 0, "no fonts enumerated: NULL\n");
|
||||
ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
|
||||
ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
|
||||
ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n");
|
||||
ret = EnumFontFamiliesW(hdc, NULL, arial_enum_procw, (LPARAM)&efdw);
|
||||
ok(ret || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "EnumFontFamiliesW error %u\n", GetLastError());
|
||||
if(ret)
|
||||
{
|
||||
get_charset_statsW(&efdw, &ansi_charset, &symbol_charset, &russian_charset);
|
||||
trace("enumerated ansi %d, symbol %d, russian %d fonts for NULL\n",
|
||||
ansi_charset, symbol_charset, russian_charset);
|
||||
ok(efdw.total > 0, "fonts enumerated: NULL\n");
|
||||
ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
|
||||
ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
|
||||
ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n");
|
||||
}
|
||||
|
||||
efd.total = 0;
|
||||
efdw.total = 0;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = EnumFontFamiliesEx(hdc, NULL, arial_enum_proc, (LPARAM)&efd, 0);
|
||||
ok(ret, "EnumFontFamiliesEx error %u\n", GetLastError());
|
||||
get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
|
||||
trace("enumerated ansi %d, symbol %d, russian %d fonts for NULL\n",
|
||||
ansi_charset, symbol_charset, russian_charset);
|
||||
ok(efd.total > 0, "no fonts enumerated: NULL\n");
|
||||
ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
|
||||
ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
|
||||
ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n");
|
||||
ret = EnumFontFamiliesExW(hdc, NULL, arial_enum_procw, (LPARAM)&efdw, 0);
|
||||
ok(ret || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "EnumFontFamiliesExW error %u\n", GetLastError());
|
||||
if(ret)
|
||||
{
|
||||
get_charset_statsW(&efdw, &ansi_charset, &symbol_charset, &russian_charset);
|
||||
trace("enumerated ansi %d, symbol %d, russian %d fonts for NULL\n",
|
||||
ansi_charset, symbol_charset, russian_charset);
|
||||
ok(efdw.total > 0, "fonts enumerated: NULL\n");
|
||||
ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
|
||||
ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
|
||||
ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n");
|
||||
}
|
||||
}
|
||||
|
||||
efd.total = 0;
|
||||
|
@ -1503,6 +1894,12 @@ static void test_negative_width(HDC hdc, const LOGFONTA *lf)
|
|||
WORD idx;
|
||||
MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} };
|
||||
|
||||
if(!pGetGlyphIndicesA)
|
||||
{
|
||||
skip("GetGlyphIndicesA is unavailable\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* negative widths are handled just as positive ones */
|
||||
lf2.lfWidth = -lf->lfWidth;
|
||||
|
||||
|
@ -1633,8 +2030,6 @@ static void test_text_metrics(const LOGFONTA *lf)
|
|||
LONG size, ret;
|
||||
const char *font_name = lf->lfFaceName;
|
||||
|
||||
trace("Testing font metrics for %s, charset %d\n", font_name, lf->lfCharSet);
|
||||
|
||||
hdc = GetDC(0);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
|
@ -1660,21 +2055,19 @@ static void test_text_metrics(const LOGFONTA *lf)
|
|||
ok(ret == size, "GetFontData should return %u not %u\n", size, ret);
|
||||
|
||||
version = GET_BE_WORD(tt_os2.version);
|
||||
trace("OS/2 chunk version %u, vendor %4.4s\n", version, (LPCSTR)&tt_os2.achVendID);
|
||||
|
||||
first_unicode_char = GET_BE_WORD(tt_os2.usFirstCharIndex);
|
||||
last_unicode_char = GET_BE_WORD(tt_os2.usLastCharIndex);
|
||||
default_char = GET_BE_WORD(tt_os2.usDefaultChar);
|
||||
break_char = GET_BE_WORD(tt_os2.usBreakChar);
|
||||
|
||||
trace("for %s first %x, last %x, default %x, break %x\n", font_name,
|
||||
first_unicode_char, last_unicode_char, default_char, break_char);
|
||||
trace("font %s charset %u: %x-%x default %x break %x OS/2 version %u vendor %4.4s\n",
|
||||
font_name, lf->lfCharSet, first_unicode_char, last_unicode_char, default_char, break_char,
|
||||
version, (LPCSTR)&tt_os2.achVendID);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetTextMetricsA(hdc, &tmA);
|
||||
ok(ret, "GetTextMetricsA error %u\n", GetLastError());
|
||||
trace("A: first %x, last %x, default %x, break %x\n",
|
||||
tmA.tmFirstChar, tmA.tmLastChar, tmA.tmDefaultChar, tmA.tmBreakChar);
|
||||
|
||||
#if 0 /* FIXME: This doesn't appear to be what Windows does */
|
||||
test_char = min(first_unicode_char - 1, 255);
|
||||
|
@ -1700,9 +2093,9 @@ static void test_text_metrics(const LOGFONTA *lf)
|
|||
"GetTextMetricsW error %u\n", GetLastError());
|
||||
if (ret)
|
||||
{
|
||||
trace("W: first %x, last %x, default %x, break %x\n",
|
||||
tmW.tmFirstChar, tmW.tmLastChar, tmW.tmDefaultChar,
|
||||
tmW.tmBreakChar);
|
||||
trace("%04x-%04x (%02x-%02x) default %x (%x) break %x (%x)\n",
|
||||
tmW.tmFirstChar, tmW.tmLastChar, tmA.tmFirstChar, tmA.tmLastChar,
|
||||
tmW.tmDefaultChar, tmA.tmDefaultChar, tmW.tmBreakChar, tmA.tmBreakChar);
|
||||
|
||||
if (lf->lfCharSet == SYMBOL_CHARSET)
|
||||
{
|
||||
|
@ -1775,17 +2168,41 @@ static void test_GetTextMetrics(void)
|
|||
|
||||
static void test_nonexistent_font(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *name;
|
||||
int charset;
|
||||
} font_subst[] =
|
||||
{
|
||||
{ "Times New Roman Baltic", 186 },
|
||||
{ "Times New Roman CE", 238 },
|
||||
{ "Times New Roman CYR", 204 },
|
||||
{ "Times New Roman Greek", 161 },
|
||||
{ "Times New Roman TUR", 162 }
|
||||
};
|
||||
LOGFONTA lf;
|
||||
HDC hdc;
|
||||
HFONT hfont;
|
||||
CHARSETINFO csi;
|
||||
INT cs, expected_cs, i;
|
||||
char buf[LF_FACESIZE];
|
||||
|
||||
if (!is_truetype_font_installed("Arial Black"))
|
||||
if (!is_truetype_font_installed("Arial") ||
|
||||
!is_truetype_font_installed("Times New Roman"))
|
||||
{
|
||||
skip("Arial not installed\n");
|
||||
skip("Arial or Times New Roman not installed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
expected_cs = GetACP();
|
||||
if (!TranslateCharsetInfo(ULongToPtr(expected_cs), &csi, TCI_SRCCODEPAGE))
|
||||
{
|
||||
skip("TranslateCharsetInfo failed for code page %d\n", expected_cs);
|
||||
return;
|
||||
}
|
||||
expected_cs = csi.ciCharset;
|
||||
trace("ACP %d -> charset %d\n", GetACP(), expected_cs);
|
||||
|
||||
hdc = GetDC(0);
|
||||
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
|
@ -1794,12 +2211,96 @@ static void test_nonexistent_font(void)
|
|||
lf.lfCharSet = ANSI_CHARSET;
|
||||
lf.lfPitchAndFamily = FF_SWISS;
|
||||
strcpy(lf.lfFaceName, "Nonexistent font");
|
||||
|
||||
hfont = CreateFontIndirectA(&lf);
|
||||
hfont = SelectObject(hdc, hfont);
|
||||
GetTextFaceA(hdc, sizeof(buf), buf);
|
||||
ok(!lstrcmpiA(buf, "Arial"), "Got %s\n", buf);
|
||||
cs = GetTextCharset(hdc);
|
||||
ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d\n", cs);
|
||||
DeleteObject(SelectObject(hdc, hfont));
|
||||
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
lf.lfHeight = -13;
|
||||
lf.lfWeight = FW_DONTCARE;
|
||||
strcpy(lf.lfFaceName, "Nonexistent font");
|
||||
hfont = CreateFontIndirectA(&lf);
|
||||
hfont = SelectObject(hdc, hfont);
|
||||
GetTextFaceA(hdc, sizeof(buf), buf);
|
||||
todo_wine /* Wine uses Arial for all substitutions */
|
||||
ok(!lstrcmpiA(buf, "Nonexistent font") /* XP, Vista */ ||
|
||||
!lstrcmpiA(buf, "MS Serif") || /* Win9x */
|
||||
!lstrcmpiA(buf, "MS Sans Serif"), /* win2k3 */
|
||||
"Got %s\n", buf);
|
||||
cs = GetTextCharset(hdc);
|
||||
ok(cs == expected_cs, "expected %d, got %d\n", expected_cs, cs);
|
||||
DeleteObject(SelectObject(hdc, hfont));
|
||||
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
lf.lfHeight = -13;
|
||||
lf.lfWeight = FW_REGULAR;
|
||||
strcpy(lf.lfFaceName, "Nonexistent font");
|
||||
hfont = CreateFontIndirectA(&lf);
|
||||
hfont = SelectObject(hdc, hfont);
|
||||
GetTextFaceA(hdc, sizeof(buf), buf);
|
||||
ok(!lstrcmpiA(buf, "Arial") /* XP, Vista */ ||
|
||||
!lstrcmpiA(buf, "Times New Roman") /* Win9x */, "Got %s\n", buf);
|
||||
cs = GetTextCharset(hdc);
|
||||
ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d\n", cs);
|
||||
DeleteObject(SelectObject(hdc, hfont));
|
||||
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
lf.lfHeight = -13;
|
||||
lf.lfWeight = FW_DONTCARE;
|
||||
strcpy(lf.lfFaceName, "Times New Roman");
|
||||
hfont = CreateFontIndirectA(&lf);
|
||||
hfont = SelectObject(hdc, hfont);
|
||||
GetTextFaceA(hdc, sizeof(buf), buf);
|
||||
ok(!lstrcmpiA(buf, "Times New Roman"), "Got %s\n", buf);
|
||||
cs = GetTextCharset(hdc);
|
||||
ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d\n", cs);
|
||||
DeleteObject(SelectObject(hdc, hfont));
|
||||
|
||||
for (i = 0; i < sizeof(font_subst)/sizeof(font_subst[0]); i++)
|
||||
{
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
lf.lfHeight = -13;
|
||||
lf.lfWeight = FW_REGULAR;
|
||||
strcpy(lf.lfFaceName, font_subst[i].name);
|
||||
hfont = CreateFontIndirectA(&lf);
|
||||
hfont = SelectObject(hdc, hfont);
|
||||
cs = GetTextCharset(hdc);
|
||||
if (font_subst[i].charset == expected_cs)
|
||||
{
|
||||
ok(cs == expected_cs, "expected %d, got %d\n", expected_cs, cs);
|
||||
GetTextFaceA(hdc, sizeof(buf), buf);
|
||||
ok(!lstrcmpiA(buf, font_subst[i].name), "expected %s, got %s\n", font_subst[i].name, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d\n", cs);
|
||||
GetTextFaceA(hdc, sizeof(buf), buf);
|
||||
ok(!lstrcmpiA(buf, "Arial") /* XP, Vista */ ||
|
||||
!lstrcmpiA(buf, "Times New Roman") /* Win9x */, "got %s\n", buf);
|
||||
}
|
||||
DeleteObject(SelectObject(hdc, hfont));
|
||||
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
lf.lfHeight = -13;
|
||||
lf.lfWeight = FW_DONTCARE;
|
||||
strcpy(lf.lfFaceName, font_subst[i].name);
|
||||
hfont = CreateFontIndirectA(&lf);
|
||||
hfont = SelectObject(hdc, hfont);
|
||||
GetTextFaceA(hdc, sizeof(buf), buf);
|
||||
ok(!lstrcmpiA(buf, "Arial") /* Wine */ ||
|
||||
!lstrcmpiA(buf, font_subst[i].name) /* XP, Vista */ ||
|
||||
!lstrcmpiA(buf, "MS Serif") /* Win9x */ ||
|
||||
!lstrcmpiA(buf, "MS Sans Serif"), /* win2k3 */
|
||||
"got %s\n", buf);
|
||||
cs = GetTextCharset(hdc);
|
||||
ok(cs == expected_cs, "expected %d, got %d\n", expected_cs, cs);
|
||||
DeleteObject(SelectObject(hdc, hfont));
|
||||
}
|
||||
|
||||
ReleaseDC(0, hdc);
|
||||
}
|
||||
|
||||
|
@ -1850,12 +2351,137 @@ static void test_GdiRealizationInfo(void)
|
|||
ReleaseDC(0, hdc);
|
||||
}
|
||||
|
||||
/* Tests on XP SP2 show that the ANSI version of GetTextFace does NOT include
|
||||
the nul in the count of characters copied when the face name buffer is not
|
||||
NULL, whereas it does if the buffer is NULL. Further, the Unicode version
|
||||
always includes it. */
|
||||
static void test_GetTextFace(void)
|
||||
{
|
||||
static const char faceA[] = "Tahoma";
|
||||
static const WCHAR faceW[] = {'T','a','h','o','m','a', 0};
|
||||
LOGFONTA fA = {0};
|
||||
LOGFONTW fW = {0};
|
||||
char bufA[LF_FACESIZE];
|
||||
WCHAR bufW[LF_FACESIZE];
|
||||
HFONT f, g;
|
||||
HDC dc;
|
||||
int n;
|
||||
|
||||
if(!is_font_installed("Tahoma"))
|
||||
{
|
||||
skip("Tahoma is not installed so skipping this test\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* 'A' case. */
|
||||
memcpy(fA.lfFaceName, faceA, sizeof faceA);
|
||||
f = CreateFontIndirectA(&fA);
|
||||
ok(f != NULL, "CreateFontIndirectA failed\n");
|
||||
|
||||
dc = GetDC(NULL);
|
||||
g = SelectObject(dc, f);
|
||||
n = GetTextFaceA(dc, sizeof bufA, bufA);
|
||||
ok(n == sizeof faceA - 1, "GetTextFaceA returned %d\n", n);
|
||||
ok(lstrcmpA(faceA, bufA) == 0, "GetTextFaceA\n");
|
||||
|
||||
/* Play with the count arg. */
|
||||
bufA[0] = 'x';
|
||||
n = GetTextFaceA(dc, 0, bufA);
|
||||
ok(n == 0, "GetTextFaceA returned %d\n", n);
|
||||
ok(bufA[0] == 'x', "GetTextFaceA buf[0] == %d\n", bufA[0]);
|
||||
|
||||
bufA[0] = 'x';
|
||||
n = GetTextFaceA(dc, 1, bufA);
|
||||
ok(n == 0, "GetTextFaceA returned %d\n", n);
|
||||
ok(bufA[0] == '\0', "GetTextFaceA buf[0] == %d\n", bufA[0]);
|
||||
|
||||
bufA[0] = 'x'; bufA[1] = 'y';
|
||||
n = GetTextFaceA(dc, 2, bufA);
|
||||
ok(n == 1, "GetTextFaceA returned %d\n", n);
|
||||
ok(bufA[0] == faceA[0] && bufA[1] == '\0', "GetTextFaceA didn't copy\n");
|
||||
|
||||
n = GetTextFaceA(dc, 0, NULL);
|
||||
ok(n == sizeof faceA, "GetTextFaceA returned %d\n", n);
|
||||
|
||||
DeleteObject(SelectObject(dc, g));
|
||||
ReleaseDC(NULL, dc);
|
||||
|
||||
/* 'W' case. */
|
||||
memcpy(fW.lfFaceName, faceW, sizeof faceW);
|
||||
SetLastError(0xdeadbeef);
|
||||
f = CreateFontIndirectW(&fW);
|
||||
if (!f && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||
{
|
||||
win_skip("CreateFontIndirectW is not implemented\n");
|
||||
return;
|
||||
}
|
||||
ok(f != NULL, "CreateFontIndirectW failed\n");
|
||||
|
||||
dc = GetDC(NULL);
|
||||
g = SelectObject(dc, f);
|
||||
n = GetTextFaceW(dc, sizeof bufW / sizeof bufW[0], bufW);
|
||||
ok(n == sizeof faceW / sizeof faceW[0], "GetTextFaceW returned %d\n", n);
|
||||
ok(lstrcmpW(faceW, bufW) == 0, "GetTextFaceW\n");
|
||||
|
||||
/* Play with the count arg. */
|
||||
bufW[0] = 'x';
|
||||
n = GetTextFaceW(dc, 0, bufW);
|
||||
ok(n == 0, "GetTextFaceW returned %d\n", n);
|
||||
ok(bufW[0] == 'x', "GetTextFaceW buf[0] == %d\n", bufW[0]);
|
||||
|
||||
bufW[0] = 'x';
|
||||
n = GetTextFaceW(dc, 1, bufW);
|
||||
ok(n == 1, "GetTextFaceW returned %d\n", n);
|
||||
ok(bufW[0] == '\0', "GetTextFaceW buf[0] == %d\n", bufW[0]);
|
||||
|
||||
bufW[0] = 'x'; bufW[1] = 'y';
|
||||
n = GetTextFaceW(dc, 2, bufW);
|
||||
ok(n == 2, "GetTextFaceW returned %d\n", n);
|
||||
ok(bufW[0] == faceW[0] && bufW[1] == '\0', "GetTextFaceW didn't copy\n");
|
||||
|
||||
n = GetTextFaceW(dc, 0, NULL);
|
||||
ok(n == sizeof faceW / sizeof faceW[0], "GetTextFaceW returned %d\n", n);
|
||||
|
||||
DeleteObject(SelectObject(dc, g));
|
||||
ReleaseDC(NULL, dc);
|
||||
}
|
||||
|
||||
static void test_orientation(void)
|
||||
{
|
||||
static const char test_str[11] = "Test String";
|
||||
HDC hdc;
|
||||
LOGFONTA lf;
|
||||
HFONT hfont, old_hfont;
|
||||
SIZE size;
|
||||
|
||||
if (!is_truetype_font_installed("Arial"))
|
||||
{
|
||||
skip("Arial is not installed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hdc = CreateCompatibleDC(0);
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
lstrcpyA(lf.lfFaceName, "Arial");
|
||||
lf.lfHeight = 72;
|
||||
lf.lfOrientation = lf.lfEscapement = 900;
|
||||
hfont = create_font("orientation", &lf);
|
||||
old_hfont = SelectObject(hdc, hfont);
|
||||
ok(GetTextExtentExPointA(hdc, test_str, sizeof(test_str), 32767, NULL, NULL, &size), "GetTextExtentExPointA failed\n");
|
||||
ok(near_match(311, size.cx), "cx should be about 311, got %d\n", size.cx);
|
||||
ok(near_match(75, size.cy), "cy should be about 75, got %d\n", size.cy);
|
||||
SelectObject(hdc, old_hfont);
|
||||
DeleteObject(hfont);
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
|
||||
START_TEST(font)
|
||||
{
|
||||
init();
|
||||
|
||||
test_logfont();
|
||||
test_bitmap_font();
|
||||
test_outline_font();
|
||||
test_bitmap_font_metrics();
|
||||
test_GdiGetCharDimensions();
|
||||
test_GetCharABCWidths();
|
||||
|
@ -1867,6 +2493,7 @@ START_TEST(font)
|
|||
test_font_charset();
|
||||
test_GetFontUnicodeRanges();
|
||||
test_nonexistent_font();
|
||||
test_orientation();
|
||||
|
||||
/* On Windows Arial has a lot of default charset aliases such as Arial Cyr,
|
||||
* I'd like to avoid them in this test.
|
||||
|
@ -1884,4 +2511,5 @@ START_TEST(font)
|
|||
skip("Arial Black or Symbol/Wingdings is not installed\n");
|
||||
test_GetTextMetrics();
|
||||
test_GdiRealizationInfo();
|
||||
test_GetTextFace();
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ static void test_gdi_objects(void)
|
|||
*/
|
||||
SetLastError(0);
|
||||
hp = SelectObject(NULL, GetStockObject(BLACK_PEN));
|
||||
ok(!hp && GetLastError() == ERROR_INVALID_HANDLE,
|
||||
ok(!hp && (GetLastError() == ERROR_INVALID_HANDLE || broken(!GetLastError())),
|
||||
"SelectObject(NULL DC) expected 0, ERROR_INVALID_HANDLE, got %p, %u\n",
|
||||
hp, GetLastError());
|
||||
|
||||
|
@ -77,7 +77,7 @@ static void test_gdi_objects(void)
|
|||
/* GetObject does not SetLastError() on a null object */
|
||||
SetLastError(0);
|
||||
i = GetObjectA(NULL, sizeof(buff), buff);
|
||||
ok (!i && !GetLastError(),
|
||||
ok (!i && (GetLastError() == 0 || GetLastError() == ERROR_INVALID_PARAMETER),
|
||||
"GetObject(NULL obj), expected 0, NO_ERROR, got %d, %u\n",
|
||||
i, GetLastError());
|
||||
|
||||
|
@ -207,7 +207,7 @@ static void test_GetCurrentObject(void)
|
|||
hobj = GetCurrentObject(hdc, OBJ_PEN);
|
||||
ok(hobj == hpen, "OBJ_PEN is wrong: %p\n", hobj);
|
||||
hobj = GetCurrentObject(hdc, OBJ_EXTPEN);
|
||||
ok(hobj == hpen, "OBJ_EXTPEN is wrong: %p\n", hobj);
|
||||
ok(hobj == hpen || broken(hobj == 0) /* win9x */, "OBJ_EXTPEN is wrong: %p\n", hobj);
|
||||
|
||||
hbrush = CreateSolidBrush(RGB(10, 20, 30));
|
||||
assert(hbrush != 0);
|
||||
|
@ -243,7 +243,7 @@ static void test_GetCurrentObject(void)
|
|||
hobj = GetCurrentObject(hdc, OBJ_PEN);
|
||||
ok(hobj == hpen, "OBJ_PEN is wrong: %p\n", hobj);
|
||||
hobj = GetCurrentObject(hdc, OBJ_EXTPEN);
|
||||
ok(hobj == hpen, "OBJ_EXTPEN is wrong: %p\n", hobj);
|
||||
ok(hobj == hpen || broken(hobj == 0) /* win9x */, "OBJ_EXTPEN is wrong: %p\n", hobj);
|
||||
|
||||
hcs = GetColorSpace(hdc);
|
||||
if (hcs)
|
||||
|
@ -254,7 +254,7 @@ static void test_GetCurrentObject(void)
|
|||
ok(hcs != 0, "CreateColorSpace failed\n");
|
||||
SelectObject(hdc, hcs);
|
||||
hobj = GetCurrentObject(hdc, OBJ_COLORSPACE);
|
||||
ok(hobj == hcs, "OBJ_COLORSPACE is wrong: %p\n", hobj);
|
||||
ok(hobj == hcs || broken(hobj == 0) /* win9x */, "OBJ_COLORSPACE is wrong: %p\n", hobj);
|
||||
}
|
||||
|
||||
hrgn = CreateRectRgn(1, 1, 100, 100);
|
||||
|
|
|
@ -51,20 +51,28 @@ static void test_GetICMProfileA( HDC dc )
|
|||
ret = GetICMProfileA( dc, &size, NULL );
|
||||
ok( !ret, "GetICMProfileA succeeded\n" );
|
||||
|
||||
ret = GetICMProfileA( dc, NULL, filename );
|
||||
ok( !ret, "GetICMProfileA succeeded\n" );
|
||||
|
||||
size = MAX_PATH;
|
||||
ret = GetICMProfileA( NULL, &size, filename );
|
||||
ok( !ret, "GetICMProfileA succeeded\n" );
|
||||
|
||||
size = 0;
|
||||
filename[0] = 0;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetICMProfileA( dc, &size, filename );
|
||||
error = GetLastError();
|
||||
ok( !ret, "GetICMProfileA succeeded\n" );
|
||||
ok( size, "expected size > 0\n" );
|
||||
ok( error == ERROR_INSUFFICIENT_BUFFER, "got %d, expected ERROR_INSUFFICIENT_BUFFER\n", error );
|
||||
ok( filename[0] == 0, "Expected filename to be empty\n" );
|
||||
ok( error == ERROR_INSUFFICIENT_BUFFER ||
|
||||
error == ERROR_SUCCESS, /* Win95 */
|
||||
"got %d, expected ERROR_INSUFFICIENT_BUFFER or ERROR_SUCCESS(Win95)\n", error );
|
||||
|
||||
/* Next test will crash on Win95 */
|
||||
if ( error == ERROR_INSUFFICIENT_BUFFER )
|
||||
{
|
||||
ret = GetICMProfileA( dc, NULL, filename );
|
||||
ok( !ret, "GetICMProfileA succeeded\n" );
|
||||
}
|
||||
|
||||
size = MAX_PATH;
|
||||
ret = GetICMProfileA( dc, &size, filename );
|
||||
|
@ -122,6 +130,15 @@ static void test_GetICMProfileW( HDC dc )
|
|||
static void test_SetICMMode( HDC dc )
|
||||
{
|
||||
INT ret, knob, save;
|
||||
BOOL impl;
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
impl = GetICMProfileA( NULL, NULL, NULL );
|
||||
if ( !impl && ( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED ) )
|
||||
{
|
||||
skip( "On NT4 where SetICMMode is not implemented but this is not advertised\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = SetICMMode( NULL, 0 );
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Unit tests for mapping functions
|
||||
*
|
||||
* Copyright (c) 2005 Huw Davies
|
||||
* Copyright (c) 2008 Dmitry Timoshkov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -28,6 +29,146 @@
|
|||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
|
||||
#define rough_match(got, expected) (abs((got) - (expected)) <= 5)
|
||||
|
||||
#define expect_LPtoDP(_hdc, _x, _y) \
|
||||
{ \
|
||||
POINT _pt = { 1000, 1000 }; \
|
||||
LPtoDP(_hdc, &_pt, 1); \
|
||||
ok(rough_match(_pt.x, _x), "expected x %d, got %d\n", (_x), _pt.x); \
|
||||
ok(rough_match(_pt.y, _y), "expected y %d, got %d\n", (_y), _pt.y); \
|
||||
}
|
||||
|
||||
#define expect_world_trasform(_hdc, _em11, _em22) \
|
||||
{ \
|
||||
BOOL _ret; \
|
||||
XFORM _xform; \
|
||||
SetLastError(0xdeadbeef); \
|
||||
_ret = GetWorldTransform(_hdc, &_xform); \
|
||||
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) \
|
||||
{ \
|
||||
ok(_ret, "GetWorldTransform error %u\n", GetLastError()); \
|
||||
ok(_xform.eM11 == (_em11), "expected %f, got %f\n", (_em11), _xform.eM11); \
|
||||
ok(_xform.eM12 == 0.0, "expected 0.0, got %f\n", _xform.eM12); \
|
||||
ok(_xform.eM21 == 0.0, "expected 0.0, got %f\n", _xform.eM21); \
|
||||
ok(_xform.eM22 == (_em22), "expected %f, got %f\n", (_em22), _xform.eM22); \
|
||||
ok(_xform.eDx == 0.0, "expected 0.0, got %f\n", _xform.eDx); \
|
||||
ok(_xform.eDy == 0.0, "expected 0.0, got %f\n", _xform.eDy); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define expect_dc_ext(_func, _hdc, _cx, _cy) \
|
||||
{ \
|
||||
BOOL _ret; \
|
||||
SIZE _size; \
|
||||
SetLastError(0xdeadbeef); \
|
||||
_ret = _func(_hdc, &_size); \
|
||||
ok(_ret, #_func " error %u\n", GetLastError()); \
|
||||
ok(_size.cx == (_cx), "expected cx %d, got %d\n", (_cx), _size.cx); \
|
||||
ok(_size.cy == (_cy), "expected cy %d, got %d\n", (_cy), _size.cy); \
|
||||
}
|
||||
|
||||
#define expect_viewport_ext(_hdc, _cx, _cy) expect_dc_ext(GetViewportExtEx, _hdc, _cx, _cy)
|
||||
#define expect_window_ext(_hdc, _cx, _cy) expect_dc_ext(GetWindowExtEx, _hdc, _cx, _cy)
|
||||
|
||||
static void test_world_transform(void)
|
||||
{
|
||||
BOOL is_win9x;
|
||||
HDC hdc;
|
||||
INT ret, size_cx, size_cy, res_x, res_y;
|
||||
XFORM xform;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
GetWorldTransform(0, NULL);
|
||||
is_win9x = GetLastError() == ERROR_CALL_NOT_IMPLEMENTED;
|
||||
|
||||
hdc = CreateCompatibleDC(0);
|
||||
|
||||
size_cx = GetDeviceCaps(hdc, HORZSIZE);
|
||||
size_cy = GetDeviceCaps(hdc, VERTSIZE);
|
||||
res_x = GetDeviceCaps(hdc, HORZRES);
|
||||
res_y = GetDeviceCaps(hdc, VERTRES);
|
||||
trace("dc size %d x %d, resolution %d x %d\n", size_cx, size_cy, res_x, res_y);
|
||||
|
||||
expect_viewport_ext(hdc, 1, 1);
|
||||
expect_window_ext(hdc, 1, 1);
|
||||
expect_world_trasform(hdc, 1.0, 1.0);
|
||||
expect_LPtoDP(hdc, 1000, 1000);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetMapMode(hdc, MM_LOMETRIC);
|
||||
ok(ret == MM_TEXT, "expected MM_TEXT, got %d\n", ret);
|
||||
|
||||
if (is_win9x)
|
||||
{
|
||||
expect_viewport_ext(hdc, GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY));
|
||||
expect_window_ext(hdc, 254, -254);
|
||||
}
|
||||
else
|
||||
{
|
||||
expect_viewport_ext(hdc, res_x, -res_y);
|
||||
expect_window_ext(hdc, size_cx * 10, size_cy * 10);
|
||||
}
|
||||
expect_world_trasform(hdc, 1.0, 1.0);
|
||||
expect_LPtoDP(hdc, MulDiv(1000 / 10, res_x, size_cx), -MulDiv(1000 / 10, res_y, size_cy));
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetMapMode(hdc, MM_TEXT);
|
||||
ok(ret == MM_LOMETRIC, "expected MM_LOMETRIC, got %d\n", ret);
|
||||
|
||||
expect_viewport_ext(hdc, 1, 1);
|
||||
expect_window_ext(hdc, 1, 1);
|
||||
expect_world_trasform(hdc, 1.0, 1.0);
|
||||
expect_LPtoDP(hdc, 1000, 1000);
|
||||
|
||||
ret = SetGraphicsMode(hdc, GM_ADVANCED);
|
||||
if (!ret)
|
||||
{
|
||||
DeleteDC(hdc);
|
||||
skip("GM_ADVANCED is not supported on this platform\n");
|
||||
return;
|
||||
}
|
||||
|
||||
expect_viewport_ext(hdc, 1, 1);
|
||||
expect_window_ext(hdc, 1, 1);
|
||||
expect_world_trasform(hdc, 1.0, 1.0);
|
||||
expect_LPtoDP(hdc, 1000, 1000);
|
||||
|
||||
xform.eM11 = 20.0f;
|
||||
xform.eM12 = 0.0f;
|
||||
xform.eM21 = 0.0f;
|
||||
xform.eM22 = 20.0f;
|
||||
xform.eDx = 0.0f;
|
||||
xform.eDy = 0.0f;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetWorldTransform(hdc, &xform);
|
||||
ok(ret, "SetWorldTransform error %u\n", GetLastError());
|
||||
|
||||
expect_viewport_ext(hdc, 1, 1);
|
||||
expect_window_ext(hdc, 1, 1);
|
||||
expect_world_trasform(hdc, 20.0, 20.0);
|
||||
expect_LPtoDP(hdc, 20000, 20000);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetMapMode(hdc, MM_LOMETRIC);
|
||||
ok(ret == MM_TEXT, "expected MM_TEXT, got %d\n", ret);
|
||||
|
||||
expect_viewport_ext(hdc, res_x, -res_y);
|
||||
expect_window_ext(hdc, size_cx * 10, size_cy * 10);
|
||||
expect_world_trasform(hdc, 20.0, 20.0);
|
||||
expect_LPtoDP(hdc, MulDiv(1000 * 2, res_x, size_cx), -MulDiv(1000 * 2, res_y, size_cy));
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SetMapMode(hdc, MM_TEXT);
|
||||
ok(ret == MM_LOMETRIC, "expected MM_LOMETRIC, got %d\n", ret);
|
||||
|
||||
expect_viewport_ext(hdc, 1, 1);
|
||||
expect_window_ext(hdc, 1, 1);
|
||||
expect_world_trasform(hdc, 20.0, 20.0);
|
||||
expect_LPtoDP(hdc, 20000, 20000);
|
||||
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
|
||||
static void test_modify_world_transform(void)
|
||||
{
|
||||
|
@ -38,6 +179,7 @@ static void test_modify_world_transform(void)
|
|||
if(!ret) /* running in win9x so quit */
|
||||
{
|
||||
ReleaseDC(0, hdc);
|
||||
skip("GM_ADVANCED is not supported on this platform\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -53,8 +195,6 @@ static void test_modify_world_transform(void)
|
|||
ReleaseDC(0, hdc);
|
||||
}
|
||||
|
||||
#define rough_match(got, expected) ((got >= expected - 2) && (got <= expected + 2))
|
||||
|
||||
static void test_SetWindowExt(HDC hdc, LONG cx, LONG cy, LONG expected_vp_cx, LONG expected_vp_cy)
|
||||
{
|
||||
SIZE windowExt, viewportExt;
|
||||
|
@ -158,5 +298,6 @@ static void test_isotropic_mapping(void)
|
|||
START_TEST(mapping)
|
||||
{
|
||||
test_modify_world_transform();
|
||||
test_world_transform();
|
||||
test_isotropic_mapping();
|
||||
}
|
||||
|
|
|
@ -975,8 +975,24 @@ static void dump_emf_record(const ENHMETARECORD *emr, const char *desc)
|
|||
printf ("};\n");
|
||||
}
|
||||
|
||||
static void dump_EMREXTTEXTOUT(const EMREXTTEXTOUTW *eto)
|
||||
{
|
||||
trace("rclBounds %d,%d - %d,%d\n", eto->rclBounds.left, eto->rclBounds.top,
|
||||
eto->rclBounds.right, eto->rclBounds.bottom);
|
||||
trace("iGraphicsMode %u\n", eto->iGraphicsMode);
|
||||
trace("exScale: %f\n", eto->exScale);
|
||||
trace("eyScale: %f\n", eto->eyScale);
|
||||
trace("emrtext.ptlReference %d,%d\n", eto->emrtext.ptlReference.x, eto->emrtext.ptlReference.y);
|
||||
trace("emrtext.nChars %u\n", eto->emrtext.nChars);
|
||||
trace("emrtext.offString %#x\n", eto->emrtext.offString);
|
||||
trace("emrtext.fOptions %#x\n", eto->emrtext.fOptions);
|
||||
trace("emrtext.rcl %d,%d - %d,%d\n", eto->emrtext.rcl.left, eto->emrtext.rcl.top,
|
||||
eto->emrtext.rcl.right, eto->emrtext.rcl.bottom);
|
||||
trace("emrtext.offDx %#x\n", eto->emrtext.offDx);
|
||||
}
|
||||
|
||||
static BOOL match_emf_record(const ENHMETARECORD *emr1, const ENHMETARECORD *emr2,
|
||||
const char *desc, BOOL todo)
|
||||
const char *desc, BOOL ignore_scaling, BOOL todo)
|
||||
{
|
||||
int diff;
|
||||
|
||||
|
@ -1010,7 +1026,37 @@ static BOOL match_emf_record(const ENHMETARECORD *emr1, const ENHMETARECORD *emr
|
|||
/* contents of EMR_GDICOMMENT are not interesting */
|
||||
if (emr1->iType == EMR_GDICOMMENT) return TRUE;
|
||||
|
||||
diff = memcmp(emr1->dParm, emr2->dParm, emr1->nSize - sizeof(EMR));
|
||||
/* different Windows versions setup DC scaling differently when
|
||||
* converting an old style metafile to an EMF.
|
||||
*/
|
||||
if (ignore_scaling && (emr1->iType == EMR_SETWINDOWEXTEX ||
|
||||
emr1->iType == EMR_SETVIEWPORTEXTEX))
|
||||
return TRUE;
|
||||
|
||||
if (emr1->iType == EMR_EXTTEXTOUTW || emr1->iType == EMR_EXTTEXTOUTA)
|
||||
{
|
||||
EMREXTTEXTOUTW *eto1, *eto2;
|
||||
|
||||
eto1 = HeapAlloc(GetProcessHeap(), 0, emr1->nSize);
|
||||
memcpy(eto1, emr1, emr1->nSize);
|
||||
eto2 = HeapAlloc(GetProcessHeap(), 0, emr2->nSize);
|
||||
memcpy(eto2, emr2, emr2->nSize);
|
||||
|
||||
/* different Windows versions setup DC scaling differently */
|
||||
eto1->exScale = eto1->eyScale = 0.0;
|
||||
eto2->exScale = eto2->eyScale = 0.0;
|
||||
|
||||
diff = memcmp(eto1, eto2, emr1->nSize);
|
||||
if (diff)
|
||||
{
|
||||
dump_EMREXTTEXTOUT(eto1);
|
||||
dump_EMREXTTEXTOUT(eto2);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, eto1);
|
||||
HeapFree(GetProcessHeap(), 0, eto2);
|
||||
}
|
||||
else
|
||||
diff = memcmp(emr1, emr2, emr1->nSize);
|
||||
if (diff && todo)
|
||||
{
|
||||
todo_wine
|
||||
|
@ -1035,7 +1081,8 @@ static BOOL match_emf_record(const ENHMETARECORD *emr1, const ENHMETARECORD *emr
|
|||
* otherwise returns the number of non-matching bytes.
|
||||
*/
|
||||
static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits,
|
||||
UINT bsize, const char *desc, BOOL todo)
|
||||
UINT bsize, const char *desc,
|
||||
BOOL ignore_scaling, BOOL todo)
|
||||
{
|
||||
unsigned char buf[MF_BUFSIZE];
|
||||
UINT mfsize, offset;
|
||||
|
@ -1093,7 +1140,7 @@ static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits,
|
|||
trace("EMF record %u, size %u/record %u, size %u\n",
|
||||
emr1->iType, emr1->nSize, emr2->iType, emr2->nSize);
|
||||
|
||||
if (!match_emf_record(emr1, emr2, desc, todo)) return -1;
|
||||
if (!match_emf_record(emr1, emr2, desc, ignore_scaling, todo)) return -1;
|
||||
|
||||
offset += emr1->nSize;
|
||||
}
|
||||
|
@ -1433,7 +1480,7 @@ static void test_emf_ExtTextOut_on_path(void)
|
|||
* are there, but their contents don't match for different reasons.
|
||||
*/
|
||||
if (compare_emf_bits(hMetafile, EMF_TEXTOUT_ON_PATH_BITS, sizeof(EMF_TEXTOUT_ON_PATH_BITS),
|
||||
"emf_TextOut_on_path", TRUE) != 0)
|
||||
"emf_TextOut_on_path", FALSE, FALSE) != 0)
|
||||
{
|
||||
dump_emf_bits(hMetafile, "emf_TextOut_on_path");
|
||||
dump_emf_records(hMetafile, "emf_TextOut_on_path");
|
||||
|
@ -1488,6 +1535,15 @@ static void translate( POINT *pt, UINT count, const XFORM *xform )
|
|||
}
|
||||
}
|
||||
|
||||
/* Compare rectangles allowing rounding errors */
|
||||
static BOOL is_equal_rect(const RECT *rc1, const RECT *rc2)
|
||||
{
|
||||
return abs(rc1->left - rc2->left) <= 1 &&
|
||||
abs(rc1->top - rc2->top) <= 1 &&
|
||||
abs(rc1->right - rc2->right) <= 1 &&
|
||||
abs(rc1->bottom - rc2->bottom) <= 1;
|
||||
}
|
||||
|
||||
static int CALLBACK clip_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
|
||||
const ENHMETARECORD *emr, int n_objs, LPARAM param)
|
||||
{
|
||||
|
@ -1574,7 +1630,7 @@ static int CALLBACK clip_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
|
|||
translate((POINT *)&rc_transformed, 2, &xform);
|
||||
trace("transformed (%d,%d-%d,%d)\n", rc_transformed.left, rc_transformed.top,
|
||||
rc_transformed.right, rc_transformed.bottom);
|
||||
ok(EqualRect(&rect, &rc_transformed), "rects don't match\n");
|
||||
ok(is_equal_rect(&rect, &rc_transformed), "rects don't match\n");
|
||||
|
||||
rect = *(const RECT *)rgn2.data.Buffer;
|
||||
trace("rect (%d,%d-%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom);
|
||||
|
@ -1582,7 +1638,7 @@ static int CALLBACK clip_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
|
|||
translate((POINT *)&rc_transformed, 2, &xform);
|
||||
trace("transformed (%d,%d-%d,%d)\n", rc_transformed.left, rc_transformed.top,
|
||||
rc_transformed.right, rc_transformed.bottom);
|
||||
ok(EqualRect(&rect, &rc_transformed), "rects don't match\n");
|
||||
ok(is_equal_rect(&rect, &rc_transformed), "rects don't match\n");
|
||||
|
||||
ok(rgn2.data.rdh.dwSize == sizeof(rgn1->data.rdh), "expected sizeof(rdh), got %u\n", rgn2.data.rdh.dwSize);
|
||||
ok(rgn2.data.rdh.iType == RDH_RECTANGLES, "expected RDH_RECTANGLES, got %u\n", rgn2.data.rdh.iType);
|
||||
|
@ -1620,7 +1676,7 @@ static void test_emf_clipping(void)
|
|||
ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
|
||||
|
||||
if (compare_emf_bits(hemf, EMF_CLIPPING, sizeof(EMF_CLIPPING),
|
||||
"emf_clipping", TRUE) != 0)
|
||||
"emf_clipping", FALSE, FALSE) != 0)
|
||||
{
|
||||
dump_emf_bits(hemf, "emf_clipping");
|
||||
dump_emf_records(hemf, "emf_clipping");
|
||||
|
@ -1686,6 +1742,7 @@ static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
|
|||
{
|
||||
HDC hdcMf;
|
||||
HMETAFILE hmf;
|
||||
HENHMETAFILE hemf;
|
||||
BOOL ret;
|
||||
UINT size;
|
||||
LPBYTE pBits;
|
||||
|
@ -1708,7 +1765,9 @@ static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
|
|||
pBits = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
GetMetaFileBitsEx(hmf, size, pBits);
|
||||
DeleteMetaFile(hmf);
|
||||
return SetWinMetaFileBits(size, pBits, NULL, mfp);
|
||||
hemf = SetWinMetaFileBits(size, pBits, NULL, mfp);
|
||||
HeapFree(GetProcessHeap(), 0, pBits);
|
||||
return hemf;
|
||||
}
|
||||
|
||||
static void test_mf_conversions(void)
|
||||
|
@ -1726,7 +1785,7 @@ static void test_mf_conversions(void)
|
|||
hemf = create_converted_emf(&mfp);
|
||||
|
||||
if (compare_emf_bits(hemf, EMF_LINETO_MM_ANISOTROPIC_BITS, sizeof(EMF_LINETO_MM_ANISOTROPIC_BITS),
|
||||
"emf_LineTo MM_ANISOTROPIC", TRUE) != 0)
|
||||
"emf_LineTo MM_ANISOTROPIC", TRUE, FALSE) != 0)
|
||||
{
|
||||
dump_emf_bits(hemf, "emf_LineTo MM_ANISOTROPIC");
|
||||
dump_emf_records(hemf, "emf_LineTo MM_ANISOTROPIC");
|
||||
|
@ -1751,7 +1810,7 @@ static void test_mf_conversions(void)
|
|||
hemf = create_converted_emf(&mfp);
|
||||
|
||||
if (compare_emf_bits(hemf, EMF_LINETO_MM_TEXT_BITS, sizeof(EMF_LINETO_MM_TEXT_BITS),
|
||||
"emf_LineTo MM_TEXT", TRUE) != 0)
|
||||
"emf_LineTo MM_TEXT", TRUE, FALSE) != 0)
|
||||
{
|
||||
dump_emf_bits(hemf, "emf_LineTo MM_TEXT");
|
||||
dump_emf_records(hemf, "emf_LineTo MM_TEXT");
|
||||
|
@ -1771,7 +1830,7 @@ static void test_mf_conversions(void)
|
|||
hemf = create_converted_emf(NULL);
|
||||
|
||||
if (compare_emf_bits(hemf, EMF_LINETO_BITS, sizeof(EMF_LINETO_BITS),
|
||||
"emf_LineTo NULL", TRUE) != 0)
|
||||
"emf_LineTo NULL", TRUE, FALSE) != 0)
|
||||
{
|
||||
dump_emf_bits(hemf, "emf_LineTo NULL");
|
||||
dump_emf_records(hemf, "emf_LineTo NULL");
|
||||
|
@ -1920,12 +1979,17 @@ static void test_SetWinMetaFileBits(void)
|
|||
ok(diffx <= 1, "SetWinMetaFileBits (MM_ISOTROPIC): Reference bounds are not isotropic\n");
|
||||
|
||||
dc = CreateCompatibleDC(NULL);
|
||||
|
||||
/* Allow 1 mm difference (rounding errors) */
|
||||
diffx = rclBoundsAnisotropic.right - GetDeviceCaps(dc, HORZRES) / 2;
|
||||
diffy = rclBoundsAnisotropic.bottom - GetDeviceCaps(dc, VERTRES) / 2;
|
||||
if (diffx < 0) diffx = -diffx;
|
||||
if (diffy < 0) diffy = -diffy;
|
||||
todo_wine
|
||||
{
|
||||
ok(rclBoundsAnisotropic.right == GetDeviceCaps(dc, HORZRES) / 2 - 1 &&
|
||||
rclBoundsAnisotropic.bottom == GetDeviceCaps(dc, VERTRES) / 2 - 1,
|
||||
ok(diffx <= 1 && diffy <= 1,
|
||||
"SetWinMetaFileBits (MM_ANISOTROPIC): Reference bounds: The whole device surface must be used (%dx%d), but got (%dx%d)\n",
|
||||
GetDeviceCaps(dc, HORZRES) / 2 - 1, GetDeviceCaps(dc, VERTRES) / 2 - 1, rclBoundsAnisotropic.right, rclBoundsAnisotropic.bottom);
|
||||
GetDeviceCaps(dc, HORZRES) / 2, GetDeviceCaps(dc, VERTRES) / 2, rclBoundsAnisotropic.right, rclBoundsAnisotropic.bottom);
|
||||
}
|
||||
|
||||
/* Allow 1 mm difference (rounding errors) */
|
||||
|
@ -2012,9 +2076,11 @@ static void test_gdiis(void)
|
|||
pGdiIsMetaFileDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaFileDC");
|
||||
pGdiIsPlayMetafileDC = (void*) GetProcAddress(hgdi32, "GdiIsPlayMetafileDC");
|
||||
|
||||
/* they should all exist or none should exist */
|
||||
if(!pGdiIsMetaPrintDC)
|
||||
if(!pGdiIsMetaPrintDC || !pGdiIsMetaFileDC || !pGdiIsPlayMetafileDC)
|
||||
{
|
||||
win_skip("Needed GdiIs* functions are not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* try with nothing */
|
||||
ok(!pGdiIsMetaPrintDC(NULL), "ismetaprint with NULL parameter\n");
|
||||
|
@ -2053,7 +2119,9 @@ static void test_SetEnhMetaFileBits(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
hemf = SetEnhMetaFileBits(sizeof(data), data);
|
||||
ok(!hemf, "SetEnhMetaFileBits should fail\n");
|
||||
ok(GetLastError() == ERROR_INVALID_DATA, "expected ERROR_INVALID_DATA, got %u\n", GetLastError());
|
||||
ok(GetLastError() == ERROR_INVALID_DATA ||
|
||||
GetLastError() == ERROR_INVALID_PARAMETER, /* Win9x, WinMe */
|
||||
"expected ERROR_INVALID_DATA or ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
|
||||
|
||||
emh = (ENHMETAHEADER *)data;
|
||||
memset(emh, 0, sizeof(*emh));
|
||||
|
@ -2075,15 +2143,23 @@ static void test_SetEnhMetaFileBits(void)
|
|||
emh->nBytes++;
|
||||
SetLastError(0xdeadbeef);
|
||||
hemf = SetEnhMetaFileBits(emh->nBytes, data);
|
||||
ok(!hemf, "SetEnhMetaFileBits should fail\n");
|
||||
/* XP doesn't set error in this case */
|
||||
ok(!hemf ||
|
||||
broken(hemf != NULL), /* Win9x, WinMe */
|
||||
"SetEnhMetaFileBits should fail\n");
|
||||
todo_wine
|
||||
ok(GetLastError() == 0xdeadbeef, "Expected deadbeef, got %u\n", GetLastError());
|
||||
DeleteEnhMetaFile(hemf);
|
||||
|
||||
emh->dSignature = 0;
|
||||
emh->nBytes--;
|
||||
SetLastError(0xdeadbeef);
|
||||
hemf = SetEnhMetaFileBits(emh->nBytes, data);
|
||||
ok(!hemf, "SetEnhMetaFileBits should fail\n");
|
||||
/* XP doesn't set error in this case */
|
||||
ok(!hemf ||
|
||||
broken(hemf != NULL), /* Win9x, WinMe */
|
||||
"SetEnhMetaFileBits should fail\n");
|
||||
todo_wine
|
||||
ok(GetLastError() == 0xdeadbeef, "Expected deadbeef, got %u\n", GetLastError());
|
||||
DeleteEnhMetaFile(hemf);
|
||||
}
|
||||
|
||||
START_TEST(metafile)
|
||||
|
|
|
@ -110,7 +110,9 @@ static void test_DIB_PAL_COLORS(void) {
|
|||
SetPixel( memhdc, 0, 0, setColor );
|
||||
chkColor = RGB( logpalettedata[3].peRed, logpalettedata[3].peGreen, logpalettedata[3].peBlue );
|
||||
getColor = GetPixel( memhdc, 0, 0 );
|
||||
ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );
|
||||
ok( getColor == chkColor ||
|
||||
broken(getColor == 0), /* win9x */
|
||||
"getColor=%08X\n", (UINT)getColor );
|
||||
|
||||
SelectPalette( memhdc, hpalOld, FALSE );
|
||||
DeleteObject( hpal );
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "wine/test.h"
|
||||
|
||||
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
|
||||
#define expect2(expected, alt, got) ok(got == expected || got == alt, \
|
||||
"Expected %.8x or %.8x, got %.8x\n", expected, alt, got)
|
||||
|
||||
static void test_logpen(void)
|
||||
{
|
||||
|
@ -68,7 +70,7 @@ static void test_logpen(void)
|
|||
|
||||
for (i = 0; i < sizeof(pen)/sizeof(pen[0]); i++)
|
||||
{
|
||||
trace("testing style %u\n", pen[i].style);
|
||||
trace("%d: testing style %u\n", i, pen[i].style);
|
||||
|
||||
/********************** cosmetic pens **********************/
|
||||
/* CreatePenIndirect behaviour */
|
||||
|
@ -142,6 +144,7 @@ static void test_logpen(void)
|
|||
/* for some reason XP differentiates PS_NULL here */
|
||||
if (pen[i].style == PS_NULL)
|
||||
{
|
||||
ok(hpen == GetStockObject(NULL_PEN), "hpen should be a stock NULL_PEN\n");
|
||||
ok(size == sizeof(EXTLOGPEN), "GetObject returned %d, error %d\n", size, GetLastError());
|
||||
ok(elp.elpPenStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, elp.elpPenStyle);
|
||||
ok(elp.elpWidth == 0, "expected 0, got %u\n", elp.elpWidth);
|
||||
|
@ -204,7 +207,10 @@ static void test_logpen(void)
|
|||
obj_type = GetObjectType(hpen);
|
||||
/* for some reason XP differentiates PS_NULL here */
|
||||
if (pen[i].style == PS_NULL)
|
||||
{
|
||||
ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
|
||||
ok(hpen == GetStockObject(NULL_PEN), "hpen should be a stock NULL_PEN\n");
|
||||
}
|
||||
else
|
||||
ok(obj_type == OBJ_EXTPEN, "wrong object type %u\n", obj_type);
|
||||
|
||||
|
@ -504,7 +510,7 @@ static void test_ps_userstyle(void)
|
|||
|
||||
pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 0, style);
|
||||
ok(pen == 0, "ExtCreatePen should fail\n");
|
||||
expect(0xdeadbeef, GetLastError());
|
||||
expect2(0xdeadbeef, ERROR_INVALID_PARAMETER, GetLastError());
|
||||
DeleteObject(pen);
|
||||
SetLastError(0xdeadbeef);
|
||||
|
||||
|
|
Loading…
Reference in a new issue