[cairo] [PATCH 3/3] W32: Add a win32 boilerplate that uses a real window
Bryce Harrington
bryce at osg.samsung.com
Tue Apr 7 14:07:38 PDT 2015
On Sat, Apr 04, 2015 at 07:21:20PM +0300, LRN wrote:
> 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.
Thanks for checking that.
> 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
> 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);
> + }
> +}
It may not matter since this is cleanup, but both ReleaseDC and
DestroyWindow return error codes.
> +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);
Check for return value 0; extended error info can be obtained via
GetLastError().
> + win32tc->wnd = CreateWindowEx (WS_EX_TOOLWINDOW,
> + "cairo_boilerplate_win32_dummy",
> + 0,
> + WS_POPUP,
> + 0,
> + 0,
> + width,
> + height,
> + 0,
> + 0,
> + 0,
> + 0);
Check ->wnd for NULL; GetLastError() for error.
> + win32tc->dc = GetDC (win32tc->wnd);
Check NULL
> + format = ChoosePixelFormat (win32tc->dc, &pfd);
Check if format == 0; then GetLastError()
> + SetPixelFormat (win32tc->dc, format, &pfd);
Returns FALSE on error
> + ShowWindow (win32tc->wnd, SW_SHOWNOACTIVATE);
Safe to ignore return value here.
> +}
> +static cairo_surface_t *
> +_cairo_boilerplate_win32_for_create_window (const char *name,
This is an odd name for a routine. Maybe a better name would be
something like _cairo_boilerplate_win32_create_window_surface() ?
> + 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));
Missing NULL check
> + *closure = win32tc;
> +
> + _cairo_boilerplate_win32_create_window(width, height, win32tc);
Actually, why not move the calloc into *create_window, and have
*create_window return the constructed win32tc instead of taking it as a
parameter?
> + 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);
If you use my suggestion to just make an API that takes a format
parameter, you can replace this if chain with it.
> + 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)
> +{
Would probably be a good idea to document this routine, and mention that
the surface parameter can get changed.
> + 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);
Error checks needed in some of the above...
> + 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
>
> pub 2048R/922360B0 2011-08-05 LRN <lrn1986 at gmail.com>
> sub 2048R/1CFF4F8C 2011-08-05 [expires: 2016-08-03]
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.11 (MingW32)
>
> iQEcBAEBAgAGBQJVIA+EAAoJEOs4Jb6SI2CwiAcIAJL7+ndpWb/TEIS7RK6cW2hy
> LjG0z9vKuzYCeCgNskFPSftGXwxqc3fvzwHXE/0bqRtwRfjY6TF49Ejr83UYPUag
> eO4fAiTvlphB5Q3j9OW0J258WuV96a+pXKlNHQAtlsUWXEUL5+i/foNofgUW44vb
> fZtT8rfkpIlK4ysb6zzi31pe4tRn5sXpeTvFnLiV2GTIdLX732FrbNGVHK1OoXUc
> e/YT9ldlNP2/Qv7DgJq+s/BqY3oi1sTPnLylfczpb0VaNptRopCvh6k9SoFdyFbl
> F1b+Vr02hqmfYIzlOz5kOx0Mdm7iiGubPhY+Xn6YCRtw/OmtiRAK1fOOLiaMOnU=
> =ukX8
> -----END PGP SIGNATURE-----
> --
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo
Bryce
More information about the cairo
mailing list