Author: akhaldi
Date: Sun Jul  3 11:29:52 2016
New Revision: 71779
URL: 
http://svn.reactos.org/svn/reactos?rev=71779&view=rev
Log:
[GDI32_WINETEST] Sync with Wine Staging 1.9.11. CORE-11368 CORE-11331
Modified:
    trunk/rostests/winetests/gdi32/bitmap.c
    trunk/rostests/winetests/gdi32/dc.c
    trunk/rostests/winetests/gdi32/font.c
    trunk/rostests/winetests/gdi32/metafile.c
Modified: trunk/rostests/winetests/gdi32/bitmap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/bitmap.c?…
==============================================================================
--- trunk/rostests/winetests/gdi32/bitmap.c     [iso-8859-1] (original)
+++ trunk/rostests/winetests/gdi32/bitmap.c     [iso-8859-1] Sun Jul  3 11:29:52 2016
@@ -23,15 +23,25 @@
 #include <assert.h>
 #include <string.h>
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
 #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
 #include "wingdi.h"
 #include "winuser.h"
 #include "mmsystem.h"
+#include "wine/winternl.h"
+#ifndef __REACTOS__ /* CORE-11331 */
+#include "wine/ddk/d3dkmthk.h"
+#endif
 #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 *pGdiGradientFill)(HDC,TRIVERTEX*,ULONG,void*,ULONG,ULONG);
 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
@@ -5651,14 +5661,265 @@
     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)
 {
     HMODULE hdll;
     hdll = GetModuleHandleA("gdi32.dll");
-    pGdiAlphaBlend   = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
-    pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
-    pSetLayout       = (void*)GetProcAddress(hdll, "SetLayout");
+#ifndef __REACTOS__ /* CORE-11331 */
+    pD3DKMTCreateDCFromMemory  = (void *)GetProcAddress( hdll,
"D3DKMTCreateDCFromMemory" );
+    pD3DKMTDestroyDCFromMemory = (void *)GetProcAddress( hdll,
"D3DKMTDestroyDCFromMemory" );
+#endif
+    pGdiAlphaBlend             = (void *)GetProcAddress( hdll, "GdiAlphaBlend"
);
+    pGdiGradientFill           = (void *)GetProcAddress( hdll,
"GdiGradientFill" );
+    pSetLayout                 = (void *)GetProcAddress( hdll, "SetLayout" );
     test_createdibitmap();
     test_dibsections();
@@ -5695,4 +5956,7 @@
     test_SetDIBits_RLE8();
     test_SetDIBitsToDevice();
     test_SetDIBitsToDevice_RLE8();
+#ifndef __REACTOS__ /* CORE-11331 */
+    test_D3DKMTCreateDCFromMemory();
+#endif
 }
Modified: trunk/rostests/winetests/gdi32/dc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/dc.c?rev=…
==============================================================================
--- trunk/rostests/winetests/gdi32/dc.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/gdi32/dc.c [iso-8859-1] Sun Jul  3 11:29:52 2016
@@ -2,7 +2,7 @@
  * Unit tests for dc functions
  *
  * 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
  * modify it under the terms of the GNU Lesser General Public
@@ -812,7 +812,6 @@
     ok(ret, "UnregisterClassA failed\n");
     ret = GetObjectType(hdc_test);
-todo_wine
     ok(!ret, "GetObjectType should fail for a deleted DC\n");
     /* CS_OWNDC */
@@ -891,7 +890,7 @@
     ret = GetBoundsRect(hdc, &rect, 0);
     ok(ret == DCB_RESET,
        "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
-    SetRect(&expect, 0, 0, 0, 0);
+    SetRectEmpty(&expect);
     ok(EqualRect(&rect, &expect) ||
        broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
        "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
@@ -986,7 +985,7 @@
        "GetBoundsRect returned %x\n", ret);
     if (ret == DCB_RESET)
     {
-        SetRect(&expect, 0, 0, 0, 0);
+        SetRectEmpty(&expect);
         ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
            rect.left, rect.top, rect.right, rect.bottom);
@@ -995,7 +994,7 @@
         ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n",
ret);
         ret = GetBoundsRect(hdc, &rect, 0);
         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",
            rect.left, rect.top, rect.right, rect.bottom);
     }
