From: Matthias Clasen Date: Thu, 20 Jul 2023 19:09:27 +0000 (-0400) Subject: Add a gtk4-rendernode-tool X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~22^2~1^2~54^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=601011ccc02dcb9607e48b44876e64fb2ef73e6b;p=gtk4.git Add a gtk4-rendernode-tool This is meant to work with serialized render nodes. --- diff --git a/docs/reference/gtk/gtk4-rendernode-tool.rst b/docs/reference/gtk/gtk4-rendernode-tool.rst new file mode 100644 index 0000000000..0e77164787 --- /dev/null +++ b/docs/reference/gtk/gtk4-rendernode-tool.rst @@ -0,0 +1,51 @@ +.. _gtk4-rendernode-tool(1): + +==================== +gtk4-rendernode-tool +==================== + +----------------------- +GskRenderNode Utility +----------------------- + +SYNOPSIS +-------- +| **gtk4-rendernode-tool** [OPTIONS...] +| +| **gtk4-rendernode-tool** info [OPTIONS...] +| **gtk4-rendernode-tool** show [OPTIONS...] +| **gtk4-rendernode-tool** render [OPTIONS...] + +DESCRIPTION +----------- + +``gtk4-rendernode-tool`` can perform various operations on serialized rendernodes. + +COMMANDS +-------- + +Information +^^^^^^^^^^^ + +The ``info`` command shows general information about the rendernode, such +as the number of nodes, and the depth of the tree. + +Showing +^^^^^^^ + +The ``show`` command displays the rendernode. + +Rendering +^^^^^^^^^ + +The ``render`` command saves a rendering of the rendernode as a png image. +The name of the file to write can be specified as a second FILE argument. + +``--renderer=RENDERER`` + + Use the given renderer. This option accepts the same values as the + ``GSK_RENDERER`` environment variable. + +``--force`` + + Overwrite an existing file. diff --git a/docs/reference/gtk/meson.build b/docs/reference/gtk/meson.build index 0954a1b33f..a123971954 100644 --- a/docs/reference/gtk/meson.build +++ b/docs/reference/gtk/meson.build @@ -75,6 +75,7 @@ if get_option('man-pages') and rst2man.found() [ 'gtk4-encode-symbolic-svg', '1', ], [ 'gtk4-launch', '1', ], [ 'gtk4-query-settings', '1', ], + [ 'gtk4-rendernode-tool', '1' ], [ 'gtk4-update-icon-cache', '1', ], ] diff --git a/po/POTFILES.in b/po/POTFILES.in index 9045ee9ea4..a0b5ae9af7 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -425,4 +425,9 @@ tools/gtk-builder-tool-screenshot.c tools/gtk-builder-tool-simplify.c tools/gtk-builder-tool-validate.c tools/gtk-launch.c +tools/gtk-rendernode-tool.c +tools/gtk-rendernode-tool-info.c +tools/gtk-rendernode-tool-show.c +tools/gtk-rendernode-tool-render.c +tools/gtk-rendernode-tool-utils.c tools/updateiconcache.c diff --git a/tools/gtk-rendernode-tool-info.c b/tools/gtk-rendernode-tool-info.c new file mode 100644 index 0000000000..4e735d9c9e --- /dev/null +++ b/tools/gtk-rendernode-tool-info.c @@ -0,0 +1,235 @@ +/* Copyright 2023 Red Hat, Inc. + * + * GTK+ is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GTK+ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GTK+; see the file COPYING. If not, + * see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include "gtk-rendernode-tool.h" + +static void +count_nodes (GskRenderNode *node, + unsigned int *counts, + unsigned int *depth) +{ + unsigned int d, dd; + + counts[gsk_render_node_get_node_type (node)] += 1; + d = 0; + + switch (gsk_render_node_get_node_type (node)) + { + case GSK_CONTAINER_NODE: + for (unsigned int i = 0; i < gsk_container_node_get_n_children (node); i++) + { + count_nodes (gsk_container_node_get_child (node, i), counts, &dd); + d = MAX (d, dd); + } + break; + + case GSK_CAIRO_NODE: + case GSK_COLOR_NODE: + case GSK_LINEAR_GRADIENT_NODE: + case GSK_REPEATING_LINEAR_GRADIENT_NODE: + case GSK_RADIAL_GRADIENT_NODE: + case GSK_REPEATING_RADIAL_GRADIENT_NODE: + case GSK_CONIC_GRADIENT_NODE: + case GSK_BORDER_NODE: + case GSK_TEXTURE_NODE: + case GSK_INSET_SHADOW_NODE: + case GSK_OUTSET_SHADOW_NODE: + break; + + case GSK_TRANSFORM_NODE: + count_nodes (gsk_transform_node_get_child (node), counts, &d); + break; + + case GSK_OPACITY_NODE: + count_nodes (gsk_opacity_node_get_child (node), counts, &d); + break; + + case GSK_COLOR_MATRIX_NODE: + count_nodes (gsk_color_matrix_node_get_child (node), counts, &d); + break; + + case GSK_REPEAT_NODE: + count_nodes (gsk_repeat_node_get_child (node), counts, &d); + break; + + case GSK_CLIP_NODE: + count_nodes (gsk_clip_node_get_child (node), counts, &d); + break; + + case GSK_ROUNDED_CLIP_NODE: + count_nodes (gsk_rounded_clip_node_get_child (node), counts, &d); + break; + + case GSK_SHADOW_NODE: + count_nodes (gsk_shadow_node_get_child (node), counts, &d); + break; + + case GSK_BLEND_NODE: + count_nodes (gsk_blend_node_get_bottom_child (node), counts, &d); + count_nodes (gsk_blend_node_get_top_child (node), counts, &dd); + d = MAX (d, dd); + break; + + case GSK_CROSS_FADE_NODE: + count_nodes (gsk_cross_fade_node_get_start_child (node), counts, &d); + count_nodes (gsk_cross_fade_node_get_end_child (node), counts, &dd); + d = MAX (d, dd); + break; + + case GSK_TEXT_NODE: + break; + + case GSK_BLUR_NODE: + count_nodes (gsk_blur_node_get_child (node), counts, &d); + break; + + case GSK_DEBUG_NODE: + count_nodes (gsk_debug_node_get_child (node), counts, &d); + break; + + case GSK_GL_SHADER_NODE: + for (unsigned int i = 0; i < gsk_gl_shader_node_get_n_children (node); i++) + { + count_nodes (gsk_gl_shader_node_get_child (node, i), counts, &dd); + d = MAX (d, dd); + } + break; + + case GSK_TEXTURE_SCALE_NODE: + break; + + case GSK_MASK_NODE: + count_nodes (gsk_mask_node_get_source (node), counts, &d); + count_nodes (gsk_mask_node_get_mask (node), counts, &dd); + d = MAX (d, dd); + break; + + case GSK_NOT_A_RENDER_NODE: + default: + g_assert_not_reached (); + } + + *depth = d + 1; +} + +static const char * +get_node_name (GskRenderNodeType type) +{ + GEnumClass *class; + GEnumValue *value; + const char *name; + + class = g_type_class_ref (GSK_TYPE_RENDER_NODE_TYPE); + value = g_enum_get_value (class, type); + name = value->value_nick; + g_type_class_unref (class); + + return name; +} + +static void +file_info (const char *filename) +{ + GskRenderNode *node; + unsigned int counts[GSK_MASK_NODE + 1] = { 0, }; + unsigned int total = 0; + unsigned int namelen = 0; + unsigned int depth = 0; + graphene_rect_t bounds; + + node = load_node_file (filename); + + count_nodes (node, counts, &depth); + + for (unsigned int i = 0; i < G_N_ELEMENTS (counts); i++) + { + total += counts[i]; + if (counts[i] > 0) + namelen = MAX (namelen, strlen (get_node_name (i))); + } + + g_print (_("Number of nodes: %u\n"), total); + for (unsigned int i = 0; i < G_N_ELEMENTS (counts); i++) + { + if (counts[i] > 0) + g_print (" %*s: %u\n", namelen, get_node_name (i), counts[i]); + } + + g_print (_("Depth: %u\n"), depth); + + gsk_render_node_get_bounds (node, &bounds); + g_print (_("Bounds: %g x %g\n"), bounds.size.width, bounds.size.height); + g_print (_("Origin: %g %g\n"), bounds.origin.x, bounds.origin.y); + + gsk_render_node_unref (node); +} + +void +do_info (int *argc, + const char ***argv) +{ + GOptionContext *context; + char **filenames = NULL; + const GOptionEntry entries[] = { + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") }, + { NULL, } + }; + GError *error = NULL; + + g_set_prgname ("gtk4-rendernode-tool info"); + context = g_option_context_new (NULL); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, _("Provide information about the render node.")); + + if (!g_option_context_parse (context, argc, (char ***)argv, &error)) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + exit (1); + } + + g_option_context_free (context); + + if (filenames == NULL) + { + g_printerr (_("No .node file specified\n")); + exit (1); + } + + if (g_strv_length (filenames) > 1) + { + g_printerr (_("Can only accept a single .node file\n")); + exit (1); + } + + file_info (filenames[0]); + + g_strfreev (filenames); +} diff --git a/tools/gtk-rendernode-tool-render.c b/tools/gtk-rendernode-tool-render.c new file mode 100644 index 0000000000..2279afc9e0 --- /dev/null +++ b/tools/gtk-rendernode-tool-render.c @@ -0,0 +1,165 @@ +/* Copyright 2023 Red Hat, Inc. + * + * GTK+ is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GTK+ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GTK+; see the file COPYING. If not, + * see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include "gtk-rendernode-tool.h" + +static char * +get_save_filename (const char *filename) +{ + int length = strlen (filename); + const char *extension = ".png"; + char *result; + + if (strcmp (filename + (length - strlen (".node")), ".node") == 0) + { + char *basename = g_strndup (filename, length - strlen (".node")); + result = g_strconcat (basename, extension, NULL); + g_free (basename); + } + else + result = g_strconcat (filename, extension, NULL); + + return result; +} + +static void +render_file (const char *filename, + const char *renderer_name, + const char *save_file, + gboolean force) +{ + GskRenderNode *node; + GBytes *bytes; + GdkTexture *texture; + char *save_to; + GskRenderer *renderer; + GdkSurface *window; + GError *error = NULL; + + 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); + + save_to = (char *)save_file; + + if (save_to == NULL) + save_to = get_save_filename (filename); + + if (g_file_test (save_to, G_FILE_TEST_EXISTS) && !force) + { + g_printerr (_("File %s exists.\n" + "Use --force to overwrite.\n"), save_to); + exit (1); + } + + bytes = gdk_texture_save_to_png_bytes (texture); + + if (g_file_set_contents (save_to, + g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + &error)) + { + if (save_file == NULL) + g_print (_("Output written to %s.\n"), save_to); + } + else + { + g_printerr (_("Failed to save %s: %s\n"), save_to, error->message); + exit (1); + } + + g_bytes_unref (bytes); + + if (save_to != save_file) + g_free (save_to); + + g_object_unref (texture); + gsk_render_node_unref (node); +} + +void +do_render (int *argc, + const char ***argv) +{ + GOptionContext *context; + char **filenames = NULL; + gboolean force = FALSE; + char *renderer = NULL; + const GOptionEntry entries[] = { + { "renderer", 0, 0, G_OPTION_ARG_STRING, &renderer, N_("Renderer to use"), N_("RENDERER") }, + { "force", 0, 0, G_OPTION_ARG_NONE, &force, N_("Overwrite existing file"), NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE…") }, + { NULL, } + }; + GError *error = NULL; + + if (gdk_display_get_default () == NULL) + { + g_printerr (_("Could not initialize windowing system\n")); + exit (1); + } + + g_set_prgname ("gtk4-rendernode-tool render"); + context = g_option_context_new (NULL); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, _("Render a .node file to an image.")); + + if (!g_option_context_parse (context, argc, (char ***)argv, &error)) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + exit (1); + } + + g_option_context_free (context); + + if (filenames == NULL) + { + g_printerr (_("No .node file specified\n")); + exit (1); + } + + if (g_strv_length (filenames) > 2) + { + g_printerr (_("Can only render a single .node file to a single output file\n")); + exit (1); + } + + render_file (filenames[0], renderer, filenames[1], force); + + g_strfreev (filenames); +} diff --git a/tools/gtk-rendernode-tool-show.c b/tools/gtk-rendernode-tool-show.c new file mode 100644 index 0000000000..487f73c293 --- /dev/null +++ b/tools/gtk-rendernode-tool-show.c @@ -0,0 +1,143 @@ +/* Copyright 2023 Red Hat, Inc. + * + * GTK+ is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GTK+ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GTK+; see the file COPYING. If not, + * see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include "gtk-rendernode-tool.h" + + +static void +set_window_title (GtkWindow *window, + const char *filename) +{ + char *name; + + name = g_path_get_basename (filename); + gtk_window_set_title (window, name); + g_free (name); +} + +static void +quit_cb (GtkWidget *widget, + gpointer user_data) +{ + gboolean *is_done = user_data; + + *is_done = TRUE; + + g_main_context_wakeup (NULL); +} + +static void +show_file (const char *filename) +{ + GskRenderNode *node; + GdkPaintable *paintable; + GtkWidget *sw; + GtkWidget *window; + gboolean done = FALSE; + GtkSnapshot *snapshot; + GtkWidget *picture; + + node = load_node_file (filename); + + snapshot = gtk_snapshot_new (); + gtk_snapshot_append_node (snapshot, node); + paintable = gtk_snapshot_free_to_paintable (snapshot, NULL); + + picture = gtk_picture_new_for_paintable (paintable); + gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE); + gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_SCALE_DOWN); + + sw = gtk_scrolled_window_new (); + gtk_scrolled_window_set_propagate_natural_width (GTK_SCROLLED_WINDOW (sw), TRUE); + gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (sw), TRUE); + gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), picture); + + window = gtk_window_new (); + set_window_title (GTK_WINDOW (window), filename); + gtk_window_set_child (GTK_WINDOW (window), sw); + + gtk_window_present (GTK_WINDOW (window)); + g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done); + + while (!done) + g_main_context_iteration (NULL, TRUE); + + g_clear_object (&paintable); + g_clear_pointer (&node, gsk_render_node_unref); +} + +void +do_show (int *argc, + const char ***argv) +{ + GOptionContext *context; + char **filenames = NULL; + const GOptionEntry entries[] = { + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") }, + { NULL, } + }; + GError *error = NULL; + + if (gdk_display_get_default () == NULL) + { + g_printerr (_("Could not initialize windowing system\n")); + exit (1); + } + + g_set_prgname ("gtk4-rendernode-tool show"); + context = g_option_context_new (NULL); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_set_summary (context, _("Show the render node.")); + + if (!g_option_context_parse (context, argc, (char ***)argv, &error)) + { + g_printerr ("%s\n", error->message); + g_error_free (error); + exit (1); + } + + g_option_context_free (context); + + if (filenames == NULL) + { + g_printerr (_("No .node file specified\n")); + exit (1); + } + + if (g_strv_length (filenames) > 1) + { + g_printerr (_("Can only preview a single .node file\n")); + exit (1); + } + + show_file (filenames[0]); + + g_strfreev (filenames); +} diff --git a/tools/gtk-rendernode-tool-utils.c b/tools/gtk-rendernode-tool-utils.c new file mode 100644 index 0000000000..07ba2d877b --- /dev/null +++ b/tools/gtk-rendernode-tool-utils.c @@ -0,0 +1,77 @@ +/* Copyright 2023 Red Hat, Inc. + * + * GTK+ is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GTK+ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GTK+; see the file COPYING. If not, + * see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include "gtk-rendernode-tool.h" + + +static void +deserialize_error_func (const GskParseLocation *start, + const GskParseLocation *end, + const GError *error, + gpointer user_data) +{ + GString *string = g_string_new (""); + + g_string_append_printf (string, ":%zu:%zu", + start->lines + 1, start->line_chars + 1); + if (start->lines != end->lines || start->line_chars != end->line_chars) + { + g_string_append (string, "-"); + if (start->lines != end->lines) + g_string_append_printf (string, "%zu:", end->lines + 1); + g_string_append_printf (string, "%zu", end->line_chars + 1); + } + + g_printerr (_("Error at %s: %s\n"), string->str, error->message); + + g_string_free (string, TRUE); +} + +GskRenderNode * +load_node_file (const char *filename) +{ + GFile *file; + GBytes *bytes; + GError *error = NULL; + + file = g_file_new_for_commandline_arg (filename); + bytes = g_file_load_bytes (file, NULL, NULL, NULL); + g_object_unref (file); + + if (bytes == NULL) + return NULL; + + if (!g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL)) + { + g_bytes_unref (bytes); + return NULL; + } + + return gsk_render_node_deserialize (bytes, deserialize_error_func, &error); +} diff --git a/tools/gtk-rendernode-tool.c b/tools/gtk-rendernode-tool.c new file mode 100644 index 0000000000..fa2d42635e --- /dev/null +++ b/tools/gtk-rendernode-tool.c @@ -0,0 +1,120 @@ +/* Copyright 2023 Red Hat, Inc. + * + * GTK+ is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GTK+ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GTK+; see the file COPYING. If not, + * see . + * + * Author: Matthias Clasen + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include "gtk-rendernode-tool.h" + +static void G_GNUC_NORETURN +usage (void) +{ + g_print (_("Usage:\n" + " gtk4-rendernode-tool [COMMAND] [OPTION…] FILE\n" + "\n" + "Perform various tasks on GTK render nodes.\n" + "\n" + "Commands:\n" + " info Provide information about the node\n" + " show Show the node\n" + " render Take a screenshot of the node\n" + "\n")); + exit (1); +} + +static GLogWriterOutput +log_writer_func (GLogLevelFlags level, + const GLogField *fields, + gsize n_fields, + gpointer user_data) +{ + gsize i; + const char *domain = NULL; + const char *message = NULL; + + for (i = 0; i < n_fields; i++) + { + if (g_strcmp0 (fields[i].key, "GLIB_DOMAIN") == 0) + domain = fields[i].value; + else if (g_strcmp0 (fields[i].key, "MESSAGE") == 0) + message = fields[i].value; + } + + if (message != NULL && !g_log_writer_default_would_drop (level, domain)) + { + const char *prefix; + switch (level & G_LOG_LEVEL_MASK) + { + case G_LOG_LEVEL_ERROR: + prefix = "ERROR"; + break; + case G_LOG_LEVEL_CRITICAL: + prefix = "CRITICAL"; + break; + case G_LOG_LEVEL_WARNING: + prefix = "WARNING"; + break; + default: + prefix = "INFO"; + break; + } + g_printerr ("%s-%s: %s\n", domain, prefix, message); + } + + return G_LOG_WRITER_HANDLED; +} + +int +main (int argc, const char *argv[]) +{ + g_set_prgname ("gtk-rendernode-tool"); + + g_log_set_writer_func (log_writer_func, NULL, NULL); + + gtk_init_check (); + + gtk_test_register_all_types (); + + if (argc < 2) + usage (); + + if (strcmp (argv[1], "--help") == 0) + usage (); + + argv++; + argc--; + + if (strcmp (argv[0], "show") == 0) + do_show (&argc, &argv); + else if (strcmp (argv[0], "render") == 0) + do_render (&argc, &argv); + else if (strcmp (argv[0], "info") == 0) + do_info (&argc, &argv); + else + usage (); + + return 0; +} diff --git a/tools/gtk-rendernode-tool.h b/tools/gtk-rendernode-tool.h new file mode 100644 index 0000000000..adece50e12 --- /dev/null +++ b/tools/gtk-rendernode-tool.h @@ -0,0 +1,8 @@ + +#pragma once + +void do_show (int *argc, const char ***argv); +void do_render (int *argc, const char ***argv); +void do_info (int *argc, const char ***argv); + +GskRenderNode *load_node_file (const char *filename); diff --git a/tools/meson.build b/tools/meson.build index af77a7abb6..5023a38737 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -31,6 +31,11 @@ gtk_tools = [ 'gtk-builder-tool-screenshot.c', 'gtk-builder-tool-preview.c', 'fake-scope.c'], [libgtk_dep] ], + ['gtk4-rendernode-tool', ['gtk-rendernode-tool.c', + 'gtk-rendernode-tool-info.c', + 'gtk-rendernode-tool-render.c', + 'gtk-rendernode-tool-show.c', + 'gtk-rendernode-tool-utils.c'], [libgtk_dep] ], ['gtk4-update-icon-cache', ['updateiconcache.c', '../gtk/gtkiconcachevalidator.c' ] + extra_update_icon_cache_objs, [ libgtk_dep ] ], ['gtk4-encode-symbolic-svg', ['encodesymbolic.c'], [ libgtk_static_dep ] ], ]