summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog44
-rwxr-xr-xcheck-FIXME.pl2
-rwxr-xr-xcheck-config-h.pl6
-rw-r--r--libnautilus-extensions/nautilus-icon-container.c10
-rw-r--r--libnautilus-extensions/nautilus-icon-factory.c321
-rw-r--r--libnautilus-extensions/nautilus-icon-factory.h6
-rw-r--r--libnautilus-private/nautilus-icon-container.c10
-rw-r--r--libnautilus-private/nautilus-icon-factory.c321
-rw-r--r--libnautilus-private/nautilus-icon-factory.h6
-rw-r--r--src/file-manager/fm-list-view.c4
10 files changed, 495 insertions, 235 deletions
diff --git a/ChangeLog b/ChangeLog
index b2076bb5d..4f6914f3c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+2000-05-02 Darin Adler <darin@eazel.com>
+
+ * check-FIXME.pl: Added -print as suggested by Morten Welinder
+ <terra@diku.dk>.
+ * check-config-h.pl: Added -print and fixed broken message as
+ suggested by Morten Welinder <terra@diku.dk>.
+
+ * libnautilus-extensions/nautilus-icon-factory.h:
+ * libnautilus-extensions/nautilus-icon-factory.c
+ (suffix_is_scalable): Simpler implementation.
+ (get_themed_icon_file_path): Look for size-specific version of
+ even .svg files. Although not so useful, it's not ridiculous to do so.
+ (nautilus_icon_factory_get_icon_for_file): Fixed the twisted logic to
+ be less twisted. Also changed the ".svg" extension check to use the
+ common function suffix_is_scalable.
+ (load_specific_image): Untwist logic here too, and note in the FIXME
+ that both the .svg library and gdk-pixbuf are limiting us to file:
+ URIs, although the gdk-pixbuf case is fixable without redoing the
+ library by just using our utility functions.
+ (load_image_for_scaling): Update for new size request structure which
+ contains maximum sizes as well as nominal ones.
+ (scale_image_and_rectangle), (revise_scale_factors_if_too_big),
+ (scale_image_down_if_too_big): New helper functions for scaling.
+ (load_image_scale_if_necessary): Take the maximum size into account.
+ (get_image_from_cache): Use new size request structure and take the
+ maximum size into account.
+ (nautilus_icon_factory_get_pixbuf_for_icon): Changed to take maximum
+ size parameters and pass them in to the underlying function.
+ (icon_cache_key_hash): Include the maximum size in the hash.
+ (icon_cache_key_equal): Check the maximum size too.
+ (nautilus_icon_factory_get_pixbuf_for_file): Pass new max. size
+ parameters to the nautilus_icon_factory_get_pixbuf_for_icon
+ function.
+
+ * libnautilus-extensions/nautilus-icon-container.c
+ (nautilus_icon_container_update_icon): Pass new max. size
+ parameters to the nautilus_icon_factory_get_pixbuf_for_icon
+ function.
+
+ * src/file-manager/fm-list-view.c
+ (fm_list_view_get_emblem_pixbufs_for_file): Pass new max. size
+ parameters to the nautilus_icon_factory_get_pixbuf_for_icon
+ function.
+
2000-05-02 John Sullivan <sullivan@eazel.com>
* data/mime/.cvsignore,
diff --git a/check-FIXME.pl b/check-FIXME.pl
index 257fd0d86..e0606b253 100755
--- a/check-FIXME.pl
+++ b/check-FIXME.pl
@@ -33,7 +33,7 @@ use strict;
my %skip_files;
if (!@ARGV)
{
- @ARGV = `find -name '*' -and ! \\( -name '*~' -or -name '#*' -or -name 'ChangeLog*' -or -name 'Entries' \\)`;
+ @ARGV = `find -name '*' -and ! \\( -name '*~' -or -name '#*' -or -name 'ChangeLog*' -or -name 'Entries' \\) -print`;
%skip_files =
(
"./TODO" => 1,
diff --git a/check-config-h.pl b/check-config-h.pl
index d7ee76856..187d3480f 100755
--- a/check-config-h.pl
+++ b/check-config-h.pl
@@ -35,10 +35,9 @@ my $edit = 0;
&GetOptions("edit" => \$edit);
# default to all the files starting from the current directory
-my %skip_files;
if (!@ARGV)
{
- @ARGV = `find -name '*.c'`;
+ @ARGV = `find -name '*.c' -print`;
}
# locate all of the target lines
@@ -46,7 +45,6 @@ my @missing_files;
FILE: foreach my $file (@ARGV)
{
chomp $file;
- next if $skip_files{$file};
open FILE, $file or die "can't open $file";
while (<FILE>)
{
@@ -59,7 +57,7 @@ FILE: foreach my $file (@ARGV)
if (@missing_files)
{
- print "\n", scalar(@missing_files), " C files don't have bug reports:\n\n";
+ print "\n", scalar(@missing_files), " C files don't have <config.h> includes:\n\n";
if (!$edit)
{
print join("\n", @missing_files), "\n";
diff --git a/libnautilus-extensions/nautilus-icon-container.c b/libnautilus-extensions/nautilus-icon-container.c
index 1102e4204..12382f4db 100644
--- a/libnautilus-extensions/nautilus-icon-container.c
+++ b/libnautilus-extensions/nautilus-icon-container.c
@@ -2427,11 +2427,17 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
/* Get the corresponding pixbufs for this size. */
icon_get_size (container, icon, &icon_size_x, &icon_size_y);
pixbuf = nautilus_icon_factory_get_pixbuf_for_icon
- (scalable_icon, icon_size_x, icon_size_y, &text_rect);
+ (scalable_icon,
+ icon_size_x, icon_size_y,
+ G_MAXINT, G_MAXINT,
+ &text_rect);
emblem_pixbufs = NULL;
for (p = emblem_icons; p != NULL; p = p->next) {
emblem_pixbuf = nautilus_icon_factory_get_pixbuf_for_icon
- (p->data, icon_size_x, icon_size_y, NULL);
+ (p->data,
+ icon_size_x, icon_size_y,
+ G_MAXINT, G_MAXINT,
+ NULL);
if (emblem_pixbuf != NULL) {
emblem_pixbufs = g_list_prepend
(emblem_pixbufs, emblem_pixbuf);
diff --git a/libnautilus-extensions/nautilus-icon-factory.c b/libnautilus-extensions/nautilus-icon-factory.c
index 1abfb6167..5ee59f3e4 100644
--- a/libnautilus-extensions/nautilus-icon-factory.c
+++ b/libnautilus-extensions/nautilus-icon-factory.c
@@ -169,21 +169,28 @@ struct NautilusScalableIcon {
char *modifier;
};
+/* A request for an icon of a particular size. */
+typedef struct {
+ guint nominal_width;
+ guint nominal_height;
+ guint maximum_width;
+ guint maximum_height;
+} IconSizeRequest;
+
/* The key to a hash table that holds the scaled icons as pixbufs.
* In a way, it's not really completely a key, because part of the
* data is stored in here, including the LRU chain.
*/
typedef struct {
NautilusScalableIcon *scalable_icon;
- guint size_in_pixels_x;
- guint size_in_pixels_y;
+ IconSizeRequest size;
NautilusCircularList recently_used_node;
gboolean custom;
gboolean scaled;
ArtIRect text_rect;
-} NautilusIconCacheKey;
+} IconCacheKey;
/* forward declarations */
@@ -201,14 +208,13 @@ static NautilusScalableIcon *nautilus_scalable_icon_get (const char
static guint nautilus_scalable_icon_hash (gconstpointer p);
static gboolean nautilus_scalable_icon_equal (gconstpointer a,
gconstpointer b);
-static void nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key);
-static guint nautilus_icon_cache_key_hash (gconstpointer p);
-static gboolean nautilus_icon_cache_key_equal (gconstpointer a,
+static void icon_cache_key_destroy (IconCacheKey *key);
+static guint icon_cache_key_hash (gconstpointer p);
+static gboolean icon_cache_key_equal (gconstpointer a,
gconstpointer b);
static gboolean vfs_file_exists (const char *file_name);
static GdkPixbuf * get_image_from_cache (NautilusScalableIcon *scalable_icon,
- guint size_in_pixels_x,
- guint size_in_pixels_y,
+ const IconSizeRequest *size,
gboolean picky,
gboolean custom,
ArtIRect *text_rect);
@@ -264,8 +270,8 @@ nautilus_icon_factory_initialize (NautilusIconFactory *factory)
{
factory->scalable_icons = g_hash_table_new (nautilus_scalable_icon_hash,
nautilus_scalable_icon_equal);
- factory->icon_cache = g_hash_table_new (nautilus_icon_cache_key_hash,
- nautilus_icon_cache_key_equal);
+ factory->icon_cache = g_hash_table_new (icon_cache_key_hash,
+ icon_cache_key_equal);
/* Empty out the recently-used list. */
factory->recently_used_dummy_head.next = &factory->recently_used_dummy_head;
@@ -294,7 +300,7 @@ nautilus_icon_factory_initialize_class (NautilusIconFactoryClass *class)
static gboolean
nautilus_icon_factory_destroy_cached_image (gpointer key, gpointer value, gpointer user_data)
{
- nautilus_icon_cache_key_destroy (key);
+ icon_cache_key_destroy (key);
gdk_pixbuf_unref (value);
return TRUE;
}
@@ -319,6 +325,11 @@ nautilus_icon_factory_clear (void)
#if 0
+/* No one ever destroys the icon factory.
+ * There's no public API for doing so.
+ * If they did, we'd have to get this right.
+ */
+
static void
nautilus_icon_factory_destroy (NautilusIconFactory *factory)
{
@@ -340,7 +351,7 @@ nautilus_icon_factory_possibly_free_cached_image (gpointer key,
gpointer value,
gpointer user_data)
{
- NautilusIconCacheKey *icon_key;
+ IconCacheKey *icon_key;
GdkPixbuf *image;
/* Don't free a cache entry that is in the recently used list. */
@@ -354,7 +365,8 @@ nautilus_icon_factory_possibly_free_cached_image (gpointer key,
/* FIXME bugzilla.eazel.com 640:
* We treat all entries as "in use", until we get a hook we can use
- * in GdkPixbuf.
+ * in GdkPixbuf. We are waiting for the "final" hook right now. The
+ * one that's in there is not approved of by the Gtk maintainers.
*/
return FALSE;
#if 0
@@ -496,12 +508,8 @@ make_full_icon_path (const char *path, const char *suffix)
static gboolean
suffix_is_scalable (const char *path)
{
- const char *suffix;
-
- suffix = (const char *)strrchr (path, '.');
- if (suffix == NULL)
- return FALSE;
- return (!strcmp (suffix, ".svg") || !strcmp (suffix, ".SVG"));
+ return nautilus_str_has_suffix (path, ".svg")
+ || nautilus_str_has_suffix (path, ".SVG");
}
/* Pick a particular icon to use, trying all the various suffixes.
@@ -532,8 +540,7 @@ get_themed_icon_file_path (const char *theme_name,
/* Try each suffix. */
for (i = 0; i < NAUTILUS_N_ELEMENTS (icon_file_name_suffixes); i++) {
- if (include_size &&
- !suffix_is_scalable (icon_file_name_suffixes[i])) {
+ if (include_size) {
/* Build a path for this icon. */
partial_path = g_strdup_printf ("%s-%u",
themed_icon_name,
@@ -753,10 +760,8 @@ nautilus_scalable_icon_equal (gconstpointer a,
NautilusScalableIcon *
nautilus_icon_factory_get_icon_for_file (NautilusFile *file, const char* modifier)
{
- char *uri, *file_uri;
+ char *uri, *file_uri, *image_uri, *icon_name;
NautilusScalableIcon *scalable_icon;
- const char *name = NULL;
- gboolean need_to_free_name = FALSE;
if (file == NULL) {
return NULL;
@@ -780,17 +785,15 @@ nautilus_icon_factory_get_icon_for_file (NautilusFile *file, const char* modifie
}
/* handle nautilus link xml files, which may specify their own image */
-
- if (nautilus_link_is_link_file(file_uri)) {
- char *image_uri = nautilus_link_get_image_uri(file_uri);
- if (image_uri) {
- if (nautilus_str_has_prefix(image_uri, "file://"))
+ icon_name = NULL;
+ if (nautilus_link_is_link_file (file_uri)) {
+ image_uri = nautilus_link_get_image_uri (file_uri);
+ if (image_uri != NULL) {
+ if (nautilus_str_has_prefix (image_uri, "file://"))
uri = image_uri;
else {
- name = (const char*) image_uri;
- need_to_free_name = TRUE;
+ icon_name = image_uri;
}
-
}
}
@@ -799,20 +802,20 @@ nautilus_icon_factory_get_icon_for_file (NautilusFile *file, const char* modifie
* we should be checking the mime-type but for now we use the suffix,
* as the mime-type isn't defined in standard setups
*/
- if (uri == NULL && nautilus_str_has_suffix(file_uri,".svg")) {
- uri = g_strdup(file_uri);
+ if (uri == NULL && suffix_is_scalable (file_uri)) {
+ uri = g_strdup (file_uri);
}
/* Get the generic icon set for this file. */
- g_free(file_uri);
- if (name == NULL)
- name = nautilus_icon_factory_get_icon_name_for_file (file);
+ g_free (file_uri);
+ if (icon_name == NULL) {
+ icon_name = g_strdup (nautilus_icon_factory_get_icon_name_for_file (file));
+ }
/* Create the icon or find it in the cache if it's already there. */
- scalable_icon = nautilus_scalable_icon_get (uri, name, modifier);
+ scalable_icon = nautilus_scalable_icon_get (uri, icon_name, modifier);
g_free (uri);
- if (need_to_free_name)
- g_free((char *) name);
+ g_free (icon_name);
return scalable_icon;
}
@@ -1155,19 +1158,21 @@ load_specific_image (NautilusScalableIcon *scalable_icon,
/* FIXME bugzilla.eazel.com 643: This works only with file:// images, because there's
* no convenience function for loading an image with gnome-vfs
- * and gdk-pixbuf.
+ * and gdk-pixbuf. And there's the same problem with the rsvg_render_file library.
*/
- /* FIXME bugzilla.eazel.com 641: should use MIME-type instead of suffix */
- if (nautilus_str_has_suffix(scalable_icon->uri, ".svg")) {
- memset (text_rect, 0, sizeof (*text_rect));
- return load_specific_image_svg (scalable_icon->uri + 7, size_in_pixels);
+ if (nautilus_str_has_prefix (scalable_icon->uri, "file://")) {
+ /* FIXME bugzilla.eazel.com 641: should use MIME-type instead of suffix */
+ if (suffix_is_scalable (scalable_icon->uri)) {
+ memset (text_rect, 0, sizeof (*text_rect));
+ return load_specific_image_svg (scalable_icon->uri + 7, size_in_pixels);
+ }
+
+ if (size_in_pixels == NAUTILUS_ICON_SIZE_STANDARD) {
+ memset (text_rect, 0, sizeof (*text_rect));
+ return gdk_pixbuf_new_from_file (scalable_icon->uri + 7);
+ }
}
- if (size_in_pixels == NAUTILUS_ICON_SIZE_STANDARD
- && nautilus_str_has_prefix (scalable_icon->uri, "file://")) {
- memset (text_rect, 0, sizeof (*text_rect));
- return gdk_pixbuf_new_from_file (scalable_icon->uri + 7);
- }
return NULL;
} else {
/* Standard icon. */
@@ -1181,10 +1186,11 @@ load_specific_image (NautilusScalableIcon *scalable_icon,
if (path == NULL) {
return NULL;
}
- if (suffix_is_scalable (path))
+ if (suffix_is_scalable (path)) {
image = load_specific_image_svg (path, size_in_pixels);
- else
+ } else {
image = gdk_pixbuf_new_from_file (path);
+ }
g_free (path);
return image;
}
@@ -1200,14 +1206,20 @@ load_image_for_scaling (NautilusScalableIcon *scalable_icon,
{
GdkPixbuf *image;
guint actual_size;
+ IconSizeRequest size_request;
static GdkPixbuf *fallback_image;
+ size_request.maximum_width = G_MAXINT;
+ size_request.maximum_height = G_MAXINT;
+
/* First check for a custom image. */
actual_size = 0;
while (get_next_icon_size_to_try (requested_size, &actual_size)) {
+ size_request.nominal_width = actual_size;
+ size_request.nominal_height = actual_size;
+
image = get_image_from_cache (scalable_icon,
- actual_size,
- actual_size,
+ &size_request,
TRUE,
TRUE,
text_rect);
@@ -1221,9 +1233,11 @@ load_image_for_scaling (NautilusScalableIcon *scalable_icon,
/* Next, go for the normal image. */
actual_size = 0;
while (get_next_icon_size_to_try (requested_size, &actual_size)) {
+ size_request.nominal_width = actual_size;
+ size_request.nominal_height = actual_size;
+
image = get_image_from_cache (scalable_icon,
- actual_size,
- actual_size,
+ &size_request,
TRUE,
FALSE,
text_rect);
@@ -1255,42 +1269,109 @@ load_image_for_scaling (NautilusScalableIcon *scalable_icon,
return fallback_image;
}
+/* Consumes the image and returns a scaled one if the image is too big.
+ * Note that this does an unref on the image and returns a new one.
+ */
+static GdkPixbuf *
+scale_image_and_rectangle (GdkPixbuf *image,
+ ArtIRect *rectangle,
+ double scale_x,
+ double scale_y)
+{
+ int width, height;
+ GdkPixbuf *scaled_image;
+
+ width = gdk_pixbuf_get_width (image);
+ height = gdk_pixbuf_get_height (image);
+
+ /* Check for no-scaling case. */
+ if ((int) (width * scale_x) == width
+ && (int) (height * scale_y) == height) {
+ return gdk_pixbuf_ref (image);
+ }
+
+ scaled_image = gdk_pixbuf_scale_simple
+ (image,
+ width * scale_x,
+ height * scale_y,
+ GDK_INTERP_BILINEAR);
+ gdk_pixbuf_unref (image);
+
+ rectangle->x0 *= scale_x;
+ rectangle->y0 *= scale_y;
+ rectangle->x1 *= scale_x;
+ rectangle->y1 *= scale_y;
+
+ return scaled_image;
+}
+
+static void
+revise_scale_factors_if_too_big (GdkPixbuf *image,
+ const IconSizeRequest *size,
+ double *scale_x,
+ double *scale_y)
+{
+ int width, height;
+ double y_distortion;
+
+ width = gdk_pixbuf_get_width (image);
+ height = gdk_pixbuf_get_height (image);
+
+ if ((int) (width * *scale_x) <= size->maximum_width
+ && (int) (height * *scale_y) <= size->maximum_height) {
+ return;
+ }
+
+ y_distortion = *scale_y / *scale_x;
+
+ *scale_x = MIN ((double) size->maximum_width / width,
+ (double) size->maximum_height / (height / y_distortion));
+ *scale_y = *scale_x * y_distortion;
+}
+
+/* Consumes the image and returns a scaled one if the image is too big.
+ * Note that this does an unref on the image and returns a new one.
+ */
+static GdkPixbuf *
+scale_image_down_if_too_big (GdkPixbuf *image,
+ const IconSizeRequest *size,
+ ArtIRect *text_rect)
+{
+ double scale_x, scale_y;
+
+ scale_x = 1.0;
+ scale_y = 1.0;
+ revise_scale_factors_if_too_big (image, size, &scale_x, &scale_y);
+ return scale_image_and_rectangle (image, text_rect, scale_x, scale_y);
+}
+
/* This load function is not allowed to return NULL. */
static GdkPixbuf *
load_image_scale_if_necessary (NautilusScalableIcon *scalable_icon,
- guint requested_size_x,
- guint requested_size_y,
+ const IconSizeRequest *size,
gboolean *scaled,
gboolean *custom,
ArtIRect *text_rect)
{
- GdkPixbuf *image, *scaled_image;
- guint actual_size;
- int scaled_width, scaled_height;
+ GdkPixbuf *image;
+ guint nominal_actual_size;
+ double scale_x, scale_y;
/* Load the image for the icon that's closest in size to what we want. */
- image = load_image_for_scaling (scalable_icon, requested_size_x,
- &actual_size, custom, text_rect);
- if (requested_size_x == actual_size && requested_size_y == actual_size) {
+ image = load_image_for_scaling (scalable_icon, size->nominal_width,
+ &nominal_actual_size, custom, text_rect);
+ if (size->nominal_width == nominal_actual_size
+ && size->nominal_height == nominal_actual_size) {
*scaled = FALSE;
- return image;
+ return scale_image_down_if_too_big (image, size, text_rect);
}
/* Scale the image to the size we want. */
- scaled_width = gdk_pixbuf_get_width (image) * requested_size_x / actual_size;
- scaled_height = gdk_pixbuf_get_height (image) * requested_size_y / actual_size;
- scaled_image = gdk_pixbuf_scale_simple
- (image, scaled_width, scaled_height, GDK_INTERP_BILINEAR);
-
- /* Scale the text rectangle to the same size. */
- text_rect->x0 = text_rect->x0 * requested_size_x / actual_size;
- text_rect->y0 = text_rect->y0 * requested_size_y / actual_size;
- text_rect->x1 = text_rect->x1 * requested_size_x / actual_size;
- text_rect->y1 = text_rect->y1 * requested_size_y / actual_size;
-
- gdk_pixbuf_unref (image);
*scaled = TRUE;
- return scaled_image;
+ scale_x = (double) size->nominal_width / nominal_actual_size;
+ scale_y = (double) size->nominal_height / nominal_actual_size;
+ revise_scale_factors_if_too_big (image, size, &scale_x, &scale_y);
+ return scale_image_and_rectangle (image, text_rect, scale_x, scale_y);
}
/* Move this item to the head of the recently-used list,
@@ -1347,15 +1428,14 @@ mark_recently_used (NautilusCircularList *node)
*/
static GdkPixbuf *
get_image_from_cache (NautilusScalableIcon *scalable_icon,
- guint size_in_pixels_x,
- guint size_in_pixels_y,
+ const IconSizeRequest *size,
gboolean picky,
gboolean custom,
ArtIRect *text_rect)
{
NautilusIconFactory *factory;
GHashTable *hash_table;
- NautilusIconCacheKey lookup_key, *key;
+ IconCacheKey lookup_key, *key;
GdkPixbuf *image;
gpointer key_in_table, value;
@@ -1366,8 +1446,7 @@ get_image_from_cache (NautilusScalableIcon *scalable_icon,
/* Check to see if it's already in the table. */
lookup_key.scalable_icon = scalable_icon;
- lookup_key.size_in_pixels_x = size_in_pixels_x;
- lookup_key.size_in_pixels_y = size_in_pixels_y;
+ lookup_key.size = *size;
if (g_hash_table_lookup_extended (hash_table, &lookup_key,
&key_in_table, &value)) {
/* Found it in the table. */
@@ -1388,24 +1467,37 @@ get_image_from_cache (NautilusScalableIcon *scalable_icon,
ArtIRect key_text_rect;
/* Not in the table, so load the image. */
+
+ /* If we're picky, then we want the image only if this exact
+ * nominal size is available.
+ */
if (picky) {
- if (size_in_pixels_x != size_in_pixels_y) {
+ /* Actual icons have nominal sizes that are square! */
+ if (size->nominal_width
+ != size->nominal_height) {
return NULL;
}
+
+ /* Get the image. */
image = load_specific_image (scalable_icon,
- size_in_pixels_x,
+ size->nominal_width,
custom,
&key_text_rect);
if (image == NULL) {
return NULL;
}
+ /* Now we have the image, but is it bigger than
+ * the maximum size? If so we scale it, even but we don't
+ * call it "scaled" for caching purposese.
+ */
+ image = scale_image_down_if_too_big (image, size, &key_text_rect);
+
got_scaled_image = FALSE;
got_custom_image = custom;
} else {
image = load_image_scale_if_necessary (scalable_icon,
- size_in_pixels_x,
- size_in_pixels_y,
+ size,
&got_scaled_image,
&got_custom_image,
&key_text_rect);
@@ -1413,11 +1505,10 @@ get_image_from_cache (NautilusScalableIcon *scalable_icon,
}
/* Create the key for the table. */
- key = g_new0 (NautilusIconCacheKey, 1);
+ key = g_new0 (IconCacheKey, 1);
nautilus_scalable_icon_ref (scalable_icon);
key->scalable_icon = scalable_icon;
- key->size_in_pixels_x = size_in_pixels_x;
- key->size_in_pixels_y = size_in_pixels_y;
+ key->size = *size;
key->scaled = got_scaled_image;
key->custom = got_custom_image;
key->text_rect = key_text_rect;
@@ -1444,42 +1535,52 @@ get_image_from_cache (NautilusScalableIcon *scalable_icon,
GdkPixbuf *
nautilus_icon_factory_get_pixbuf_for_icon (NautilusScalableIcon *scalable_icon,
- guint size_in_pixels_x, guint size_in_pixels_y,
+ guint nominal_width,
+ guint nominal_height,
+ guint maximum_width,
+ guint maximum_height,
ArtIRect *text_rect)
{
- return get_image_from_cache (scalable_icon,
- size_in_pixels_x, size_in_pixels_y,
- FALSE, FALSE, text_rect);
+ IconSizeRequest size;
+ size.nominal_width = nominal_width;
+ size.nominal_height = nominal_width;
+ size.maximum_width = maximum_width;
+ size.maximum_height = maximum_width;
+ return get_image_from_cache (scalable_icon, &size, FALSE, FALSE, text_rect);
}
static void
-nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key)
+icon_cache_key_destroy (IconCacheKey *key)
{
nautilus_scalable_icon_unref (key->scalable_icon);
}
static guint
-nautilus_icon_cache_key_hash (gconstpointer p)
+icon_cache_key_hash (gconstpointer p)
{
- const NautilusIconCacheKey *key;
+ const IconCacheKey *key;
key = p;
- return (((GPOINTER_TO_UINT (key->scalable_icon) << 4)
- ^ key->size_in_pixels_x) << 4)
- ^ key->size_in_pixels_y;
+ return (((((((GPOINTER_TO_UINT (key->scalable_icon) << 4)
+ ^ key->size.nominal_width) << 4)
+ ^ key->size.nominal_height) << 4)
+ ^ key->size.maximum_width) << 4)
+ ^ key->size.maximum_height;
}
static gboolean
-nautilus_icon_cache_key_equal (gconstpointer a, gconstpointer b)
+icon_cache_key_equal (gconstpointer a, gconstpointer b)
{
- const NautilusIconCacheKey *key_a, *key_b;
+ const IconCacheKey *key_a, *key_b;
key_a = a;
key_b = b;
return key_a->scalable_icon == key_b->scalable_icon
- && key_a->size_in_pixels_x == key_b->size_in_pixels_x
- && key_a->size_in_pixels_y == key_b->size_in_pixels_y;
+ && key_a->size.nominal_width == key_b->size.nominal_width
+ && key_a->size.nominal_height == key_b->size.nominal_height
+ && key_a->size.maximum_width == key_b->size.maximum_width
+ && key_a->size.maximum_height == key_b->size.maximum_height;
}
/* Return nominal icon size for given zoom level.
@@ -1525,10 +1626,11 @@ nautilus_icon_factory_get_pixbuf_for_file (NautilusFile *file,
g_return_val_if_fail (file != NULL, NULL);
icon = nautilus_icon_factory_get_icon_for_file (file, NULL);
- pixbuf = nautilus_icon_factory_get_pixbuf_for_icon (icon,
- size_in_pixels,
- size_in_pixels,
- NULL);
+ pixbuf = nautilus_icon_factory_get_pixbuf_for_icon
+ (icon,
+ size_in_pixels, size_in_pixels,
+ size_in_pixels, size_in_pixels,
+ NULL);
nautilus_scalable_icon_unref (icon);
return pixbuf;
}
@@ -1720,9 +1822,8 @@ check_for_thumbnails (NautilusIconFactory *factory)
}
/* utility to draw the thumbnail frame. The frame is rectangular, so it doesn't need an alpha channel */
-
static void
-draw_thumbnail_frame(GdkPixbuf *frame_pixbuf)
+draw_thumbnail_frame (GdkPixbuf *frame_pixbuf)
{
gint index, width, height, depth, rowstride, fill_value;
guchar *pixels, *temp_pixels;
diff --git a/libnautilus-extensions/nautilus-icon-factory.h b/libnautilus-extensions/nautilus-icon-factory.h
index 8df218903..6940fdc78 100644
--- a/libnautilus-extensions/nautilus-icon-factory.h
+++ b/libnautilus-extensions/nautilus-icon-factory.h
@@ -100,8 +100,10 @@ GList * nautilus_icon_factory_get_emblem_icons_for_file (Nautil
* text, then the rectangle is (0, 0, 0, 0).
*/
GdkPixbuf * nautilus_icon_factory_get_pixbuf_for_icon (NautilusScalableIcon *scalable_icon,
- guint size_in_pixels_x,
- guint size_in_pixels_y,
+ guint nominal_size_in_pixels_x,
+ guint nominal_size_in_pixels_y,
+ guint maximum_size_in_pixels_x,
+ guint maximum_size_in_pixels_y,
ArtIRect *embedded_text_rectangle);
/* Convenience functions for the common case where you want to choose
diff --git a/libnautilus-private/nautilus-icon-container.c b/libnautilus-private/nautilus-icon-container.c
index 1102e4204..12382f4db 100644
--- a/libnautilus-private/nautilus-icon-container.c
+++ b/libnautilus-private/nautilus-icon-container.c
@@ -2427,11 +2427,17 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
/* Get the corresponding pixbufs for this size. */
icon_get_size (container, icon, &icon_size_x, &icon_size_y);
pixbuf = nautilus_icon_factory_get_pixbuf_for_icon
- (scalable_icon, icon_size_x, icon_size_y, &text_rect);
+ (scalable_icon,
+ icon_size_x, icon_size_y,
+ G_MAXINT, G_MAXINT,
+ &text_rect);
emblem_pixbufs = NULL;
for (p = emblem_icons; p != NULL; p = p->next) {
emblem_pixbuf = nautilus_icon_factory_get_pixbuf_for_icon
- (p->data, icon_size_x, icon_size_y, NULL);
+ (p->data,
+ icon_size_x, icon_size_y,
+ G_MAXINT, G_MAXINT,
+ NULL);
if (emblem_pixbuf != NULL) {
emblem_pixbufs = g_list_prepend
(emblem_pixbufs, emblem_pixbuf);
diff --git a/libnautilus-private/nautilus-icon-factory.c b/libnautilus-private/nautilus-icon-factory.c
index 1abfb6167..5ee59f3e4 100644
--- a/libnautilus-private/nautilus-icon-factory.c
+++ b/libnautilus-private/nautilus-icon-factory.c
@@ -169,21 +169,28 @@ struct NautilusScalableIcon {
char *modifier;
};
+/* A request for an icon of a particular size. */
+typedef struct {
+ guint nominal_width;
+ guint nominal_height;
+ guint maximum_width;
+ guint maximum_height;
+} IconSizeRequest;
+
/* The key to a hash table that holds the scaled icons as pixbufs.
* In a way, it's not really completely a key, because part of the
* data is stored in here, including the LRU chain.
*/
typedef struct {
NautilusScalableIcon *scalable_icon;
- guint size_in_pixels_x;
- guint size_in_pixels_y;
+ IconSizeRequest size;
NautilusCircularList recently_used_node;
gboolean custom;
gboolean scaled;
ArtIRect text_rect;
-} NautilusIconCacheKey;
+} IconCacheKey;
/* forward declarations */
@@ -201,14 +208,13 @@ static NautilusScalableIcon *nautilus_scalable_icon_get (const char
static guint nautilus_scalable_icon_hash (gconstpointer p);
static gboolean nautilus_scalable_icon_equal (gconstpointer a,
gconstpointer b);
-static void nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key);
-static guint nautilus_icon_cache_key_hash (gconstpointer p);
-static gboolean nautilus_icon_cache_key_equal (gconstpointer a,
+static void icon_cache_key_destroy (IconCacheKey *key);
+static guint icon_cache_key_hash (gconstpointer p);
+static gboolean icon_cache_key_equal (gconstpointer a,
gconstpointer b);
static gboolean vfs_file_exists (const char *file_name);
static GdkPixbuf * get_image_from_cache (NautilusScalableIcon *scalable_icon,
- guint size_in_pixels_x,
- guint size_in_pixels_y,
+ const IconSizeRequest *size,
gboolean picky,
gboolean custom,
ArtIRect *text_rect);
@@ -264,8 +270,8 @@ nautilus_icon_factory_initialize (NautilusIconFactory *factory)
{
factory->scalable_icons = g_hash_table_new (nautilus_scalable_icon_hash,
nautilus_scalable_icon_equal);
- factory->icon_cache = g_hash_table_new (nautilus_icon_cache_key_hash,
- nautilus_icon_cache_key_equal);
+ factory->icon_cache = g_hash_table_new (icon_cache_key_hash,
+ icon_cache_key_equal);
/* Empty out the recently-used list. */
factory->recently_used_dummy_head.next = &factory->recently_used_dummy_head;
@@ -294,7 +300,7 @@ nautilus_icon_factory_initialize_class (NautilusIconFactoryClass *class)
static gboolean
nautilus_icon_factory_destroy_cached_image (gpointer key, gpointer value, gpointer user_data)
{
- nautilus_icon_cache_key_destroy (key);
+ icon_cache_key_destroy (key);
gdk_pixbuf_unref (value);
return TRUE;
}
@@ -319,6 +325,11 @@ nautilus_icon_factory_clear (void)
#if 0
+/* No one ever destroys the icon factory.
+ * There's no public API for doing so.
+ * If they did, we'd have to get this right.
+ */
+
static void
nautilus_icon_factory_destroy (NautilusIconFactory *factory)
{
@@ -340,7 +351,7 @@ nautilus_icon_factory_possibly_free_cached_image (gpointer key,
gpointer value,
gpointer user_data)
{
- NautilusIconCacheKey *icon_key;
+ IconCacheKey *icon_key;
GdkPixbuf *image;
/* Don't free a cache entry that is in the recently used list. */
@@ -354,7 +365,8 @@ nautilus_icon_factory_possibly_free_cached_image (gpointer key,
/* FIXME bugzilla.eazel.com 640:
* We treat all entries as "in use", until we get a hook we can use
- * in GdkPixbuf.
+ * in GdkPixbuf. We are waiting for the "final" hook right now. The
+ * one that's in there is not approved of by the Gtk maintainers.
*/
return FALSE;
#if 0
@@ -496,12 +508,8 @@ make_full_icon_path (const char *path, const char *suffix)
static gboolean
suffix_is_scalable (const char *path)
{
- const char *suffix;
-
- suffix = (const char *)strrchr (path, '.');
- if (suffix == NULL)
- return FALSE;
- return (!strcmp (suffix, ".svg") || !strcmp (suffix, ".SVG"));
+ return nautilus_str_has_suffix (path, ".svg")
+ || nautilus_str_has_suffix (path, ".SVG");
}
/* Pick a particular icon to use, trying all the various suffixes.
@@ -532,8 +540,7 @@ get_themed_icon_file_path (const char *theme_name,
/* Try each suffix. */
for (i = 0; i < NAUTILUS_N_ELEMENTS (icon_file_name_suffixes); i++) {
- if (include_size &&
- !suffix_is_scalable (icon_file_name_suffixes[i])) {
+ if (include_size) {
/* Build a path for this icon. */
partial_path = g_strdup_printf ("%s-%u",
themed_icon_name,
@@ -753,10 +760,8 @@ nautilus_scalable_icon_equal (gconstpointer a,
NautilusScalableIcon *
nautilus_icon_factory_get_icon_for_file (NautilusFile *file, const char* modifier)
{
- char *uri, *file_uri;
+ char *uri, *file_uri, *image_uri, *icon_name;
NautilusScalableIcon *scalable_icon;
- const char *name = NULL;
- gboolean need_to_free_name = FALSE;
if (file == NULL) {
return NULL;
@@ -780,17 +785,15 @@ nautilus_icon_factory_get_icon_for_file (NautilusFile *file, const char* modifie
}
/* handle nautilus link xml files, which may specify their own image */
-
- if (nautilus_link_is_link_file(file_uri)) {
- char *image_uri = nautilus_link_get_image_uri(file_uri);
- if (image_uri) {
- if (nautilus_str_has_prefix(image_uri, "file://"))
+ icon_name = NULL;
+ if (nautilus_link_is_link_file (file_uri)) {
+ image_uri = nautilus_link_get_image_uri (file_uri);
+ if (image_uri != NULL) {
+ if (nautilus_str_has_prefix (image_uri, "file://"))
uri = image_uri;
else {
- name = (const char*) image_uri;
- need_to_free_name = TRUE;
+ icon_name = image_uri;
}
-
}
}
@@ -799,20 +802,20 @@ nautilus_icon_factory_get_icon_for_file (NautilusFile *file, const char* modifie
* we should be checking the mime-type but for now we use the suffix,
* as the mime-type isn't defined in standard setups
*/
- if (uri == NULL && nautilus_str_has_suffix(file_uri,".svg")) {
- uri = g_strdup(file_uri);
+ if (uri == NULL && suffix_is_scalable (file_uri)) {
+ uri = g_strdup (file_uri);
}
/* Get the generic icon set for this file. */
- g_free(file_uri);
- if (name == NULL)
- name = nautilus_icon_factory_get_icon_name_for_file (file);
+ g_free (file_uri);
+ if (icon_name == NULL) {
+ icon_name = g_strdup (nautilus_icon_factory_get_icon_name_for_file (file));
+ }
/* Create the icon or find it in the cache if it's already there. */
- scalable_icon = nautilus_scalable_icon_get (uri, name, modifier);
+ scalable_icon = nautilus_scalable_icon_get (uri, icon_name, modifier);
g_free (uri);
- if (need_to_free_name)
- g_free((char *) name);
+ g_free (icon_name);
return scalable_icon;
}
@@ -1155,19 +1158,21 @@ load_specific_image (NautilusScalableIcon *scalable_icon,
/* FIXME bugzilla.eazel.com 643: This works only with file:// images, because there's
* no convenience function for loading an image with gnome-vfs
- * and gdk-pixbuf.
+ * and gdk-pixbuf. And there's the same problem with the rsvg_render_file library.
*/
- /* FIXME bugzilla.eazel.com 641: should use MIME-type instead of suffix */
- if (nautilus_str_has_suffix(scalable_icon->uri, ".svg")) {
- memset (text_rect, 0, sizeof (*text_rect));
- return load_specific_image_svg (scalable_icon->uri + 7, size_in_pixels);
+ if (nautilus_str_has_prefix (scalable_icon->uri, "file://")) {
+ /* FIXME bugzilla.eazel.com 641: should use MIME-type instead of suffix */
+ if (suffix_is_scalable (scalable_icon->uri)) {
+ memset (text_rect, 0, sizeof (*text_rect));
+ return load_specific_image_svg (scalable_icon->uri + 7, size_in_pixels);
+ }
+
+ if (size_in_pixels == NAUTILUS_ICON_SIZE_STANDARD) {
+ memset (text_rect, 0, sizeof (*text_rect));
+ return gdk_pixbuf_new_from_file (scalable_icon->uri + 7);
+ }
}
- if (size_in_pixels == NAUTILUS_ICON_SIZE_STANDARD
- && nautilus_str_has_prefix (scalable_icon->uri, "file://")) {
- memset (text_rect, 0, sizeof (*text_rect));
- return gdk_pixbuf_new_from_file (scalable_icon->uri + 7);
- }
return NULL;
} else {
/* Standard icon. */
@@ -1181,10 +1186,11 @@ load_specific_image (NautilusScalableIcon *scalable_icon,
if (path == NULL) {
return NULL;
}
- if (suffix_is_scalable (path))
+ if (suffix_is_scalable (path)) {
image = load_specific_image_svg (path, size_in_pixels);
- else
+ } else {
image = gdk_pixbuf_new_from_file (path);
+ }
g_free (path);
return image;
}
@@ -1200,14 +1206,20 @@ load_image_for_scaling (NautilusScalableIcon *scalable_icon,
{
GdkPixbuf *image;
guint actual_size;
+ IconSizeRequest size_request;
static GdkPixbuf *fallback_image;
+ size_request.maximum_width = G_MAXINT;
+ size_request.maximum_height = G_MAXINT;
+
/* First check for a custom image. */
actual_size = 0;
while (get_next_icon_size_to_try (requested_size, &actual_size)) {
+ size_request.nominal_width = actual_size;
+ size_request.nominal_height = actual_size;
+
image = get_image_from_cache (scalable_icon,
- actual_size,
- actual_size,
+ &size_request,
TRUE,
TRUE,
text_rect);
@@ -1221,9 +1233,11 @@ load_image_for_scaling (NautilusScalableIcon *scalable_icon,
/* Next, go for the normal image. */
actual_size = 0;
while (get_next_icon_size_to_try (requested_size, &actual_size)) {
+ size_request.nominal_width = actual_size;
+ size_request.nominal_height = actual_size;
+
image = get_image_from_cache (scalable_icon,
- actual_size,
- actual_size,
+ &size_request,
TRUE,
FALSE,
text_rect);
@@ -1255,42 +1269,109 @@ load_image_for_scaling (NautilusScalableIcon *scalable_icon,
return fallback_image;
}
+/* Consumes the image and returns a scaled one if the image is too big.
+ * Note that this does an unref on the image and returns a new one.
+ */
+static GdkPixbuf *
+scale_image_and_rectangle (GdkPixbuf *image,
+ ArtIRect *rectangle,
+ double scale_x,
+ double scale_y)
+{
+ int width, height;
+ GdkPixbuf *scaled_image;
+
+ width = gdk_pixbuf_get_width (image);
+ height = gdk_pixbuf_get_height (image);
+
+ /* Check for no-scaling case. */
+ if ((int) (width * scale_x) == width
+ && (int) (height * scale_y) == height) {
+ return gdk_pixbuf_ref (image);
+ }
+
+ scaled_image = gdk_pixbuf_scale_simple
+ (image,
+ width * scale_x,
+ height * scale_y,
+ GDK_INTERP_BILINEAR);
+ gdk_pixbuf_unref (image);
+
+ rectangle->x0 *= scale_x;
+ rectangle->y0 *= scale_y;
+ rectangle->x1 *= scale_x;
+ rectangle->y1 *= scale_y;
+
+ return scaled_image;
+}
+
+static void
+revise_scale_factors_if_too_big (GdkPixbuf *image,
+ const IconSizeRequest *size,
+ double *scale_x,
+ double *scale_y)
+{
+ int width, height;
+ double y_distortion;
+
+ width = gdk_pixbuf_get_width (image);
+ height = gdk_pixbuf_get_height (image);
+
+ if ((int) (width * *scale_x) <= size->maximum_width
+ && (int) (height * *scale_y) <= size->maximum_height) {
+ return;
+ }
+
+ y_distortion = *scale_y / *scale_x;
+
+ *scale_x = MIN ((double) size->maximum_width / width,
+ (double) size->maximum_height / (height / y_distortion));
+ *scale_y = *scale_x * y_distortion;
+}
+
+/* Consumes the image and returns a scaled one if the image is too big.
+ * Note that this does an unref on the image and returns a new one.
+ */
+static GdkPixbuf *
+scale_image_down_if_too_big (GdkPixbuf *image,
+ const IconSizeRequest *size,
+ ArtIRect *text_rect)
+{
+ double scale_x, scale_y;
+
+ scale_x = 1.0;
+ scale_y = 1.0;
+ revise_scale_factors_if_too_big (image, size, &scale_x, &scale_y);
+ return scale_image_and_rectangle (image, text_rect, scale_x, scale_y);
+}
+
/* This load function is not allowed to return NULL. */
static GdkPixbuf *
load_image_scale_if_necessary (NautilusScalableIcon *scalable_icon,
- guint requested_size_x,
- guint requested_size_y,
+ const IconSizeRequest *size,
gboolean *scaled,
gboolean *custom,
ArtIRect *text_rect)
{
- GdkPixbuf *image, *scaled_image;
- guint actual_size;
- int scaled_width, scaled_height;
+ GdkPixbuf *image;
+ guint nominal_actual_size;
+ double scale_x, scale_y;
/* Load the image for the icon that's closest in size to what we want. */
- image = load_image_for_scaling (scalable_icon, requested_size_x,
- &actual_size, custom, text_rect);
- if (requested_size_x == actual_size && requested_size_y == actual_size) {
+ image = load_image_for_scaling (scalable_icon, size->nominal_width,
+ &nominal_actual_size, custom, text_rect);
+ if (size->nominal_width == nominal_actual_size
+ && size->nominal_height == nominal_actual_size) {
*scaled = FALSE;
- return image;
+ return scale_image_down_if_too_big (image, size, text_rect);
}
/* Scale the image to the size we want. */
- scaled_width = gdk_pixbuf_get_width (image) * requested_size_x / actual_size;
- scaled_height = gdk_pixbuf_get_height (image) * requested_size_y / actual_size;
- scaled_image = gdk_pixbuf_scale_simple
- (image, scaled_width, scaled_height, GDK_INTERP_BILINEAR);
-
- /* Scale the text rectangle to the same size. */
- text_rect->x0 = text_rect->x0 * requested_size_x / actual_size;
- text_rect->y0 = text_rect->y0 * requested_size_y / actual_size;
- text_rect->x1 = text_rect->x1 * requested_size_x / actual_size;
- text_rect->y1 = text_rect->y1 * requested_size_y / actual_size;
-
- gdk_pixbuf_unref (image);
*scaled = TRUE;
- return scaled_image;
+ scale_x = (double) size->nominal_width / nominal_actual_size;
+ scale_y = (double) size->nominal_height / nominal_actual_size;
+ revise_scale_factors_if_too_big (image, size, &scale_x, &scale_y);
+ return scale_image_and_rectangle (image, text_rect, scale_x, scale_y);
}
/* Move this item to the head of the recently-used list,
@@ -1347,15 +1428,14 @@ mark_recently_used (NautilusCircularList *node)
*/
static GdkPixbuf *
get_image_from_cache (NautilusScalableIcon *scalable_icon,
- guint size_in_pixels_x,
- guint size_in_pixels_y,
+ const IconSizeRequest *size,
gboolean picky,
gboolean custom,
ArtIRect *text_rect)
{
NautilusIconFactory *factory;
GHashTable *hash_table;
- NautilusIconCacheKey lookup_key, *key;
+ IconCacheKey lookup_key, *key;
GdkPixbuf *image;
gpointer key_in_table, value;
@@ -1366,8 +1446,7 @@ get_image_from_cache (NautilusScalableIcon *scalable_icon,
/* Check to see if it's already in the table. */
lookup_key.scalable_icon = scalable_icon;
- lookup_key.size_in_pixels_x = size_in_pixels_x;
- lookup_key.size_in_pixels_y = size_in_pixels_y;
+ lookup_key.size = *size;
if (g_hash_table_lookup_extended (hash_table, &lookup_key,
&key_in_table, &value)) {
/* Found it in the table. */
@@ -1388,24 +1467,37 @@ get_image_from_cache (NautilusScalableIcon *scalable_icon,
ArtIRect key_text_rect;
/* Not in the table, so load the image. */
+
+ /* If we're picky, then we want the image only if this exact
+ * nominal size is available.
+ */
if (picky) {
- if (size_in_pixels_x != size_in_pixels_y) {
+ /* Actual icons have nominal sizes that are square! */
+ if (size->nominal_width
+ != size->nominal_height) {
return NULL;
}
+
+ /* Get the image. */
image = load_specific_image (scalable_icon,
- size_in_pixels_x,
+ size->nominal_width,
custom,
&key_text_rect);
if (image == NULL) {
return NULL;
}
+ /* Now we have the image, but is it bigger than
+ * the maximum size? If so we scale it, even but we don't
+ * call it "scaled" for caching purposese.
+ */
+ image = scale_image_down_if_too_big (image, size, &key_text_rect);
+
got_scaled_image = FALSE;
got_custom_image = custom;
} else {
image = load_image_scale_if_necessary (scalable_icon,
- size_in_pixels_x,
- size_in_pixels_y,
+ size,
&got_scaled_image,
&got_custom_image,
&key_text_rect);
@@ -1413,11 +1505,10 @@ get_image_from_cache (NautilusScalableIcon *scalable_icon,
}
/* Create the key for the table. */
- key = g_new0 (NautilusIconCacheKey, 1);
+ key = g_new0 (IconCacheKey, 1);
nautilus_scalable_icon_ref (scalable_icon);
key->scalable_icon = scalable_icon;
- key->size_in_pixels_x = size_in_pixels_x;
- key->size_in_pixels_y = size_in_pixels_y;
+ key->size = *size;
key->scaled = got_scaled_image;
key->custom = got_custom_image;
key->text_rect = key_text_rect;
@@ -1444,42 +1535,52 @@ get_image_from_cache (NautilusScalableIcon *scalable_icon,
GdkPixbuf *
nautilus_icon_factory_get_pixbuf_for_icon (NautilusScalableIcon *scalable_icon,
- guint size_in_pixels_x, guint size_in_pixels_y,
+ guint nominal_width,
+ guint nominal_height,
+ guint maximum_width,
+ guint maximum_height,
ArtIRect *text_rect)
{
- return get_image_from_cache (scalable_icon,
- size_in_pixels_x, size_in_pixels_y,
- FALSE, FALSE, text_rect);
+ IconSizeRequest size;
+ size.nominal_width = nominal_width;
+ size.nominal_height = nominal_width;
+ size.maximum_width = maximum_width;
+ size.maximum_height = maximum_width;
+ return get_image_from_cache (scalable_icon, &size, FALSE, FALSE, text_rect);
}
static void
-nautilus_icon_cache_key_destroy (NautilusIconCacheKey *key)
+icon_cache_key_destroy (IconCacheKey *key)
{
nautilus_scalable_icon_unref (key->scalable_icon);
}
static guint
-nautilus_icon_cache_key_hash (gconstpointer p)
+icon_cache_key_hash (gconstpointer p)
{
- const NautilusIconCacheKey *key;
+ const IconCacheKey *key;
key = p;
- return (((GPOINTER_TO_UINT (key->scalable_icon) << 4)
- ^ key->size_in_pixels_x) << 4)
- ^ key->size_in_pixels_y;
+ return (((((((GPOINTER_TO_UINT (key->scalable_icon) << 4)
+ ^ key->size.nominal_width) << 4)
+ ^ key->size.nominal_height) << 4)
+ ^ key->size.maximum_width) << 4)
+ ^ key->size.maximum_height;
}
static gboolean
-nautilus_icon_cache_key_equal (gconstpointer a, gconstpointer b)
+icon_cache_key_equal (gconstpointer a, gconstpointer b)
{
- const NautilusIconCacheKey *key_a, *key_b;
+ const IconCacheKey *key_a, *key_b;
key_a = a;
key_b = b;
return key_a->scalable_icon == key_b->scalable_icon
- && key_a->size_in_pixels_x == key_b->size_in_pixels_x
- && key_a->size_in_pixels_y == key_b->size_in_pixels_y;
+ && key_a->size.nominal_width == key_b->size.nominal_width
+ && key_a->size.nominal_height == key_b->size.nominal_height
+ && key_a->size.maximum_width == key_b->size.maximum_width
+ && key_a->size.maximum_height == key_b->size.maximum_height;
}
/* Return nominal icon size for given zoom level.
@@ -1525,10 +1626,11 @@ nautilus_icon_factory_get_pixbuf_for_file (NautilusFile *file,
g_return_val_if_fail (file != NULL, NULL);
icon = nautilus_icon_factory_get_icon_for_file (file, NULL);
- pixbuf = nautilus_icon_factory_get_pixbuf_for_icon (icon,
- size_in_pixels,
- size_in_pixels,
- NULL);
+ pixbuf = nautilus_icon_factory_get_pixbuf_for_icon
+ (icon,
+ size_in_pixels, size_in_pixels,
+ size_in_pixels, size_in_pixels,
+ NULL);
nautilus_scalable_icon_unref (icon);
return pixbuf;
}
@@ -1720,9 +1822,8 @@ check_for_thumbnails (NautilusIconFactory *factory)
}
/* utility to draw the thumbnail frame. The frame is rectangular, so it doesn't need an alpha channel */
-
static void
-draw_thumbnail_frame(GdkPixbuf *frame_pixbuf)
+draw_thumbnail_frame (GdkPixbuf *frame_pixbuf)
{
gint index, width, height, depth, rowstride, fill_value;
guchar *pixels, *temp_pixels;
diff --git a/libnautilus-private/nautilus-icon-factory.h b/libnautilus-private/nautilus-icon-factory.h
index 8df218903..6940fdc78 100644
--- a/libnautilus-private/nautilus-icon-factory.h
+++ b/libnautilus-private/nautilus-icon-factory.h
@@ -100,8 +100,10 @@ GList * nautilus_icon_factory_get_emblem_icons_for_file (Nautil
* text, then the rectangle is (0, 0, 0, 0).
*/
GdkPixbuf * nautilus_icon_factory_get_pixbuf_for_icon (NautilusScalableIcon *scalable_icon,
- guint size_in_pixels_x,
- guint size_in_pixels_y,
+ guint nominal_size_in_pixels_x,
+ guint nominal_size_in_pixels_y,
+ guint maximum_size_in_pixels_x,
+ guint maximum_size_in_pixels_y,
ArtIRect *embedded_text_rectangle);
/* Convenience functions for the common case where you want to choose
diff --git a/src/file-manager/fm-list-view.c b/src/file-manager/fm-list-view.c
index 59e50918c..bc9c4a59e 100644
--- a/src/file-manager/fm-list-view.c
+++ b/src/file-manager/fm-list-view.c
@@ -1179,8 +1179,8 @@ fm_list_view_get_emblem_pixbufs_for_file (FMListView *list_view,
for (p = emblem_icons; p != NULL; p = p->next) {
emblem_pixbuf = nautilus_icon_factory_get_pixbuf_for_icon
(p->data,
- emblem_size,
- emblem_size,
+ emblem_size, emblem_size,
+ emblem_size, emblem_size,
NULL);
if (emblem_pixbuf != NULL) {
emblem_pixbufs = g_list_prepend