Re: [PATCH 3/3] W32: Add a win32 boilerplate that uses a real window
Bryce Harrington <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <[email protected]> |
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?= <[email protected]> > 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 <[email protected]> > 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 > [email protected] > http://lists.cairographics.org/mailman/listinfo/cairo Bryce -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo