mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-12 13:30:19 +00:00
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).
This commit is contained in:
parent
166777dd55
commit
3f16f7e0d4
@ -28,6 +28,9 @@
|
||||
#include <glib/gstdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtk-rendernode-tool.h"
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
#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);
|
||||
|
||||
window = gdk_surface_new_toplevel (gdk_display_get_default ());
|
||||
renderer = gsk_renderer_new_for_surface (window);
|
||||
|
||||
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);
|
||||
#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
|
||||
bytes = gdk_texture_save_to_png_bytes (texture);
|
||||
#endif
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GskRenderer *renderer;
|
||||
GdkSurface *window;
|
||||
|
||||
if (renderer_name)
|
||||
g_object_set_data_full (G_OBJECT (gdk_display_get_default ()), "gsk-renderer",
|
||||
g_strdup (renderer_name), g_free);
|
||||
|
||||
window = gdk_surface_new_toplevel (gdk_display_get_default ());
|
||||
renderer = gsk_renderer_new_for_surface (window);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user