# HG changeset patch # User Nathan Walp # Date 1087666469 0 # Node ID 01c50436203eb8f4fa194643a131352974dd2b87 # Parent 8e1ddf5d81d0d38e02530d0ad8bb9dbba467beb7 [gaim-migrate @ 10126] i think this is more intelligent scaling. it would certainly be hard for it to be less intelligent scaling committer: Tailor Script diff -r 8e1ddf5d81d0 -r 01c50436203e src/gtkaccount.c --- a/src/gtkaccount.c Sat Jun 19 16:05:50 2004 +0000 +++ b/src/gtkaccount.c Sat Jun 19 17:34:29 2004 +0000 @@ -451,13 +451,16 @@ GdkPixbufFormat *format; GaimPluginProtocolInfo *prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gaim_find_prpl(account->protocol_id)); char **prpl_formats = g_strsplit (prpl_info->icon_spec.format,",",0); - + format = gdk_pixbuf_get_file_info (path, &width, &height); pixbuf_formats = gdk_pixbuf_format_get_extensions(format); if (str_array_match(pixbuf_formats, prpl_formats) && /* This is an acceptable format AND */ - ((prpl_info->icon_spec.width > 0 && prpl_info->icon_spec.height > 0) || /* The prpl doesn't care about size OR*/ - (prpl_info->icon_spec.width == width && prpl_info->icon_spec.height == height))) { /* The icon is the correct size */ + (!(prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) || /* The prpl doesn't scale before it sends OR */ + (prpl_info->icon_spec.min_width <= width && + prpl_info->icon_spec.max_width >= width && + prpl_info->icon_spec.min_height <= height && + prpl_info->icon_spec.max_height >= height))) { /* The icon is the correct size */ #endif gaim_account_set_buddy_icon(account, path); #if GTK_CHECK_VERSION(2,4,0) @@ -469,8 +472,21 @@ char *random = g_strdup_printf("%x", g_random_int()); const char *dirname = gaim_buddy_icons_get_cache_dir(); char *filename = g_build_filename(dirname, random, NULL); - if (prpl_info->icon_spec.width > 0 && prpl_info->icon_spec.height > 0) { - scale = gdk_pixbuf_scale_simple (pixbuf, prpl_info->icon_spec.width, prpl_info->icon_spec.height, GDK_INTERP_HYPER); + if (!error && prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) { + int new_width = gdk_pixbuf_get_width(pixbuf); + int new_height = gdk_pixbuf_get_height(pixbuf); + + if(new_width > prpl_info->icon_spec.max_width) + new_width = prpl_info->icon_spec.max_width; + else if(new_width < prpl_info->icon_spec.min_width) + new_width = prpl_info->icon_spec.min_width; + if(new_height > prpl_info->icon_spec.max_height) + new_height = prpl_info->icon_spec.max_height; + else if(new_height < prpl_info->icon_spec.min_height) + new_height = prpl_info->icon_spec.min_height; + + scale = gdk_pixbuf_scale_simple (pixbuf, new_width, new_height, + GDK_INTERP_HYPER); gdk_pixbuf_unref(pixbuf); pixbuf = scale; } diff -r 8e1ddf5d81d0 -r 01c50436203e src/gtkconv.c --- a/src/gtkconv.c Sat Jun 19 16:05:50 2004 +0000 +++ b/src/gtkconv.c Sat Jun 19 17:34:29 2004 +0000 @@ -109,10 +109,6 @@ #define NUM_NICK_COLORS (sizeof(nick_colors) / sizeof(*nick_colors)) -#define SCALE(x) \ - ((gdk_pixbuf_animation_get_width(x) <= 48 && gdk_pixbuf_animation_get_height(x) <= 48) ? 48 : \ - (gdk_pixbuf_animation_get_width(x) > 75 && gdk_pixbuf_animation_get_height(x) > 75) ? 96 : 50) - typedef struct { GtkWidget *window; @@ -2276,17 +2272,47 @@ } } +static void +get_icon_scale_size(GdkPixbufAnimation *icon, GaimBuddyIconSpec *spec, int *width, int *height) +{ + *width = gdk_pixbuf_animation_get_width(icon); + *height = gdk_pixbuf_animation_get_height(icon); + + /* this should eventually get smarter about preserving the aspect + * ratio when scaling, but gimmie a break, I just woke up */ + if(spec && spec->scale_rules & GAIM_ICON_SCALE_DISPLAY) { + if(*width < spec->min_width) + *width = spec->min_width; + else if(*width > spec->max_width) + *width = spec->max_width; + + if(*height < spec->min_height) + *height = spec->min_height; + else if(*width > spec->max_height) + *height = spec->max_height; + } + + /* and now for some arbitrary sanity checks */ + if(*width > 100) + *width = 100; + if(*height > 100) + *height = 100; +} + static gboolean redraw_icon(gpointer data) { GaimConversation *conv = (GaimConversation *)data; GaimGtkConversation *gtkconv; + GaimAccount *account; + GaimPluginProtocolInfo *prpl_info = NULL; GdkPixbuf *buf; GdkPixbuf *scale; GdkPixmap *pm; GdkBitmap *bm; gint delay; + int scale_width, scale_height; if (!g_list_find(gaim_get_ims(), conv)) { gaim_debug(GAIM_DEBUG_WARNING, "gtkconv", @@ -2296,14 +2322,21 @@ } gtkconv = GAIM_GTK_CONVERSATION(conv); + account = gaim_conversation_get_account(conv); + if(account && account->gc) + prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(account->gc->prpl); gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); + get_icon_scale_size(gtkconv->u.im->anim, prpl_info ? &prpl_info->icon_spec : + NULL, &scale_width, &scale_height); + + /* this code is ugly, and scares me */ scale = gdk_pixbuf_scale_simple(buf, - MAX(gdk_pixbuf_get_width(buf) * SCALE(gtkconv->u.im->anim) / + MAX(gdk_pixbuf_get_width(buf) * scale_width / gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1), - MAX(gdk_pixbuf_get_height(buf) * SCALE(gtkconv->u.im->anim) / + MAX(gdk_pixbuf_get_height(buf) * scale_height / gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1), GDK_INTERP_NEAREST); @@ -5405,7 +5438,10 @@ GdkPixbuf *scale; GdkPixmap *pm; GdkBitmap *bm; - int sf = 0; + int scale_width, scale_height; + + GaimAccount *account; + GaimPluginProtocolInfo *prpl_info = NULL; GaimButtonStyle button_type; @@ -5414,6 +5450,9 @@ g_return_if_fail(gaim_conversation_get_type(conv) == GAIM_CONV_IM); gtkconv = GAIM_GTK_CONVERSATION(conv); + account = gaim_conversation_get_account(conv); + if(account && account->gc) + prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(account->gc->prpl); remove_icon(gtkconv); @@ -5498,11 +5537,12 @@ start_anim(NULL, conv); } - sf = SCALE(gtkconv->u.im->anim); + get_icon_scale_size(gtkconv->u.im->anim, prpl_info ? &prpl_info->icon_spec : + NULL, &scale_width, &scale_height); scale = gdk_pixbuf_scale_simple(buf, - MAX(gdk_pixbuf_get_width(buf) * sf / + MAX(gdk_pixbuf_get_width(buf) * scale_width / gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1), - MAX(gdk_pixbuf_get_height(buf) * sf / + MAX(gdk_pixbuf_get_height(buf) * scale_height / gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1), GDK_INTERP_NEAREST); @@ -5536,7 +5576,7 @@ gtk_widget_show(event); gtkconv->u.im->icon = gtk_image_new_from_pixmap(pm, bm); - gtk_widget_set_size_request(gtkconv->u.im->icon, sf, sf); + gtk_widget_set_size_request(gtkconv->u.im->icon, scale_width, scale_height); gtk_container_add(GTK_CONTAINER(event), gtkconv->u.im->icon); gtk_widget_show(gtkconv->u.im->icon); diff -r 8e1ddf5d81d0 -r 01c50436203e src/protocols/msn/msn.c --- a/src/protocols/msn/msn.c Sat Jun 19 16:05:50 2004 +0000 +++ b/src/protocols/msn/msn.c Sat Jun 19 17:34:29 2004 +0000 @@ -1634,7 +1634,7 @@ OPT_PROTO_MAIL_CHECK, NULL, NULL, - {"png", 0, 0}, + {"png", 0, 0, 0, 0, 0}, msn_list_icon, msn_list_emblems, msn_status_text, diff -r 8e1ddf5d81d0 -r 01c50436203e src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Sat Jun 19 16:05:50 2004 +0000 +++ b/src/protocols/oscar/oscar.c Sat Jun 19 17:34:29 2004 +0000 @@ -7150,7 +7150,7 @@ OPT_PROTO_MAIL_CHECK | OPT_PROTO_IM_IMAGE, NULL, NULL, - {"jpeg,gif,bmp,ico", 50, 50}, + {"jpeg,gif,bmp,ico", 48, 48, 50, 50, GAIM_ICON_SCALE_DISPLAY}, oscar_list_icon, oscar_list_emblems, oscar_status_text, diff -r 8e1ddf5d81d0 -r 01c50436203e src/protocols/rendezvous/rendezvous.c --- a/src/protocols/rendezvous/rendezvous.c Sat Jun 19 16:05:50 2004 +0000 +++ b/src/protocols/rendezvous/rendezvous.c Sat Jun 19 17:34:29 2004 +0000 @@ -638,19 +638,22 @@ GaimAccountOption *option; char hostname[255]; - prpl_info.api_version = GAIM_PRPL_API_VERSION; - prpl_info.options = OPT_PROTO_NO_PASSWORD; - prpl_info.icon_spec.format = "jpeg"; - prpl_info.icon_spec.width = 0; - prpl_info.icon_spec.height = 0; - prpl_info.list_icon = rendezvous_prpl_list_icon; - prpl_info.list_emblems = rendezvous_prpl_list_emblems; - prpl_info.status_text = rendezvous_prpl_status_text; - prpl_info.tooltip_text = rendezvous_prpl_tooltip_text; - prpl_info.login = rendezvous_prpl_login; - prpl_info.close = rendezvous_prpl_close; - prpl_info.send_im = rendezvous_prpl_send_im; - prpl_info.set_away = rendezvous_prpl_set_away; + prpl_info.api_version = GAIM_PRPL_API_VERSION; + prpl_info.options = OPT_PROTO_NO_PASSWORD; + prpl_info.icon_spec.format = "jpeg"; + prpl_info.icon_spec.min_width = 0; + prpl_info.icon_spec.min_height = 0; + prpl_info.icon_spec.max_width = 0; + prpl_info.icon_spec.max_height = 0; + prpl_info.icon_spec.stretch = 0; + prpl_info.list_icon = rendezvous_prpl_list_icon; + prpl_info.list_emblems = rendezvous_prpl_list_emblems; + prpl_info.status_text = rendezvous_prpl_status_text; + prpl_info.tooltip_text = rendezvous_prpl_tooltip_text; + prpl_info.login = rendezvous_prpl_login; + prpl_info.close = rendezvous_prpl_close; + prpl_info.send_im = rendezvous_prpl_send_im; + prpl_info.set_away = rendezvous_prpl_set_away; if (gethostname(hostname, 255) != 0) { gaim_debug_warning("rendezvous", "Error %d when getting host name. Using \"localhost.\"\n", errno); diff -r 8e1ddf5d81d0 -r 01c50436203e src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Sat Jun 19 16:05:50 2004 +0000 +++ b/src/protocols/yahoo/yahoo.c Sat Jun 19 17:34:29 2004 +0000 @@ -3190,7 +3190,7 @@ OPT_PROTO_MAIL_CHECK | OPT_PROTO_CHAT_TOPIC, NULL, /* user_splits */ NULL, /* protocol_options */ - {"png", 96, 96}, + {"png", 96, 96, 96, 96, GAIM_ICON_SCALE_SEND}, yahoo_list_icon, yahoo_list_emblems, yahoo_status_text, diff -r 8e1ddf5d81d0 -r 01c50436203e src/prpl.h --- a/src/prpl.h Sat Jun 19 16:05:50 2004 +0000 +++ b/src/prpl.h Sat Jun 19 17:34:29 2004 +0000 @@ -100,6 +100,12 @@ } GaimConvImFlags; +typedef enum { + GAIM_ICON_SCALE_DISPLAY = 0x01, /**< We scale the icon when we display it */ + GAIM_ICON_SCALE_SEND = 0x02 /**< We scale the icon before we send it to the server */ +} GaimIconScaleRules; + + /** * A description of a Buddy Icon specification. This tells Gaim what kind of image file * it should give this prpl, and what kind of image file it should expect back. @@ -109,12 +115,15 @@ char *format; /**< This is a comma-delimited list of image formats or NULL if icons are not supported. * The core nor the prpl will actually check to see if the data it's given matches this, it's entirely * up to the UI to do what it wants */ - int width; /**< The width of this icon */ - int height; /**< The height of this icon */ + int min_width; /**< The minimum width of this icon */ + int min_height; /**< The minimum height of this icon */ + int max_width; /**< The maximum width of this icon */ + int max_height; /**< The maximum height of this icon */ + GaimIconScaleRules scale_rules; /**< How to stretch this icon */ } GaimBuddyIconSpec; /* This #define exists just to make it easier to fill out the buddy icon field in he prpl info struct for protocols that couldn't care less. */ -#define NO_BUDDY_ICONS {NULL, 0, 0} +#define NO_BUDDY_ICONS {NULL, 0, 0, 0, 0, 0} #include "blist.h" #include "proxy.h"