changeset 9318:01c50436203e

[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 <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Sat, 19 Jun 2004 17:34:29 +0000
parents 8e1ddf5d81d0
children a4257646861a
files src/gtkaccount.c src/gtkconv.c src/protocols/msn/msn.c src/protocols/oscar/oscar.c src/protocols/rendezvous/rendezvous.c src/protocols/yahoo/yahoo.c src/prpl.h
diffstat 7 files changed, 103 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- 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;
 		}
--- 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);
 
--- 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,
--- 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,
--- 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);
--- 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,
--- 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"