[cairo] [PATCH 3/3] W32: Add a win32 boilerplate that uses a real window

LRN lrn1986 at gmail.com
Sat Apr 4 09:21:20 PDT 2015


See the discussion in "[PATCH 2/3] Support a different pixel format for HDC"
for background information and the previous 2 patches.

This patch adds a boilerplate code for win32 that uses a real window (instead
of a device-independent bitmap) as a backend for the surface.

There is a summary of testsuite results in the commit message (obtained by
counting the number of '*.fail.png' and '*.pass.png' for a particular target.

IMO, the results prove that patch 1/3 (the one that adds
cairo_win32_surface_create_with_alpha()) does not make things worse.

-- 
O< ascii ribbon - stop html email! - www.asciiribbon.org
-------------- next part --------------
From 5e8811893688966cd29b0f63432e3ee65644d10b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1?=
 =?UTF-8?q?=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= <lrn1986 at gmail.com>
Date: Sat, 4 Apr 2015 15:58:53 +0000
Subject: [PATCH 3/3] W32: Add a win32 boilerplate that uses a real window

This way it uses the codepath for cairo_win32_surface_create()
and cairo_win32_surface_create_with_alpha(), instead of the
cairo_win32_surface_create_with_dib().

Without the recording tests (which crash the testsuite hard)
the testsuite results for win32 are:

win32.rgb24:
169 fails
104 passes

win32.argb32:
82 fails
173 passes

win32-window-color.rgb24:
162 fails
111 passes

win32-window-coloralpha.argb32:
80 fails
175 passes
---
 boilerplate/cairo-boilerplate-win32.c | 168 ++++++++++++++++++++++++++++++++++
 1 file changed, 168 insertions(+)

diff --git a/boilerplate/cairo-boilerplate-win32.c b/boilerplate/cairo-boilerplate-win32.c
index 7469cc7..bda4f2d 100644
--- a/boilerplate/cairo-boilerplate-win32.c
+++ b/boilerplate/cairo-boilerplate-win32.c
@@ -28,6 +28,144 @@
 
 #include <cairo-win32.h>
 
+static const cairo_user_data_key_t win32_closure_key;
+
+typedef struct _win32_target_closure {
+    HWND wnd;
+    HDC dc;
+    cairo_surface_t *surface;
+} win32_target_closure_t;
+
+static void
+_cairo_boilerplate_win32_cleanup (void *closure)
+{
+    win32_target_closure_t *win32tc = closure;
+
+    if (win32tc)
+    {
+        ReleaseDC(win32tc->wnd, win32tc->dc);
+        DestroyWindow (win32tc->wnd);
+
+        free (win32tc);
+    }
+}
+
+static void
+_cairo_boilerplate_win32_create_window (int			width,
+					int			height,
+					win32_target_closure_t *win32tc)
+{
+    WNDCLASSEXA wincl;
+    int format;
+
+    PIXELFORMATDESCRIPTOR pfd = {
+      sizeof(PIXELFORMATDESCRIPTOR),
+      1,                                /* Version Number */
+      PFD_DRAW_TO_WINDOW      |         /* Format Must Support Window */
+      PFD_SUPPORT_COMPOSITION |         /* Format Must Support Composition */
+      PFD_DOUBLEBUFFER,                 /* Must Support Double Buffering */
+      PFD_TYPE_RGBA,                    /* Request An RGBA Format */
+      32,                               /* Select Our Color Depth */
+      0, 0, 0, 0, 0, 0,                 /* Color Bits Ignored */
+      8,                                /* An Alpha Buffer */
+      0,                                /* Shift Bit Ignored */
+      0,                                /* No Accumulation Buffer */
+      0, 0, 0, 0,                       /* Accumulation Bits Ignored */
+      24,                               /* 24Bit Z-Buffer (Depth Buffer) */
+      8,                                /* Some Stencil Buffer */
+      0,                                /* No Auxiliary Buffer */
+      PFD_MAIN_PLANE,                   /* Main Drawing Layer */
+      0,                                /* Reserved */
+      0, 0, 0                           /* Layer Masks Ignored */
+    };
+
+    ZeroMemory (&wincl, sizeof (WNDCLASSEXA));
+    wincl.cbSize = sizeof (WNDCLASSEXA);
+    wincl.hInstance = GetModuleHandle (0);
+    wincl.lpszClassName = "cairo_boilerplate_win32_dummy";
+    wincl.lpfnWndProc = DefWindowProcA;
+    wincl.style = CS_OWNDC;
+
+    RegisterClassExA (&wincl);
+
+    win32tc->wnd = CreateWindowEx (WS_EX_TOOLWINDOW,
+				   "cairo_boilerplate_win32_dummy",
+				   0,
+				   WS_POPUP,
+				   0,
+				   0,
+				   width,
+				   height,
+				   0,
+				   0,
+				   0,
+				   0);
+    win32tc->dc = GetDC (win32tc->wnd);
+
+    format = ChoosePixelFormat (win32tc->dc, &pfd);
+    SetPixelFormat (win32tc->dc, format, &pfd);
+
+    ShowWindow (win32tc->wnd, SW_SHOWNOACTIVATE);
+}
+
+static cairo_surface_t *
+_cairo_boilerplate_win32_for_create_window (const char		       *name,
+					    cairo_content_t		content,
+					    double			width,
+					    double			height,
+					    double			max_width,
+					    double			max_height,
+					    cairo_boilerplate_mode_t    mode,
+					    void		      **closure)
+{
+    win32_target_closure_t *win32tc;
+    cairo_surface_t *surface;
+    cairo_format_t format;
+
+    win32tc = calloc (1, sizeof (win32_target_closure_t));
+
+    *closure = win32tc;
+
+     _cairo_boilerplate_win32_create_window(width, height, win32tc);
+
+    format = cairo_boilerplate_format_from_content (content);
+
+    if (format == CAIRO_FORMAT_ARGB32)
+      surface = cairo_win32_surface_create_with_alpha (win32tc->dc);
+    else
+      surface = cairo_win32_surface_create (win32tc->dc);
+
+    win32tc->surface = surface;
+
+    if (cairo_surface_status (surface)) {
+	_cairo_boilerplate_win32_cleanup (win32tc);
+	return NULL;
+    }
+
+    return surface;
+}
+
+static cairo_status_t
+_cairo_boilerplate_win32_finish_window (cairo_surface_t *surface)
+{
+    win32_target_closure_t *win32tc = cairo_surface_get_user_data (surface,
+								   &win32_closure_key);
+
+    if (win32tc != NULL && win32tc->surface != NULL) {
+	cairo_t *cr;
+
+	cr = cairo_create (win32tc->surface);
+	cairo_set_source_surface (cr, surface, 0, 0);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+	cairo_paint (cr);
+	cairo_destroy (cr);
+
+	surface = win32tc->surface;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 static cairo_surface_t *
 _cairo_boilerplate_win32_create_surface (const char		   *name,
 					 cairo_content_t	    content,
@@ -73,5 +211,35 @@ static const cairo_boilerplate_target_t targets[] = {
 	cairo_surface_write_to_png,
 	NULL, NULL, NULL, FALSE, FALSE, FALSE
     },
+    {
+	"win32-window-coloralpha", "win32", NULL, NULL,
+	CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR_ALPHA, 1,
+	"cairo_win32_surface_create_with_alpha",
+	_cairo_boilerplate_win32_for_create_window,
+	cairo_surface_create_similar,
+	NULL,
+	_cairo_boilerplate_win32_finish_window,
+	_cairo_boilerplate_get_image_surface,
+	cairo_surface_write_to_png,
+	_cairo_boilerplate_win32_cleanup,
+	NULL,
+        NULL,
+	FALSE, FALSE, FALSE
+    },
+    {
+	"win32-window-color", "win32", NULL, NULL,
+	CAIRO_SURFACE_TYPE_WIN32, CAIRO_CONTENT_COLOR, 1,
+	"cairo_win32_surface_create",
+	_cairo_boilerplate_win32_for_create_window,
+	cairo_surface_create_similar,
+	NULL,
+	_cairo_boilerplate_win32_finish_window,
+	_cairo_boilerplate_get_image_surface,
+	cairo_surface_write_to_png,
+	_cairo_boilerplate_win32_cleanup,
+	NULL,
+        NULL,
+	FALSE, FALSE, FALSE
+    },
 };
 CAIRO_BOILERPLATE (win32, targets)
-- 
1.8.5.3

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0x922360B0.asc
Type: application/pgp-keys
Size: 1717 bytes
Desc: not available
URL: <http://lists.cairographics.org/archives/cairo/attachments/20150404/6edbc1fe/attachment-0001.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.cairographics.org/archives/cairo/attachments/20150404/6edbc1fe/attachment-0001.sig>


More information about the cairo mailing list