#include <gtk/gtk.h>
#include "../reftests/reftest-compare.h"
static char *arg_output_dir = NULL;
static const char *
get_output_dir (void )
{
static const char *output_dir = NULL;
GError *error = NULL;
GFile *file;
if (output_dir)
return output_dir;
if (arg_output_dir)
{
GFile *arg_file = g_file_new_for_commandline_arg (arg_output_dir);
const char *subdir;
subdir = g_getenv ("TEST_OUTPUT_SUBDIR" );
if (subdir)
{
GFile *child = g_file_get_child (arg_file, subdir);
g_object_unref (arg_file);
arg_file = child;
}
output_dir = g_file_get_path (arg_file);
g_object_unref (arg_file);
}
else
{
output_dir = g_get_tmp_dir ();
}
/* Just try to create the output directory.
* If it already exists , that ' s exactly what we wanted to check ,
* so we can happily skip that error .
*/
file = g_file_new_for_path (output_dir);
if (!g_file_make_directory_with_parents (file, NULL, &error))
{
g_object_unref (file);
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
{
g_error ("Failed to create output dir: %s" , error->message);
g_error_free (error);
return NULL;
}
g_error_free (error);
}
else
g_object_unref (file);
return output_dir;
}
static char *
file_replace_extension (const char *old_file,
const char *old_ext,
const char *new_ext)
{
GString *file = g_string_new (NULL);
if (g_str_has_suffix (old_file, old_ext))
g_string_append_len (file, old_file, strlen (old_file) - strlen (old_ext));
else
g_string_append (file, old_file);
g_string_append (file, new_ext);
return g_string_free (file, FALSE );
}
static char *
get_output_file (const char *file,
const char *variant,
const char *orig_ext,
const char *new_ext)
{
const char *dir;
char *result, *base;
char *name;
dir = get_output_dir ();
base = g_path_get_basename (file);
if (variant)
{
char *s = file_replace_extension (base, orig_ext, "" );
name = g_strconcat (s, "-" , variant, new_ext, NULL);
g_free (s);
}
else
{
name = file_replace_extension (base, orig_ext, new_ext);
}
result = g_strconcat (dir, G_DIR_SEPARATOR_S, name, NULL);
g_free (base);
g_free (name);
return result;
}
static void
save_image (GdkTexture *texture,
const char *file,
const char *variant_name,
const char *extension)
{
char *filename = get_output_file (file, variant_name, ".svg" , extension);
gboolean result;
g_print ("Storing test result image at %s\n" , filename);
result = gdk_texture_save_to_png (texture, filename);
g_assert_true (result);
g_free (filename);
}
static GdkTexture *
svg_to_texture (const char *filename)
{
GFile *file;
GtkIconPaintable *icon;
GtkSnapshot *snapshot;
GdkRGBA colors[4 ] = {
{ 0 , 0 , 0 , 1 },
{ 1 , 0 , 0 , 1 },
{ 1 , 1 , 0 , 1 },
{ 0 , 1 , 0 , 1 },
};
GskRenderNode *node;
GdkSurface *surface;
GskRenderer *renderer;
GdkTexture *texture;
file = g_file_new_for_commandline_arg (filename);
icon = gtk_icon_paintable_new_for_file (file, 16 , 1 );
snapshot = gtk_snapshot_new ();
gtk_symbolic_paintable_snapshot_symbolic (GTK_SYMBOLIC_PAINTABLE (icon),
snapshot,
16 , 16 ,
colors,
G_N_ELEMENTS (colors));
node = gtk_snapshot_free_to_node (snapshot);
if (node == NULL)
node = gsk_color_node_new (&(GdkRGBA) { 0 , 0 , 0 , 0 }, &GRAPHENE_RECT_INIT (0 , 0 , 16 , 16 ));
surface = gdk_surface_new_toplevel (gdk_display_get_default ());
renderer = gsk_renderer_new_for_surface (surface);
texture = gsk_renderer_render_texture (renderer, node, &GRAPHENE_RECT_INIT (0 , 0 , 16 , 16 ));
gsk_render_node_unref (node);
gsk_renderer_unrealize (renderer);
g_object_unref (renderer);
gdk_surface_destroy (surface);
g_object_unref (icon);
g_object_unref (file);
return texture;
}
static void
test_symbolic (gconstpointer data)
{
GFile *file = (GFile *) data;
const char *filename;
char *ref_filename;
GdkTexture *texture, *reference, *diff;
GError *error = NULL;
filename = g_file_peek_path (file);
texture = svg_to_texture (filename);
ref_filename = file_replace_extension (filename, ".svg" , ".png" );
reference = gdk_texture_new_from_filename (ref_filename, &error);
if (reference == NULL)
{
g_print ("Error loading reference image: %s\n" , error->message);
g_clear_error (&error);
g_test_fail ();
return ;
}
diff = reftest_compare_textures (reference, texture);
if (diff)
{
save_image (texture, filename, NULL, ".out.png" );
save_image (diff, filename, NULL, ".diff.png" );
g_test_fail ();
}
g_object_unref (reference);
g_free (ref_filename);
g_object_unref (texture);
}
static int
compare_files (gconstpointer a, gconstpointer b)
{
GFile *file1 = G_FILE (a);
GFile *file2 = G_FILE (b);
char *path1, *path2;
int result;
path1 = g_file_get_path (file1);
path2 = g_file_get_path (file2);
result = strcmp (path1, path2);
g_free (path1);
g_free (path2);
return result;
}
int
main (int argc, char *argv[])
{
GOptionEntry options[] = {
{ "output" , 0 , 0 , G_OPTION_ARG_FILENAME, &arg_output_dir, "Directory to save image files to" , "DIR" },
{ NULL }
};
GOptionContext *context;
char *dir;
GFile *file;
GFileEnumerator *enumerator;
GFileInfo *info;
GList *files;
GError *error = NULL;
gtk_test_init (&argc, &argv);
context = g_option_context_new ("" );
g_option_context_add_main_entries (context, options, NULL);
g_option_context_set_ignore_unknown_options (context, TRUE );
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_error ("Option parsing failed: %s\n" , error->message);
return 1 ;
}
g_option_context_free (context);
if (argc > 1 )
{
GdkTexture *texture;
char *out;
texture = svg_to_texture (argv[1 ]);
g_assert_nonnull (texture);
out = file_replace_extension (argv[1 ], ".svg" , ".png" );
gdk_texture_save_to_png (texture, out);
g_free (out);
g_object_unref (texture);
return 0 ;
}
dir = g_test_build_filename (G_TEST_DIST, "symbolic-icons" , NULL);
file = g_file_new_for_path (dir);
enumerator = g_file_enumerate_children (file, G_FILE_ATTRIBUTE_STANDARD_NAME, 0 , NULL, &error);
g_assert_no_error (error);
files = NULL;
while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)) != NULL)
{
const char *filename;
filename = g_file_info_get_name (info);
if (!g_str_has_suffix (filename, ".svg" ))
{
g_object_unref (info);
continue ;
}
files = g_list_prepend (files, g_file_get_child (file, filename));
g_object_unref (info);
}
g_object_unref (enumerator);
g_object_unref (file);
g_free (dir);
files = g_list_sort (files, compare_files);
for (GList *l = files; l; l = l->next)
{
file = l->data;
char *basename, *testname;
basename = g_file_get_basename (file);
testname = g_strconcat ("/symbolic/" , basename, NULL);
g_test_add_data_func_full (testname, g_object_ref (file), test_symbolic, g_object_unref);
g_free (testname);
g_free (basename);
}
g_list_free_full (files, g_object_unref);
return g_test_run ();
}
Messung V0.5 in Prozent C=98 H=93 G=95
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-07-02)
¤
*© Formatika GbR, Deutschland