Icon scaling
- From: Soeren Sandmann <sandmann daimi au dk>
- To: nautilus-list gnome org
- Subject: Icon scaling
- Date: 27 Mar 2004 22:45:27 +0100
Currently the list view spends a lot of time scaling down icons that
have a greater nominal size than base size.
Every time the list model is asked for an icon, and it finds out that
that icon is too large, it scales it down. This means that every
expose of the list view results in a lot icons getting scaled down
which is showing up on profiles.
This patch adds the ability to cache these scaled icons.
(It also adds a hash table to stop warnings from being displayed more
than once, but that's not really related).
Søren
Index: libnautilus-private/nautilus-file.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file.c,v
retrieving revision 1.344
diff -u -p -u -r1.344 nautilus-file.c
--- libnautilus-private/nautilus-file.c 8 Mar 2004 09:50:30 -0000 1.344
+++ libnautilus-private/nautilus-file.c 27 Mar 2004 21:18:26 -0000
@@ -4701,10 +4701,19 @@ get_description (NautilusFile *file)
"probably means that your gnome-vfs.keys file is in the wrong place "
"or isn't being found for some other reason."));
} else {
- g_warning (_("No description found for mime type \"%s\" (file is \"%s\"), "
- "please tell the gnome-vfs mailing list."),
- mime_type,
- file->details->relative_uri);
+ static GHashTable *warned = NULL;
+
+ if (!warned)
+ warned = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ if (!g_hash_table_lookup (warned, mime_type)) {
+ g_warning (_("No description found for mime type \"%s\" (file is \"%s\"), "
+ "please tell the gnome-vfs mailing list."),
+ mime_type,
+ file->details->relative_uri);
+
+ g_hash_table_insert (warned, g_strdup (mime_type), GINT_TO_POINTER (1));
+ }
}
return mime_type;
}
Index: libnautilus-private/nautilus-icon-factory.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-factory.c,v
retrieving revision 1.302
diff -u -p -u -r1.302 nautilus-icon-factory.c
--- libnautilus-private/nautilus-icon-factory.c 5 Mar 2004 13:33:53 -0000 1.302
+++ libnautilus-private/nautilus-icon-factory.c 27 Mar 2004 21:18:27 -0000
@@ -99,6 +99,7 @@ typedef struct {
char *name; /* Icon name or absolute filename */
char *modifier;
guint nominal_size;
+ gboolean force_nominal;
} CacheKey;
/* The value in the same table. */
@@ -186,7 +187,8 @@ static CacheIcon *cache_icon_new
double scale_y);
static CacheIcon *get_icon_from_cache (const char *icon,
const char *modifier,
- guint nominal_size);
+ guint nominal_size,
+ gboolean force_nominal);
static void nautilus_icon_factory_clear (void);
GNOME_CLASS_BOILERPLATE (NautilusIconFactory,
@@ -1084,6 +1086,7 @@ static GdkPixbuf *
load_icon_file (const char *filename,
guint base_size,
guint nominal_size,
+ gboolean force_nominal,
double *scale_x,
double *scale_y)
{
@@ -1129,6 +1132,14 @@ load_icon_file (const char *filename,
base_size = NAUTILUS_ICON_SIZE_STANDARD;
}
}
+ } else if (force_nominal) {
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ size = MAX (width, height);
+
+ if (size > base_size) {
+ base_size = size;
+ }
}
if (base_size != nominal_size) {
@@ -1147,7 +1158,8 @@ load_icon_file (const char *filename,
static CacheIcon *
create_normal_cache_icon (const char *icon,
const char *modifier,
- guint nominal_size)
+ guint nominal_size,
+ gboolean force_nominal)
{
NautilusIconFactory *factory;
const char *filename;
@@ -1208,6 +1220,7 @@ create_normal_cache_icon (const char *ic
pixbuf = load_icon_file (filename,
base_size,
nominal_size,
+ force_nominal,
&scale_x, &scale_y);
if (pixbuf == NULL) {
if (info) {
@@ -1232,11 +1245,14 @@ create_normal_cache_icon (const char *ic
* If @picky is true, then only an unscaled icon is acceptable.
* Also, if @picky is true, the icon must be a custom icon if
* @custom is true or a standard icon is @custom is false.
+ * If @force_nominal is #TRUE, the returned icon will be guaranteed
+ * to be smaller than the nominal size
*/
static CacheIcon *
get_icon_from_cache (const char *icon,
const char *modifier,
- guint nominal_size)
+ guint nominal_size,
+ gboolean force_nominal)
{
NautilusIconFactory *factory;
GHashTable *hash_table;
@@ -1258,6 +1274,7 @@ get_icon_from_cache (const char *icon,
lookup_key.name = (char *)icon;
lookup_key.modifier = (char *)modifier;
lookup_key.nominal_size = nominal_size;
+ lookup_key.force_nominal = force_nominal;
if (g_hash_table_lookup_extended (hash_table, &lookup_key,
&key_in_table, &value)) {
@@ -1288,12 +1305,14 @@ get_icon_from_cache (const char *icon,
cached_icon = create_normal_cache_icon (icon,
modifier,
- nominal_size);
+ nominal_size,
+ force_nominal);
/* Try to fallback without modifier */
if (cached_icon == NULL && modifier != NULL) {
cached_icon = create_normal_cache_icon (icon,
NULL,
- nominal_size);
+ nominal_size,
+ force_nominal);
}
if (cached_icon == NULL) {
@@ -1306,6 +1325,7 @@ get_icon_from_cache (const char *icon,
key->name = g_strdup (icon);
key->modifier = g_strdup (modifier);
key->nominal_size = nominal_size;
+ key->force_nominal = force_nominal;
g_hash_table_insert (hash_table, key, cached_icon);
}
@@ -1322,14 +1342,15 @@ get_icon_from_cache (const char *icon,
return cached_icon;
}
-GdkPixbuf *
-nautilus_icon_factory_get_pixbuf_for_icon (const char *icon,
- const char *modifier,
- guint nominal_size,
- NautilusEmblemAttachPoints *attach_points,
- GdkRectangle *embedded_text_rect,
- gboolean wants_default,
- char **display_name)
+static GdkPixbuf *
+nautilus_icon_factory_get_pixbuf_for_icon_internal (const char *icon,
+ const char *modifier,
+ guint nominal_size,
+ gboolean force_size,
+ NautilusEmblemAttachPoints *attach_points,
+ GdkRectangle *embedded_text_rect,
+ gboolean wants_default,
+ char **display_name)
{
NautilusIconFactory *factory;
CacheIcon *cached_icon;
@@ -1339,7 +1360,8 @@ nautilus_icon_factory_get_pixbuf_for_ico
factory = get_icon_factory ();
cached_icon = get_icon_from_cache (icon,
modifier,
- nominal_size);
+ nominal_size,
+ force_size);
if (attach_points != NULL) {
if (cached_icon->attach_points != NULL) {
@@ -1381,6 +1403,20 @@ nautilus_icon_factory_get_pixbuf_for_ico
return pixbuf;
}
+GdkPixbuf *
+nautilus_icon_factory_get_pixbuf_for_icon (const char *icon,
+ const char *modifier,
+ guint nominal_size,
+ NautilusEmblemAttachPoints *attach_points,
+ GdkRectangle *embedded_text_rect,
+ gboolean wants_default,
+ char **display_name)
+{
+ return nautilus_icon_factory_get_pixbuf_for_icon_internal (icon, modifier, nominal_size, FALSE,
+ attach_points, embedded_text_rect,
+ wants_default, display_name);
+}
+
static guint
cache_key_hash (gconstpointer p)
{
@@ -1390,12 +1426,12 @@ cache_key_hash (gconstpointer p)
key = p;
hash = g_str_hash (key->name) ^
- (key->nominal_size << 4);
+ ((key->nominal_size << 4) + (gint)key->force_nominal);
if (key->modifier) {
hash ^= g_str_hash (key->modifier);
}
-
+
return hash;
}
@@ -1409,6 +1445,7 @@ cache_key_equal (gconstpointer a, gconst
return eel_strcmp (key_a->name, key_b->name) == 0 &&
key_a->nominal_size == key_b->nominal_size &&
+ key_a->force_nominal == key_b->force_nominal &&
eel_strcmp (key_a->modifier, key_b->modifier) == 0;
}
@@ -1443,10 +1480,11 @@ nautilus_get_icon_size_for_zoom_level (N
/* Convenience cover for nautilus_icon_factory_get_icon_for_file
* and nautilus_icon_factory_get_pixbuf_for_icon.
*/
-GdkPixbuf *
-nautilus_icon_factory_get_pixbuf_for_file (NautilusFile *file,
- const char *modifier,
- guint size_in_pixels)
+static GdkPixbuf *
+nautilus_icon_factory_get_pixbuf_for_file_internal (NautilusFile *file,
+ const char *modifier,
+ guint size_in_pixels,
+ gboolean force_size)
{
char *icon;
GdkPixbuf *pixbuf;
@@ -1458,16 +1496,39 @@ nautilus_icon_factory_get_pixbuf_for_fil
return NULL;
}
- pixbuf = nautilus_icon_factory_get_pixbuf_for_icon (icon, modifier,
- size_in_pixels,
- NULL, NULL,
- TRUE, NULL);
+ pixbuf = nautilus_icon_factory_get_pixbuf_for_icon_internal (icon, modifier,
+ size_in_pixels,
+ force_size,
+ NULL, NULL,
+ TRUE, NULL);
g_free (icon);
return pixbuf;
}
+GdkPixbuf *
+nautilus_icon_factory_get_pixbuf_for_file (NautilusFile *file,
+ const char *modifier,
+ guint size_in_pixels)
+{
+ return nautilus_icon_factory_get_pixbuf_for_file_internal (file,
+ modifier,
+ size_in_pixels,
+ FALSE);
+}
+
+GdkPixbuf *
+nautilus_icon_factory_get_pixbuf_for_file_force_size (NautilusFile *file,
+ const char *modifier,
+ guint size_in_pixels)
+{
+ return nautilus_icon_factory_get_pixbuf_for_file_internal (file,
+ modifier,
+ size_in_pixels,
+ TRUE);
+}
+
/* Convenience routine for getting a pixbuf from an icon name. */
GdkPixbuf *
nautilus_icon_factory_get_pixbuf_from_name (const char *icon_name,
Index: libnautilus-private/nautilus-icon-factory.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-factory.h,v
retrieving revision 1.48
diff -u -p -u -r1.48 nautilus-icon-factory.h
--- libnautilus-private/nautilus-icon-factory.h 18 Dec 2003 18:38:23 -0000 1.48
+++ libnautilus-private/nautilus-icon-factory.h 27 Mar 2004 21:18:28 -0000
@@ -138,6 +138,9 @@ GdkPixbuf * nautilus_icon_fact
GdkPixbuf * nautilus_icon_factory_get_pixbuf_for_file (NautilusFile *file,
const char *modifer,
guint size_in_pixels);
+GdkPixbuf * nautilus_icon_factory_get_pixbuf_for_file_force_size (NautilusFile *file,
+ const char *modifier,
+ guint size_in_pixels);
/* Convenience routine for getting a pixbuf from an icon name
*/
Index: src/file-manager/fm-list-model.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-list-model.c,v
retrieving revision 1.28
diff -u -p -u -r1.28 fm-list-model.c
--- src/file-manager/fm-list-model.c 10 Mar 2004 12:44:17 -0000 1.28
+++ src/file-manager/fm-list-model.c 27 Mar 2004 21:18:29 -0000
@@ -229,16 +229,8 @@ fm_list_model_get_value (GtkTreeModel *t
modifier = "visiting";
}
- icon = nautilus_icon_factory_get_pixbuf_for_file (file, modifier, icon_size);
+ icon = nautilus_icon_factory_get_pixbuf_for_file_force_size (file, modifier, icon_size);
- height = gdk_pixbuf_get_height (icon);
- if (height > icon_size) {
- width = gdk_pixbuf_get_width (icon) * icon_size / height;
- height = icon_size;
- tmp = gdk_pixbuf_scale_simple (icon, width, height, GDK_INTERP_BILINEAR);
- g_object_unref (icon);
- icon = tmp;
- }
g_value_set_object (value, icon);
g_object_unref (icon);
break;
@@ -265,8 +257,9 @@ fm_list_model_get_value (GtkTreeModel *t
if (emblem_icons != NULL) {
zoom_level = fm_list_model_get_zoom_level_from_emblem_column_id (column);
icon_size = nautilus_get_icon_size_for_zoom_level (zoom_level);
- icon = nautilus_icon_factory_get_pixbuf_for_icon (emblem_icons->data, NULL, icon_size,
- NULL, NULL, FALSE, NULL);
+ icon = nautilus_icon_factory_get_pixbuf_for_icon_force_size (
+ emblem_icons->data, NULL, icon_size,
+ NULL, NULL, FALSE, NULL);
eel_g_list_free_deep (emblem_icons);
height = gdk_pixbuf_get_height (icon);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]