[GDI+: 3/5] added graphics implementation and tests

Evan Stade estade at gmail.com
Fri Jun 8 15:49:24 CDT 2007


Hi,

The test file is long but unfortunately could hardly be broken up.

Changelog:
*added graphics implementation, test

 dlls/gdiplus/Makefile.in       |    1
 dlls/gdiplus/gdiplus.spec      |   10 +
 dlls/gdiplus/graphics.c        |  115 ++++++++++++
 dlls/gdiplus/tests/Makefile.in |    1
 dlls/gdiplus/tests/graphics.c  |  385 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 507 insertions(+), 5 deletions(-)

-Evan Stade
-------------- next part --------------
diff --git a/dlls/gdiplus/Makefile.in b/dlls/gdiplus/Makefile.in
index 3f57760..a3de5d4 100644
--- a/dlls/gdiplus/Makefile.in
+++ b/dlls/gdiplus/Makefile.in
@@ -8,6 +8,7 @@ IMPORTS   = gdi32 advapi32 kernel32 ntdl
 
 C_SRCS = \
 	gdiplus.c \
+	graphics.c \
 	pen.c
 
 @MAKE_DLL_RULES@
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index 2bb3ba9..dfb4e63 100644
--- a/dlls/gdiplus/gdiplus.spec
+++ b/dlls/gdiplus/gdiplus.spec
@@ -81,8 +81,8 @@
 @ stub GdipCreateFontFromLogfontA
 @ stub GdipCreateFontFromLogfontW
 @ stub GdipCreateFromHDC2
-@ stub GdipCreateFromHDC
-@ stub GdipCreateFromHWND
+@ stdcall GdipCreateFromHDC(ptr ptr)
+@ stdcall GdipCreateFromHWND(ptr ptr)
 @ stub GdipCreateFromHWNDICM
 @ stub GdipCreateHBITMAPFromBitmap
 @ stub GdipCreateHICONFromBitmap
@@ -132,7 +132,7 @@
 @ stub GdipDeleteCustomLineCap
 @ stub GdipDeleteFont
 @ stub GdipDeleteFontFamily
-@ stub GdipDeleteGraphics
+@ stdcall GdipDeleteGraphics(ptr)
 @ stub GdipDeleteMatrix
 @ stub GdipDeletePath
 @ stub GdipDeletePathIter
@@ -175,7 +175,7 @@
 @ stub GdipDrawImageRectRect
 @ stub GdipDrawImageRectRectI
 @ stub GdipDrawLine
-@ stub GdipDrawLineI
+@ stdcall GdipDrawLineI(ptr ptr long long long long)
 @ stub GdipDrawLines
 @ stub GdipDrawLinesI
 @ stub GdipDrawPath
@@ -184,7 +184,7 @@
 @ stub GdipDrawPolygon
 @ stub GdipDrawPolygonI
 @ stub GdipDrawRectangle
-@ stub GdipDrawRectangleI
+@ stdcall GdipDrawRectangleI(ptr ptr long long long long)
 @ stub GdipDrawRectangles
 @ stub GdipDrawRectanglesI
 @ stub GdipDrawString
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
new file mode 100644
index 0000000..d2a4317
--- /dev/null
+++ b/dlls/gdiplus/graphics.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007 Google (Evan Stade)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include <math.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "gdiplus.h"
+#include "gdiplus_private.h"
+#include "wine/debug.h"
+
+GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics)
+{
+    if(hdc == NULL)
+        return OutOfMemory;
+
+    if(graphics == NULL)
+        return InvalidParameter;
+
+    *graphics = (GpGraphics*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
+        sizeof(GpGraphics));
+    (*graphics)->hdc = hdc;
+    (*graphics)->hwnd = NULL;
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics)
+{
+    GpStatus ret;
+
+    if((ret = GdipCreateFromHDC(GetDC(hwnd), graphics)) != Ok)
+        return ret;
+
+    (*graphics)->hwnd = hwnd;
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
+{
+    if(!graphics) return InvalidParameter;
+    if(graphics->hwnd)
+        ReleaseDC(graphics->hwnd, graphics->hdc);
+
+    HeapFree(GetProcessHeap(), 0, graphics);
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1, 
+    INT y1, INT x2, INT y2)
+{
+    HGDIOBJ old_obj;
+
+    if(!pen || !graphics)
+        return InvalidParameter;
+
+    old_obj = SelectObject(graphics->hdc, pen->gdipen);
+    MoveToEx(graphics->hdc, x1, y1, NULL);
+    LineTo(graphics->hdc, x2, y2);
+    SelectObject(graphics->hdc, old_obj);
+
+    return Ok;
+}
+
+GpStatus WINGDIPAPI GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, 
+    INT y, INT width, INT height)
+{
+    LOGBRUSH lb;
+    HPEN hpen;
+    HGDIOBJ old_obj;
+
+    if(!pen || !graphics)
+        return InvalidParameter;
+
+    lb.lbStyle = BS_SOLID;
+    lb.lbColor = pen->color;
+    lb.lbHatch = 0;
+
+    hpen = ExtCreatePen(PS_GEOMETRIC | PS_ENDCAP_SQUARE, (INT) pen->width, 
+        &lb, 0, NULL);
+
+    old_obj = SelectObject(graphics->hdc, hpen);
+
+    /* assume pen aligment centered */
+    MoveToEx(graphics->hdc, x, y, NULL);
+    LineTo(graphics->hdc, x+width, y);
+    LineTo(graphics->hdc, x+width, y+height);
+    LineTo(graphics->hdc, x, y+height);
+    LineTo(graphics->hdc, x, y);
+
+    SelectObject(graphics->hdc, old_obj);
+    DeleteObject(hpen);
+
+    return Ok;
+}
diff --git a/dlls/gdiplus/tests/Makefile.in b/dlls/gdiplus/tests/Makefile.in
index 14bc936..4f3007d 100644
--- a/dlls/gdiplus/tests/Makefile.in
+++ b/dlls/gdiplus/tests/Makefile.in
@@ -6,6 +6,7 @@ TESTDLL   = gdiplus.dll
 IMPORTS   = user32 gdi32 kernel32 gdiplus
 
 CTESTS = \