@@ -1386,6 +1385,119 @@
     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)
 {
     pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"),
"SetLayout");
@@ -1400,4 +1512,5 @@
     test_desktop_colorres();
     test_gamma();
     test_printer_dc();
-}
+    test_pscript_printer_dc();
+}
Modified: trunk/rostests/winetests/gdi32/font.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/font.c?re…
==============================================================================
--- trunk/rostests/winetests/gdi32/font.c       [iso-8859-1] (original)
+++ trunk/rostests/winetests/gdi32/font.c       [iso-8859-1] Sun Jul  3 11:29:52 2016
@@ -105,6 +105,22 @@
     pGetFontFileData = (void *)GetProcAddress(hgdi32, "GetFontFileData");
     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)
@@ -1016,7 +1032,7 @@
                 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("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)
             {
@@ -2736,24 +2752,22 @@
     ReleaseDC(NULL, hdc);
 }
-#define MAX_ENUM_FONTS 4096
-
 struct enum_font_data
 {
-    int total;
-    LOGFONTA lf[MAX_ENUM_FONTS];
+    int total, size;
+    LOGFONTA *lf;
 };
 struct enum_fullname_data
 {
-    int total;
-    ENUMLOGFONTA elf[MAX_ENUM_FONTS];
+    int total, size;
+    ENUMLOGFONTA *elf;
 };
 struct enum_font_dataW
 {
-    int total;
-    LOGFONTW lf[MAX_ENUM_FONTS];
+    int total, size;
+    LOGFONTW *lf;
 };
 static INT CALLBACK arial_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD
type, LPARAM lParam)
@@ -2771,10 +2785,13 @@
     if (0) /* Disabled to limit console spam */
         trace("enumed font \"%s\", charset %d, height %d, weight %d,
italic %d\n",
               lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight,
lf->lfItalic);
-    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);
+    if (efd->total >= efd->size)
+    {
+        efd->size = max( (efd->total + 1) * 2, 256 );
+        efd->lf = heap_realloc( efd->lf, efd->size * sizeof(*efd->lf) );
+        if (!efd->lf) return 0;
+    }
+    efd->lf[efd->total++] = *lf;
     return 1;
 }
@@ -2794,10 +2811,13 @@
     if (0) /* Disabled to limit console spam */
         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);
-    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);
+    if (efd->total >= efd->size)
+    {
+        efd->size = max( (efd->total + 1) * 2, 256 );
+        efd->lf = heap_realloc( efd->lf, efd->size * sizeof(*efd->lf) );
+        if (!efd->lf) return 0;
+    }
+    efd->lf[efd->total++] = *lf;
     return 1;
 }
@@ -2871,6 +2891,8 @@
         skip("%s is not installed\n", font_name);
         return;
     }
+    memset( &efd, 0, sizeof(efd) );
+    memset( &efdw, 0, sizeof(efdw) );
     hdc = GetDC(0);
@@ -3064,6 +3086,9 @@
     }
     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)
@@ -3093,10 +3118,13 @@
     if (type != TRUETYPE_FONTTYPE) return 1;
-    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);
+    if (efd->total >= efd->size)
+    {
+        efd->size = max( (efd->total + 1) * 2, 256 );
+        efd->lf = heap_realloc( efd->lf, efd->size * sizeof(*efd->lf) );
+        if (!efd->lf) return 0;
+    }
+    efd->lf[efd->total++] = *lf;
     return 1;
 }
@@ -3107,10 +3135,13 @@
     if (type != TRUETYPE_FONTTYPE) return 1;
-    if (efnd->total < MAX_ENUM_FONTS)
-        efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
-    else
-        trace("enum tests invalid; you have more than %d fonts\n",
MAX_ENUM_FONTS);
+    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;
     return 1;
 }
@@ -3144,7 +3175,7 @@
         target.lfCharSet = ANSI_CHARSET;
     }
