|
56 | 56 |
|
57 | 57 | #include <regex.h> |
58 | 58 |
|
| 59 | +#include <cairo.h> // To get the size of icons, determine_icon_destination() |
| 60 | + |
59 | 61 | #define FNM_FILE_NAME 2 |
60 | 62 |
|
61 | 63 | #define URI_MAX (FILE_MAX * 3 + 8) |
@@ -125,6 +127,56 @@ char * get_thumbnail_path(char *path, char *thumbnail_size, gboolean verbose) |
125 | 127 | return thumbnail_path; |
126 | 128 | } |
127 | 129 |
|
| 130 | +/* Return the path where a given icon can be installed in $HOME. |
| 131 | + * This is needed because png and xpm icons cannot be installed in a generic |
| 132 | + * location but are only picked up in directories that have the size of |
| 133 | + * the icon as part of their directory name, as specified in the theme.index |
| 134 | + * See https://github.com/probonopd/AppImageKit/issues/258 |
| 135 | + */ |
| 136 | + |
| 137 | +gchar* determine_icon_destination(gchar *icon_path) |
| 138 | +{ |
| 139 | + gchar *dest_dir; |
| 140 | + |
| 141 | + if((g_str_has_suffix (icon_path, ".svg")) || (g_str_has_suffix (icon_path, ".svgz"))) { |
| 142 | + dest_dir = g_build_path("/", g_get_user_data_dir(), "/icons/hicolor/scalable", NULL); |
| 143 | + } |
| 144 | + |
| 145 | + if((g_str_has_suffix (icon_path, ".png")) || (g_str_has_suffix (icon_path, ".xpm"))) { |
| 146 | + |
| 147 | + cairo_surface_t *image; |
| 148 | + |
| 149 | + if(g_str_has_suffix (icon_path, ".xpm")) { |
| 150 | + // TODO: GdkPixbuf has a convenient way to load XPM data. Then you can call |
| 151 | + // gdk_cairo_set_source_pixbuf() to transfer the data to a Cairo surface. |
| 152 | + fprintf(stderr, "XPM size parsing not yet implemented\n"); |
| 153 | + return NULL; |
| 154 | + } |
| 155 | + |
| 156 | + if(g_str_has_suffix (icon_path, ".png")) { |
| 157 | + image = cairo_image_surface_create_from_png(icon_path); |
| 158 | + } |
| 159 | + |
| 160 | + int w = cairo_image_surface_get_width (image); |
| 161 | + int h = cairo_image_surface_get_height (image); |
| 162 | + |
| 163 | + // FIXME: The following sizes are taken from the hicolor icon theme. |
| 164 | + // Probably the right thing to do would be to figure out at runtime which icon sizes are allowable. |
| 165 | + // Or could we put our own index.theme into .local/share/icons/ and have it observed? |
| 166 | + if((w != h) || ((w != 16) && (w != 24) && (w != 32) && (w != 36) && (w != 48) && (w != 64) && (w != 72) && (w != 96) && (w != 128) && (w != 192) && (w != 256) && (w != 512))){ |
| 167 | + fprintf(stderr, "%s has nonstandard size w = %i, h = %i; please fix it\n", icon_path, w, h); |
| 168 | + return NULL; |
| 169 | + } |
| 170 | + |
| 171 | + cairo_surface_destroy (image); |
| 172 | + |
| 173 | + dest_dir = g_build_path("/", g_get_user_data_dir(), "/icons/hicolor/", g_strdup_printf("%ix%i", w, h), NULL); |
| 174 | + } |
| 175 | + |
| 176 | + return(dest_dir); |
| 177 | + |
| 178 | +} |
| 179 | + |
128 | 180 | /* Check if a file is an AppImage. Returns the image type if it is, or -1 if it isn't */ |
129 | 181 | int check_appimage_type(char *path, gboolean verbose) |
130 | 182 | { |
|
0 commit comments