/* Copyright (C) 2025 Red Hat, Inc
* Author : Matthias Clasen
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation ; either
* version 2 of the License , or ( at your option ) any later version .
*
* This library 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
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library . If not , see < http : //www.gnu.org/licenses/>.
*/
#include <gtk/gtk.h>
#include "svgpaintable.h"
/* Compare librsvg and SVG renderer rendering of a directory full of SVGs
*/
int
main (int argc, char *argv[])
{
GtkWidget *window, *sw, *grid;
GFile *file;
GFileEnumerator *dir;
int row;
GtkWidget *label;
GPtrArray *files;
GOptionContext *context;
gboolean allow_shrink = FALSE ;
gboolean show_rsvg = TRUE ;
gboolean show_gtk = TRUE ;
gboolean show_sym = TRUE ;
gboolean show_png = TRUE ;
int size = 24 ;
const GOptionEntry entries[] = {
{ "no-rsvg" , 0 , G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &show_rsvg, "Don't show rsvg rendering" , NULL },
{ "no-gtk" , 0 , G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &show_gtk, "Don't show gtk svg rendering" , NULL },
{ "no-symbolic" , 0 , G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &show_sym, "Don't show gtk symbolic rendering" , NULL },
{ "no-png" , 0 , G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &show_png, "Don't show reference image" , NULL },
{ "allow-shrink" , 0 , 0 , G_OPTION_ARG_NONE, &allow_shrink, "Allow to shrink rendering" , NULL },
{ "size" , 0 , 0 , G_OPTION_ARG_INT, &size, "Minimum size" },
{ NULL, 0 },
};
GError *error = NULL;
g_set_prgname ("svg-compare" );
context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_set_summary (context, "Compare svg rendering between gtk and rsvg." );
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s\n" , error->message);
g_error_free (error);
exit (1 );
}
gtk_init ();
window = gtk_window_new ();
gtk_window_set_default_size (GTK_WINDOW (window), 600 , 400 );
if (argc < 2 )
{
char *directory = g_get_current_dir ();
file = g_file_new_for_commandline_arg (directory);
g_free (directory);
}
else
{
file = g_file_new_for_commandline_arg (argv[1 ]);
}
sw = gtk_scrolled_window_new ();
gtk_window_set_child (GTK_WINDOW (window), sw);
grid = gtk_grid_new ();
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), grid);
files = g_ptr_array_new_with_free_func (g_free);
if (g_file_query_file_type (file, 0 , NULL) == G_FILE_TYPE_DIRECTORY)
{
dir = g_file_enumerate_children (file,
"standard::name" ,
G_FILE_QUERY_INFO_NONE,
NULL,
&error);
if (!dir)
g_error ("%s" , error->message);
while (1 )
{
GFile *child;
const char *path;
if (!g_file_enumerator_iterate (dir, NULL, &child, NULL, &error))
g_error ("%s" , error->message);
if (!child)
break ;
path = g_file_peek_path (child);
if ((g_str_has_suffix (path, ".svg" ) ||
g_str_has_suffix (path, ".gpa" )) &&
!g_str_has_suffix (path, ".ref.svg" ))
g_ptr_array_add (files, g_strdup (path));
}
g_object_unref (dir);
}
else
{
g_ptr_array_add (files, g_file_get_path (file));
}
g_ptr_array_sort_values (files, (GCompareFunc) strcmp);
if (show_rsvg)
{
label = gtk_label_new ("rsvg" );
gtk_label_set_xalign (GTK_LABEL (label), 0 .5 );
gtk_grid_attach (GTK_GRID (grid), label, 1 , -1 , 1 , 1 );
}
if (show_gtk)
{
label = gtk_label_new ("GtkSvg" );
gtk_label_set_xalign (GTK_LABEL (label), 0 .5 );
gtk_grid_attach (GTK_GRID (grid), label, 2 , -1 , 1 , 1 );
}
if (show_sym)
{
label = gtk_label_new ("GtkIconPaintable" );
gtk_label_set_xalign (GTK_LABEL (label), 0 .5 );
gtk_grid_attach (GTK_GRID (grid), label, 3 , -1 , 1 , 1 );
}
if (show_png)
{
label = gtk_label_new ("png" );
gtk_label_set_xalign (GTK_LABEL (label), 0 .5 );
gtk_grid_attach (GTK_GRID (grid), label, 4 , -1 , 1 , 1 );
}
row = 0 ;
for (unsigned int i = 0 ; i < files->len; i++)
{
GFile *child;
const char *path;
char *basename;
GdkPaintable *svg;
GBytes *bytes;
GtkWidget *img;
path = g_ptr_array_index (files, i);
child = g_file_new_for_path (path);
basename = g_file_get_basename (child);
label = gtk_label_new (basename);
gtk_label_set_xalign (GTK_LABEL (label), 0 );
gtk_grid_attach (GTK_GRID (grid), label, 0 , row, 1 , 1 );
if (show_rsvg)
{
svg = GDK_PAINTABLE (svg_paintable_new (child));
if (svg)
{
img = gtk_picture_new_for_paintable (svg);
gtk_picture_set_can_shrink (GTK_PICTURE (img), allow_shrink);
gtk_widget_set_size_request (img, size, size);
gtk_grid_attach (GTK_GRID (grid), img, 1 , row, 1 , 1 );
g_object_unref (svg);
}
}
if (show_gtk)
{
bytes = g_file_load_bytes (child, NULL, NULL, NULL);
svg = GDK_PAINTABLE (gtk_svg_new_from_bytes (bytes));
if (svg)
{
img = gtk_picture_new_for_paintable (svg);
gtk_svg_play (GTK_SVG (svg));
gtk_picture_set_can_shrink (GTK_PICTURE (img), allow_shrink);
gtk_widget_set_size_request (img, size, size);
gtk_grid_attach (GTK_GRID (grid), img, 2 , row, 1 , 1 );
g_object_unref (svg);
g_bytes_unref (bytes);
}
else
{
g_warning ("%s" , error->message);
g_clear_error (&error);
}
}
if (show_sym)
{
GdkPaintable *sym;
sym = GDK_PAINTABLE (gtk_icon_paintable_new_for_file (child, size, 1 ));
if (sym)
{
img = gtk_picture_new_for_paintable (sym);
gtk_picture_set_can_shrink (GTK_PICTURE (img), allow_shrink);
gtk_widget_set_size_request (img, size, size);
gtk_grid_attach (GTK_GRID (grid), img, 3 , row, 1 , 1 );
g_object_unref (sym);
}
}
if (show_png)
{
char *png_path = g_strdup (path);
GdkPaintable *paintable;
png_path[strlen (path) - 3 ] = 'p' ;
png_path[strlen (path) - 2 ] = 'n' ;
png_path[strlen (path) - 1 ] = 'g' ;
paintable = GDK_PAINTABLE (gdk_texture_new_from_filename (png_path, NULL));
if (paintable)
{
img = gtk_picture_new_for_paintable (paintable);
gtk_picture_set_can_shrink (GTK_PICTURE (img), allow_shrink);
gtk_widget_set_size_request (img, size, size);
gtk_widget_set_halign (img, GTK_ALIGN_START);
gtk_grid_attach (GTK_GRID (grid), img, 4 , row, 1 , 1 );
g_object_unref (paintable);
}
g_free (png_path);
}
row++;
g_free (basename);
}
g_ptr_array_unref (files);
g_object_unref (file);
gtk_window_present (GTK_WINDOW (window));
while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0 )
g_main_context_iteration (NULL, TRUE );
return 0 ;
}
Messung V0.5 in Prozent C=99 H=99 G=98
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland