From bc999325be74e0b157dc04158fd67fa9f7ab8cef Mon Sep 17 00:00:00 2001 From: Jehan Date: Fri, 28 Jan 2022 22:34:02 +0100 Subject: [PATCH] icons, tools: new colorsvg2png tool to build PNG out of SVG. Build-time tool, which basically just rasterize SVG images (it doesn't do anything special like gtk-encode-symbolic-svg which creates special PNG for GTK to recolor them). It looks like I had this prepared since 2018 according to file header, but I just never finished doing it! :P Basically now PNG icons of the Color icon themes do not need anymore to be committed in the repository. They will be generated from the SVG icons. Also adding a missing icon from the 16px list (the Playground icon for Preferences dialog was needed in 16x16 as well, yet missing). --- configure.ac | 42 +++++++++++++--- icons/Color/Makefile.am | 43 +++++++++++++++++ icons/Color/icon-list.mk | 1 + icons/Color/meson.build | 38 +++++++++------ icons/Symbolic/icon-list.mk | 1 + icons/icon-lists/bitmap_16.list | 1 + meson.build | 17 +++++++ tools/Makefile.am | 14 ++++++ tools/colorsvg2png.c | 85 +++++++++++++++++++++++++++++++++ tools/meson.build | 12 +++++ 10 files changed, 233 insertions(+), 21 deletions(-) create mode 100644 tools/colorsvg2png.c diff --git a/configure.ac b/configure.ac index aa8ace294c..e2bb934db1 100644 --- a/configure.ac +++ b/configure.ac @@ -2015,12 +2015,6 @@ PKG_CHECK_MODULES(SVG, librsvg-2.0 >= rsvg_required_version,, MIME_TYPES="$MIME_TYPES;image/svg+xml" -AC_CHECK_PROGS(GTK_ENCODE_SYMBOLIC_SVG, gtk-encode-symbolic-svg, no) - -if test "x$GTK_ENCODE_SYMBOLIC_SVG" = xno; then - add_deps_error([gtk-encode-symbolic-svg], - [Could not find gtk-encode-symbolic-svg in your PATH.]) -fi #################################### # Allow to disable the print plug-in @@ -2589,6 +2583,42 @@ WARNING: You enabled vector icons on Win32. Make sure to run: fi fi +if test "x$enable_vector_icons" != "xyes"; then + # The trick when disabling vector icons is that librsvg is still + # needed at compile time (on build machine) to generate PNG, even + # though it won't be needed at runtime for icon display. + # + # The tool gtk-encode-symbolic-svg also requires a SVG GdkPixbuf + # loader, which usually uses librsvg as well anyway. + warning_vector_icons_windows=" +WARNING: vector icons are disabled. Be aware that librsvg is still + needed to create the PNG icons on the build machine, yet it + won't be needed for runtime icon display of distributed themes." + + AC_CHECK_PROGS(GTK_ENCODE_SYMBOLIC_SVG, gtk-encode-symbolic-svg, no) + + if test "x$GTK_ENCODE_SYMBOLIC_SVG" = xno; then + add_deps_error([gtk-encode-symbolic-svg], + [Could not find gtk-encode-symbolic-svg in your PATH.]) + fi + + if pkg-config --atleast-version=glib_required_version glib-2.0 && + pkg-config gio-2.0; then + NATIVE_GLIB_LIBS=`pkg-config --libs gio-2.0 glib-2.0` + NATIVE_GLIB_CFLAGS=`pkg-config --cflags gio-2.0 glib-2.0` + if pkg-config --atleast-version=rsvg_required_version librsvg-2.0; then + NATIVE_SVG_LIBS=`pkg-config --libs librsvg-2.0` + NATIVE_SVG_CFLAGS=`pkg-config --cflags librsvg-2.0` + AC_SUBST(NATIVE_SVG_CFLAGS) + AC_SUBST(NATIVE_SVG_LIBS) + else + add_deps_error([native librsvg-2.0], [Could not find librsvg for the build system.]) + fi + else + add_deps_error([native glib], [Could not find GLib for the build system.]) + fi +fi + AC_SUBST(NATIVE_GLIB_LIBS) AC_SUBST(NATIVE_GLIB_CFLAGS) AM_CONDITIONAL(ENABLE_VECTOR_ICONS, test "x$enable_vector_icons" = "xyes") diff --git a/icons/Color/Makefile.am b/icons/Color/Makefile.am index 75dfe5dc92..191eeb7270 100644 --- a/icons/Color/Makefile.am +++ b/icons/Color/Makefile.am @@ -23,6 +23,49 @@ endif # SVG=`$(top_srcdir)/tools/extract-vector-icon.sh $< $*` && \ # echo $${SVG} > $@ +12/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +16/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +16/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +18/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +20/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +22/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +24/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +32/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +48/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +64/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +96/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +128/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +192/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) +256/%.png: scalable/%.svg ../../tools/colorsvg2png + mkdir -p $(@D) && \ + $(top_builddir)/tools/colorsvg2png $< $@ $(@D) + ## Compiled-in icons for both the core and libgimpwidgets CORE_IMAGES = \ diff --git a/icons/Color/icon-list.mk b/icons/Color/icon-list.mk index c8a99194dd..8f43274f17 100644 --- a/icons/Color/icon-list.mk +++ b/icons/Color/icon-list.mk @@ -567,6 +567,7 @@ icons16_images = \ 16/gimp-prefs-image-windows.png \ 16/gimp-prefs-import-export.png \ 16/gimp-prefs-interface.png \ + 16/gimp-prefs-playground.png \ 16/gimp-prefs-theme.png \ 16/gimp-prefs-toolbox.png \ 16/gimp-prefs-window-management.png \ diff --git a/icons/Color/meson.build b/icons/Color/meson.build index 73b3514380..b14549c0db 100644 --- a/icons/Color/meson.build +++ b/icons/Color/meson.build @@ -6,22 +6,30 @@ if have_vector_icons 'bitmap_64-always': [ '64x64', '64', '.png' ], } else + sizes = [ '12', '16', '18', '20', '22', '24', '32', + '48', '64', '96', '128', '192', '256' ] + + foreach size : sizes + icon_list = '../icon-lists/bitmap_@0@.list'.format(size) + cmd = run_command('python3', '-c', + 'print(",".join([line.strip() for line in open("@0@") if line.strip() != ""]))'.format(icon_list), + check: true) + source_icons = cmd.stdout().strip().split(',') + + if size == '64' + icon_list = '../icon-lists/bitmap_64-system.list' + cmd = run_command('python3', '-c', + 'print(",".join([line.strip() for line in open("@0@") if line.strip() != ""]))'.format(icon_list), + check: true) + source_icons += cmd.stdout().strip().split(',') + endif + + subdir(size) + endforeach + + # These are available as PNG directly. source_icons = { - 'bitmap_12': [ '12x12', '12', '.png' ], - 'bitmap_16': [ '16x16', '16', '.png' ], - 'bitmap_18': [ '18x18', '18', '.png' ], - 'bitmap_20': [ '20x20', '20', '.png' ], - 'bitmap_22': [ '22x22', '22', '.png' ], - 'bitmap_24': [ '24x24', '24', '.png' ], - 'bitmap_32': [ '32x32', '32', '.png' ], - 'bitmap_48': [ '48x48', '48', '.png' ], - 'bitmap_64': [ '64x64', '64', '.png' ], - 'bitmap_96': [ '96x96', '96', '.png' ], - 'bitmap_128': [ '128x128', '128', '.png' ], - 'bitmap_192': [ '192x192', '192', '.png' ], - 'bitmap_256': [ '256x256', '256', '.png' ], - 'bitmap_64-system': [ '64x64', '64', '.png' ], - 'bitmap_64-always': [ '64x64', '64', '.png' ], + 'bitmap_64-always': [ '64x64', '64', '.png' ], } endif diff --git a/icons/Symbolic/icon-list.mk b/icons/Symbolic/icon-list.mk index 28b3ff341f..3a1e9d0393 100644 --- a/icons/Symbolic/icon-list.mk +++ b/icons/Symbolic/icon-list.mk @@ -567,6 +567,7 @@ icons16_images = \ 16/gimp-prefs-image-windows-symbolic.symbolic.png \ 16/gimp-prefs-import-export-symbolic.symbolic.png \ 16/gimp-prefs-interface-symbolic.symbolic.png \ + 16/gimp-prefs-playground-symbolic.symbolic.png \ 16/gimp-prefs-theme-symbolic.symbolic.png \ 16/gimp-prefs-toolbox-symbolic.symbolic.png \ 16/gimp-prefs-window-management-symbolic.symbolic.png \ diff --git a/icons/icon-lists/bitmap_16.list b/icons/icon-lists/bitmap_16.list index b342d29ae2..54b395f855 100644 --- a/icons/icon-lists/bitmap_16.list +++ b/icons/icon-lists/bitmap_16.list @@ -178,6 +178,7 @@ gimp-prefs-icon-theme gimp-prefs-image-windows gimp-prefs-import-export gimp-prefs-interface +gimp-prefs-playground gimp-prefs-theme gimp-prefs-toolbox gimp-prefs-window-management diff --git a/meson.build b/meson.build index 4fe4f0cc6d..1de77eedf7 100644 --- a/meson.build +++ b/meson.build @@ -1034,6 +1034,23 @@ if have_vector_icons else shared_mime_info = dependency('shared-mime-info') endif +else + # The trick when disabling vector icons is that librsvg is still + # needed at compile time (on build machine) to generate PNG, even + # though it won't be needed at runtime for icon display. + # + # The tool gtk-encode-symbolic-svg also requires a SVG GdkPixbuf + # loader, which usually uses librsvg as well anyway. + vec_warning = ''' + Vector icons are disabled. Be aware that librsvg is still + needed to create the PNG icons on the build machine, yet it + won't be needed for runtime icon display of distributed themes. + ''' + warning(vec_warning) + warnings += vec_warning + + native_glib = dependency('glib-2.0', version: '>='+glib_minver, native: true) + native_rsvg = dependency('librsvg-2.0', version: '>='+rsvg_minver, native: true) endif # Running tests headless diff --git a/tools/Makefile.am b/tools/Makefile.am index 85ec53b527..9390d800f3 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -61,6 +61,20 @@ if ENABLE_VECTOR_ICONS #noinst_PROGRAMS = compute-svg-viewbox #DISTCLEANFILES = compute-svg-viewbox$(BUILD_EXEEXT) + +else +colorsvg2png_SOURCES = colorsvg2png.c + +colorsvg2png_CFLAGS = $(NATIVE_GLIB_CFLAGS) $(NATIVE_SVG_CFLAGS) + +colorsvg2png_LDADD = $(NATIVE_GLIB_LIBS) $(NATIVE_SVG_LIBS) + +# Build tools which must be built for the build platform. +all-local: colorsvg2png$(BUILD_EXEEXT) + +noinst_PROGRAMS = colorsvg2png + +DISTCLEANFILES = colorsvg2png$(BUILD_EXEEXT) endif AM_CPPFLAGS = \ diff --git a/tools/colorsvg2png.c b/tools/colorsvg2png.c new file mode 100644 index 0000000000..ba32d0ebfa --- /dev/null +++ b/tools/colorsvg2png.c @@ -0,0 +1,85 @@ +/* colorsvg2png.c + * Copyright (C) 2018 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +int +main (int argc, char **argv) +{ + GError *error = NULL; + RsvgHandle *handle; + cairo_surface_t *surface; + cairo_t *cr; + RsvgDimensionData original_dim; + + gchar *input; + gchar *output; + gint dim; + + if (argc != 4) + { + g_fprintf (stderr, "Usage: colorsvg2png svg-image png-output size\n"); + return 1; + } + + input = argv[1]; + output = argv[2]; + dim = (gint) g_ascii_strtoull (argv[3], NULL, 10); + if (dim < 1) + { + g_fprintf (stderr, "Usage: invalid dimension %d\n", dim); + return 1; + } + + handle = rsvg_handle_new_from_file (input, &error); + if (! handle) + { + g_fprintf (stderr, + "Error: failed to load '%s' as SVG: %s\n", + input, error->message); + g_error_free (error); + return 1; + } + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, dim, dim); + cr = cairo_create (surface); + rsvg_handle_get_dimensions (handle, &original_dim); + cairo_surface_destroy (surface); + cairo_scale (cr, + (gdouble) dim / (gdouble) original_dim.width, + (gdouble) dim / (gdouble) original_dim.height); + + if (! rsvg_handle_render_cairo (handle, cr)) + { + g_fprintf (stderr, + "Error: failed to render '%s'\n", + input); + return 1; + } + + if (cairo_surface_write_to_png (surface, output) != CAIRO_STATUS_SUCCESS) + { + g_fprintf (stderr, + "Error: failed to write '%s'\n", + output); + return 1; + } + cairo_destroy (cr); + + return 0; +} diff --git a/tools/meson.build b/tools/meson.build index b7a73f94a7..802f441925 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -35,3 +35,15 @@ executable('kernelgen', include_directories: rootInclude, install: false, ) + +if not have_vector_icons + colorsvg2png = executable('colorsvg2png', + 'colorsvg2png.c', + native: true, + dependencies: [ + native_glib, + native_rsvg + ], + install: false, + ) +endif