[GDI32_WINETEST] Sync with Wine Staging 1.9.14.
[reactos.git] / rostests / winetests / gdi32 / dc.c
index 5f19370..d248989 100644 (file)
@@ -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
@@ -134,14 +134,12 @@ static void test_savedc_2(void)
     ret = GetClipRgn(hdc, hrgn);
     ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
     ret = GetRgnBox(hrgn, &rc);
-    ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
-       ret, rc.left, rc.top, rc.right, rc.bottom);
+    ok(ret == NULLREGION, "GetRgnBox returned %d %s instead of NULLREGION\n",
+       ret, wine_dbgstr_rect(&rc));
     /*dump_region(hrgn);*/
     SetRect(&rc, 0, 0, 100, 100);
-    ok(EqualRect(&rc, &rc_clip),
-       "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
-       rc.left, rc.top, rc.right, rc.bottom,
-       rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
+    ok(EqualRect(&rc, &rc_clip), "rects are not equal: %s - %s\n", wine_dbgstr_rect(&rc),
+       wine_dbgstr_rect(&rc_clip));
 
     ret = SaveDC(hdc);
     ok(ret == 1, "ret = %d\n", ret);
@@ -162,10 +160,8 @@ static void test_savedc_2(void)
     ret = GetClipBox(hdc, &rc_clip);
     ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
     SetRect(&rc, 0, 0, 50, 50);
-    ok(EqualRect(&rc, &rc_clip),
-       "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
-       rc.left, rc.top, rc.right, rc.bottom,
-       rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
+    ok(EqualRect(&rc, &rc_clip), "rects are not equal: %s - %s\n", wine_dbgstr_rect(&rc),
+       wine_dbgstr_rect(&rc_clip));
 
     ret = RestoreDC(hdc, 1);
     ok(ret, "ret = %d\n", ret);
@@ -173,10 +169,8 @@ static void test_savedc_2(void)
     ret = GetClipBox(hdc, &rc_clip);
     ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION), "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
     SetRect(&rc, 0, 0, 100, 100);
-    ok(EqualRect(&rc, &rc_clip),
-       "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
-       rc.left, rc.top, rc.right, rc.bottom,
-       rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
+    ok(EqualRect(&rc, &rc_clip), "rects are not equal: %s - %s\n", wine_dbgstr_rect(&rc),
+       wine_dbgstr_rect(&rc_clip));
 
     DeleteObject(hrgn);
     ReleaseDC(hwnd, hdc);
@@ -424,9 +418,7 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
         else
             ok( ret || broken(!ret) /* NT4 */, "GetDeviceGammaRamp failed on %s (type %d), error %u\n", descr, GetObjectType( hdc ), GetLastError() );
         type = GetClipBox( hdc, &rect );
-        if (GetObjectType( hdc ) == OBJ_ENHMETADC)
-            todo_wine ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
-        else
+        todo_wine_if (GetObjectType( hdc ) == OBJ_ENHMETADC)
             ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
 
         type = GetBoundsRect( hdc, &rect, 0 );
@@ -434,8 +426,8 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
             "GetBoundsRect returned type %x for %s\n", type, descr );
         if (type == DCB_RESET)
             ok( rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0,
-                "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
-                rect.left, rect.top, rect.right, rect.bottom, type, descr );
+                "GetBoundsRect returned %s type %x for %s\n", wine_dbgstr_rect( &rect ),
+                type, descr );
         type = SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
         ok( type == (DCB_RESET | DCB_DISABLE) || broken(type == (DCB_SET | DCB_ENABLE)) /* XP */,
             "SetBoundsRect returned %x for %s (hdc type %d)\n", type, descr, GetObjectType( hdc ) );
@@ -443,26 +435,44 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
         SetMapMode( hdc, MM_TEXT );
         Rectangle( hdc, 2, 2, 4, 4 );
         type = GetBoundsRect( hdc, &rect, DCB_RESET );
-        if (GetObjectType( hdc ) == OBJ_ENHMETADC || (GetObjectType( hdc ) == OBJ_DC && GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER))
-            todo_wine
-            ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
-                "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
-                rect.left, rect.top, rect.right, rect.bottom, type, descr );
-        else
+        todo_wine_if (GetObjectType( hdc ) == OBJ_ENHMETADC || (GetObjectType( hdc ) == OBJ_DC && GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER))
             ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
