From: Stefan Dösinger stefan@codeweavers.com
--- dlls/gdi32/tests/metafile.c | 106 ++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index ab7882f9641..a1c8ede04dc 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -4556,6 +4556,111 @@ static void test_mf_select(void) ok(ret, "DeleteMetaFile(%p) error %ld\n", hmf, GetLastError()); }
+static void test_emf_extpen(void) +{ + static const DWORD user_style[3] = { 0xabc, 0xdef, 0x888 }; + HENHMETAFILE hemf; + HPEN pen, pen2; + LOGBRUSH brush; + HGDIOBJ obj; + DWORD size; + BOOL ret; + HDC hdc; + + /* EMREXTCREATEPEN has two pitfalls: + * + * 1) EXTLOGPEN contains a pointer-sized integer. Metafiles always use the + * 32 bit version of this structure. + * + * 2) Native adds an extra 4 bytes to the EXTLOGPEN32 structure, presumably + * because someone forgot to account for the elpStyleEntry[1] dummy array. + * This is filled with zeroes and at the end of the struct, so it only + * matters when you make assumptions about the metafile or entry size. */ + static const unsigned char extpen_bits[] = + { + 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe9, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff, + 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, + 0x38, 0x01, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x05, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x00, + 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00, + 0x80, 0xa9, 0x03, 0x00, 0x5f, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x45, 0x67, 0x89, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x34, 0x56, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xbc, 0x0a, 0x00, 0x00, + 0xef, 0x0d, 0x00, 0x00, 0x88, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x80, 0x28, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 + }; + + hdc = CreateEnhMetaFileA(NULL, NULL, NULL, NULL); + ok(hdc != 0, "CreateEnhMetaFileA failed\n"); + + brush.lbStyle = BS_SOLID; + brush.lbColor = RGB(0x45,0x67,0x89); + brush.lbHatch = HS_CROSS; + pen = ExtCreatePen(PS_SOLID, 1, &brush, 0, NULL); + ok(!!pen, "ExtCreatePen failed: %lu\n", GetLastError()); + size = GetObjectW(pen, 0, NULL); + ok(size == offsetof(EXTLOGPEN, elpStyleEntry[0] ), "Got unexpected size %#lx\n", size); + + obj = SelectObject(hdc, pen); + ok(obj == GetStockObject(BLACK_PEN), "pen is not a stock BLACK_PEN: %p\n", obj); + + brush.lbColor = RGB(0x12,0x34,0x56); + pen2 = ExtCreatePen(PS_USERSTYLE, 1, &brush, 3, user_style); + ok(!!pen2, "ExtCreatePen failed: %lu\n", GetLastError()); + size = GetObjectW(pen2, 0, NULL); /* cf pen.c, test_logpen() */ + ok(size == offsetof(EXTLOGPEN, elpStyleEntry[3]), "Got unexpected size %#lx\n", size); + + obj = SelectObject(hdc, pen2); + ok(obj == pen, "Expected pen %p, got %p.\n", obj, pen); + + obj = SelectObject(hdc, GetStockObject(BLACK_PEN)); + ok(obj == pen2, "Expected pen %p, got %p.\n", obj, pen2); + + DeleteObject(pen2); + DeleteObject(pen); + hemf = CloseEnhMetaFile(hdc); + ok(hemf != 0, "CloseEnhMetaFile failed\n"); + + if (compare_emf_bits(hemf, extpen_bits, sizeof(extpen_bits), "emf_extpen", FALSE)) + { + dump_emf_bits(hemf, "emf_extpen"); + dump_emf_records(hemf, "emf_extpen"); + } + + ret = DeleteEnhMetaFile(hemf); + ok(ret, "DeleteEnhMetaFile(%p) error %ld\n", hemf, GetLastError()); +} + + static void test_emf_select(void) { HENHMETAFILE hemf; @@ -10831,6 +10936,7 @@ START_TEST(metafile) test_emf_StretchDIBits(); test_emf_SetDIBitsToDevice(); test_emf_palette(); + test_emf_extpen();
/* For win-format metafiles (mfdrv) */ test_mf_SaveDC();