📄 metafile.c
字号:
{
if (buf[i] != bits[i])
diff++;
}
if (diff != 0 && todo)
{
todo_wine
{
ok(diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
desc, mfsize, bsize, diff);
}
return diff;
}
else
{
ok(diff == 0, "%s: mfsize=%d, bsize=%d, diff=%d\n",
desc, mfsize, bsize, diff);
return diff;
}
}
/* Test a blank metafile. May be used as a template for new tests. */
static void test_mf_Blank(void)
{
HDC hdcMetafile;
HMETAFILE hMetafile;
INT caps;
BOOL ret;
INT type;
hdcMetafile = CreateMetaFileA(NULL);
ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
trace("hdcMetafile %p\n", hdcMetafile);
/* Tests on metafile initialization */
caps = GetDeviceCaps (hdcMetafile, TECHNOLOGY);
ok (caps == DT_METAFILE,
"GetDeviceCaps: TECHNOLOGY=%d != DT_METAFILE.\n", caps);
hMetafile = CloseMetaFile(hdcMetafile);
ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
type = GetObjectType(hMetafile);
ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
"mf_blank") != 0)
{
dump_mf_bits(hMetafile, "mf_Blank");
EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
}
ret = DeleteMetaFile(hMetafile);
ok( ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError());
}
static void test_CopyMetaFile(void)
{
HDC hdcMetafile;
HMETAFILE hMetafile, hmf_copy;
BOOL ret;
char temp_path[MAX_PATH];
char mf_name[MAX_PATH];
INT type;
hdcMetafile = CreateMetaFileA(NULL);
ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
trace("hdcMetafile %p\n", hdcMetafile);
hMetafile = CloseMetaFile(hdcMetafile);
ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
type = GetObjectType(hMetafile);
ok(type == OBJ_METAFILE, "CloseMetaFile created object with type %d\n", type);
if (compare_mf_bits (hMetafile, MF_BLANK_BITS, sizeof(MF_BLANK_BITS),
"mf_blank") != 0)
{
dump_mf_bits(hMetafile, "mf_Blank");
EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
}
GetTempPathA(MAX_PATH, temp_path);
GetTempFileNameA(temp_path, "wmf", 0, mf_name);
hmf_copy = CopyMetaFileA(hMetafile, mf_name);
ok(hmf_copy != 0, "CopyMetaFile error %ld\n", GetLastError());
type = GetObjectType(hmf_copy);
ok(type == OBJ_METAFILE, "CopyMetaFile created object with type %d\n", type);
ret = DeleteMetaFile(hMetafile);
ok( ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError());
if (compare_mf_disk_bits(mf_name, MF_BLANK_BITS, sizeof(MF_BLANK_BITS), "mf_blank") != 0)
{
dump_mf_bits(hMetafile, "mf_Blank");
EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
}
ret = DeleteMetaFile(hmf_copy);
ok( ret, "DeleteMetaFile(%p) error %ld\n", hmf_copy, GetLastError());
DeleteFileA(mf_name);
}
static void test_SetMetaFileBits(void)
{
HMETAFILE hmf;
INT type;
BOOL ret;
BYTE buf[256];
METAHEADER *mh;
hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), MF_GRAPHICS_BITS);
ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError());
type = GetObjectType(hmf);
ok(type == OBJ_METAFILE, "SetMetaFileBitsEx created object with type %d\n", type);
if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
{
dump_mf_bits(hmf, "mf_Graphics");
EnumMetaFile(0, hmf, mf_enum_proc, 0);
}
ret = DeleteMetaFile(hmf);
ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError());
/* NULL data crashes XP SP1 */
/*hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), NULL);*/
/* Now with not zero size */
SetLastError(0xdeadbeef);
hmf = SetMetaFileBitsEx(0, MF_GRAPHICS_BITS);
ok(!hmf, "SetMetaFileBitsEx should fail\n");
ok(GetLastError() == ERROR_INVALID_DATA, "wrong error %ld\n", GetLastError());
/* Now with not even size */
SetLastError(0xdeadbeef);
hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS) - 1, MF_GRAPHICS_BITS);
ok(!hmf, "SetMetaFileBitsEx should fail\n");
ok(GetLastError() == 0xdeadbeef /* XP SP1 */, "wrong error %ld\n", GetLastError());
/* Now with zeroed out or faked some header fields */
assert(sizeof(buf) >= sizeof(MF_GRAPHICS_BITS));
memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
mh = (METAHEADER *)buf;
/* corruption of any of the below fields leads to a failure */
mh->mtType = 0;
mh->mtVersion = 0;
mh->mtHeaderSize = 0;
SetLastError(0xdeadbeef);
hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
ok(!hmf, "SetMetaFileBitsEx should fail\n");
ok(GetLastError() == ERROR_INVALID_DATA, "wrong error %ld\n", GetLastError());
/* Now with corrupted mtSize field */
memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
mh = (METAHEADER *)buf;
/* corruption of mtSize doesn't lead to a failure */
mh->mtSize *= 2;
hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError());
if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
{
dump_mf_bits(hmf, "mf_Graphics");
EnumMetaFile(0, hmf, mf_enum_proc, 0);
}
ret = DeleteMetaFile(hmf);
ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError());
/* Now with zeroed out mtSize field */
memcpy(buf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS));
mh = (METAHEADER *)buf;
/* zeroing mtSize doesn't lead to a failure */
mh->mtSize = 0;
hmf = SetMetaFileBitsEx(sizeof(MF_GRAPHICS_BITS), buf);
ok(hmf != 0, "SetMetaFileBitsEx error %ld\n", GetLastError());
if (compare_mf_bits(hmf, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS), "mf_Graphics") != 0)
{
dump_mf_bits(hmf, "mf_Graphics");
EnumMetaFile(0, hmf, mf_enum_proc, 0);
}
ret = DeleteMetaFile(hmf);
ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError());
}
/* Simple APIs from mfdrv/graphics.c
*/
static void test_mf_Graphics(void)
{
HDC hdcMetafile;
HMETAFILE hMetafile;
POINT oldpoint;
BOOL ret;
hdcMetafile = CreateMetaFileA(NULL);
ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
trace("hdcMetafile %p\n", hdcMetafile);
ret = MoveToEx(hdcMetafile, 1, 1, NULL);
ok( ret, "MoveToEx error %ld.\n", GetLastError());
ret = LineTo(hdcMetafile, 2, 2);
ok( ret, "LineTo error %ld.\n", GetLastError());
ret = MoveToEx(hdcMetafile, 1, 1, &oldpoint);
ok( ret, "MoveToEx error %ld.\n", GetLastError());
/* oldpoint gets garbage under Win XP, so the following test would
* work under Wine but fails under Windows:
*
* ok((oldpoint.x == 2) && (oldpoint.y == 2),
* "MoveToEx: (x, y) = (%ld, %ld), should be (2, 2).\n",
* oldpoint.x, oldpoint.y);
*/
ret = Ellipse(hdcMetafile, 0, 0, 2, 2);
ok( ret, "Ellipse error %ld.\n", GetLastError());
hMetafile = CloseMetaFile(hdcMetafile);
ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
if (compare_mf_bits (hMetafile, MF_GRAPHICS_BITS, sizeof(MF_GRAPHICS_BITS),
"mf_Graphics") != 0)
{
dump_mf_bits(hMetafile, "mf_Graphics");
EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
}
ret = DeleteMetaFile(hMetafile);
ok( ret, "DeleteMetaFile(%p) error %ld\n",
hMetafile, GetLastError());
}
static void test_mf_PatternBrush(void)
{
HDC hdcMetafile;
HMETAFILE hMetafile;
LOGBRUSH *orig_lb;
HBRUSH hBrush;
BOOL ret;
orig_lb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGBRUSH));
orig_lb->lbStyle = BS_PATTERN;
orig_lb->lbColor = RGB(0, 0, 0);
orig_lb->lbHatch = (ULONG_PTR)CreateBitmap (8, 8, 1, 1, SAMPLE_PATTERN_BRUSH);
ok((HBITMAP)orig_lb->lbHatch != NULL, "CreateBitmap error %ld.\n", GetLastError());
hBrush = CreateBrushIndirect (orig_lb);
ok(hBrush != 0, "CreateBrushIndirect error %ld\n", GetLastError());
hdcMetafile = CreateMetaFileA(NULL);
ok(hdcMetafile != 0, "CreateMetaFileA error %ld\n", GetLastError());
trace("hdcMetafile %p\n", hdcMetafile);
hBrush = SelectObject(hdcMetafile, hBrush);
ok(hBrush != 0, "SelectObject error %ld.\n", GetLastError());
hMetafile = CloseMetaFile(hdcMetafile);
ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
ok(!GetObjectType(hdcMetafile), "CloseMetaFile has to destroy metafile hdc\n");
if (compare_mf_bits (hMetafile, MF_PATTERN_BRUSH_BITS, sizeof(MF_PATTERN_BRUSH_BITS),
"mf_Pattern_Brush") != 0)
{
dump_mf_bits(hMetafile, "mf_Pattern_Brush");
EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
}
ret = DeleteMetaFile(hMetafile);
ok( ret, "DeleteMetaFile error %ld\n", GetLastError());
ret = DeleteObject(hBrush);
ok( ret, "DeleteObject(HBRUSH) error %ld\n", GetLastError());
ret = DeleteObject((HBITMAP)orig_lb->lbHatch);
ok( ret, "DeleteObject(HBITMAP) error %ld\n",
GetLastError());
HeapFree (GetProcessHeap(), 0, orig_lb);
}
static void test_mf_ExtTextOut_on_path(void)
{
HDC hdcMetafile;
HMETAFILE hMetafile;
BOOL ret;
static const INT dx[4] = { 3, 5, 8, 12 };
hdcMetafile = CreateMetaFileA(NULL);
ok(hdcMetafile != 0, "CreateMetaFileA(NULL) error %ld\n", GetLastError());
trace("hdcMetafile %p\n", hdcMetafile);
ret = BeginPath(hdcMetafile);
ok(!ret, "BeginPath on metafile DC should fail\n");
ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
ok(ret, "ExtTextOut error %ld\n", GetLastError());
ret = EndPath(hdcMetafile);
ok(!ret, "EndPath on metafile DC should fail\n");
hMetafile = CloseMetaFile(hdcMetafile);
ok(hMetafile != 0, "CloseMetaFile error %ld\n", GetLastError());
if (compare_mf_bits(hMetafile, MF_TEXTOUT_ON_PATH_BITS, sizeof(MF_TEXTOUT_ON_PATH_BITS),
"mf_TextOut_on_path") != 0)
{
dump_mf_bits(hMetafile, "mf_TextOut_on_path");
EnumMetaFile(0, hMetafile, mf_enum_proc, 0);
}
ret = DeleteMetaFile(hMetafile);
ok(ret, "DeleteMetaFile(%p) error %ld\n", hMetafile, GetLastError());
}
static void test_emf_ExtTextOut_on_path(void)
{
HWND hwnd;
HDC hdcDisplay, hdcMetafile;
HENHMETAFILE hMetafile;
BOOL ret;
static const INT dx[4] = { 3, 5, 8, 12 };
/* Win9x doesn't play EMFs on invisible windows */
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
0, 0, 200, 200, 0, 0, 0, NULL);
ok(hwnd != 0, "CreateWindowExA error %ld\n", GetLastError());
hdcDisplay = GetDC(hwnd);
ok(hdcDisplay != 0, "GetDC error %ld\n", GetLastError());
hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
ok(hdcMetafile != 0, "CreateEnhMetaFileA error %ld\n", GetLastError());
ret = BeginPath(hdcMetafile);
ok(ret, "BeginPath error %ld\n", GetLastError());
ret = ExtTextOutA(hdcMetafile, 11, 22, 0, NULL, "Test", 4, dx);
ok(ret, "ExtTextOut error %ld\n", GetLastError());
ret = EndPath(hdcMetafile);
ok(ret, "EndPath error %ld\n", GetLastError());
hMetafile = CloseEnhMetaFile(hdcMetafile);
ok(hMetafile != 0, "CloseEnhMetaFile error %ld\n", GetLastError());
/* this doesn't succeed yet: EMF has correct size, all EMF records
* 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)
{
dump_emf_bits(hMetafile, "emf_TextOut_on_path");
dump_emf_records(hMetafile, "emf_TextOut_on_path");
}
ret = DeleteEnhMetaFile(hMetafile);
ok(ret, "DeleteEnhMetaFile error %ld\n", GetLastError());
ret = ReleaseDC(hwnd, hdcDisplay);
ok(ret, "ReleaseDC error %ld\n", GetLastError());
DestroyWindow(hwnd);
}
static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
{
LPMETAFILEPICT lpMFP = (LPMETAFILEPICT)lpData;
POINT mapping[2] = { { 0, 0 }, { 10, 10 } };
/* When using MM_TEXT Win9x does not update the mapping mode
* until a record is played which actually outputs something */
PlayEnhMetaFileRecord(hdc, lpHTable, lpEMFR, nObj);
LPtoDP(hdc, mapping, 2);
trace("Meta record: iType %ld, nSize %ld, (%ld,%ld)-(%ld,%ld)\n",
lpEMFR->iType, lpEMFR->nSize,
mapping[0].x, mapping[0].y, mapping[1].x, mapping[1].y);
if (lpEMFR->iType == EMR_LINETO)
{
INT x0, y0, x1, y1;
if (!lpMFP || lpMFP->mm == MM_TEXT)
{
x0 = 0;
y0 = 0;
x1 = (INT)floor(10 * 100.0 / LINE_X + 0.5);
y1 = (INT)floor(10 * 100.0 / LINE_Y + 0.5);
}
else
{
ok(lpMFP->mm == MM_ANISOTROPIC, "mm=%ld\n", lpMFP->mm);
x0 = MulDiv(0, GetDeviceCaps(hdc, HORZSIZE) * 100, GetDeviceCaps(hdc, HORZRES));
y0 = MulDiv(0, GetDeviceCaps(hdc, VERTSIZE) * 100, GetDeviceCaps(hdc, VERTRES));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -