Ziqing Hui : gdiplus/tests: Add tests for drawing on printer DC.

Alexandre Julliard julliard at winehq.org
Mon Jan 18 17:00:36 CST 2021


Module: wine
Branch: master
Commit: ae7d81317bf7a8cd537ee41e972dad4ad635dd3a
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ae7d81317bf7a8cd537ee41e972dad4ad635dd3a

Author: Ziqing Hui <zhui at codeweavers.com>
Date:   Sat Jan 16 11:17:48 2021 +0800

gdiplus/tests: Add tests for drawing on printer DC.

Signed-off-by: Ziqing Hui <zhui at codeweavers.com>
Signed-off-by: Esme Povirk <esme at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdiplus/tests/graphics.c | 157 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 157 insertions(+)

diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index 2b1628f4e9c..738656b1c63 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -23,6 +23,7 @@
 
 #include "objbase.h"
 #include "gdiplus.h"
+#include "winspool.h"
 #include "wine/test.h"
 
 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (INT)(expected), (INT)(got))
@@ -7071,6 +7072,161 @@ static void test_gdi_interop_hdc(void)
     DeleteObject(hbm);
 }
 
+static HDC create_printer_dc(void)
+{
+    char buffer[260];
+    DWORD len;
+    PRINTER_INFO_2A *pbuf = NULL;
+    DRIVER_INFO_3A *dbuf = NULL;
+    HANDLE hprn = 0;
+    HDC hdc = 0;
+    HMODULE winspool = LoadLibraryA("winspool.drv");
+    BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
+    BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
+    BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
+    BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
+    BOOL (WINAPI *pClosePrinter)(HANDLE);
+
+    pGetDefaultPrinterA = (void *)GetProcAddress(winspool, "GetDefaultPrinterA");
+    pOpenPrinterA = (void *)GetProcAddress(winspool, "OpenPrinterA");
+    pGetPrinterA = (void *)GetProcAddress(winspool, "GetPrinterA");
+    pGetPrinterDriverA = (void *)GetProcAddress(winspool, "GetPrinterDriverA");
+    pClosePrinter = (void *)GetProcAddress(winspool, "ClosePrinter");
+
+    if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
+        goto done;
+
+    len = sizeof(buffer);
+    if (!pGetDefaultPrinterA(buffer, &len)) goto done;
+    if (!pOpenPrinterA(buffer, &hprn, NULL)) goto done;
+
+    pGetPrinterA(hprn, 2, NULL, 0, &len);
+    pbuf = HeapAlloc(GetProcessHeap(), 0, len);
+    if (!pGetPrinterA(hprn, 2, (LPBYTE)pbuf, len, &len)) goto done;
+
+    pGetPrinterDriverA(hprn, NULL, 3, NULL, 0, &len);
+    dbuf = HeapAlloc(GetProcessHeap(), 0, len);
+    if (!pGetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, len, &len)) goto done;
+
+    hdc = CreateDCA(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode);
+    trace("hdc %p for driver '%s' printer '%s' port '%s'\n", hdc,
+          dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName);
+done:
+    HeapFree(GetProcessHeap(), 0, dbuf);
+    HeapFree(GetProcessHeap(), 0, pbuf);
+    if (hprn) pClosePrinter(hprn);
+    if (winspool) FreeLibrary(winspool);
+    return hdc;
+}
+
+static BOOL check_rect_pixels(const DWORD *pixel, const RectF *rect, UINT width, DWORD expected, Point *failed)
+{
+    UINT x, y;
+    BOOL ret = TRUE;
+
+    for (y = (UINT)rect->Y; y < (UINT)(rect->Y + rect->Height); y++)
+    {
+        for (x = (UINT)rect->X; x < (UINT)(rect->X + rect->Width); x++)
+        {
+            if (pixel[x + y * width] != expected)
+            {
+                ret = FALSE;
+                goto done;
+            }
+        }
+    }
+
+done:
+    if (!ret)
+    {
+        failed->X = x;
+        failed->Y = y;
+    }
+    else
+    {
+        failed->X = 0;
+        failed->Y = 0;
+    }
+    return ret;
+}
+
+static void test_printer_dc(void)
+{
+    HDC hdc_printer, hdc;
+    Status status;
+    GpGraphics *graphics;
+    REAL dpi_x, dpi_y, pixel_per_unit_x, pixel_per_unit_y;
+    HBITMAP bitmap;
+    UINT width = 16, height = 16;
+    GpUnit unit;
+    GpSolidFill *brush;
+    DWORD *pixel;
+    BOOL match;
+    RectF rect;
+    Point pt;
+
+    hdc_printer = create_printer_dc();
+    if (!hdc_printer)
+    {
+        skip("could not create a DC for the default printer\n");
+        return;
+    }
+
+    hdc = CreateCompatibleDC(hdc_printer);
+    bitmap = CreateCompatibleBitmap(hdc, width, height);
+    SelectObject(hdc, bitmap);
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+
+    GdipGetPageUnit(graphics, &unit);
+    expect(UnitDisplay, unit);
+
+    GdipGetDpiX(graphics, &dpi_x);
+    GdipGetDpiY(graphics, &dpi_y);
+    expectf((REAL)GetDeviceCaps(hdc, LOGPIXELSX), dpi_x);
+    expectf((REAL)GetDeviceCaps(hdc, LOGPIXELSY), dpi_y);
+
+    /* For graphics created from printer DC, UnitDisplay specifies that a unit is 1/100 inch */
+    pixel_per_unit_x = dpi_x / 100.0;
+    pixel_per_unit_y = dpi_y / 100.0;
+
+    status = GdipCreateSolidFill((ARGB)0xffffffff, &brush);
+    expect(Ok, status);
+
+    status = GdipFillRectangleI(graphics, (GpBrush *)brush, 1, 1, 1, 1);
+    expect(Ok, status);
+
+    pixel = GetBitmapPixelBuffer(hdc, bitmap, width, height);
+
+    /* pixels at (0, 0) should all be 0 */
+    rect.X = 0;
+    rect.Y = 0;
+    rect.Width = pixel_per_unit_x;
+    rect.Height = pixel_per_unit_y;
+    match = check_rect_pixels(pixel, &rect, width, 0, &pt);
+    todo_wine
+    ok(match, "Expected pixel (%u, %u) to be %08x, got %08x\n",
+       pt.X, pt.Y, 0, pixel[pt.X + pt.Y * width]);
+
+    /* pixels at (1, 1) should all be 0x00ffffff */
+    rect.X = pixel_per_unit_x;
+    rect.Y = pixel_per_unit_y;
+    rect.Width = pixel_per_unit_x;
+    rect.Height = pixel_per_unit_y;
+    match = check_rect_pixels(pixel, &rect, width, 0x00ffffff, &pt);
+    todo_wine
+    ok(match, "Expected pixel (%u, %u) to be %08x, got %08x\n",
+       pt.X, pt.Y, 0x00ffffff, pixel[pt.X + pt.Y * width]);
+
+    GdipFree(pixel);
+    GdipDeleteBrush((GpBrush *)brush);
+    GdipDeleteGraphics(graphics);
+    DeleteObject(bitmap);
+    DeleteDC(hdc);
+    DeleteDC(hdc_printer);
+}
+
 START_TEST(graphics)
 {
     struct GdiplusStartupInput gdiplusStartupInput;
@@ -7166,6 +7322,7 @@ START_TEST(graphics)
     test_hdc_caching();
     test_gdi_interop_bitmap();
     test_gdi_interop_hdc();
+    test_printer_dc();
 
     GdiplusShutdown(gdiplusToken);
     DestroyWindow( hwnd );




More information about the wine-cvs mailing list