[GDI32_WINETEST] Sync with Wine Staging 1.9.11. CORE-11368 CORE-11331

svn path=/trunk/; revision=71779
This commit is contained in:
Amine Khaldi 2016-07-03 11:29:52 +00:00
parent b5f83611ac
commit 5ed7ca77cb
4 changed files with 853 additions and 68 deletions

View file

@ -23,15 +23,25 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "mmsystem.h" #include "mmsystem.h"
#include "wine/winternl.h"
#ifndef __REACTOS__ /* CORE-11331 */
#include "wine/ddk/d3dkmthk.h"
#endif
#include "wine/test.h" #include "wine/test.h"
#ifndef __REACTOS__ /* CORE-11331 */
static NTSTATUS (WINAPI *pD3DKMTCreateDCFromMemory)( D3DKMT_CREATEDCFROMMEMORY *desc );
static NTSTATUS (WINAPI *pD3DKMTDestroyDCFromMemory)( const D3DKMT_DESTROYDCFROMMEMORY *desc );
#endif
static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION); static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
static BOOL (WINAPI *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG); static BOOL (WINAPI *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout); static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
@ -5651,14 +5661,265 @@ static void test_SetDIBitsToDevice_RLE8(void)
HeapFree( GetProcessHeap(), 0, info ); HeapFree( GetProcessHeap(), 0, info );
} }
#ifndef __REACTOS__ /* CORE-11331 */
static void test_D3DKMTCreateDCFromMemory( void )
{
D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
D3DKMT_CREATEDCFROMMEMORY create_desc;
unsigned int width_bytes;
unsigned int i, x, y, z;
DWORD expected, colour;
BYTE data[12][48];
NTSTATUS status;
HGDIOBJ *bitmap;
DIBSECTION dib;
BOOL fail, ret;
DWORD type;
int size;
static const struct
{
const char *name;
D3DDDIFORMAT format;
unsigned int bit_count;
DWORD mask_r, mask_g, mask_b;
NTSTATUS status;
}
test_data[] =
{
{ "R8G8B8", D3DDDIFMT_R8G8B8, 24, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS },
{ "A8R8G8B8", D3DDDIFMT_A8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS },
{ "X8R8G8B8", D3DDDIFMT_X8R8G8B8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS },
{ "R5G6B5", D3DDDIFMT_R5G6B5, 16, 0x0000f800, 0x000007e0, 0x0000001f, STATUS_SUCCESS },
{ "X1R5G5B5", D3DDDIFMT_X1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, STATUS_SUCCESS },
{ "A1R5G5B5", D3DDDIFMT_A1R5G5B5, 16, 0x00007c00, 0x000003e0, 0x0000001f, STATUS_SUCCESS },
{ "R3G3B2", D3DDDIFMT_R3G3B2, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "A2B10G10R10", D3DDDIFMT_A2B10G10R10, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "A8B8G8R8", D3DDDIFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "X8B8G8R8", D3DDDIFMT_A8B8G8R8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "A2R10G10B10", D3DDDIFMT_A2R10G10B10, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "P8", D3DDDIFMT_P8, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_SUCCESS },
{ "L8", D3DDDIFMT_L8, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "A8L8", D3DDDIFMT_A8L8, 16, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "V8U8", D3DDDIFMT_V8U8, 16, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "Q8W8V8U8", D3DDDIFMT_Q8W8V8U8, 32, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "DXT1", D3DDDIFMT_DXT1, 4, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "DXT2", D3DDDIFMT_DXT2, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "DXT3", D3DDDIFMT_DXT3, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "DXT4", D3DDDIFMT_DXT4, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
{ "DXT5", D3DDDIFMT_DXT5, 8, 0x00000000, 0x00000000, 0x00000000, STATUS_INVALID_PARAMETER },
};
if (!pD3DKMTCreateDCFromMemory)
{
win_skip("D3DKMTCreateDCFromMemory() is not implemented.\n");
return;
}
status = pD3DKMTCreateDCFromMemory( NULL );
ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status);
for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
{
memset( data, 0xaa, sizeof(data) );
create_desc.pMemory = data;
create_desc.Format = test_data[i].format;
create_desc.Width = 9;
create_desc.Height = 7;
create_desc.Pitch = sizeof(*data);
create_desc.hDeviceDc = NULL;
create_desc.pColorTable = NULL;
create_desc.hDc = (void *)0x010baade;
create_desc.hBitmap = (void *)0x020baade;
status = pD3DKMTCreateDCFromMemory( &create_desc );
ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n",
test_data[i].name, status);
create_desc.hDeviceDc = CreateCompatibleDC( NULL );
create_desc.pMemory = NULL;
status = pD3DKMTCreateDCFromMemory( &create_desc );
ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n",
test_data[i].name, status);
create_desc.pMemory = data;
create_desc.Height = 0;
status = pD3DKMTCreateDCFromMemory( &create_desc );
ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n",
test_data[i].name, status);
ok(create_desc.hDc == (void *)0x010baade, "%s: Got unexpected dc %p.\n",
test_data[i].name, create_desc.hDc);
ok(create_desc.hBitmap == (void *)0x020baade, "%s: Got unexpected bitmap %p.\n",
test_data[i].name, create_desc.hBitmap);
create_desc.Height = 7;
create_desc.Width = 0;
status = pD3DKMTCreateDCFromMemory( &create_desc );
ok(status == test_data[i].status, "%s: Got unexpected status %#x, expected %#x.\n",
test_data[i].name, status, test_data[i].status);
if (status == STATUS_SUCCESS)
{
destroy_desc.hDc = create_desc.hDc;
destroy_desc.hBitmap = create_desc.hBitmap;
status = pD3DKMTDestroyDCFromMemory( &destroy_desc );
ok(status == STATUS_SUCCESS, "%s: Got unexpected status %#x.\n", test_data[i].name, status);
create_desc.hDc = (void *)0x010baade;
create_desc.hBitmap = (void *)0x020baade;
}
create_desc.Pitch = 0;
status = pD3DKMTCreateDCFromMemory( &create_desc );
ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n",
test_data[i].name, status);
ok(create_desc.hDc == (void *)0x010baade, "%s: Got unexpected dc %p.\n",
test_data[i].name, create_desc.hDc);
ok(create_desc.hBitmap == (void *)0x020baade, "%s: Got unexpected bitmap %p.\n",
test_data[i].name, create_desc.hBitmap);
create_desc.Width = 9;
create_desc.Pitch = sizeof(*data);
status = pD3DKMTCreateDCFromMemory( &create_desc );
ok(status == test_data[i].status, "%s: Got unexpected status %#x, expected %#x.\n",
test_data[i].name, status, test_data[i].status);
if (status == STATUS_SUCCESS)
{
ok(!!create_desc.hDc, "%s: Got unexpected dc %p.\n",
test_data[i].name, create_desc.hDc);
ok(!!create_desc.hBitmap, "%s: Got unexpected bitmap %p.\n",
test_data[i].name, create_desc.hBitmap);
}
else
{
ok(create_desc.hDc == (void *)0x010baade, "%s: Got unexpected dc %p.\n",
test_data[i].name, create_desc.hDc);
ok(create_desc.hBitmap == (void *)0x020baade, "%s: Got unexpected bitmap %p.\n",
test_data[i].name, create_desc.hBitmap);
continue;
}
type = GetObjectType( create_desc.hDc );
ok(type == OBJ_MEMDC, "%s: Got unexpected object type %#x.\n", test_data[i].name, type);
type = GetObjectType( create_desc.hBitmap );
ok(type == OBJ_BITMAP, "%s: Got unexpected object type %#x.\n", test_data[i].name, type);
bitmap = GetCurrentObject( create_desc.hDc, OBJ_BITMAP );
ok(bitmap == create_desc.hBitmap, "%s: Got unexpected bitmap %p, expected %p.\n",
test_data[i].name, bitmap, create_desc.hBitmap);
size = GetObjectA( bitmap, sizeof(dib), &dib );
ok(size == sizeof(dib), "%s: Got unexpected size %d.\n", test_data[i].name, size);
ok(!dib.dsBm.bmType, "%s: Got unexpected type %#x.\n",
test_data[i].name, dib.dsBm.bmType);
ok(dib.dsBm.bmWidth == create_desc.Width, "%s: Got unexpected width %d.\n",
test_data[i].name, dib.dsBm.bmWidth);
ok(dib.dsBm.bmHeight == create_desc.Height, "%s: Got unexpected height %d.\n",
test_data[i].name, dib.dsBm.bmHeight);
width_bytes = get_dib_stride( create_desc.Width, test_data[i].bit_count );
ok(dib.dsBm.bmWidthBytes == width_bytes, "%s: Got unexpected width bytes %d.\n",
test_data[i].name, dib.dsBm.bmWidthBytes);
ok(dib.dsBm.bmPlanes == 1, "%s: Got unexpected plane count %d.\n",
test_data[i].name, dib.dsBm.bmPlanes);
ok(dib.dsBm.bmBitsPixel == test_data[i].bit_count, "%s: Got unexpected bit count %d.\n",
test_data[i].name, dib.dsBm.bmBitsPixel);
ok(dib.dsBm.bmBits == create_desc.pMemory, "%s: Got unexpected bits %p, expected %p.\n",
test_data[i].name, dib.dsBm.bmBits, create_desc.pMemory);
ok(dib.dsBmih.biSize == sizeof(dib.dsBmih), "%s: Got unexpected size %u.\n",
test_data[i].name, dib.dsBmih.biSize);
ok(dib.dsBmih.biWidth == create_desc.Width, "%s: Got unexpected width %d.\n",
test_data[i].name, dib.dsBmih.biHeight);
ok(dib.dsBmih.biHeight == create_desc.Height, "%s: Got unexpected height %d.\n",
test_data[i].name, dib.dsBmih.biHeight);
ok(dib.dsBmih.biPlanes == 1, "%s: Got unexpected plane count %u.\n",
test_data[i].name, dib.dsBmih.biPlanes);
ok(dib.dsBmih.biBitCount == test_data[i].bit_count, "%s: Got unexpected bit count %u.\n",
test_data[i].name, dib.dsBmih.biBitCount);
ok(dib.dsBmih.biCompression == (test_data[i].bit_count == 16 ? BI_BITFIELDS : BI_RGB),
"%s: Got unexpected compression %#x.\n",
test_data[i].name, dib.dsBmih.biCompression);
ok(!dib.dsBmih.biSizeImage, "%s: Got unexpected image size %u.\n",
test_data[i].name, dib.dsBmih.biSizeImage);
ok(!dib.dsBmih.biXPelsPerMeter, "%s: Got unexpected horizontal resolution %d.\n",
test_data[i].name, dib.dsBmih.biXPelsPerMeter);
ok(!dib.dsBmih.biYPelsPerMeter, "%s: Got unexpected vertical resolution %d.\n",
test_data[i].name, dib.dsBmih.biYPelsPerMeter);
if (test_data[i].format == D3DDDIFMT_P8)
{
ok(dib.dsBmih.biClrUsed == 256, "%s: Got unexpected used colour count %u.\n",
test_data[i].name, dib.dsBmih.biClrUsed);
ok(dib.dsBmih.biClrImportant == 256, "%s: Got unexpected important colour count %u.\n",
test_data[i].name, dib.dsBmih.biClrImportant);
}
else
{
ok(!dib.dsBmih.biClrUsed, "%s: Got unexpected used colour count %u.\n",
test_data[i].name, dib.dsBmih.biClrUsed);
ok(!dib.dsBmih.biClrImportant, "%s: Got unexpected important colour count %u.\n",
test_data[i].name, dib.dsBmih.biClrImportant);
}
ok(dib.dsBitfields[0] == test_data[i].mask_r && dib.dsBitfields[1] == test_data[i].mask_g
&& dib.dsBitfields[2] == test_data[i].mask_b,
"%s: Got unexpected colour masks 0x%08x 0x%08x 0x%08x.\n",
test_data[i].name, dib.dsBitfields[0], dib.dsBitfields[1], dib.dsBitfields[2]);
ok(!dib.dshSection, "%s: Got unexpected section %p.\n", test_data[i].name, dib.dshSection);
ok(!dib.dsOffset, "%s: Got unexpected offset %u.\n", test_data[i].name, dib.dsOffset);
ret = BitBlt( create_desc.hDc, 0, 0, 4, 10, NULL, 0, 0, BLACKNESS );
ok(ret, "Failed to blit.\n");
ret = BitBlt( create_desc.hDc, 1, 1, 2, 2, NULL, 0, 0, WHITENESS );
ok(ret, "Failed to blit.\n");
destroy_desc.hDc = create_desc.hDc;
destroy_desc.hBitmap = create_desc.hBitmap;
status = pD3DKMTDestroyDCFromMemory( NULL );
ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", test_data[i].name, status);
status = pD3DKMTDestroyDCFromMemory( &destroy_desc );
ok(status == STATUS_SUCCESS, "%s: Got unexpected status %#x.\n", test_data[i].name, status);
status = pD3DKMTDestroyDCFromMemory( &destroy_desc );
ok(status == STATUS_INVALID_PARAMETER, "%s: Got unexpected status %#x.\n", test_data[i].name, status);
ret = DeleteDC( create_desc.hDeviceDc );
ok(ret, "Failed to delete dc.\n");
for (y = 0, fail = FALSE; y < 12 && !fail; ++y)
{
for (x = 0; x < sizeof(*data) / (test_data[i].bit_count / 8) && !fail; ++x)
{
for (z = 0, colour = 0; z < test_data[i].bit_count / 8; ++z)
{
colour = colour << 8 | data[y][x * (test_data[i].bit_count / 8) + z];
}
if ((x == 1 || x == 2) && (y == 1 || y == 2))
expected = 0xffffffff >> (32 - test_data[i].bit_count);
else if (x < 4 && y < 7)
expected = 0x00000000;
else
expected = 0xaaaaaaaa >> (32 - test_data[i].bit_count);
ok(colour == expected, "%s: Got unexpected colour 0x%08x at %u, %u, expected 0x%08x.\n",
test_data[i].name, colour, x, y, expected);
if (colour != expected)
fail = TRUE;
}
}
}
}
#endif /* __REACTOS__ */
START_TEST(bitmap) START_TEST(bitmap)
{ {
HMODULE hdll; HMODULE hdll;
hdll = GetModuleHandleA("gdi32.dll"); hdll = GetModuleHandleA("gdi32.dll");
pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend"); #ifndef __REACTOS__ /* CORE-11331 */
pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill"); pD3DKMTCreateDCFromMemory = (void *)GetProcAddress( hdll, "D3DKMTCreateDCFromMemory" );
pSetLayout = (void*)GetProcAddress(hdll, "SetLayout"); pD3DKMTDestroyDCFromMemory = (void *)GetProcAddress( hdll, "D3DKMTDestroyDCFromMemory" );
#endif
pGdiAlphaBlend = (void *)GetProcAddress( hdll, "GdiAlphaBlend" );
pGdiGradientFill = (void *)GetProcAddress( hdll, "GdiGradientFill" );
pSetLayout = (void *)GetProcAddress( hdll, "SetLayout" );
test_createdibitmap(); test_createdibitmap();
test_dibsections(); test_dibsections();
@ -5695,4 +5956,7 @@ START_TEST(bitmap)
test_SetDIBits_RLE8(); test_SetDIBits_RLE8();
test_SetDIBitsToDevice(); test_SetDIBitsToDevice();
test_SetDIBitsToDevice_RLE8(); test_SetDIBitsToDevice_RLE8();
#ifndef __REACTOS__ /* CORE-11331 */
test_D3DKMTCreateDCFromMemory();
#endif
} }