-    efd.total = 0;
+    memset(&efd, 0, sizeof(efd));
     memset(&enum_font, 0, sizeof(enum_font));
     strcpy(enum_font.lfFaceName, target.lfFaceName);
     enum_font.lfCharSet = DEFAULT_CHARSET;
@@ -3152,15 +3183,14 @@
     ReleaseDC(0, hdc);
     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);
-        return;
-    }
-
-    ok(efd.lf[0].lfCharSet == target.lfCharSet,
-       "(%s) got charset %d expected %d\n",
-       efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, target.lfCharSet);
-
+    else
+        ok(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;
 }
@@ -5215,6 +5245,12 @@
     if (type != TRUETYPE_FONTTYPE) 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;
     return 0;
 }
@@ -5230,6 +5266,12 @@
     if (type != TRUETYPE_FONTTYPE) 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;
     return 0;
 }
@@ -5261,7 +5303,7 @@
     memset(&lf, 0, sizeof(lf));
     lf.lfCharSet = DEFAULT_CHARSET;
-    memset(&efnd, 0, sizeof(efnd));
+    efnd.total = 0;
     strcpy(lf.lfFaceName, "MS Shell Dlg");
     ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg_proc, (LPARAM)&efnd,
0);
     ok(!ret, "MS Shell Dlg should be enumerated\n");
@@ -5271,12 +5313,12 @@
     ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg");
     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);
     ok(ret, "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");
     ret = EnumFontFamiliesExA(hdc, &lf, enum_ms_shell_dlg2_proc, (LPARAM)&efnd,
0);
     ok(!ret, "MS Shell Dlg 2 should be enumerated\n");
@@ -5286,6 +5328,7 @@
     ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg 2");
     ok(ret, "did not expect MS Shell Dlg 2\n");
+    heap_free(efnd.elf);
     DeleteDC(hdc);
 }
@@ -5396,7 +5439,7 @@
     lf.lfItalic = FALSE;
     lf.lfWeight = FW_DONTCARE;
     strcpy(lf.lfFaceName, Family);
-    efnd.total = 0;
+    memset(&efnd, 0, sizeof(efnd));
     EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0);
     if (efnd.total == 0)
         skip("%s is not installed\n", lf.lfFaceName);
@@ -5477,6 +5520,7 @@
         HeapFree(GetProcessHeap(), 0, bufW);
         HeapFree(GetProcessHeap(), 0, bufA);
     }
+    heap_free(efnd.elf);
     DeleteDC(hdc);
 }
@@ -6225,7 +6269,7 @@
     lf.lfQuality = DEFAULT_QUALITY;
     lf.lfItalic = FALSE;
     lf.lfWeight = FW_DONTCARE;
-    efd.total = 0;
+    memset( &efd, 0, sizeof(efd) );
     EnumFontFamiliesExA(hdc, &lf, enum_font_data_proc, (LPARAM)&efd, 0);
     for (i = 0; i < efd.total; i++)
     {
@@ -6239,6 +6283,7 @@
             }
         }
     }
+    heap_free( efd.lf );
     DeleteDC( hdc );
 }
Modified: trunk/rostests/winetests/gdi32/metafile.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/metafile.…
==============================================================================
--- trunk/rostests/winetests/gdi32/metafile.c   [iso-8859-1] (original)
+++ trunk/rostests/winetests/gdi32/metafile.c   [iso-8859-1] Sun Jul  3 11:29:52 2016
@@ -148,6 +148,13 @@
         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(!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++)
         {
             ok(orig_dx[i] == dx[i], "pass %d: dx[%d] (%d) didn't match
%d\n",
@@ -227,6 +234,20 @@
     /* 2. pass custom lpDx */
     ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx);
+    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);
@@ -989,7 +1010,7 @@
 /* with the nominal results. */
 /* Maximum size of sample metafiles in bytes. */
-#define MF_BUFSIZE 512
+#define MF_BUFSIZE 1024
 /* 8x8 bitmap data for a pattern brush */
 static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
