nautilus r14309 - in trunk: . libnautilus-private src/file-manager



Author: cneumair
Date: Mon Jun 30 13:26:34 2008
New Revision: 14309
URL: http://svn.gnome.org/viewvc/nautilus?rev=14309&view=rev

Log:
2008-06-30  Christian Neumair  <cneumair gnome org>

	* libnautilus-private/nautilus-directory-async.c (thumbnail_done),
	(thumbnail_loader_size_prepared), (get_pixbuf_for_content),
	(thumbnail_start):
	* libnautilus-private/nautilus-file.h:
	Scale down huge pixbufs when loading. Massively speed up loading of
	directories where the original image is used as thumbnail.
	Also try to write the whole file at once rather than writing in chunks.

	* libnautilus-private/nautilus-file-private.h:
	* libnautilus-private/nautilus-file.c (nautilus_file_get_icon):
	Rewrite some flaky parts of thumbnailing.

	Never scale any thumbnails up.
	Always compose thumbnail on the fly instead storing it once and
	scaling it up and down.
	Add flag to force that thumbnail size matches
	the output icon size for tree view.

	* src/file-manager/fm-list-model.c (fm_list_model_get_value):
	Use this flag.


Modified:
   trunk/ChangeLog
   trunk/libnautilus-private/nautilus-directory-async.c
   trunk/libnautilus-private/nautilus-file-private.h
   trunk/libnautilus-private/nautilus-file.c
   trunk/libnautilus-private/nautilus-file.h
   trunk/src/file-manager/fm-list-model.c

Modified: trunk/libnautilus-private/nautilus-directory-async.c
==============================================================================
--- trunk/libnautilus-private/nautilus-directory-async.c	(original)
+++ trunk/libnautilus-private/nautilus-directory-async.c	Mon Jun 30 13:26:34 2008
@@ -3768,7 +3768,6 @@
 		g_object_unref (file->details->thumbnail);
 		file->details->thumbnail = NULL;
 	}