View file

@ -2,7 +2,7 @@
* Unit tests for dc functions * Unit tests for dc functions
* *
* Copyright (c) 2005 Huw Davies * Copyright (c) 2005 Huw Davies
* Copyright (c) 2005 Dmitry Timoshkov * Copyright (c) 2005,2016 Dmitry Timoshkov
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -812,7 +812,6 @@ static void test_DeleteDC(void)
ok(ret, "UnregisterClassA failed\n"); ok(ret, "UnregisterClassA failed\n");
ret = GetObjectType(hdc_test); ret = GetObjectType(hdc_test);
todo_wine
ok(!ret, "GetObjectType should fail for a deleted DC\n"); ok(!ret, "GetObjectType should fail for a deleted DC\n");
/* CS_OWNDC */ /* CS_OWNDC */
@ -891,7 +890,7 @@ static void test_boundsrect(void)
ret = GetBoundsRect(hdc, &rect, 0); ret = GetBoundsRect(hdc, &rect, 0);
ok(ret == DCB_RESET, ok(ret == DCB_RESET,
"Expected GetBoundsRect to return DCB_RESET, got %u\n", ret); "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
SetRect(&expect, 0, 0, 0, 0); SetRectEmpty(&expect);
ok(EqualRect(&rect, &expect) || ok(EqualRect(&rect, &expect) ||
broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */ broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
"Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n", "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
@ -986,7 +985,7 @@ static void test_boundsrect(void)
"GetBoundsRect returned %x\n", ret); "GetBoundsRect returned %x\n", ret);
if (ret == DCB_RESET) if (ret == DCB_RESET)
{ {
SetRect(&expect, 0, 0, 0, 0); SetRectEmpty(&expect);
ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
rect.left, rect.top, rect.right, rect.bottom); rect.left, rect.top, rect.right, rect.bottom);
@ -995,7 +994,7 @@ static void test_boundsrect(void)
ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret); ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
ret = GetBoundsRect(hdc, &rect, 0); ret = GetBoundsRect(hdc, &rect, 0);
ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret); ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
SetRect(&expect, 0, 0, 0, 0); SetRectEmpty(&expect);
ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
rect.left, rect.top, rect.right, rect.bottom); rect.left, rect.top, rect.right, rect.bottom);
} }
@ -1386,6 +1385,119 @@ static void test_printer_dc(void)
DeleteObject( bmp ); DeleteObject( bmp );
} }
static void print_something(HDC hdc)
{
static const char psadobe[10] = "%!PS-Adobe";
char buf[1024], *p;
char temp_path[MAX_PATH], file_name[MAX_PATH];
DOCINFOA di;
DWORD ret;
HANDLE hfile;
GetTempPathA(sizeof(temp_path), temp_path);
GetTempFileNameA(temp_path, "ps", 0, file_name);
di.cbSize = sizeof(di);
di.lpszDocName = "Let's dance";
di.lpszOutput = file_name;
di.lpszDatatype = NULL;
di.fwType = 0;
ret = StartDocA(hdc, &di);
ok(ret > 0, "StartDoc failed: %d\n", ret);
strcpy(buf + 2, "\n% ===> before DOWNLOADHEADER <===\n");
*(WORD *)buf = strlen(buf + 2);
ret = Escape(hdc, POSTSCRIPT_PASSTHROUGH, 0, buf, NULL);
ok(ret == *(WORD *)buf, "POSTSCRIPT_PASSTHROUGH failed: %d\n", ret);
strcpy(buf, "deadbeef");
ret = ExtEscape(hdc, DOWNLOADHEADER, 0, NULL, sizeof(buf), buf );
ok(ret == 1, "DOWNLOADHEADER failed\n");
ok(strcmp(buf, "deadbeef") != 0, "DOWNLOADHEADER failed\n");
strcpy(buf + 2, "\n% ===> after DOWNLOADHEADER <===\n");
*(WORD *)buf = strlen(buf + 2);
ret = Escape(hdc, POSTSCRIPT_PASSTHROUGH, 0, buf, NULL);
ok(ret == *(WORD *)buf, "POSTSCRIPT_PASSTHROUGH failed: %d\n", ret);
ret = EndDoc(hdc);
ok(ret == 1, "EndDoc failed\n");
hfile = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed\n");
memset(buf, 0, sizeof(buf));
ret = ReadFile(hfile, buf, sizeof(buf), &ret, NULL);
ok(ret, "ReadFile failed\n");
CloseHandle(hfile);
/* skip the HP PCL language selector */
buf[sizeof(buf) - 1] = 0;
p = buf;
while (*p)
{
if (!(p[0] == 0x1b && p[1] == '%') && memcmp(p, "@PJL", 4) != 0)
break;
p = strchr(p, '\n');
if (!p) break;
while (*p == '\r' || *p == '\n') p++;
}
ok(p && !memcmp(p, psadobe, sizeof(psadobe)), "wrong signature: %.14s\n", p ? p : buf);
DeleteFileA(file_name);
}
static void test_pscript_printer_dc(void)
{
HDC hdc;
char buf[256];
DWORD query, ret;
hdc = create_printer_dc(100, FALSE);
if (!hdc) return;
if (!is_postscript_printer(hdc))
{
skip("Default printer is not a PostScript device\n");
DeleteDC( hdc );
return;
}
query = GETFACENAME;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
ok(!ret, "GETFACENAME is supported\n");
query = DOWNLOADFACE;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
ok(ret == 1, "DOWNLOADFACE is not supported\n");
query = OPENCHANNEL;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
ok(ret == 1, "OPENCHANNEL is not supported\n");
query = DOWNLOADHEADER;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
ok(ret == 1, "DOWNLOADHEADER is not supported\n");
query = CLOSECHANNEL;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
ok(ret == 1, "CLOSECHANNEL is not supported\n");
query = POSTSCRIPT_PASSTHROUGH;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
ok(ret == 1, "POSTSCRIPT_PASSTHROUGH is not supported\n");
ret = ExtEscape(hdc, GETFACENAME, 0, NULL, sizeof(buf), buf);
ok(ret == 1, "GETFACENAME failed\n");
trace("face name: %s\n", buf);
print_something(hdc);
DeleteDC(hdc);
}
START_TEST(dc) START_TEST(dc)
{ {
pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout"); pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout");
@ -1400,4 +1512,5 @@ START_TEST(dc)
test_desktop_colorres(); test_desktop_colorres();
test_gamma(); test_gamma();
test_printer_dc(); test_printer_dc();
test_pscript_printer_dc();
} }