+	graphics.c \
 	pen.c
 
 @MAKE_TEST_RULES@
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
new file mode 100644
index 0000000..2937e4d
--- /dev/null
+++ b/dlls/gdiplus/tests/graphics.c
@@ -0,0 +1,385 @@
+/*
+ * Unit test suite for graphics
+ *
+ * Copyright (C) 2007 Google (Evan Stade)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "windows.h"
+#include "wingdi.h"
+#include "windef.h"
+#include "winbase.h"
+#include "gdiplus.h"
+#include "wine/test.h"
+
+#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
+
+/* heighth and width of test windows */
+#define WND_SZ (16)
+
+#define SIMPLE_WINDOW_PROC(testname) \
+static LRESULT WINAPI testname##_window_proc(HWND hwnd, UINT msg, WPARAM wparam, \
+    LPARAM lparam) \
+{ \
+    PAINTSTRUCT  ps; \
+    HDC hdc; \
+ \
+    switch (msg) \
+    { \
+        case WM_PAINT: \
+            hdc = BeginPaint(hwnd, &ps); \
+            testname (hwnd, hdc); \
+            EndPaint(hwnd, &ps); \
+            return 0; \
+        default: \
+            return DefWindowProc(hwnd, msg, wparam, lparam); \
+    } \
+}
+
+static const INT drawline_bmp1[192] =
+{0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xddffffff,0xccddbbcc,0xffffffbb,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xddbbccdd,0xccddbbcc,0xffffffbb,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xbbccddff,0xddbbccdd,
+ 0xffffbbcc,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xccddffff,0xbbccddbb,0xffbbccdd,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xddffffff,
+ 0xccddbbcc,0xbbccddbb,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xddbbccdd,0xccddbbcc,0xffffffbb,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xbbccddff,0xddbbccdd,0xffffbbcc,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffbbccdd,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff};
+
+static const INT drawline_bmp2[192] =
+{0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xbbccddff,
+ 0xddbbccdd,0xccddbbcc,0xbbccddbb,0xddbbccdd,0xffffbbcc,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xbbccddff,0xddbbccdd,0xccddbbcc,
+ 0xbbccddbb,0xddbbccdd,0xffffbbcc,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff};
+
+static const INT drawrect_bmp1[192] =
+{0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xddffffff,0xccddbbcc,0xbbccddbb,0xddbbccdd,0xffffbbcc,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xddffffff,0xccddbbcc,0xbbccddbb,0xddbbccdd,0xffffbbcc,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xddffffff,0xccddbbcc,
+ 0xffffffbb,0xddbbccdd,0xffffbbcc,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xddffffff,0xccddbbcc,0xffffffbb,0xddbbccdd,
+ 0xffffbbcc,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xddffffff,0xccddbbcc,0xffffffbb,0xddbbccdd,0xffffbbcc,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xddffffff,
+ 0xccddbbcc,0xbbccddbb,0xddbbccdd,0xffffbbcc,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xddffffff,0xccddbbcc,0xbbccddbb,
+ 0xddbbccdd,0xffffbbcc,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff};
+
+static INT smart_GetDIBits(HDC hdc, HBITMAP hbm, BYTE** buff, INT *bytes,
+    INT bitcount, INT compression, INT imagesize)
+{
+    INT ret;
+    BITMAPINFO bi;
+
+    bi.bmiHeader.biSize         = sizeof(BITMAPINFOHEADER);
+    bi.bmiHeader.biHeight       = 0;
+    bi.bmiHeader.biWidth        = 0;
+    bi.bmiHeader.biPlanes       = 1;
+    bi.bmiHeader.biBitCount     = 0;
+    bi.bmiHeader.biCompression  = 0;
+
+    ret = GetDIBits(hdc, hbm, 0, 0, NULL, &bi, DIB_RGB_COLORS);
+    assert(ret);
+
+    bi.bmiHeader.biBitCount     = bitcount;
+    bi.bmiHeader.biCompression  = compression;
+    bi.bmiHeader.biSizeImage    = imagesize;
+
+    ret = GetDIBits(hdc, hbm, 0, 0, NULL, &bi, DIB_RGB_COLORS);
+    assert(ret);
+    *buff = (BYTE*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
+            bi.bmiHeader.biSizeImage);
+    *bytes = bi.bmiHeader.biSizeImage;
+    return GetDIBits(hdc, hbm, 0, bi.bmiHeader.biHeight, *buff, &bi, 
+            DIB_RGB_COLORS);
+}
+
+/* captures bitmap into buff and returns height of captured bitmap */
+static INT capture_dc(HDC hdc, BYTE** buff, INT* bytes)
+{
+    HDC hdcCap;
+    HBITMAP hbmCap;
+    INT scanlines;
+
+    hdcCap = CreateCompatibleDC(hdc);
+    hbmCap = CreateCompatibleBitmap(hdc, WND_SZ, WND_SZ);
+    SelectObject(hdcCap, hbmCap);
+    BitBlt(hdcCap, 
+            0,0, 
+            WND_SZ, WND_SZ, 
+            hdc, 
+            0,0, 
+            SRCCOPY);
+
+    /* get bitmap, 3 bytes per pixel */
+    scanlines = smart_GetDIBits(hdc, hbmCap, buff, bytes,
+                24, 0, WND_SZ*WND_SZ*3);
+
+    DeleteDC(hdcCap);
+    DeleteObject(hbmCap);
+
+    return scanlines;
+}
+
+static void constructor(HWND hwnd, HDC hdc)
+{
+    GpStatus stat;
+    GpGraphics *graphics = NULL;
+
+    stat = GdipCreateFromHDC(NULL, &graphics);
+    expect(stat, OutOfMemory);
+    stat = GdipDeleteGraphics(graphics);
+    expect(stat, InvalidParameter);
+
+    stat = GdipCreateFromHDC(hdc, &graphics);
+    expect(stat, Ok);
+    stat = GdipDeleteGraphics(graphics);
+    expect(stat, Ok);
+
+    stat = GdipCreateFromHWND(NULL, &graphics);
+    expect(stat, Ok);
+    stat = GdipDeleteGraphics(graphics);
+    expect(stat, Ok);
+
+    stat = GdipCreateFromHWND(hwnd, &graphics);
+    expect(stat, Ok);
+    stat = GdipDeleteGraphics(graphics);
+    expect(stat, Ok);
+
+    stat = GdipCreateFromHDC(hdc, NULL);
+    expect(stat, InvalidParameter);
+}
+
+static void drawline(HWND hwnd, HDC hdc)
+{
+    GpStatus stat;
+    GpPen *pen, *eraser;
+    GpGraphics *graphics;
+
+    INT height = 0, num_bytes = 0;
+    BYTE* buff;
+
+    stat = GdipCreatePen1((ARGB)0xffffffff, 2.0f, UnitPixel, &eraser);
+
+    stat = GdipCreateFromHDC(hdc, &graphics);
+    expect(stat, Ok);
+    stat = GdipCreatePen1((ARGB)0xffbbccdd, 2.0f, UnitPixel, &pen);
+    expect(stat, Ok);
+    stat = GdipDrawLineI(graphics, pen, 3, 3, 10, 10);
+    expect(stat, Ok);
+
+    height = capture_dc(hdc, &buff, &num_bytes);
+    assert(height == WND_SZ);
+
+    /* diagonal lines do not come out the same */
+    todo_wine
+        ok(!memcmp(buff, drawline_bmp1, num_bytes), "Expected different bitmap\n");
+
+    GdipDrawLineI(graphics, eraser, 3, 3, 10, 10);
+    GdipDrawLineI(graphics, pen, 3, 10, 10, 10);
+
+    HeapFree(GetProcessHeap(), 0, buff);
+    height = capture_dc(hdc, &buff, &num_bytes);
+    assert(height == WND_SZ);
+
+    ok(!memcmp(buff, drawline_bmp2, num_bytes), "Expected different bitmap\n");
+
+    HeapFree(GetProcessHeap(), 0, buff);
+    GdipDeleteGraphics(graphics);
+    GdipDeletePen(pen);
+    GdipDeletePen(eraser);
+}
+
+static void drawrect(HWND hwnd, HDC hdc)
+{
+    GpStatus stat;
+    GpPen *pen;
+    GpGraphics *graphics;
+
+    INT height = 0, num_bytes = 0;
+    BYTE* buff;
+
+    stat = GdipCreateFromHDC(hdc, &graphics);
+    expect(stat, Ok);
+    stat = GdipCreatePen1((ARGB)0xffbbccdd, 2.0f, UnitPixel, &pen);
+    expect(stat, Ok);
+    stat = GdipDrawRectangleI(graphics, pen, 6, 6, 3, 5);
+    expect(stat, Ok);
+
+    height = capture_dc(hdc, &buff, &num_bytes);
+    assert(height == WND_SZ);
+
+    ok(!memcmp(buff, drawrect_bmp1, num_bytes), "Expected different bitmap\n");
+
+    HeapFree(GetProcessHeap(), 0, buff);
+    GdipDeleteGraphics(graphics);
+    GdipDeletePen(pen);
+}
+
+SIMPLE_WINDOW_PROC(constructor)
+SIMPLE_WINDOW_PROC(drawline)
+SIMPLE_WINDOW_PROC(drawrect)
+
+static BOOL RegisterHelper(WNDPROC x, LPCTSTR ClassName)
+{
+    WNDCLASS wndClass;
+
+    wndClass.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+    wndClass.lpfnWndProc    = x;
+    wndClass.cbClsExtra     = 0;
+    wndClass.cbWndExtra     = 0;
+    wndClass.hInstance      = NULL;
+
+    wndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
+    wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
+    wndClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
+    wndClass.lpszMenuName   = NULL;
+    wndClass.lpszClassName  = TEXT(ClassName);
+
+    if(!RegisterClassA(&wndClass)) return FALSE;
+
+    return TRUE;
+}
+
+static BOOL RegisterWindowClasses(void)
+{
+    BOOL ret;
+
+    ret = RegisterHelper(constructor_window_proc, TEXT("Constructor"));
+    ret = ret && RegisterHelper(drawline_window_proc, TEXT("DrawLine"));
+    ret = ret && RegisterHelper(drawrect_window_proc, TEXT("DrawRect"));
+
+    return ret;
+}
+
+static void window_test_runner(LPCTSTR ClassName, LPCTSTR Caption)
+{
+    HWND hwnd;
+
+    hwnd = CreateWindow(
+        ClassName,
+        Caption,
+        WS_POPUP,
+        0, 0, WND_SZ, WND_SZ,
+        0, 0, 0, NULL);
+
+    assert(hwnd);
+
+    ShowWindow(hwnd, SW_SHOW);
+    UpdateWindow(hwnd);
+    DestroyWindow(hwnd);
+}
+
+static void test_constructor_destructor(void)
+{
+    window_test_runner(TEXT("Constructor"), TEXT("Graphics constructor test"));
+}
+
+static void test_drawline(void)
+{
+    window_test_runner(TEXT("DrawLine"), TEXT("Draw line test"));
+}
+
+static void test_drawrect(void)
+{
+    window_test_runner(TEXT("DrawRect"), TEXT("Draw rect test"));
+}
+
+START_TEST(graphics)
+{
+    GdiplusStartupInput gdiplusStartupInput;
+    ULONG_PTR gdiplusToken;
+
+    if (!RegisterWindowClasses()) assert(0);
+
+    gdiplusStartupInput.GdiplusVersion=1;
+    gdiplusStartupInput.DebugEventCallback=NULL;
+    gdiplusStartupInput.SuppressBackgroundThread=0;
+    gdiplusStartupInput.SuppressExternalCodecs=0;
+
+    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
+
+    test_constructor_destructor();
+    test_drawline();
+    test_drawrect();
+
+    GdiplusShutdown(gdiplusToken);
+}
-- 
1.4.1


More information about the wine-patches mailing list