summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2014-07-10 11:14:12 +0100
committerRichard Hughes <richard@hughsie.com>2014-07-10 11:14:12 +0100
commitd1abe34531841bb9ed3589fcfa83f073f4cb808f (patch)
tree3a3d9e44ac191652b8757d26114287ef449fc4d3
parent868758f37443c4d7a4099ba8ea9288a4c5abab2d (diff)
downloadappstream-glib-d1abe34531841bb9ed3589fcfa83f073f4cb808f.tar.gz
Never upscale icons, either pad or downscale with sharpening
-rw-r--r--libappstream-builder/plugins/asb-plugin-desktop.c73
1 files changed, 60 insertions, 13 deletions
diff --git a/libappstream-builder/plugins/asb-plugin-desktop.c b/libappstream-builder/plugins/asb-plugin-desktop.c
index b6971d4..a83ba91 100644
--- a/libappstream-builder/plugins/asb-plugin-desktop.c
+++ b/libappstream-builder/plugins/asb-plugin-desktop.c
@@ -25,6 +25,9 @@
#include <asb-plugin.h>
+#define __APPSTREAM_GLIB_PRIVATE_H
+#include <as-utils-private.h>
+
/**
* asb_plugin_get_name:
*/
@@ -77,33 +80,77 @@ static GdkPixbuf *
asb_app_load_icon (const gchar *filename, const gchar *logfn, GError **error)
{
GdkPixbuf *pixbuf = NULL;
- _cleanup_object_unref_ GdkPixbuf *pixbuf_tmp;
+ guint pixbuf_height;
+ guint pixbuf_width;
+ guint tmp_height;
+ guint tmp_width;
+ _cleanup_object_unref_ GdkPixbuf *pixbuf_src = NULL;
+ _cleanup_object_unref_ GdkPixbuf *pixbuf_tmp = NULL;
/* open file in native size */
- pixbuf_tmp = gdk_pixbuf_new_from_file (filename, error);
- if (pixbuf_tmp == NULL)
+ pixbuf_src = gdk_pixbuf_new_from_file (filename, error);
+ if (pixbuf_src == NULL)
return NULL;
/* check size */
- if (gdk_pixbuf_get_width (pixbuf_tmp) < 32 ||
- gdk_pixbuf_get_height (pixbuf_tmp) < 32) {
+ if (gdk_pixbuf_get_width (pixbuf_src) < 32 ||
+ gdk_pixbuf_get_height (pixbuf_src) < 32) {
g_set_error (error,
ASB_PLUGIN_ERROR,
ASB_PLUGIN_ERROR_FAILED,
"icon %s was too small %ix%i",
logfn,
- gdk_pixbuf_get_width (pixbuf_tmp),
- gdk_pixbuf_get_height (pixbuf_tmp));
+ gdk_pixbuf_get_width (pixbuf_src),
+ gdk_pixbuf_get_height (pixbuf_src));
return NULL;
}
- /* re-open file at correct size */
- pixbuf = gdk_pixbuf_new_from_file_at_scale (filename, 64, 64,
- FALSE, error);
- if (pixbuf == NULL) {
- g_prefix_error (error, "Failed to open icon %s: ", logfn);
- return NULL;
+ /* don't do anything to an icon with the perfect size */
+ pixbuf_width = gdk_pixbuf_get_width (pixbuf_src);
+ pixbuf_height = gdk_pixbuf_get_height (pixbuf_src);
+ if (pixbuf_width == 64 && pixbuf_height == 64)
+ return g_object_ref (pixbuf_src);
+
+ /* never scale up, just pad */
+ if (pixbuf_width < 64 && pixbuf_height < 64) {
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 64, 64);
+ gdk_pixbuf_fill (pixbuf, 0x00000000);
+ gdk_pixbuf_copy_area (pixbuf_src,
+ 0, 0, /* of src */
+ pixbuf_width, pixbuf_height,
+ pixbuf,
+ (64 - pixbuf_width) / 2,
+ (64 - pixbuf_height) / 2);
+ return pixbuf;
+ }
+
+ /* is the aspect ratio perfectly square */
+ if (pixbuf_width == pixbuf_height) {
+ pixbuf = gdk_pixbuf_scale_simple (pixbuf_src, 64, 64,
+ GDK_INTERP_HYPER);
+ as_pixbuf_sharpen (pixbuf, 1, -0.5);
+ return pixbuf;
+ }
+
+ /* create new square pixbuf with alpha padding */
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 64, 64);
+ gdk_pixbuf_fill (pixbuf, 0x00000000);
+ if (pixbuf_width > pixbuf_height) {
+ tmp_width = 64;
+ tmp_height = 64 * pixbuf_height / pixbuf_width;
+ } else {
+ tmp_width = 64 * pixbuf_width / pixbuf_height;
+ tmp_height = 64;
}
+ pixbuf_tmp = gdk_pixbuf_scale_simple (pixbuf_src, tmp_width, tmp_height,
+ GDK_INTERP_HYPER);
+ as_pixbuf_sharpen (pixbuf_tmp, 1, -0.5);
+ gdk_pixbuf_copy_area (pixbuf_tmp,
+ 0, 0, /* of src */
+ tmp_width, tmp_height,
+ pixbuf,
+ (64 - tmp_width) / 2,
+ (64 - tmp_height) / 2);
return pixbuf;
}