View file

@ -107,6 +107,22 @@ static void init(void)
system_lang_id = PRIMARYLANGID(GetSystemDefaultLangID()); system_lang_id = PRIMARYLANGID(GetSystemDefaultLangID());
} }
static void *heap_alloc( size_t len )
{
return HeapAlloc( GetProcessHeap(), 0, len );
}
static void *heap_realloc( void *p, size_t len )
{
if (!p) return heap_alloc( len );
return HeapReAlloc( GetProcessHeap(), 0, p, len );
}
static void heap_free( void *p )
{
HeapFree( GetProcessHeap(), 0, p );
}
static INT CALLBACK is_truetype_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam) static INT CALLBACK is_truetype_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
{ {
if (type != TRUETYPE_FONTTYPE) return 1; if (type != TRUETYPE_FONTTYPE) return 1;
@ -1016,7 +1032,7 @@ static void test_bitmap_font_metrics(void)
ok(ret == expected_cs, "got charset %d, expected %d\n", ret, expected_cs); ok(ret == expected_cs, "got charset %d, expected %d\n", ret, expected_cs);
trace("created %s, height %d charset %x dpi %d\n", face_name, tm.tmHeight, tm.tmCharSet, tm.tmDigitizedAspectX); trace("created %s, height %d charset %x dpi %d\n", face_name, tm.tmHeight, tm.tmCharSet, tm.tmDigitizedAspectX);
trace("expected %s, height %d scaled_hight %d, dpi %d\n", fd[i].face_name, height, fd[i].scaled_height, fd[i].dpi); trace("expected %s, height %d scaled_height %d, dpi %d\n", fd[i].face_name, height, fd[i].scaled_height, fd[i].dpi);
if(fd[i].dpi == tm.tmDigitizedAspectX) if(fd[i].dpi == tm.tmDigitizedAspectX)
{ {
@ -2736,24 +2752,22 @@ static void test_GetFontUnicodeRanges(void)
ReleaseDC(NULL, hdc); ReleaseDC(NULL, hdc);
} }
#define MAX_ENUM_FONTS 4096
struct enum_font_data struct enum_font_data
{ {
int total; int total, size;
LOGFONTA lf[MAX_ENUM_FONTS]; LOGFONTA *lf;
}; };
struct enum_fullname_data struct enum_fullname_data
{ {
int total; int total, size;
ENUMLOGFONTA elf[MAX_ENUM_FONTS]; ENUMLOGFONTA *elf;
}; };
struct enum_font_dataW struct enum_font_dataW
{ {
int total; int total, size;
LOGFONTW lf[MAX_ENUM_FONTS]; LOGFONTW *lf;
}; };
static INT CALLBACK arial_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam) static INT CALLBACK arial_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
@ -2771,10 +2785,13 @@ static INT CALLBACK arial_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, D
if (0) /* Disabled to limit console spam */ if (0) /* Disabled to limit console spam */
trace("enumed font \"%s\", charset %d, height %d, weight %d, italic %d\n", trace("enumed font \"%s\", charset %d, height %d, weight %d, italic %d\n",
lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic); lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
if (efd->total < MAX_ENUM_FONTS) if (efd->total >= efd->size)
efd->lf[efd->total++] = *lf; {
else efd->size = max( (efd->total + 1) * 2, 256 );
trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS); efd->lf = heap_realloc( efd->lf, efd->size * sizeof(*efd->lf) );
if (!efd->lf) return 0;
}
efd->lf[efd->total++] = *lf;
return 1; return 1;
} }
@ -2794,10 +2811,13 @@ static INT CALLBACK arial_enum_procw(const LOGFONTW *lf, const TEXTMETRICW *tm,
if (0) /* Disabled to limit console spam */ if (0) /* Disabled to limit console spam */
trace("enumed font %s, charset %d, height %d, weight %d, italic %d\n", trace("enumed font %s, charset %d, height %d, weight %d, italic %d\n",
wine_dbgstr_w(lf->lfFaceName), lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic); wine_dbgstr_w(lf->lfFaceName), lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
if (efd->total < MAX_ENUM_FONTS) if (efd->total >= efd->size)
efd->lf[efd->total++] = *lf; {
else efd->size = max( (efd->total + 1) * 2, 256 );
trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS); efd->lf = heap_realloc( efd->lf, efd->size * sizeof(*efd->lf) );
if (!efd->lf) return 0;
}
efd->lf[efd->total++] = *lf;
return 1; return 1;
} }
@ -2871,6 +2891,8 @@ static void test_EnumFontFamilies(const char *font_name, INT font_charset)
skip("%s is not installed\n", font_name); skip("%s is not installed\n", font_name);
return; return;
} }
memset( &efd, 0, sizeof(efd) );
memset( &efdw, 0, sizeof(efdw) );
hdc = GetDC(0); hdc = GetDC(0);
@ -3064,6 +3086,9 @@ else
} }
ReleaseDC(0, hdc); ReleaseDC(0, hdc);
heap_free( efd.lf );
heap_free( efdw.lf );
} }
static INT CALLBACK enum_multi_charset_font_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam) static INT CALLBACK enum_multi_charset_font_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
@ -3093,10 +3118,13 @@ static INT CALLBACK enum_font_data_proc(const LOGFONTA *lf, const TEXTMETRICA *n
if (type != TRUETYPE_FONTTYPE) return 1; if (type != TRUETYPE_FONTTYPE) return 1;
if (efd->total < MAX_ENUM_FONTS) if (efd->total >= efd->size)
efd->lf[efd->total++] = *lf; {
else efd->size = max( (efd->total + 1) * 2, 256 );
trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS); efd->lf = heap_realloc( efd->lf, efd->size * sizeof(*efd->lf) );
if (!efd->lf) return 0;
}
efd->lf[efd->total++] = *lf;
return 1; return 1;
} }
@ -3107,10 +3135,13 @@ static INT CALLBACK enum_fullname_data_proc(const LOGFONTA *lf, const TEXTMETRIC
if (type != TRUETYPE_FONTTYPE) return 1; if (type != TRUETYPE_FONTTYPE) return 1;
if (efnd->total < MAX_ENUM_FONTS) if (efnd->total >= efnd->size)
efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf; {
else efnd->size = max( (efnd->total + 1) * 2, 256 );
trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS); efnd->elf = heap_realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
if (!efnd->elf) return 0;
}
efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
return 1; return 1;
} }
@ -3144,7 +3175,7 @@ static void test_EnumFontFamiliesEx_default_charset(void)
target.lfCharSet = ANSI_CHARSET; target.lfCharSet = ANSI_CHARSET;
} }
efd.total = 0; memset(&efd, 0, sizeof(efd));
memset(&enum_font, 0, sizeof(enum_font)); memset(&enum_font, 0, sizeof(enum_font));
strcpy(enum_font.lfFaceName, target.lfFaceName); strcpy(enum_font.lfFaceName, target.lfFaceName);
enum_font.lfCharSet = DEFAULT_CHARSET; enum_font.lfCharSet = DEFAULT_CHARSET;
@ -3152,15 +3183,14 @@ static void test_EnumFontFamiliesEx_default_charset(void)
ReleaseDC(0, hdc); ReleaseDC(0, hdc);
trace("'%s' has %d charsets.\n", target.lfFaceName, efd.total); trace("'%s' has %d charsets.\n", target.lfFaceName, efd.total);
if (efd.total < 2) { if (efd.total < 2)
ok(0, "EnumFontFamilies is broken. Expected >= 2, got %d.\n", efd.total); ok(0, "EnumFontFamilies is broken. Expected >= 2, got %d.\n", efd.total);
return; else
} ok(efd.lf[0].lfCharSet == target.lfCharSet,
"(%s) got charset %d expected %d\n",
ok(efd.lf[0].lfCharSet == target.lfCharSet, efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, target.lfCharSet);
"(%s) got charset %d expected %d\n",
efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, target.lfCharSet);
heap_free(efd.lf);
return; return;
} }
@ -5215,6 +5245,12 @@ if (0) /* Disabled to limit console spam */
if (type != TRUETYPE_FONTTYPE) return 1; if (type != TRUETYPE_FONTTYPE) return 1;
if (strcmp(lf->lfFaceName, "MS Shell Dlg") != 0) return 1; if (strcmp(lf->lfFaceName, "MS Shell Dlg") != 0) return 1;
if (efnd->total >= efnd->size)
{
efnd->size = max( (efnd->total + 1) * 2, 256 );
efnd->elf = heap_realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
if (!efnd->elf) return 0;
}
efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf; efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
return 0; return 0;
} }
@ -5230,6 +5266,12 @@ if (0) /* Disabled to limit console spam */
if (type != TRUETYPE_FONTTYPE) return 1; if (type != TRUETYPE_FONTTYPE) return 1;
if (strcmp(lf->lfFaceName, "MS Shell Dlg 2") != 0) return 1; if (strcmp(lf->lfFaceName, "MS Shell Dlg 2") != 0) return 1;
if (efnd->total >= efnd->size)
{
efnd->size = max( (efnd->total + 1) * 2, 256 );
efnd->elf = heap_realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
if (!efnd->elf) return 0;
}
efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf; efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
return 0; return 0;
} }
@ -5261,7 +5303,7 @@ static void test_EnumFonts_subst(void)
memset(&lf, 0, sizeof(lf)); memset(&lf, 0, sizeof(lf));
lf.lfCharSet = DEFAULT_CHARSET; lf.lfCharSet = DEFAULT_CHARSET;
memset(&efnd, 0, sizeof(efnd)); efnd.total = 0;
strcpy(lf.lfFaceName, "MS Shell Dlg"); strcpy(lf.lfFaceName, "MS Shell Dlg");
ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg_proc, (LPARAM)&efnd, 0); ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg_proc, (LPARAM)&efnd, 0);
ok(!ret, "MS Shell Dlg should be enumerated\n"); ok(!ret, "MS Shell Dlg should be enumerated\n");
@ -5271,12 +5313,12 @@ static void test_EnumFonts_subst(void)
ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg"); ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg");
ok(ret, "did not expect MS Shell Dlg\n"); ok(ret, "did not expect MS Shell Dlg\n");
memset(&efnd, 0, sizeof(efnd)); efnd.total = 0;
ret = EnumFontFamiliesExA(hdc, NULL, enum_ms_shell_dlg2_proc, (LPARAM)&efnd, 0); ret = EnumFontFamiliesExA(hdc, NULL, enum_ms_shell_dlg2_proc, (LPARAM)&efnd, 0);
ok(ret, "MS Shell Dlg 2 should not be enumerated\n"); ok(ret, "MS Shell Dlg 2 should not be enumerated\n");
ok(!efnd.total, "MS Shell Dlg 2 should not be enumerated\n"); ok(!efnd.total, "MS Shell Dlg 2 should not be enumerated\n");
memset(&efnd, 0, sizeof(efnd)); efnd.total = 0;
strcpy(lf.lfFaceName, "MS Shell Dlg 2"); strcpy(lf.lfFaceName, "MS Shell Dlg 2");
ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg2_proc, (LPARAM)&efnd, 0); ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg2_proc, (LPARAM)&efnd, 0);
ok(!ret, "MS Shell Dlg 2 should be enumerated\n"); ok(!ret, "MS Shell Dlg 2 should be enumerated\n");
@ -5286,6 +5328,7 @@ static void test_EnumFonts_subst(void)
ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg 2"); ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg 2");
ok(ret, "did not expect MS Shell Dlg 2\n"); ok(ret, "did not expect MS Shell Dlg 2\n");
heap_free(efnd.elf);
DeleteDC(hdc); DeleteDC(hdc);
} }
@ -5396,7 +5439,7 @@ static void test_fullname2_helper(const char *Family)
lf.lfItalic = FALSE; lf.lfItalic = FALSE;
lf.lfWeight = FW_DONTCARE; lf.lfWeight = FW_DONTCARE;
strcpy(lf.lfFaceName, Family); strcpy(lf.lfFaceName, Family);
efnd.total = 0; memset(&efnd, 0, sizeof(efnd));
EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0); EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0);
if (efnd.total == 0) if (efnd.total == 0)
skip("%s is not installed\n", lf.lfFaceName); skip("%s is not installed\n", lf.lfFaceName);
@ -5477,6 +5520,7 @@ static void test_fullname2_helper(const char *Family)
HeapFree(GetProcessHeap(), 0, bufW); HeapFree(GetProcessHeap(), 0, bufW);
HeapFree(GetProcessHeap(), 0, bufA); HeapFree(GetProcessHeap(), 0, bufA);
} }
heap_free(efnd.elf);
DeleteDC(hdc); DeleteDC(hdc);
} }
@ -6225,7 +6269,7 @@ static void test_vertical_order(void)
lf.lfQuality = DEFAULT_QUALITY; lf.lfQuality = DEFAULT_QUALITY;
lf.lfItalic = FALSE; lf.lfItalic = FALSE;
lf.lfWeight = FW_DONTCARE; lf.lfWeight = FW_DONTCARE;
efd.total = 0; memset( &efd, 0, sizeof(efd) );
EnumFontFamiliesExA(hdc, &lf, enum_font_data_proc, (LPARAM)&efd, 0); EnumFontFamiliesExA(hdc, &lf, enum_font_data_proc, (LPARAM)&efd, 0);
for (i = 0; i < efd.total; i++) for (i = 0; i < efd.total; i++)
{ {
@ -6239,6 +6283,7 @@ static void test_vertical_order(void)
} }
} }
} }
heap_free( efd.lf );
DeleteDC( hdc ); DeleteDC( hdc );
} }