@@ -1269,16 +1290,16 @@
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x03, 0x00, 0x00, 0x00, 0x03, 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,
-    0xa0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x64, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x23, 0x04, 0x00, 0x00, 0x3b, 0x02, 0x00, 0x00,
-    0x75, 0x01, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x08, 0xb1, 0x05, 0x00,
-    0x28, 0x11, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+    0x80, 0x07, 0x00, 0x00, 0xb0, 0x04, 0x00, 0x00,
+    0xfc, 0x01, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+    0x30, 0xda, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00,
     0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -1314,9 +1335,34 @@
     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
+    0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00,
+    0xc4, 0x00, 0x00, 0x00, 0x00, 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[] =
@@ -1409,6 +1455,97 @@
     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
  * new test functions.
  */
@@ -1757,6 +1894,14 @@
        broken(emh1->nSize - diff_nt4 == emh2->nSize) ||
        broken(emh1->nSize - diff_9x == 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->nBytes == emh2->nBytes ||
        broken(emh1->nBytes - diff_nt4 == emh2->nBytes) ||
@@ -1805,6 +1950,7 @@
         0,      /* biClrImportant */
     };
     void *bits;
+    XFORM xform;
     BOOL ret;
     hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL);
@@ -1812,6 +1958,7 @@
     hdcBitmap = CreateCompatibleDC(hdcDisplay);
     ok( hdcBitmap != 0, "CreateCompatibleDC failed\n" );
+    ok(SetGraphicsMode(hdcBitmap, GM_ADVANCED), "SetGraphicsMode failed\n");
     bmih.biXPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSX), 100, 3937);
     bmih.biYPelsPerMeter = MulDiv(GetDeviceCaps(hdcDisplay, LOGPIXELSY), 100, 3937);
     hBitmap = CreateDIBSection(hdcDisplay, (const BITMAPINFO *)&bmih,
@@ -1829,6 +1976,19 @@
     ok( ret, "BitBlt(SRCCOPY) failed\n" );
     ret = BitBlt(hdcMetafile, 0, 0, BMP_DIM, BMP_DIM, 0, 0, 0, WHITENESS);
     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);
     ok( hMetafile != 0, "CloseEnhMetaFile failed\n" );
@@ -2775,6 +2935,63 @@
     DeleteMetaFile(hmf);
     ReleaseDC(hwnd, hdc);
     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)
@@ -3483,16 +3700,16 @@
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     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,
-    0xf8, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
+    0x0c, 0x02, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x80, 0x07, 0x00, 0x00, 0xd3, 0x03, 0x00, 0x00,
-    0xfc, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
-    0xd3, 0xf3, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
+    0x80, 0x07, 0x00, 0x00, 0x3e, 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, 0x3b, 0x00, 0x00, 0x00,
     0x08, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
     0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
     0x32, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
@@ -3506,14 +3723,51 @@
     0x32, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
     0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
     0x0a, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
-    0x13, 0x00, 0x00, 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
+    0x13, 0x00, 0x00, 0x00, 0x2d, 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, 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)
 {
+    POINT pts[4] = {{10, 10}, {20, 10}, {10, 20}, {20, 20}};
+    DWORD counts[2] = {2, 2};
     HDC hdcMetafile;
     HENHMETAFILE hemf;
     BOOL ret;
@@ -3523,7 +3777,8 @@
     hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
     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);
     ok( ret, "MoveToEx error %d.\n", GetLastError());
     ret = LineTo(hdcMetafile, 50, 150);
@@ -3535,10 +3790,17 @@
     ret = LineTo(hdcMetafile, 50, 50);
     ok( ret, "LineTo error %d.\n", GetLastError());
     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);
     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);
     ok(hemf != 0, "CloseEnhMetaFile error %d\n", GetLastError());
@@ -3550,6 +3812,104 @@
     }
     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)
@@ -3566,6 +3926,8 @@
     test_emf_clipping();
     test_emf_polybezier();
     test_emf_GetPath();
+    test_emf_PolyPolyline();
+    test_emf_GradientFill();
     /* For win-format metafiles (mfdrv) */
     test_mf_SaveDC();
@@ -3577,6 +3939,7 @@
     test_SetMetaFileBits();
     test_mf_ExtTextOut_on_path();
     test_mf_clipping();
+    test_mf_GetPath();
     /* For metafile conversions */
     test_mf_conversions();