-                "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
-                rect.left, rect.top, rect.right, rect.bottom, type, descr );
+                "GetBoundsRect returned %s type %x for %s\n", wine_dbgstr_rect( &rect ),
+                type, descr );
     }
 
     type = GetClipBox( ref_dc, &rect );
     if (type != COMPLEXREGION && type != ERROR)  /* region can be complex on multi-monitor setups */
     {
+        RECT ref_rect;
+
         ok( type == SIMPLEREGION, "GetClipBox returned %d on %s\n", type, descr );
-        ok( rect.left == 0 && rect.top == 0 &&
-            rect.right == GetDeviceCaps( ref_dc, DESKTOPHORZRES ) &&
-            rect.bottom == GetDeviceCaps( ref_dc, DESKTOPVERTRES ),
-            "GetClipBox returned %d,%d,%d,%d on %s\n",
-            rect.left, rect.top, rect.right, rect.bottom, descr );
+        if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY)
+        {
+            todo_wine_if (GetSystemMetrics( SM_CXSCREEN ) != GetSystemMetrics( SM_CXVIRTUALSCREEN ))
+                ok( GetDeviceCaps( ref_dc, DESKTOPHORZRES ) == GetSystemMetrics( SM_CXSCREEN ),
+                    "Got DESKTOPHORZRES %d on %s, expected %d\n",
+                    GetDeviceCaps( ref_dc, DESKTOPHORZRES ), descr, GetSystemMetrics( SM_CXSCREEN ) );
+
+            todo_wine_if (GetSystemMetrics( SM_CYSCREEN ) != GetSystemMetrics( SM_CYVIRTUALSCREEN ))
+                ok( GetDeviceCaps( ref_dc, DESKTOPVERTRES ) == GetSystemMetrics( SM_CYSCREEN ),
+                    "Got DESKTOPVERTRES %d on %s, expected %d\n",
+                    GetDeviceCaps( ref_dc, DESKTOPVERTRES ), descr, GetSystemMetrics( SM_CYSCREEN ) );
+
+            SetRect( &ref_rect, GetSystemMetrics( SM_XVIRTUALSCREEN ), GetSystemMetrics( SM_YVIRTUALSCREEN ),
+                     GetSystemMetrics( SM_XVIRTUALSCREEN ) + GetSystemMetrics( SM_CXVIRTUALSCREEN ),
+                     GetSystemMetrics( SM_YVIRTUALSCREEN ) + GetSystemMetrics( SM_CYVIRTUALSCREEN ) );
+        }
+        else
+        {
+            SetRect( &ref_rect, 0, 0, GetDeviceCaps( ref_dc, DESKTOPHORZRES ),
+                     GetDeviceCaps( ref_dc, DESKTOPVERTRES ) );
+        }
+
+        todo_wine_if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY && GetObjectType( hdc ) != OBJ_ENHMETADC &&
+            (GetSystemMetrics( SM_XVIRTUALSCREEN ) || GetSystemMetrics( SM_YVIRTUALSCREEN )))
+            ok( EqualRect( &rect, &ref_rect ), "GetClipBox returned %s on %s\n",
+                wine_dbgstr_rect( &rect ), descr );
     }
 
     SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_ACCUMULATE );
@@ -472,8 +482,7 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
     /* it may or may not work on non-memory DCs */
     ok( (rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0 && type == DCB_RESET) ||
         (rect.left == 3 && rect.top == 3 && rect.right == 5 && rect.bottom == 5 && type == DCB_SET),
-        "GetBoundsRect returned %d,%d,%d,%d type %x on %s\n",
-        rect.left, rect.top, rect.right, rect.bottom, type, descr );
+        "GetBoundsRect returned %s type %x on %s\n", wine_dbgstr_rect( &rect ), type, descr );
 
     if (GetObjectType( hdc ) == OBJ_MEMDC)
     {
@@ -505,16 +514,15 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
         type = GetClipBox( hdc, &rect );
         ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
         ok( rect.left == 0 && rect.top == 0 && rect.right == 16 && rect.bottom == 16,
-            "GetClipBox returned %d,%d,%d,%d on memdc for %s\n",
-            rect.left, rect.top, rect.right, rect.bottom, descr );
+            "GetClipBox returned %s on memdc for %s\n", wine_dbgstr_rect( &rect ), descr );
 
         SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
         SetMapMode( hdc, MM_TEXT );
         Rectangle( hdc, 5, 5, 12, 14 );
         type = GetBoundsRect( hdc, &rect, DCB_RESET );
         ok( rect.left == 5 && rect.top == 5 && rect.right == 12 && rect.bottom == 14 && type == DCB_SET,
-            "GetBoundsRect returned %d,%d,%d,%d type %x on memdc for %s\n",
-            rect.left, rect.top, rect.right, rect.bottom, type, descr );
+            "GetBoundsRect returned %s type %x on memdc for %s\n", wine_dbgstr_rect( &rect ),
+            type, descr );
 
         SelectObject( hdc, old );
         DeleteObject( dib );
@@ -531,19 +539,19 @@ static void test_CreateCompatibleDC(void)
     HDC hdc, hNewDC, hdcMetafile, screen_dc;
     HBITMAP bitmap;
     INT caps;
-    DEVMODE dm;
+    DEVMODEA dm;
 
     bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
 
-    bRet = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
+    bRet = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
     ok(bRet, "EnumDisplaySettingsEx failed\n");
     dm.u1.s1.dmScale = 200;
     dm.dmFields |= DM_SCALE;
-    hdc = CreateDC( "DISPLAY", NULL, NULL, &dm );
+    hdc = CreateDCA( "DISPLAY", NULL, NULL, &dm );
 
-    screen_dc = CreateDC( "DISPLAY", NULL, NULL, NULL );
+    screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
     test_device_caps( hdc, screen_dc, "display dc", 1 );
-    ResetDC( hdc, &dm );
+    ResetDCA( hdc, &dm );
     test_device_caps( hdc, screen_dc, "display dc", 1 );
     DeleteDC( hdc );
 
@@ -573,7 +581,7 @@ static void test_CreateCompatibleDC(void)
     caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
     ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
     test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
-    ResetDC( hdcMetafile, &dm );
+    ResetDCA( hdcMetafile, &dm );
     test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
     DeleteDC( hNewDC );
     DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
@@ -586,7 +594,7 @@ static void test_CreateCompatibleDC(void)
     caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
     ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
     test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
-    ResetDC( hdcMetafile, &dm );
+    ResetDCA( hdcMetafile, &dm );
     test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
     DeleteMetaFile( CloseMetaFile( hdcMetafile ));
 
@@ -596,11 +604,13 @@ static void test_CreateCompatibleDC(void)
 
 static void test_DC_bitmap(void)
 {
+    PIXELFORMATDESCRIPTOR descr;
     HDC hdc, hdcmem;
     DWORD bits[64];
     HBITMAP hbmp, oldhbmp;
     COLORREF col;
     int i, bitspixel;
+    int ret, ret2;
 
     /* fill bitmap data with b&w pattern */
     for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
@@ -611,7 +621,31 @@ static void test_DC_bitmap(void)
     /* create a memory dc */
     hdcmem = CreateCompatibleDC( hdc);
     ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
-    /* tests */
+
+    /* test DescribePixelFormat with descr == NULL */
+    ret2 = DescribePixelFormat(hdcmem, 0, sizeof(descr), NULL);
+    ok(ret2 > 0, "expected ret2 > 0, got %d\n", ret2);
+    ret = DescribePixelFormat(hdcmem, 1, sizeof(descr), NULL);
+    ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
+    ret = DescribePixelFormat(hdcmem, 0x10000, sizeof(descr), NULL);
+    ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
+
+    /* test DescribePixelFormat with descr != NULL */
+    memset(&descr, 0, sizeof(descr));
+    ret = DescribePixelFormat(hdcmem, 0, sizeof(descr), &descr);
+    ok(ret == 0, "expected ret == 0, got %d\n", ret);
+    ok(descr.nSize == 0, "expected descr.nSize == 0, got %d\n", descr.nSize);
+
+    memset(&descr, 0, sizeof(descr));
+    ret = DescribePixelFormat(hdcmem, 1, sizeof(descr), &descr);
+    ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
+    ok(descr.nSize == sizeof(descr), "expected desc.nSize == sizeof(descr), got %d\n", descr.nSize);
+
+    memset(&descr, 0, sizeof(descr));
+    ret = DescribePixelFormat(hdcmem, 0x10000, sizeof(descr), &descr);
+    ok(ret == 0, "expected ret == 0, got %d\n", ret);
+    ok(descr.nSize == 0, "expected descr.nSize == 0, got %d\n", descr.nSize);
+
     /* test monochrome bitmap: should always work */
     hbmp = CreateBitmap(32, 32, 1, 1, bits);
     ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
@@ -673,7 +707,7 @@ static void test_DeleteDC(void)
 {
     HWND hwnd;
     HDC hdc, hdc_test;
-    WNDCLASSEX cls;
+    WNDCLASSEXA cls;
     int ret;
 
     /* window DC */
@@ -727,7 +761,7 @@ static void test_DeleteDC(void)
     memset(&cls, 0, sizeof(cls));
     cls.cbSize = sizeof(cls);
     cls.style = CS_CLASSDC;
-    cls.hInstance = GetModuleHandle(0);
+    cls.hInstance = GetModuleHandleA(NULL);
     cls.lpszClassName = "Wine class DC";
     cls.lpfnWndProc = DefWindowProcA;
     ret = RegisterClassExA(&cls);
@@ -766,18 +800,17 @@ static void test_DeleteDC(void)
     ret = GetObjectType(hdc_test);
     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
 
-    ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
+    ret = UnregisterClassA("Wine class DC", GetModuleHandleA(NULL));
     ok(ret, "UnregisterClassA failed\n");
 
     ret = GetObjectType(hdc_test);
-todo_wine
     ok(!ret, "GetObjectType should fail for a deleted DC\n");
 
     /* CS_OWNDC */
     memset(&cls, 0, sizeof(cls));
     cls.cbSize = sizeof(cls);
     cls.style = CS_OWNDC;
-    cls.hInstance = GetModuleHandle(0);
+    cls.hInstance = GetModuleHandleA(NULL);
     cls.lpszClassName = "Wine own DC";
     cls.lpfnWndProc = DefWindowProcA;
     ret = RegisterClassExA(&cls);
@@ -811,7 +844,7 @@ todo_wine
 
     DestroyWindow(hwnd);
 
-    ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
+    ret = UnregisterClassA("Wine own DC", GetModuleHandleA(NULL));
     ok(ret, "UnregisterClassA failed\n");
 }
 
@@ -849,11 +882,9 @@ static void test_boundsrect(void)
     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);
-    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",
-       rect.left, rect.top, rect.right, rect.bottom);
+    SetRectEmpty(&expect);
+    ok(EqualRect(&rect, &expect), "Expected output rectangle (0,0)-(0,0), got %s\n",
+       wine_dbgstr_rect(&rect));
 
     ret = GetBoundsRect(NULL, NULL, 0);
     ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
@@ -874,23 +905,20 @@ static void test_boundsrect(void)
     ret = GetBoundsRect(hdc, &rect, 0);
     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
     SetRect(&expect, 10, 20, 40, 50);
-    ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-       rect.left, rect.top, rect.right, rect.bottom);
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     SetMapMode( hdc, MM_ANISOTROPIC );
     SetViewportExtEx( hdc, 2, 2, NULL );
     ret = GetBoundsRect(hdc, &rect, 0);
     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
     SetRect(&expect, 5, 10, 20, 25);
-    ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-       rect.left, rect.top, rect.right, rect.bottom);
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     SetViewportOrgEx( hdc, 20, 30, NULL );
     ret = GetBoundsRect(hdc, &rect, 0);
     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
     SetRect(&expect, -5, -5, 10, 10);
-    ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-       rect.left, rect.top, rect.right, rect.bottom);
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     SetRect(&set_rect, 10, 20, 40, 50);
     ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
@@ -899,16 +927,14 @@ static void test_boundsrect(void)
     ret = GetBoundsRect(hdc, &rect, 0);
     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
     SetRect(&expect, 10, 20, 40, 50);
-    ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-       rect.left, rect.top, rect.right, rect.bottom);
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     SetMapMode( hdc, MM_TEXT );
     SetViewportOrgEx( hdc, 0, 0, NULL );
     ret = GetBoundsRect(hdc, &rect, 0);
     ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
     SetRect(&expect, 40, 70, 100, 130);
-    ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-       rect.left, rect.top, rect.right, rect.bottom);
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     if (pSetLayout)
     {
@@ -916,23 +942,20 @@ static void test_boundsrect(void)
         ret = GetBoundsRect(hdc, &rect, 0);
         ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
         SetRect(&expect, 159, 70, 99, 130);
-        ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-           rect.left, rect.top, rect.right, rect.bottom);
+        ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
         SetRect(&set_rect, 50, 25, 30, 35);
         ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
         ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
         ret = GetBoundsRect(hdc, &rect, 0);
         ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
         SetRect(&expect, 50, 25, 30, 35);
-        ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-           rect.left, rect.top, rect.right, rect.bottom);
+        ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
         pSetLayout( hdc, LAYOUT_LTR );
         ret = GetBoundsRect(hdc, &rect, 0);
         ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
         SetRect(&expect, 149, 25, 169, 35);
-        ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-           rect.left, rect.top, rect.right, rect.bottom);
+        ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     }
 
     /* empty rect resets, except on nt4 */
@@ -944,18 +967,16 @@ static void test_boundsrect(void)
        "GetBoundsRect returned %x\n", ret);
     if (ret == DCB_RESET)
     {
-        SetRect(&expect, 0, 0, 0, 0);
-        ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-           rect.left, rect.top, rect.right, rect.bottom);
+        SetRectEmpty(&expect);
+        ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
         SetRect(&expect, 20, 20, 20, 20);
         ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
         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);
-        ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
-           rect.left, rect.top, rect.right, rect.bottom);
+        SetRectEmpty(&expect);
+        ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     }
 
     SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
@@ -964,47 +985,47 @@ static void test_boundsrect(void)
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 10, 10, 21, 21 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok( EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     SetRect( &rect, 8, 8, 23, 23 );
     expect = rect;
     SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     level = SaveDC( hdc );
     LineTo( hdc, 30, 25 );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 8, 8, 31, 26 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     SetBoundsRect( hdc, NULL, DCB_DISABLE );
     LineTo( hdc, 40, 40 );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 8, 8, 31, 26 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     SetRect( &rect, 6, 6, 30, 30 );
     SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 6, 6, 31, 30 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     RestoreDC( hdc, level );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     LineTo( hdc, 40, 40 );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     SelectObject( hdc, old );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 6, 6, 1, 1 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     SetBoundsRect( hdc, NULL, DCB_ENABLE );
     LineTo( hdc, 50, 40 );
 
@@ -1012,13 +1033,13 @@ static void test_boundsrect(void)
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 6, 6, 51, 41 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     SelectObject( hdc, GetStockObject( NULL_PEN ));
     LineTo( hdc, 50, 50 );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 6, 6, 51, 51 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     memset( buffer, 0, sizeof(buffer) );
     info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
@@ -1033,22 +1054,22 @@ static void test_boundsrect(void)
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 6, 6, 51, 51 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     LineTo( hdc, 55, 30 );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 6, 6, 56, 51 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     LineTo( hdc, 300, 30 );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 6, 6, 256, 51 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
     LineTo( hdc, -300, -300 );
     ret = GetBoundsRect( hdc, &rect, 0 );
     ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
     SetRect( &expect, 0, 0, 256, 51 );
-    ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
+    ok(EqualRect(&rect, &expect), "Got %s\n", wine_dbgstr_rect(&rect));
 
     /* test the wide pen heuristics */
     SetBoundsRect( hdc, NULL, DCB_ENABLE | DCB_RESET );
@@ -1089,10 +1110,8 @@ static void test_boundsrect(void)
         expect.top    = max( expect.top, 0 );
         expect.right  = min( expect.right, 256 );
         expect.bottom = min( expect.bottom, 256 );
-        ok( EqualRect(&rect, &expect),
-            "Got %d,%d,%d,%d expected %d,%d,%d,%d %u/%x/%x\n",
-            rect.left, rect.top, rect.right, rect.bottom,
-            expect.left, expect.top, expect.right, expect.bottom, width, endcap, join );
+        ok(EqualRect(&rect, &expect), "Got %s expected %s %u/%x/%x\n", wine_dbgstr_rect(&rect),
+           wine_dbgstr_rect(&expect), width, endcap, join);
         DeleteObject( SelectObject( hdc, old ));
     }
 
@@ -1262,7 +1281,7 @@ static HDC create_printer_dc(int scale, BOOL reset)
            dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName,
            is_postscript_printer(hdc) ? "" : "NOT " );
 
-    if (reset) ResetDC( hdc, pbuf->pDevMode );
+    if (reset) ResetDCA( hdc, pbuf->pDevMode );
 done:
     HeapFree( GetProcessHeap(), 0, dbuf );
     HeapFree( GetProcessHeap(), 0, pbuf );
@@ -1344,9 +1363,122 @@ static void test_printer_dc(void)
     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( GetModuleHandle("gdi32.dll"), "SetLayout");
+    pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout");
     test_dc_values();
     test_savedc();
     test_savedc_2();
@@ -1358,4 +1490,5 @@ START_TEST(dc)
     test_desktop_colorres();
     test_gamma();
     test_printer_dc();
+    test_pscript_printer_dc();
 }