View file

@ -148,6 +148,13 @@ static int CALLBACK eto_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n"); ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n"); ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
ok(!emr_ExtTextOutW->rclBounds.left, "emr_ExtTextOutW->rclBounds.left = %d\n",
emr_ExtTextOutW->rclBounds.left);
ok(emr_ExtTextOutW->rclBounds.right != -1, "emr_ExtTextOutW->rclBounds.right = %d\n",
emr_ExtTextOutW->rclBounds.right);
ok(emr_ExtTextOutW->rclBounds.bottom != -1, "emr_ExtTextOutW->rclBounds.bottom = %d\n",
emr_ExtTextOutW->rclBounds.bottom);
for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++) for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++)
{ {
ok(orig_dx[i] == dx[i], "pass %d: dx[%d] (%d) didn't match %d\n", ok(orig_dx[i] == dx[i], "pass %d: dx[%d] (%d) didn't match %d\n",
@ -229,6 +236,20 @@ static void test_ExtTextOut(void)
ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx); ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx);
ok( ret, "ExtTextOutA error %d\n", GetLastError()); ok( ret, "ExtTextOutA error %d\n", GetLastError());
/* 3. pass NULL lprc */
ret = ExtTextOutA(hdcMetafile, 0, 40, 0, NULL, text, lstrlenA(text), NULL);
ok( ret, "ExtTextOutA error %d\n", GetLastError());
/* 4. test with unmatched BeginPath/EndPath calls */
ret = BeginPath(hdcMetafile);
ok( ret, "BeginPath error %d\n", GetLastError());
ret = BeginPath(hdcMetafile);
ok( ret, "BeginPath error %d\n", GetLastError());
ret = EndPath(hdcMetafile);
ok( ret, "BeginPath error %d\n", GetLastError());
ret = ExtTextOutA(hdcMetafile, 0, 60, 0, NULL, text, lstrlenA(text), NULL);
ok( ret, "ExtTextOutA error %d\n", GetLastError());
hFont = SelectObject(hdcMetafile, hFont); hFont = SelectObject(hdcMetafile, hFont);
ret = DeleteObject(hFont); ret = DeleteObject(hFont);
ok( ret, "DeleteObject error %d\n", GetLastError()); ok( ret, "DeleteObject error %d\n", GetLastError());
@ -989,7 +1010,7 @@ static void test_mf_SaveDC(void)
/* with the nominal results. */ /* with the nominal results. */
/* Maximum size of sample metafiles in bytes. */ /* Maximum size of sample metafiles in bytes. */
#define MF_BUFSIZE 512 #define MF_BUFSIZE 1024
/* 8x8 bitmap data for a pattern brush */ /* 8x8 bitmap data for a pattern brush */
static const unsigned char SAMPLE_PATTERN_BRUSH[] = { static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
@ -1269,16 +1290,16 @@ static const unsigned char EMF_BITBLT[] =
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6a, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
0xa0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x64, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x23, 0x04, 0x00, 0x00, 0x3b, 0x02, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00,
0x75, 0x01, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0xb1, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
0x28, 0x11, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x30, 0xda, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00,
0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -1314,9 +1335,34 @@ static const unsigned char EMF_BITBLT[] =
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0xcc, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0a, 0xd7, 0xa3, 0x3b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0x23, 0x3c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
0x94, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x90, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00
}; };
static const unsigned char EMF_DCBRUSH_BITS[] = static const unsigned char EMF_DCBRUSH_BITS[] =
@ -1409,6 +1455,97 @@ static const unsigned char EMF_BEZIER_BITS[] =
0x14, 0x00, 0x00, 0x00 0x14, 0x00, 0x00, 0x00
}; };
static const unsigned char EMF_POLYPOLYLINE_BITS[] =
{
0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x90, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
0x61, 0x01, 0x00, 0x00, 0xc2, 0x02, 0x00, 0x00,
0x7a, 0xd4, 0x13, 0x00, 0xe8, 0x44, 0x00, 0x00,
0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
0x84, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa1, 0x05, 0x00, 0x00, 0x47, 0x03, 0x00, 0x00,
0xfc, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc0, 0xc1, 0x07, 0x00,
0x2c, 0x84, 0x04, 0x00, 0x5a, 0x00, 0x00, 0x00,
0x20, 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, 0x5a, 0x00, 0x00, 0x00,
0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00,
0x5a, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x14, 0x00, 0x64, 0x00, 0xc8, 0x00,
0x07, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
0x00, 0x90, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x90, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00,
0x00, 0x90, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00,
0x90, 0x01, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00
};
static const unsigned char EMF_GRADIENTFILL_BITS[] =
{
0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x2b, 0x01, 0x00, 0x00, 0x35, 0x01, 0x00, 0x00,
0x23, 0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00,
0x31, 0x29, 0x00, 0x00, 0xa3, 0x2a, 0x00, 0x00,
0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
0x0c, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x05, 0x00, 0x00, 0x46, 0x03, 0x00, 0x00,
0xda, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x15, 0x3c, 0x07, 0x00,
0xcb, 0x82, 0x04, 0x00, 0x76, 0x00, 0x00, 0x00,
0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x2b, 0x01, 0x00, 0x00,
0x35, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x00, 0xff, 0x00, 0x80, 0x00, 0x00, 0x01, 0x80,
0xc8, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
0xb4, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00,
0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, 0xf0, 0xde,
0x2c, 0x01, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
0x90, 0x01, 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00
};
/* For debugging or dumping the raw metafiles produced by /* For debugging or dumping the raw metafiles produced by
* new test functions. * new test functions.
*/ */
@ -1757,6 +1894,14 @@ static int compare_emf_bits(const HENHMETAFILE mf, const unsigned char *bits,
broken(emh1->nSize - diff_nt4 == emh2->nSize) || broken(emh1->nSize - diff_nt4 == emh2->nSize) ||
broken(emh1->nSize - diff_9x == emh2->nSize), broken(emh1->nSize - diff_9x == emh2->nSize),
"expected nSize %u, got %u\n", emh1->nSize, emh2->nSize); "expected nSize %u, got %u\n", emh1->nSize, emh2->nSize);
ok(emh1->rclBounds.left == emh2->rclBounds.left, "%s: expected rclBounds.left = %d, got %d\n",
desc, emh1->rclBounds.left, emh2->rclBounds.left);
ok(emh1->rclBounds.top == emh2->rclBounds.top, "%s: expected rclBounds.top = %d, got %d\n",
desc, emh1->rclBounds.top, emh2->rclBounds.top);
ok(emh1->rclBounds.right == emh2->rclBounds.right, "%s: expected rclBounds.right = %d, got %d\n",
desc, emh1->rclBounds.right, emh2->rclBounds.right);
ok(emh1->rclBounds.bottom == emh2->rclBounds.bottom, "%s: expected rclBounds.bottom = %d, got %d\n",
desc, emh1->rclBounds.bottom, emh2->rclBounds.bottom);
ok(emh1->dSignature == emh2->dSignature, "expected dSignature %u, got %u\n", emh1->dSignature, emh2->dSignature); ok(emh1->dSignature == emh2->dSignature, "expected dSignature %u, got %u\n", emh1->dSignature, emh2->dSignature);
ok(emh1->nBytes == emh2->nBytes || ok(emh1->nBytes == emh2->nBytes ||
broken(emh1->nBytes - diff_nt4 == emh2->nBytes) || broken(emh1->nBytes - diff_nt4 == emh2->nBytes) ||
@ -1805,6 +1950,7 @@ static void test_emf_BitBlt(void)
0, /* biClrImportant */ 0, /* biClrImportant */
}; };
void *bits; void *bits;
XFORM xform;
BOOL ret; BOOL ret;
hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL); hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL);
@ -1812,6 +1958,7 @@ static void test_emf_BitBlt(void)
hdcBitmap = CreateCompatibleDC(hdcDisplay); hdcBitmap = CreateCompatibleDC(hdcDisplay);
ok( hdcBitmap != 0, "CreateCompatibleDC failed\n" ); ok( hdcBitmap != 0, "CreateCompatibleDC failed\n" );
ok(SetGraphicsMode(hdcBitmap, GM_ADVANCED), "SetGraphicsMode failed\n");
bmih.biXPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSX), 100, 3937); bmih.biXPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSX), 100, 3937);
bmih.biYPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSY), 100, 3937); bmih.biYPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSY), 100, 3937);
hBitmap = CreateDIBSection(hdcDisplay, (const BITMAPINFO *)&bmih, hBitmap = CreateDIBSection(hdcDisplay, (const BITMAPINFO *)&bmih,
@ -1830,6 +1977,19 @@ static void test_emf_BitBlt(void)
ret = BitBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, 0, 0, 0, WHITENESS); ret = BitBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, 0, 0, 0, WHITENESS);
ok( ret, "BitBlt(WHITENESS) failed\n" ); ok( ret, "BitBlt(WHITENESS) failed\n" );
ok(SetMapMode(hdcBitmap, MM_ANISOTROPIC), "SetMapMode failed\n");
ok(SetWindowOrgEx(hdcBitmap, 0, 0, NULL), "SetWindowOrgEx failed\n");
ok(SetWindowExtEx(hdcBitmap, 400, 400, NULL), "SetWindowExtEx failed\n");
ok(SetViewportOrgEx(hdcBitmap, 0, 0, NULL), "SetViewportOrgEx failed\n");
ok(SetViewportExtEx(hdcBitmap, BMP_DIM, BMP_DIM, NULL), "SetViewportExtEx failed\n");
memset(&xform, 0, sizeof(xform));
xform.eM11 = 0.5;
xform.eM22 = 1.0;
ok(SetWorldTransform(hdcBitmap, &xform), "SetWorldTransform failed\n");
ret = StretchBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, hdcBitmap, 0, 0, 400, 400, SRCCOPY);
ok( ret, "StretchBlt(SRCCOPY) failed\n" );
hMetafile = CloseEnhMetaFile(hdcMetafile); hMetafile = CloseEnhMetaFile(hdcMetafile);
ok( hMetafile != 0, "CloseEnhMetaFile failed\n" ); ok( hMetafile != 0, "CloseEnhMetaFile failed\n" );
@ -2777,6 +2937,63 @@ static void test_mf_clipping(void)
DestroyWindow(hwnd); DestroyWindow(hwnd);
} }
static const unsigned char MF_PATH_BITS[] =
{
0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x2c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x02,
0x32, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00,
0x13, 0x02, 0x96, 0x00, 0x32, 0x00, 0x05, 0x00,
0x00, 0x00, 0x13, 0x02, 0x96, 0x00, 0x96, 0x00,
0x05, 0x00, 0x00, 0x00, 0x13, 0x02, 0x32, 0x00,
0x96, 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x02,
0x32, 0x00, 0x32, 0x00, 0x07, 0x00, 0x00, 0x00,
0x1b, 0x04, 0x14, 0x00, 0x14, 0x00, 0x0a, 0x00,
0x0a, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
};
static void test_mf_GetPath(void)
{
HDC hdc;
HMETAFILE hmf;
BOOL ret;
int size;
SetLastError(0xdeadbeef);
hdc = CreateMetaFileA(NULL);
ok(hdc != 0, "CreateMetaFileA error %d\n", GetLastError());
ret = BeginPath(hdc);
ok(!ret, "BeginPath on metafile DC should fail\n");
ret = MoveToEx(hdc, 50, 50, NULL);
ok( ret, "MoveToEx error %d.\n", GetLastError());
ret = LineTo(hdc, 50, 150);
ok( ret, "LineTo error %d.\n", GetLastError());
ret = LineTo(hdc, 150, 150);
ok( ret, "LineTo error %d.\n", GetLastError());
ret = LineTo(hdc, 150, 50);
ok( ret, "LineTo error %d.\n", GetLastError());
ret = LineTo(hdc, 50, 50);
ok( ret, "LineTo error %d.\n", GetLastError());
Rectangle(hdc, 10, 10, 20, 20);
EndPath(hdc);
size = GetPath(hdc, NULL, NULL, 0);
ok( size == -1, "GetPath returned %d.\n", size);
hmf = CloseMetaFile(hdc);
ok(hmf != 0, "CloseMetaFile error %d\n", GetLastError());
if (compare_mf_bits (hmf, MF_PATH_BITS, sizeof(MF_PATH_BITS), "mf_GetPath") != 0)
{
dump_mf_bits(hmf, "mf_GetPath");
EnumMetaFile(0, hmf, mf_enum_proc, 0);
}
ret = DeleteMetaFile(hmf);
ok( ret, "DeleteMetaFile error %d\n", GetLastError());
}
static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData) static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData)
{ {
LPMETAFILEPICT lpMFP = (LPMETAFILEPICT)lpData; LPMETAFILEPICT lpMFP = (LPMETAFILEPICT)lpData;
@ -3483,16 +3700,16 @@ static const unsigned char EMF_PATH_BITS[] =
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe6, 0xff, 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xea, 0xff, 0xff, 0xff,
0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00, 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
0xf8, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x07, 0x00, 0x00, 0xd3, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x3e, 0x04, 0x00, 0x00,
0xfc, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
0xd3, 0xf3, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
0x32, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
@ -3506,14 +3723,51 @@ static const unsigned char EMF_PATH_BITS[] =
0x32, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
0x1d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
0x1d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x1c, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
0x1d, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00,
0x0a, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00,
0x5a, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x0a, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00,
0x0a, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00,
0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00
}; };
static void test_emf_GetPath(void) static void test_emf_GetPath(void)
{ {
POINT pts[4] = {{10, 10}, {20, 10}, {10, 20}, {20, 20}};
DWORD counts[2] = {2, 2};
HDC hdcMetafile; HDC hdcMetafile;
HENHMETAFILE hemf; HENHMETAFILE hemf;
BOOL ret; BOOL ret;
@ -3523,7 +3777,8 @@ static void test_emf_GetPath(void)
hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL); hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError()); ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
BeginPath(hdcMetafile); ret = BeginPath(hdcMetafile);
ok(ret, "BeginPath error %d\n", GetLastError());
ret = MoveToEx(hdcMetafile, 50, 50, NULL); ret = MoveToEx(hdcMetafile, 50, 50, NULL);
ok( ret, "MoveToEx error %d.\n", GetLastError()); ok( ret, "MoveToEx error %d.\n", GetLastError());
ret = LineTo(hdcMetafile, 50, 150); ret = LineTo(hdcMetafile, 50, 150);
@ -3535,10 +3790,17 @@ static void test_emf_GetPath(void)
ret = LineTo(hdcMetafile, 50, 50); ret = LineTo(hdcMetafile, 50, 50);
ok( ret, "LineTo error %d.\n", GetLastError()); ok( ret, "LineTo error %d.\n", GetLastError());
Rectangle(hdcMetafile, 10, 10, 20, 20); Rectangle(hdcMetafile, 10, 10, 20, 20);
Arc(hdcMetafile, 21, 21, 39, 29, 39, 29, 21, 21);
Chord(hdcMetafile, 21, 21, 39, 29, 39, 29, 21, 21);
Pie(hdcMetafile, 21, 21, 39, 29, 39, 29, 21, 21);
Ellipse(hdcMetafile, 10, 10, 20, 20);
RoundRect(hdcMetafile, 10, 10, 20, 20, 3, 5);
Polyline(hdcMetafile, pts, 4);
PolyPolyline(hdcMetafile, pts, counts, 2);
EndPath(hdcMetafile); EndPath(hdcMetafile);
size = GetPath(hdcMetafile, NULL, NULL, 0); size = GetPath(hdcMetafile, NULL, NULL, 0);
ok( size == 9, "GetPath returned %d.\n", size); todo_wine ok( size == 77, "GetPath returned %d.\n", size);
hemf = CloseEnhMetaFile(hdcMetafile); hemf = CloseEnhMetaFile(hdcMetafile);
ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError()); ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
@ -3552,6 +3814,104 @@ static void test_emf_GetPath(void)
DeleteEnhMetaFile(hemf); DeleteEnhMetaFile(hemf);
} }
static void test_emf_PolyPolyline(void)
{
HDC hdcMetafile;
HENHMETAFILE hemf;
POINT pts[4] = {{10, 20}, {100, 200}, {0x9000,300}, {400, 500}};
DWORD counts[2];
BOOL ret;
SetLastError(0xdeadbeef);
hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
ret = PolyPolyline(hdcMetafile, NULL, NULL, 0);
ok( !ret, "PolyPolyline\n" );
SetLastError( 0xdeadbeef );
counts[0] = 0;
counts[1] = 1;
ret = PolyPolyline(hdcMetafile, pts, counts, 2);
ok( !ret, "PolyPolyline\n" );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "gle %d\n", GetLastError() );
SetLastError( 0xdeadbeef );
counts[0] = 1;
counts[1] = 1;
ret = PolyPolyline(hdcMetafile, pts, counts, 2);
ok( !ret, "PolyPolyline\n" );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "gle %d\n", GetLastError() );
SetLastError( 0xdeadbeef );
counts[0] = 2;
counts[1] = 1;
ret = PolyPolyline(hdcMetafile, pts, counts, 2);
ok( !ret, "PolyPolyline\n" );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "gle %d\n", GetLastError() );
counts[0] = 2;
counts[1] = 2;
ret = PolyPolyline(hdcMetafile, pts, counts, 2);
ok( ret, "PolyPolyline\n" );
hemf = CloseEnhMetaFile(hdcMetafile);
ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
if(compare_emf_bits(hemf, EMF_POLYPOLYLINE_BITS, sizeof(EMF_POLYPOLYLINE_BITS),
"emf_PolyPolyline", FALSE) != 0)
{
dump_emf_bits(hemf, "emf_PolyPolyline");
dump_emf_records(hemf, "emf_PolyPolyline");
}
DeleteEnhMetaFile(hemf);
}
static void test_emf_GradientFill(void)
{
HDC mf;
HENHMETAFILE hemf;
TRIVERTEX v[] =
{
{ 1, 10, 0xff00, 0x8000, 0x0000, 0x8001 },
{ 200, 210, 0x0000, 0x0000, 0xff00, 0xff00 },
{ 180, 190, 0x1234, 0x5678, 0x9abc, 0xdef0 },
{ 300, 310, 0xff00, 0xff00, 0xff00, 0x0000 },
{ 400, 410, 0xff00, 0xff00, 0xff00, 0x0000 }
};
GRADIENT_TRIANGLE tri[] = { { 0, 1, 2 }, { 3, 1, 0 } };
BOOL ret;
mf = CreateEnhMetaFileA( GetDC( 0 ), NULL, NULL, NULL );
ok( mf != 0, "CreateEnhMetaFileA error %d\n", GetLastError() );
/* Don't test the GRADIENT_FILL_RECT_ modes since a Windows bug
* means it allocates three mesh indices rather than two per
* rectangle. This results in uninitialised values being written
* to the EMF which is rather difficult to test against.
*
* Note also that the final vertex here is not required, yet it is
* written to the EMF, but is not considered in the bounds
* calculation.
*/
ret = GdiGradientFill( mf, v, sizeof(v) / sizeof(v[0]), tri, sizeof(tri) / sizeof(tri[0]),
GRADIENT_FILL_TRIANGLE );
ok( ret, "GradientFill\n" );
hemf = CloseEnhMetaFile( mf );
ok( hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError() );
if (compare_emf_bits( hemf, EMF_GRADIENTFILL_BITS, sizeof(EMF_GRADIENTFILL_BITS),
"emf_GradientFill", FALSE ) != 0)
{
dump_emf_bits( hemf, "emf_GradientFill" );
dump_emf_records( hemf, "emf_GradientFill" );
}
DeleteEnhMetaFile( hemf );
}
START_TEST(metafile) START_TEST(metafile)
{ {
init_function_pointers(); init_function_pointers();
@ -3566,6 +3926,8 @@ START_TEST(metafile)
test_emf_clipping(); test_emf_clipping();
test_emf_polybezier(); test_emf_polybezier();
test_emf_GetPath(); test_emf_GetPath();
test_emf_PolyPolyline();
test_emf_GradientFill();
/* For win-format metafiles (mfdrv) */ /* For win-format metafiles (mfdrv) */
test_mf_SaveDC(); test_mf_SaveDC();
@ -3577,6 +3939,7 @@ START_TEST(metafile)
test_SetMetaFileBits(); test_SetMetaFileBits();
test_mf_ExtTextOut_on_path(); test_mf_ExtTextOut_on_path();
test_mf_clipping(); test_mf_clipping();
test_mf_GetPath();
/* For metafile conversions */ /* For metafile conversions */
test_mf_conversions(); test_mf_conversions();