-	file->details->thumbnail_size = 0;
 	if (pixbuf) {
 		thumb_mtime_str = gdk_pixbuf_get_option (pixbuf, "tEXt::Thumb::MTime");
 		if (thumb_mtime_str) {
@@ -3838,6 +3837,35 @@
 	g_free (state);
 }
 
+extern int cached_thumbnail_size;
+
+/* scale very large images down to the max. size we need */
+static void
+thumbnail_loader_size_prepared (GdkPixbufLoader *loader,
+				int width,
+				int height,
+				gpointer user_data)
+{
+	int max_thumbnail_size;
+	double aspect_ratio;
+
+	aspect_ratio = ((double) width) / height;
+
+	/* cf. nautilus_file_get_icon() */
+	max_thumbnail_size = NAUTILUS_ICON_SIZE_LARGEST * cached_thumbnail_size / NAUTILUS_ICON_SIZE_STANDARD;
+	if (MAX (width, height) > max_thumbnail_size) {
+		if (width > height) {
+			width = max_thumbnail_size;
+			height = width / aspect_ratio;
+		} else {
+			height = max_thumbnail_size;
+			width = height * aspect_ratio;
+		}
+
+		gdk_pixbuf_loader_set_size (loader, width, height);
+	}
+}
+
 static GdkPixbuf *
 get_pixbuf_for_content (goffset file_len,
 			char *file_contents)
@@ -3849,11 +3877,14 @@
 	pixbuf = NULL;
 	
 	loader = gdk_pixbuf_loader_new ();
+	g_signal_connect (loader, "size-prepared",
+			  G_CALLBACK (thumbnail_loader_size_prepared),
+			  NULL);
 
 	/* For some reason we have to write in chunks, or gdk-pixbuf fails */
 	res = TRUE;
 	while (res && file_len > 0) {
-		chunk_len = MIN (32*1024, file_len);
+		chunk_len = file_len;
 		res = gdk_pixbuf_loader_write (loader, file_contents, chunk_len, NULL);
 		file_contents += chunk_len;
 		file_len -= chunk_len;
@@ -3959,7 +3990,7 @@
 	state->file = file;
 	state->cancellable = g_cancellable_new ();
 
-	if (file->details->thumbnail_size > 128) {
+	if (file->details->thumbnail_wants_original) {
 		state->tried_original = TRUE;
 		state->trying_original = TRUE;
 		location = nautilus_file_get_location (file);

Modified: trunk/libnautilus-private/nautilus-file-private.h
==============================================================================
--- trunk/libnautilus-private/nautilus-file-private.h	(original)
+++ trunk/libnautilus-private/nautilus-file-private.h	Mon Jun 30 13:26:34 2008
@@ -107,7 +107,6 @@
 	char *thumbnail_path;
 	GdkPixbuf *thumbnail;
 	time_t thumbnail_mtime;
-	int thumbnail_size; /* 0 means original unframed thumbnail */
 	
 	GList *mime_list; /* If this is a directory, the list of MIME types in it. */
 	char *top_left_text;
@@ -182,6 +181,7 @@
 	eel_boolean_bit got_custom_activation_location : 1;
 
 	eel_boolean_bit thumbnail_is_up_to_date       : 1;
+	eel_boolean_bit thumbnail_wants_original      : 1;
 	eel_boolean_bit thumbnail_tried_original      : 1;
 	eel_boolean_bit thumbnailing_failed           : 1;
 	

Modified: trunk/libnautilus-private/nautilus-file.c
==============================================================================
--- trunk/libnautilus-private/nautilus-file.c	(original)
+++ trunk/libnautilus-private/nautilus-file.c	Mon Jun 30 13:26:34 2008
@@ -3228,7 +3228,7 @@
 
 
 static int cached_thumbnail_limit;
-static int cached_thumbnail_size;
+int cached_thumbnail_size;
 static int show_image_thumbs;
 
 GFilesystemPreviewType
@@ -3387,51 +3387,52 @@
 		return icon;
 	}
 
-	modified_size = size * cached_thumbnail_size / NAUTILUS_ICON_SIZE_STANDARD; 
+	if (flags & NAUTILUS_FILE_ICON_FLAGS_FORCE_THUMBNAIL_SIZE) {
+		modified_size = size;
+	} else {
+		modified_size = size * cached_thumbnail_size / NAUTILUS_ICON_SIZE_STANDARD; 
+	}
 
 	if (flags & NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS &&
 	    nautilus_file_should_show_thumbnail (file)) {
 		if (file->details->thumbnail) {
-			if (file->details->thumbnail_size == modified_size) {
-				scaled_pixbuf = g_object_ref (file->details->thumbnail);
-			} else {
-				int w, h, s;
-				double scale;
-				
-				if (file->details->thumbnail_size == 0) {
-					raw_pixbuf = g_object_ref (file->details->thumbnail);
-				} else {
-					raw_pixbuf = nautilus_thumbnail_unframe_image (file->details->thumbnail);
-				}
+			int w, h, s;
+			double scale;
+
+			raw_pixbuf = g_object_ref (file->details->thumbnail);
 
-				w = gdk_pixbuf_get_width (raw_pixbuf);
-				h = gdk_pixbuf_get_height (raw_pixbuf);
-				
-				s = MAX (w, h);
-				
-				scale = (double)modified_size / s;
+			w = gdk_pixbuf_get_width (raw_pixbuf);
+			h = gdk_pixbuf_get_height (raw_pixbuf);
+			
+			s = MAX (w, h);
+			scale = (double)modified_size / s;
 
-				/* These compensate for the size of the frame which will be added around the raw image */
+
+			if (scale > 0.99) {
+				/* never scale any thumbnails up */
+				scaled_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+								gdk_pixbuf_get_has_alpha (raw_pixbuf),
+								gdk_pixbuf_get_bits_per_sample (raw_pixbuf),
+								w * scale, h * scale);
+				gdk_pixbuf_fill (scaled_pixbuf, 0xffffff00);
+				gdk_pixbuf_copy_area (raw_pixbuf,
+						      0, 0, w, h,
+						      scaled_pixbuf,
+						      (gdk_pixbuf_get_width (scaled_pixbuf) - w) / 2,
+						      (gdk_pixbuf_get_height (scaled_pixbuf) - h) / 2);
+			} else {
 				scaled_pixbuf = gdk_pixbuf_scale_simple (raw_pixbuf,
-									 NAUTILUS_THUMBNAIL_FRAME_LEFT + w * scale + NAUTILUS_THUMBNAIL_FRAME_RIGHT,
-									 NAUTILUS_THUMBNAIL_FRAME_TOP + h * scale + NAUTILUS_THUMBNAIL_FRAME_BOTTOM,
+									 w * scale, h * scale,
 									 GDK_INTERP_BILINEAR);
-				nautilus_thumbnail_frame_image (&scaled_pixbuf);
-				
-				g_object_unref (raw_pixbuf);
-
-				if (modified_size > file->details->thumbnail_size) {
-					/* Invalidate if we resize upward (and the
-					   loaded was not the original raw version, w/ size 0).
-					*/
-					if (file->details->thumbnail_size != 0 ||
-					    (modified_size > 128 && !file->details->thumbnail_tried_original)) {
-						nautilus_file_invalidate_attributes (file, NAUTILUS_FILE_ATTRIBUTE_THUMBNAIL);
-					}
-					file->details->thumbnail_size = modified_size;
-					g_object_unref (file->details->thumbnail);
-					file->details->thumbnail = g_object_ref (scaled_pixbuf);
-				}
+			}
+			nautilus_thumbnail_frame_image (&scaled_pixbuf);
+			g_object_unref (raw_pixbuf);
+
+			if (modified_size > 128 &&
+			    !file->details->thumbnail_wants_original) {
+				/* Invalidate if we resize upward */
+				file->details->thumbnail_wants_original = TRUE;
+				nautilus_file_invalidate_attributes (file, NAUTILUS_FILE_ATTRIBUTE_THUMBNAIL);
 			}
 			
 			icon = nautilus_icon_info_new_for_pixbuf (scaled_pixbuf);

Modified: trunk/libnautilus-private/nautilus-file.h
==============================================================================
--- trunk/libnautilus-private/nautilus-file.h	(original)
+++ trunk/libnautilus-private/nautilus-file.h	Mon Jun 30 13:26:34 2008
@@ -77,7 +77,9 @@
 	NAUTILUS_FILE_ICON_FLAGS_IGNORE_VISITING = (1<<1),
 	NAUTILUS_FILE_ICON_FLAGS_EMBEDDING_TEXT = (1<<2),
 	NAUTILUS_FILE_ICON_FLAGS_FOR_DRAG_ACCEPT = (1<<3),
-	NAUTILUS_FILE_ICON_FLAGS_FOR_OPEN_FOLDER = (1<<4)
+	NAUTILUS_FILE_ICON_FLAGS_FOR_OPEN_FOLDER = (1<<4),
+	/* whether the thumbnail size must match the display icon size */
+	NAUTILUS_FILE_ICON_FLAGS_FORCE_THUMBNAIL_SIZE = (1<<5)
 } NautilusFileIconFlags;	
 
 /* Emblems sometimes displayed for NautilusFiles. Do not localize. */ 

Modified: trunk/src/file-manager/fm-list-model.c
==============================================================================
--- trunk/src/file-manager/fm-list-model.c	(original)
+++ trunk/src/file-manager/fm-list-model.c	Mon Jun 30 13:26:34 2008
@@ -286,7 +286,8 @@
 			zoom_level = fm_list_model_get_zoom_level_from_column_id (column);
 			icon_size = nautilus_get_icon_size_for_zoom_level (zoom_level);
 
-			flags = NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS;
+			flags = NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS |
+				NAUTILUS_FILE_ICON_FLAGS_FORCE_THUMBNAIL_SIZE;
 			if (model->details->drag_view != NULL) {
 				GtkTreePath *path_a, *path_b;
 				



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]