=== modified file 'src/pidgin-libnotify.c' --- old/src/pidgin-libnotify.c 2009-03-24 21:50:05 +0000 +++ new/src/pidgin-libnotify.c 2009-03-26 19:26:26 +0000 @@ -27,6 +27,8 @@ #define PURPLE_PLUGINS #endif +#include + #include #include #include @@ -187,6 +189,77 @@ return icon; } +/* + * This takes a pixbuf that we want to send to the notify server, and + * transforms it to the desired dimensions suitable for a notification. + * We scale the pixbuf down to size * size (square), but preserve the + * original aspect ratio and fill in the edges with transparent pixels + * if the original pixbuf was not square. + */ +static GdkPixbuf * +normalize_icon (GdkPixbuf *icon, gint size) +{ + gint origw = gdk_pixbuf_get_width (icon); + gint origh = gdk_pixbuf_get_height (icon); + gint ratiow = (gdouble)origw / (gdouble)size; + gint ratioh = (gdouble)origh / (gdouble)size; + gint new_width, new_height; + GdkPixbuf *scaled_icon = NULL; + GdkPixbuf *new_icon = NULL; + gboolean needs_copy = TRUE; + gint dest_x; + gint dest_y; + + /* Preserve the aspect ratio of the original pixbuf when we scale */ + if (ratioh > ratiow) { + new_width = rint (origw / ratioh); + new_height = size; + + dest_x = (size - new_width) / 2; + dest_y = 0; + } else if (ratiow > ratioh) { + new_width = size; + new_height = rint (origh / ratiow); + + dest_x = 0; + dest_y = (ratioh - new_height) / 2; + } else { + new_width = new_height = size; + needs_copy = FALSE; + } + + scaled_icon = gdk_pixbuf_scale_simple (icon, + MAX (new_width, 1), + MAX (new_height, 1), + GDK_INTERP_HYPER); + g_object_unref (icon); + + if (!needs_copy) { + return scaled_icon; + } + + /* Create a pixbuf with an alpha channel, dimensions size * size */ + new_icon = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (scaled_icon), + TRUE, + gdk_pixbuf_get_bits_per_sample (scaled_icon), + size, size); + + /* Clear the pixbuf so it is transparent */ + gdk_pixbuf_fill (new_icon, 0x00000000); + + /* Copy from the aspect ratio-preserved scaled pixbuf into the + * new pixbuf, at a centered position. */ + gdk_pixbuf_copy_area (scaled_icon, + 0, 0, + gdk_pixbuf_get_width (scaled_icon), + gdk_pixbuf_get_height (scaled_icon), + new_icon, + dest_x, dest_y); + g_object_unref (scaled_icon); + + return new_icon; +} + static void action_cb (NotifyNotification *notification, gchar *action, gpointer user_data) @@ -349,6 +422,8 @@ } } + icon = normalize_icon (icon, 48); + if (icon != NULL) { notify_notification_set_icon_from_pixbuf (notification, icon); g_object_unref (icon);