diff options
Diffstat (limited to 'boilerplate')
-rw-r--r-- | boilerplate/cairo-boilerplate-glx.c | 4 | ||||
-rw-r--r-- | boilerplate/cairo-boilerplate-xcb.c | 67 | ||||
-rw-r--r-- | boilerplate/cairo-boilerplate-xlib.c | 58 | ||||
-rw-r--r-- | boilerplate/cairo-boilerplate.c | 72 | ||||
-rw-r--r-- | boilerplate/cairo-boilerplate.h | 11 |
5 files changed, 206 insertions, 6 deletions
diff --git a/boilerplate/cairo-boilerplate-glx.c b/boilerplate/cairo-boilerplate-glx.c index f41907025..690844ead 100644 --- a/boilerplate/cairo-boilerplate-glx.c +++ b/boilerplate/cairo-boilerplate-glx.c @@ -373,6 +373,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1, "cairo_gl_surface_create", _cairo_boilerplate_gl_create_surface, + cairo_surface_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, @@ -386,6 +387,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR, 1, "cairo_gl_surface_create", _cairo_boilerplate_gl_create_surface, + cairo_surface_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, @@ -399,6 +401,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1, "cairo_gl_surface_create_for_window", _cairo_boilerplate_gl_create_window, + cairo_surface_create_similar, NULL, _cairo_boilerplate_gl_finish_window, _cairo_boilerplate_get_image_surface, @@ -413,6 +416,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_GL, CAIRO_CONTENT_COLOR_ALPHA, 1, "cairo_gl_surface_create_for_window", _cairo_boilerplate_gl_create_window_db, + cairo_surface_create_similar, NULL, _cairo_boilerplate_gl_finish_window, _cairo_boilerplate_get_image_surface, diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c index 418e138fb..7cccbdac5 100644 --- a/boilerplate/cairo-boilerplate-xcb.c +++ b/boilerplate/cairo-boilerplate-xcb.c @@ -170,6 +170,66 @@ find_depth (xcb_connection_t *connection, return NULL; } +static const cairo_user_data_key_t key; + +struct similar { + xcb_connection_t *connection; + xcb_drawable_t pixmap; +}; + +static void _destroy_similar (void *closure) +{ + struct similar *similar = closure; + + xcb_free_pixmap (similar->connection, similar->pixmap); + free (similar); +} + +static cairo_surface_t * +_cairo_boilerplate_xcb_create_similar (cairo_surface_t *other, + cairo_content_t content, + int width, int height) +{ + xcb_screen_t *root; + cairo_surface_t *surface; + struct similar *similar; + xcb_render_pictforminfo_t *render_format; + int depth; + void *formats; + + similar = malloc (sizeof (*similar)); + + switch (content) { + default: + case CAIRO_CONTENT_COLOR_ALPHA: depth = 32; break; + case CAIRO_CONTENT_COLOR: depth = 24; break; + case CAIRO_CONTENT_ALPHA: depth = 8; break; + } + + similar->connection = + cairo_xcb_device_get_connection (cairo_surface_get_device(other)); + similar->pixmap = xcb_generate_id (similar->connection); + + root = xcb_setup_roots_iterator(xcb_get_setup(similar->connection)).data; + xcb_create_pixmap (similar->connection, depth, + similar->pixmap, root->root, + width, height); + + render_format = find_depth (similar->connection, depth, &formats); + if (render_format == NULL) + return NULL; + + surface = cairo_xcb_surface_create_with_xrender_format (similar->connection, + root, + similar->pixmap, + render_format, + width, height); + cairo_surface_set_user_data (surface, &key, similar, _destroy_similar); + free(formats); + + return surface; +} + static cairo_surface_t * _cairo_boilerplate_xcb_create_surface (const char *name, cairo_content_t content, @@ -681,6 +741,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1, "cairo_xcb_surface_create_with_xrender_format", _cairo_boilerplate_xcb_create_surface, + _cairo_boilerplate_xcb_create_similar, NULL, _cairo_boilerplate_xcb_finish_surface, _cairo_boilerplate_get_image_surface, @@ -695,6 +756,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1, "cairo_xcb_surface_create_with_xrender_format", _cairo_boilerplate_xcb_create_surface, + _cairo_boilerplate_xcb_create_similar, NULL, _cairo_boilerplate_xcb_finish_surface, _cairo_boilerplate_get_image_surface, @@ -709,6 +771,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1, "cairo_xcb_surface_create_with_xrender_format", _cairo_boilerplate_xcb_create_window, + _cairo_boilerplate_xcb_create_similar, NULL, _cairo_boilerplate_xcb_finish_surface, _cairo_boilerplate_get_image_surface, @@ -723,6 +786,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1, "cairo_xcb_surface_create_with_xrender_format", _cairo_boilerplate_xcb_create_window_db, + _cairo_boilerplate_xcb_create_similar, NULL, _cairo_boilerplate_xcb_finish_surface, _cairo_boilerplate_get_image_surface, @@ -737,6 +801,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR_ALPHA, 1, "cairo_xcb_surface_create_with_xrender_format", _cairo_boilerplate_xcb_create_render_0_0, + cairo_surface_create_similar, NULL, _cairo_boilerplate_xcb_finish_surface, _cairo_boilerplate_get_image_surface, @@ -751,6 +816,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1, "cairo_xcb_surface_create_with_xrender_format", _cairo_boilerplate_xcb_create_render_0_0, + cairo_surface_create_similar, NULL, _cairo_boilerplate_xcb_finish_surface, _cairo_boilerplate_get_image_surface, @@ -765,6 +831,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XCB, CAIRO_CONTENT_COLOR, 1, "cairo_xcb_surface_create_with_xrender_format", _cairo_boilerplate_xcb_create_fallback, + cairo_surface_create_similar, NULL, _cairo_boilerplate_xcb_finish_surface, _cairo_boilerplate_get_image_surface, diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c index f82b78b8d..797fe9724 100644 --- a/boilerplate/cairo-boilerplate-xlib.c +++ b/boilerplate/cairo-boilerplate-xlib.c @@ -35,6 +35,8 @@ #include <X11/Xutil.h> /* for XDestroyImage */ +static const cairo_user_data_key_t key; + typedef struct _xlib_target_closure { Display *dpy; Drawable drawable; @@ -215,6 +217,58 @@ _cairo_boilerplate_xlib_perf_create_surface (Display *dpy, width, height); } +struct similar { + Display *dpy; + Pixmap pixmap; +}; + +static void _destroy_similar (void *closure) +{ + struct similar *similar = closure; + + XFreePixmap (similar->dpy, similar->pixmap); + free (similar); +} + +static cairo_surface_t * +_cairo_boilerplate_xlib_create_similar (cairo_surface_t *other, + cairo_content_t content, + int width, + int height) +{ + XRenderPictFormat *xrender_format; + uint32_t format; + struct similar *similar; + cairo_surface_t *surface; + + similar = malloc (sizeof (*similar)); + similar->dpy = cairo_xlib_surface_get_display (other); + + switch (content) { + default: + case CAIRO_CONTENT_COLOR_ALPHA: format = PictStandardARGB32; break; + case CAIRO_CONTENT_COLOR: format = PictStandardRGB24; break; + case CAIRO_CONTENT_ALPHA: format = PictStandardA8; break; + } + + xrender_format = XRenderFindStandardFormat (similar->dpy, format); + similar->pixmap = XCreatePixmap (similar->dpy, + DefaultRootWindow (similar->dpy), + width, height, + xrender_format->depth); + + surface = + cairo_xlib_surface_create_with_xrender_format (similar->dpy, + similar->pixmap, + DefaultScreenOfDisplay (similar->dpy), + xrender_format, + width, height); + + cairo_surface_set_user_data (surface, &key, similar, _destroy_similar); + + return surface; +} + static cairo_surface_t * _cairo_boilerplate_xlib_create_surface (const char *name, cairo_content_t content, @@ -511,6 +565,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1, "cairo_xlib_surface_create_with_xrender_format", _cairo_boilerplate_xlib_create_surface, + _cairo_boilerplate_xlib_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, @@ -524,6 +579,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, "cairo_xlib_surface_create_with_xrender_format", _cairo_boilerplate_xlib_create_surface, + _cairo_boilerplate_xlib_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, @@ -537,6 +593,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, "cairo_xlib_surface_create", _cairo_boilerplate_xlib_window_create_surface, + cairo_surface_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, @@ -554,6 +611,7 @@ static const cairo_boilerplate_target_t targets[] = { CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, "cairo_xlib_surface_create", _cairo_boilerplate_xlib_fallback_create_surface, + cairo_surface_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c index a77fa578a..b89e6d817 100644 --- a/boilerplate/cairo-boilerplate.c +++ b/boilerplate/cairo-boilerplate.c @@ -151,6 +151,35 @@ _cairo_boilerplate_image_create_surface (const char *name, return cairo_image_surface_create (format, ceil (width), ceil (height)); } +static const cairo_user_data_key_t key; + +static cairo_surface_t * +_cairo_boilerplate_image_create_similar (cairo_surface_t *other, + cairo_content_t content, + int width, int height) +{ + cairo_format_t format; + cairo_surface_t *surface; + int stride; + void *ptr; + + switch (content) { + case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break; + case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB24; break; + default: + case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break; + } + + stride = cairo_format_stride_for_width(format, width); + ptr = malloc (stride* height); + + surface = cairo_image_surface_create_for_data (ptr, format, + width, height, stride); + cairo_surface_set_user_data (surface, &key, ptr, free); + + return surface; +} + static cairo_surface_t * _cairo_boilerplate_image16_create_surface (const char *name, cairo_content_t content, @@ -160,7 +189,7 @@ _cairo_boilerplate_image16_create_surface (const char *name, double max_height, cairo_boilerplate_mode_t mode, int id, - void **closure) + void **closure) { *closure = NULL; @@ -168,6 +197,33 @@ _cairo_boilerplate_image16_create_surface (const char *name, return cairo_image_surface_create (CAIRO_FORMAT_RGB16_565, ceil (width), ceil (height)); } +static cairo_surface_t * +_cairo_boilerplate_image16_create_similar (cairo_surface_t *other, + cairo_content_t content, + int width, int height) +{ + cairo_format_t format; + cairo_surface_t *surface; + int stride; + void *ptr; + + switch (content) { + case CAIRO_CONTENT_ALPHA: format = CAIRO_FORMAT_A8; break; + case CAIRO_CONTENT_COLOR: format = CAIRO_FORMAT_RGB16_565; break; + default: + case CAIRO_CONTENT_COLOR_ALPHA: format = CAIRO_FORMAT_ARGB32; break; + } + + stride = cairo_format_stride_for_width(format, width); + ptr = malloc (stride* height); + + surface = cairo_image_surface_create_for_data (ptr, format, + width, height, stride); + cairo_surface_set_user_data (surface, &key, ptr, free); + + return surface; +} + static char * _cairo_boilerplate_image_describe (void *closure) { @@ -334,7 +390,9 @@ static const cairo_boilerplate_target_t builtin_targets[] = { { "image", "image", NULL, NULL, CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR_ALPHA, 0, - NULL, _cairo_boilerplate_image_create_surface, + NULL, + _cairo_boilerplate_image_create_surface, + _cairo_boilerplate_image_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, @@ -345,7 +403,9 @@ static const cairo_boilerplate_target_t builtin_targets[] = { { "image", "image", NULL, NULL, CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0, - NULL, _cairo_boilerplate_image_create_surface, + NULL, + _cairo_boilerplate_image_create_surface, + _cairo_boilerplate_image_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, @@ -356,7 +416,9 @@ static const cairo_boilerplate_target_t builtin_targets[] = { { "image16", "image", NULL, NULL, CAIRO_SURFACE_TYPE_IMAGE, CAIRO_CONTENT_COLOR, 0, - NULL, _cairo_boilerplate_image16_create_surface, + NULL, + _cairo_boilerplate_image16_create_surface, + _cairo_boilerplate_image16_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, @@ -370,6 +432,7 @@ static const cairo_boilerplate_target_t builtin_targets[] = { CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR_ALPHA, 0, "cairo_recording_surface_create", _cairo_boilerplate_recording_create_surface, + cairo_surface_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, @@ -382,6 +445,7 @@ static const cairo_boilerplate_target_t builtin_targets[] = { CAIRO_SURFACE_TYPE_RECORDING, CAIRO_CONTENT_COLOR, 0, "cairo_recording_surface_create", _cairo_boilerplate_recording_create_surface, + cairo_surface_create_similar, NULL, NULL, _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png, diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h index c0a045222..d145a1e1c 100644 --- a/boilerplate/cairo-boilerplate.h +++ b/boilerplate/cairo-boilerplate.h @@ -126,6 +126,12 @@ typedef cairo_surface_t * int id, void **closure); +typedef cairo_surface_t * +(*cairo_boilerplate_create_similar_t) (cairo_surface_t *other, + cairo_content_t content, + int width, + int height); + typedef void (*cairo_boilerplate_force_fallbacks_t) (cairo_surface_t *surface, double x_pixels_per_inch, @@ -163,11 +169,12 @@ typedef struct _cairo_boilerplate_target { unsigned int error_tolerance; const char *probe; /* runtime dl check */ cairo_boilerplate_create_surface_t create_surface; - cairo_boilerplate_force_fallbacks_t force_fallbacks; + cairo_boilerplate_create_similar_t create_similar; + cairo_boilerplate_force_fallbacks_t force_fallbacks; cairo_boilerplate_finish_surface_t finish_surface; cairo_boilerplate_get_image_surface_t get_image_surface; cairo_boilerplate_write_to_png_t write_to_png; - cairo_boilerplate_cleanup_t cleanup; + cairo_boilerplate_cleanup_t cleanup; cairo_boilerplate_wait_t synchronize; cairo_boilerplate_describe_t describe; cairo_bool_t is_measurable; |