From: Benjamin Otte Date: Sun, 30 Jul 2023 18:00:34 +0000 (+0200) Subject: rendernode-tool: Add another magic format X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~22^2~1^2~21^2~3 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=3f16f7e0d4ff44ff62d10fc0b4c2fb230999f36d;p=gtk4.git rendernode-tool: Add another magic format Make .svg use the Cairo renderer to save to an SVG file. It's useful when comparing rendering behavior and times with web browsers (as long as one is aware that browsers build a full DOM tree out of those SVGs). --- diff --git a/tools/gtk-rendernode-tool-render.c b/tools/gtk-rendernode-tool-render.c index 066ac661c8..c8d98da3f8 100644 --- a/tools/gtk-rendernode-tool-render.c +++ b/tools/gtk-rendernode-tool-render.c @@ -28,6 +28,9 @@ #include #include #include "gtk-rendernode-tool.h" +#ifdef CAIRO_HAS_SVG_SURFACE +#include +#endif static char * get_save_filename (const char *filename) @@ -48,6 +51,58 @@ get_save_filename (const char *filename) return result; } +#ifdef CAIRO_HAS_SVG_SURFACE +static cairo_status_t +cairo_serializer_write (gpointer user_data, + const unsigned char *data, + unsigned int length) +{ + g_byte_array_append (user_data, data, length); + + return CAIRO_STATUS_SUCCESS; +} + +static GBytes * +create_svg (GskRenderNode *node, + GError **error) +{ + cairo_surface_t *surface; + cairo_t *cr; + graphene_rect_t bounds; + GByteArray *array; + + gsk_render_node_get_bounds (node, &bounds); + array = g_byte_array_new (); + + surface = cairo_svg_surface_create_for_stream (cairo_serializer_write, + array, + bounds.size.width, + bounds.size.height); + cairo_svg_surface_set_document_unit (surface, CAIRO_SVG_UNIT_PX); + cairo_surface_set_device_offset (surface, -bounds.origin.x, -bounds.origin.y); + + cr = cairo_create (surface); + gsk_render_node_draw (node, cr); + cairo_destroy (cr); + + cairo_surface_finish (surface); + if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS) + { + cairo_surface_destroy (surface); + return g_byte_array_free_to_bytes (array); + } + else + { + g_set_error (error, + G_IO_ERROR, G_IO_ERROR_FAILED, + "%s", cairo_status_to_string (cairo_surface_status (surface))); + cairo_surface_destroy (surface); + g_byte_array_unref (array); + return NULL; + } +} +#endif + static void render_file (const char *filename, const char *renderer_name, @@ -55,10 +110,7 @@ render_file (const char *filename, { GskRenderNode *node; GBytes *bytes; - GdkTexture *texture; char *save_to; - GskRenderer *renderer; - GdkSurface *window; GError *error = NULL; save_to = (char *) save_file; @@ -76,20 +128,40 @@ render_file (const char *filename, node = load_node_file (filename); - if (renderer_name) - g_object_set_data_full (G_OBJECT (gdk_display_get_default ()), "gsk-renderer", - g_strdup (renderer_name), g_free); +#ifdef CAIRO_HAS_SVG_SURFACE + if (g_str_has_suffix (save_to, ".svg")) + { + bytes = create_svg (node, &error); + if (bytes == NULL) + { + g_printerr (_("Failed to generate SVG: %s\n"), error->message); + exit (1); + } + } + else +#endif + { + GdkTexture *texture; + GskRenderer *renderer; + GdkSurface *window; - window = gdk_surface_new_toplevel (gdk_display_get_default ()); - renderer = gsk_renderer_new_for_surface (window); + if (renderer_name) + g_object_set_data_full (G_OBJECT (gdk_display_get_default ()), "gsk-renderer", + g_strdup (renderer_name), g_free); - texture = gsk_renderer_render_texture (renderer, node, NULL); + window = gdk_surface_new_toplevel (gdk_display_get_default ()); + renderer = gsk_renderer_new_for_surface (window); - if (g_str_has_suffix (save_to, ".tif") || - g_str_has_suffix (save_to, ".tiff")) - bytes = gdk_texture_save_to_tiff_bytes (texture); - else - bytes = gdk_texture_save_to_png_bytes (texture); + texture = gsk_renderer_render_texture (renderer, node, NULL); + + if (g_str_has_suffix (save_to, ".tif") || + g_str_has_suffix (save_to, ".tiff")) + bytes = gdk_texture_save_to_tiff_bytes (texture); + else + bytes = gdk_texture_save_to_png_bytes (texture); + + g_object_unref (texture); + } if (g_file_set_contents (save_to, g_bytes_get_data (bytes, NULL), @@ -110,7 +182,6 @@ render_file (const char *filename, if (save_to != save_file) g_free (save_to); - g_object_unref (texture); gsk_render_node_unref (node); }