[gthumb] removed use of the gdk_draw_* functions, use cairo instead



commit 6e1a206b6729995c8bd45485c23b97be878fa536
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Thu Jul 22 21:54:03 2010 +0200

    removed use of the gdk_draw_* functions, use cairo instead

 extensions/gstreamer_tools/gth-media-viewer-page.c |   87 ++--
 extensions/image_viewer/gth-image-viewer-page.c    |   12 +-
 gthumb/Makefile.am                                 |    4 +-
 gthumb/gth-cell-renderer-thumbnail.c               |  131 ++---
 gthumb/gth-empty-list.c                            |   30 +-
 gthumb/gth-image-dragger.c                         |    4 +-
 gthumb/gth-image-navigator.c                       |  503 +++++++++++++++++
 gthumb/gth-image-navigator.h                       |   58 ++
 gthumb/gth-image-selector.c                        |  112 ++--
 gthumb/gth-image-viewer-tool.c                     |    5 +-
 gthumb/gth-image-viewer-tool.h                     |    6 +-
 gthumb/gth-image-viewer.c                          |  263 ++++-----
 gthumb/gth-image-viewer.h                          |    2 +
 gthumb/gth-nav-window.c                            |  574 --------------------
 gthumb/gth-nav-window.h                            |   58 --
 po/POTFILES.in                                     |    4 +-
 16 files changed, 870 insertions(+), 983 deletions(-)
---
diff --git a/extensions/gstreamer_tools/gth-media-viewer-page.c b/extensions/gstreamer_tools/gth-media-viewer-page.c
index ccbc6d5..f4139e6 100644
--- a/extensions/gstreamer_tools/gth-media-viewer-page.c
+++ b/extensions/gstreamer_tools/gth-media-viewer-page.c
@@ -99,18 +99,25 @@ _gth_media_viewer_page_update_caption (GthMediaViewerPage *self)
 		return;
 
 	if (self->priv->file_data != NULL) {
-		const char  *text;
+		GString     *description;
 		GthMetadata *metadata;
 
-		text = NULL;
+		description = g_string_new ("");
 		metadata = (GthMetadata *) g_file_info_get_attribute_object (self->priv->file_data->info, "general::title");
-		if (metadata != NULL)
-			text = gth_metadata_get_formatted (metadata);
+		if (metadata != NULL) {
+			g_string_append (description, gth_metadata_get_formatted (metadata));
+			metadata = (GthMetadata *) g_file_info_get_attribute_object (self->priv->file_data->info, "audio-video::general::artist");
+			if (metadata != NULL) {
+				g_string_append (description, "\n");
+				g_string_append (description, gth_metadata_get_formatted (metadata));
+			}
+		}
 		else
-			text = g_file_info_get_display_name (self->priv->file_data->info);
+			g_string_append (description, g_file_info_get_display_name (self->priv->file_data->info));
+
+		pango_layout_set_text (self->priv->caption_layout, description->str, -1);
 
-		if (text != NULL)
-			pango_layout_set_text (self->priv->caption_layout, text, -1);
+		g_string_free (description, TRUE);
 	}
 	else
 		pango_layout_set_text (self->priv->caption_layout, "", -1);
@@ -126,6 +133,7 @@ video_area_realize_cb (GtkWidget *widget,
 	GthMediaViewerPage *self = user_data;
 
 	self->priv->caption_layout = gtk_widget_create_pango_layout (widget, "");
+	pango_layout_set_alignment (self->priv->caption_layout, PANGO_ALIGN_CENTER);
 	_gth_media_viewer_page_update_caption (self);
 }
 
@@ -147,6 +155,9 @@ video_area_expose_event_cb (GtkWidget      *widget,
 			    gpointer        user_data)
 {
 	GthMediaViewerPage *self = user_data;
+	GtkAllocation       allocation;
+	GtkStyle           *style;
+	cairo_t            *cr;
 
 	if (event->count > 0)
 		return FALSE;
@@ -154,6 +165,9 @@ video_area_expose_event_cb (GtkWidget      *widget,
 	if (self->priv->xwin_assigned && self->priv->has_video)
 		return FALSE;
 
+	gtk_widget_get_allocation (widget, &allocation);
+	style = gtk_widget_get_style (widget);
+
 	if (self->priv->icon == NULL) {
 		char  *type;
 		GIcon *icon;
@@ -165,9 +179,9 @@ video_area_expose_event_cb (GtkWidget      *widget,
 		if (type == NULL)
 			type = g_content_type_from_mime_type ("text/plain");
 		icon = g_content_type_get_icon (type);
-		size = widget->allocation.width;
-		if (size > widget->allocation.height)
-			size = widget->allocation.height;
+		size = allocation.width;
+		if (size > allocation.height)
+			size = allocation.height;
 		size = size / 3;
 		self->priv->icon = _g_icon_get_pixbuf (icon, size, gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget)));
 
@@ -175,44 +189,49 @@ video_area_expose_event_cb (GtkWidget      *widget,
 		g_free (type);
 	}
 
-	gdk_draw_rectangle (gtk_widget_get_window (widget),
-			    self->priv->has_video ? widget->style->black_gc : widget->style->text_gc[GTK_WIDGET_STATE (widget)],
-			    TRUE,
-			    event->area.x,
-			    event->area.y,
-			    event->area.width,
-			    event->area.height);
+	cr = gdk_cairo_create (gtk_widget_get_window (widget));
+	gdk_cairo_region (cr, event->region);
+	cairo_clip (cr);
+	if (self->priv->has_video)
+		cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+	else
+		gdk_cairo_set_source_color (cr, &style->text[gtk_widget_get_state (widget)]);
+	gdk_cairo_region (cr, event->region);
+	cairo_fill (cr);
 
 	if (self->priv->icon != NULL) {
 		int            icon_w, icon_h;
+		int            text_w;
 		int            icon_x, icon_y;
 		PangoRectangle logical_rect;
 		int            x, y;
 
 		icon_w = gdk_pixbuf_get_width (self->priv->icon);
 		icon_h = gdk_pixbuf_get_height (self->priv->icon);
-		pango_layout_set_width (self->priv->caption_layout, PANGO_SCALE * (icon_w * 3 / 2));
+
+		text_w = (icon_w * 3 / 2);
+		pango_layout_set_width (self->priv->caption_layout, PANGO_SCALE * text_w);
 		pango_layout_get_extents (self->priv->caption_layout, NULL, &logical_rect);
-		icon_x = (widget->allocation.width - icon_w) / 2;
-		x = (widget->allocation.width - PANGO_PIXELS (logical_rect.width)) / 2 + PANGO_PIXELS (logical_rect.x);
-		icon_y = (widget->allocation.height - (icon_h + PANGO_PIXELS (logical_rect.height))) / 2;
+
+		icon_x = (allocation.width - icon_w) / 2;
+		x = (allocation.width - text_w) / 2;
+
+		icon_y = (allocation.height - (icon_h + PANGO_PIXELS (logical_rect.height))) / 2;
 		y = icon_y + icon_h;
 
-		gdk_draw_pixbuf (gtk_widget_get_window (widget),
-				 widget->style->base_gc[GTK_WIDGET_STATE (widget)],
-				 self->priv->icon,
-				 0, 0,
-				 icon_x, icon_y,
-				 icon_w, icon_h,
-				 GDK_RGB_DITHER_NORMAL,
-				 0, 0);
-		gdk_draw_layout (gtk_widget_get_window (widget),
-				 widget->style->base_gc[GTK_WIDGET_STATE (widget)],
-				 x, y,
-				 self->priv->caption_layout);
+		gdk_cairo_set_source_pixbuf (cr, self->priv->icon, icon_x, icon_y);
+		cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h);
+		cairo_fill (cr);
+
+		cairo_move_to (cr, x, y);
+		pango_cairo_layout_path (cr, self->priv->caption_layout);
+		gdk_cairo_set_source_color (cr, &style->base[gtk_widget_get_state (widget)]);
+		cairo_fill (cr);
 	}
 
-	return FALSE;
+	cairo_destroy (cr);
+
+	return TRUE;
 }
 
 
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index d6ff354..f944861 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -33,7 +33,7 @@
 
 struct _GthImageViewerPagePrivate {
 	GthBrowser        *browser;
-	GtkWidget         *nav_window;
+	GtkWidget         *image_navigator;
 	GtkWidget         *viewer;
 	GthImagePreloader *preloader;
 	GtkActionGroup    *actions;
@@ -460,10 +460,10 @@ gth_image_viewer_page_real_activate (GthViewerPage *base,
 			  G_CALLBACK (viewer_key_press_cb),
 			  self);
 
-	self->priv->nav_window = gth_nav_window_new (GTH_IMAGE_VIEWER (self->priv->viewer));
-	gtk_widget_show (self->priv->nav_window);
+	self->priv->image_navigator = gth_image_navigator_new (GTH_IMAGE_VIEWER (self->priv->viewer));
+	gtk_widget_show (self->priv->image_navigator);
 
-	gth_browser_set_viewer_widget (browser, self->priv->nav_window);
+	gth_browser_set_viewer_widget (browser, self->priv->image_navigator);
 	gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
 
 	/* gconf notifications */
@@ -653,11 +653,11 @@ gth_image_viewer_page_real_fullscreen (GthViewerPage *base,
 
 	self = (GthImageViewerPage *) base;
 	if (active) {
-		gth_nav_window_set_scrollbars_visible (GTH_NAV_WINDOW (self->priv->nav_window), FALSE);
+		gth_image_navigator_set_scrollbars_visible (GTH_IMAGE_NAVIGATOR (self->priv->image_navigator), FALSE);
 		gth_image_viewer_set_black_background (GTH_IMAGE_VIEWER (self->priv->viewer), TRUE);
 	}
 	else {
-		gth_nav_window_set_scrollbars_visible (GTH_NAV_WINDOW (self->priv->nav_window), TRUE);
+		gth_image_navigator_set_scrollbars_visible (GTH_IMAGE_NAVIGATOR (self->priv->image_navigator), TRUE);
 		gth_image_viewer_set_black_background (GTH_IMAGE_VIEWER (self->priv->viewer), eel_gconf_get_boolean (PREF_BLACK_BACKGROUND, FALSE));
 	}
 }
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 67ab85b..4daa84a 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -69,6 +69,7 @@ PUBLIC_HEADER_FILES = 					\
 	gth-image-dragger.h				\
 	gth-image-history.h				\
 	gth-image-loader.h				\
+	gth-image-navigator.h				\
 	gth-image-preloader.h				\
 	gth-image-selector.h				\
 	gth-image-viewer.h				\
@@ -81,7 +82,6 @@ PUBLIC_HEADER_FILES = 					\
 	gth-metadata-provider.h				\
 	gth-monitor.h					\
 	gth-multipage.h					\
-	gth-nav-window.h				\
 	gth-overwrite-dialog.h				\
 	gth-pixbuf-task.h				\
 	gth-pixbuf-list-task.h				\
@@ -184,6 +184,7 @@ gthumb_SOURCES = 					\
 	gth-image-dragger.c				\
 	gth-image-history.c				\
 	gth-image-loader.c				\
+	gth-image-navigator.c				\
 	gth-image-preloader.c				\
 	gth-image-selector.c				\
 	gth-image-viewer.c				\
@@ -202,7 +203,6 @@ gthumb_SOURCES = 					\
 	gth-metadata-provider-file.c			\
 	gth-monitor.c					\
 	gth-multipage.c					\
-	gth-nav-window.c				\
 	gth-overwrite-dialog.c				\
 	gth-pixbuf-task.c				\
 	gth-pixbuf-list-task.c				\
diff --git a/gthumb/gth-cell-renderer-thumbnail.c b/gthumb/gth-cell-renderer-thumbnail.c
index 9a1c40c..a0b99d6 100644
--- a/gthumb/gth-cell-renderer-thumbnail.c
+++ b/gthumb/gth-cell-renderer-thumbnail.c
@@ -347,6 +347,10 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer      *cell,
   		state = ((flags & GTK_CELL_RENDERER_FOCUSED) == GTK_CELL_RENDERER_FOCUSED) ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL;
 
 	if (self->priv->is_icon || ((image_rect.width < self->priv->size) && (image_rect.height < self->priv->size))) {
+
+		/* use a gray rounded box for icons or when the original size
+		 * is smaller than the thumbnail size... */
+
 		if (state == GTK_STATE_NORMAL)
 			gdk_cairo_set_source_color (cr, &widget->style->bg[state]);
 		else
@@ -356,8 +360,10 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer      *cell,
 		cairo_close_path (cr);
 		cairo_fill (cr);
 	}
+	else {
+
+		/* ...else draw a frame with a drop-shadow effect */
 
-	if (! self->priv->is_icon && ! ((image_rect.width < self->priv->size) && (image_rect.height < self->priv->size))) {
 		GdkRectangle frame_rect;
 
 		if (state == GTK_STATE_ACTIVE)
@@ -379,71 +385,41 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer      *cell,
 			frame_rect = image_rect;
 		}
 
-		/*
-		gdk_cairo_set_source_color (cr, &style->dark[state]);
-		_cairo_draw_rounded_box (cr,
-				         frame_rect.x - border + 2.5,
-				         frame_rect.y - border + 2.5,
-				         frame_rect.width + (border * 2) - 1,
-				         frame_rect.height + (border * 2) - 1,
-				         0.0);
-		cairo_close_path (cr);
-		cairo_fill (cr);
-
 		cairo_set_line_width (cr, 0.5);
-		_cairo_draw_rounded_box (cr,
-				         frame_rect.x - border + 0.5,
-				         frame_rect.y - border + 0.5,
-				         frame_rect.width + (border * 2) - 1,
-				         frame_rect.height + (border * 2) - 1,
-				         0.0);
-		cairo_close_path (cr);
-		gdk_cairo_set_source_color (cr, &style->base[state]);
-		cairo_fill_preserve (cr);
+		cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
 		gdk_cairo_set_source_color (cr, &style->dark[state]);
+
+		/* the outer frame */
+
+		cairo_rectangle (cr,
+				 frame_rect.x - border + 0.5,
+				 frame_rect.y - border + 0.5,
+				 frame_rect.width + (border * 2) - 1,
+				 frame_rect.height + (border * 2) - 1);
+
+		/* the drop shadow */
+
+		cairo_move_to (cr,
+			       frame_rect.x - (border / 2) + 0.5,
+			       frame_rect.y + frame_rect.height + border + 0.5);
+		cairo_line_to (cr,
+			       frame_rect.x + frame_rect.width + border + 0.5,
+			       frame_rect.y + frame_rect.height + border + 0.5);
+		cairo_line_to (cr,
+			       frame_rect.x + frame_rect.width + border + 0.5,
+			       frame_rect.y - (border / 2) + 0.5);
+
+		cairo_move_to (cr,
+			       frame_rect.x - (border / 2) + 0.5,
+			       frame_rect.y + frame_rect.height + border + 1.5);
+		cairo_line_to (cr,
+			       frame_rect.x + frame_rect.width + border + 1.5,
+			       frame_rect.y + frame_rect.height + border + 1.5);
+		cairo_line_to (cr,
+			       frame_rect.x + frame_rect.width + border + 1.5,
+			       frame_rect.y - (border / 2) + 0.5);
+
 		cairo_stroke (cr);
-		*/
-
-	  	gdk_draw_rectangle (GDK_DRAWABLE (window), style->dark_gc[state], FALSE,
-  				    frame_rect.x - border,
-  				    frame_rect.y - border,
-  				    frame_rect.width + (border * 2) - 1,
-				    frame_rect.height + (border * 2) - 1);
-
-  		gdk_draw_line (GDK_DRAWABLE (window), style->dark_gc[state],
-  			       frame_rect.x - (border / 2),
-  			       frame_rect.y + frame_rect.height + border,
-  			       frame_rect.x + frame_rect.width + border,
-  			       frame_rect.y + frame_rect.height + border);
-  		gdk_draw_line (GDK_DRAWABLE (window), style->dark_gc[state],
-  			       frame_rect.x + frame_rect.width + border,
-  			       frame_rect.y + frame_rect.height + border,
-  			       frame_rect.x + frame_rect.width + border,
-  			       frame_rect.y - (border / 2));
-
-		gdk_draw_line (GDK_DRAWABLE (window), style->mid_gc[state],
-  			       frame_rect.x - (border / 2) + 1,
-  			       frame_rect.y + frame_rect.height + border + 1,
-  			       frame_rect.x + frame_rect.width + border + 1,
-  			       frame_rect.y + frame_rect.height + border + 1);
-  		gdk_draw_line (GDK_DRAWABLE (window), style->mid_gc[state],
-  			       frame_rect.x + frame_rect.width + border + 1,
-  			       frame_rect.y + frame_rect.height + border + 1,
-  			       frame_rect.x + frame_rect.width + border + 1,
-  			       frame_rect.y - (border / 2) + 1);
-
-  		/*
-  		gdk_draw_rectangle (GDK_DRAWABLE (window), style->light_gc[state], TRUE,
-  				    frame_rect.x - (border - 1),
-  				    frame_rect.y - (border - 1),
-  				    frame_rect.width + ((border - 1) * 2),
-  				    frame_rect.height + ((border - 1) * 2));
-  		gdk_draw_rectangle (GDK_DRAWABLE (window), style->mid_gc[state], FALSE,
-  				    image_rect.x - 1,
-  				    image_rect.y - 1,
-  				    image_rect.width + 1,
-  				    image_rect.height + 1);
-  		*/
 	}
 
   	if (! self->priv->checked || ((flags & (GTK_CELL_RENDERER_SELECTED | GTK_CELL_RENDERER_PRELIT)) != 0)) {
@@ -451,33 +427,12 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer      *cell,
 		pixbuf = colorized;
 	}
 
-  	gdk_draw_pixbuf (GDK_DRAWABLE (window),
-  			 NULL,
-  			 pixbuf,
-  			 0, 0,
-  			 image_rect.x,
-  			 image_rect.y,
-  			 image_rect.width,
-  			 image_rect.height,
-  			 GDK_RGB_DITHER_NORMAL,
-  			 0, 0);
-
-  	/*if (! self->priv->checked) {
-  		cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 0.5);
-		cairo_set_line_width (cr, 6.0);
-
-		cairo_move_to (cr, thumb_rect.x, thumb_rect.y);
-		cairo_line_to (cr, thumb_rect.x + thumb_rect.width, thumb_rect.y + thumb_rect.height);
-		cairo_stroke (cr);
-		cairo_move_to (cr, thumb_rect.x + thumb_rect.width, thumb_rect.y);
-		cairo_line_to (cr, thumb_rect.x, thumb_rect.y + thumb_rect.height);
-		cairo_stroke (cr);
-  	}*/
+  	gdk_cairo_set_source_pixbuf (cr, pixbuf, image_rect.x, image_rect.y);
+  	cairo_rectangle (cr, image_rect.x, image_rect.y, image_rect.width, image_rect.height);
+  	cairo_fill (cr);
 
+  	_g_object_unref (colorized);
   	cairo_destroy (cr);
-
-  	if (colorized != NULL)
-		g_object_unref (colorized);
 }
 
 
diff --git a/gthumb/gth-empty-list.c b/gthumb/gth-empty-list.c
index 064a02e..9686b43 100644
--- a/gthumb/gth-empty-list.c
+++ b/gthumb/gth-empty-list.c
@@ -238,8 +238,11 @@ static gboolean
 gth_empty_list_expose_event (GtkWidget      *widget,
 		             GdkEventExpose *event)
 {
-	GthEmptyList    *self = (GthEmptyList*) widget;
-	PangoRectangle   bounds;
+	GthEmptyList   *self = (GthEmptyList*) widget;
+	PangoRectangle  bounds;
+	GtkAllocation   allocation;
+	GtkStyle       *style;
+	cairo_t        *cr;
 	
 	if (event->window != self->priv->bin_window)
 		return FALSE;
@@ -251,24 +254,29 @@ gth_empty_list_expose_event (GtkWidget      *widget,
 	pango_layout_set_text (self->priv->layout, self->priv->text, strlen (self->priv->text));
 	pango_layout_get_pixel_extents (self->priv->layout, NULL, &bounds);
 
-	gdk_draw_layout (self->priv->bin_window,
-			 widget->style->text_gc[GTK_WIDGET_STATE (widget)],
-			 0,
-			 (widget->allocation.height - bounds.height) / 2,
-			 self->priv->layout);
+	gtk_widget_get_allocation (widget, &allocation);
+	style = gtk_widget_get_style (widget);
+
+	cr = gdk_cairo_create (self->priv->bin_window);
+	cairo_move_to (cr, 0, (allocation.height - bounds.height) / 2);
+	pango_cairo_layout_path (cr, self->priv->layout);
+	gdk_cairo_set_source_color (cr, &style->text[gtk_widget_get_state (widget)]);
+	cairo_fill (cr);
 
 	if (GTK_WIDGET_HAS_FOCUS (widget)) {
-		gtk_paint_focus (widget->style,
+		gtk_paint_focus (style,
 				 self->priv->bin_window,
-				 GTK_WIDGET_STATE (widget),
+				 gtk_widget_get_state (widget),
 				 &event->area,
 				 widget,
 				 NULL,
 				 1, 1,
-				 widget->allocation.width - 2, 
-				 widget->allocation.height - 2);
+				 allocation.width - 2,
+				 allocation.height - 2);
 	}
 
+	cairo_destroy (cr);
+
 	return FALSE;
 }
 
diff --git a/gthumb/gth-image-dragger.c b/gthumb/gth-image-dragger.c
index a6e294e..9088917 100644
--- a/gthumb/gth-image-dragger.c
+++ b/gthumb/gth-image-dragger.c
@@ -128,7 +128,8 @@ gth_image_dragger_unmap (GthImageViewerTool *base)
 
 static void
 gth_image_dragger_expose (GthImageViewerTool *self,
-			  GdkEventExpose     *event)
+			  GdkEventExpose     *event,
+		          cairo_t            *cr)
 {
 	GthImageDragger *dragger;
 	GthImageViewer  *viewer;
@@ -149,6 +150,7 @@ gth_image_dragger_expose (GthImageViewerTool *self,
 		interp_type = GDK_INTERP_NEAREST;
 
 	gth_image_viewer_paint_region (viewer,
+				       cr,
 				       gth_image_viewer_get_current_pixbuf (viewer),
 				       viewer->x_offset - viewer->image_area.x,
 				       viewer->y_offset - viewer->image_area.y,
diff --git a/gthumb/gth-image-navigator.c b/gthumb/gth-image-navigator.c
new file mode 100644
index 0000000..8005230
--- /dev/null
+++ b/gthumb/gth-image-navigator.c
@@ -0,0 +1,503 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2006-2010 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <math.h>
+#include <gdk/gdkkeysyms.h>
+#include "gth-image-navigator.h"
+#include "gth-image-viewer.h"
+#include "gtk-utils.h"
+#include "pixbuf-utils.h"
+#include "icons/nav_button.xpm"
+
+
+#define VISIBLE_AREA_BORDER 3.0
+#define POPUP_BORDER        4
+#define POPUP_BORDER_2      8
+#define POPUP_MAX_WIDTH     112
+#define POPUP_MAX_HEIGHT    112
+
+
+struct _GthImageNavigatorPrivate {
+	GthImageViewer *viewer;
+	GtkWidget      *viewer_vscr;
+	GtkWidget      *viewer_hscr;
+	GtkWidget      *navigator_event_area;
+	gboolean        scrollbars_visible;
+};
+
+
+static GtkHBoxClass *parent_class = NULL;
+
+
+static void
+gth_image_navigator_class_init (GthImageNavigatorClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (GthImageNavigatorPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+}
+
+
+static void
+gth_image_navigator_init (GthImageNavigator *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigatorPrivate);
+	self->priv->scrollbars_visible = TRUE;
+}
+
+
+GType
+gth_image_navigator_get_type (void)
+{
+	static GType type = 0;
+
+	if (! type) {
+		GTypeInfo type_info = {
+			sizeof (GthImageNavigatorClass),
+                        NULL,
+                        NULL,
+                        (GClassInitFunc) gth_image_navigator_class_init,
+                        NULL,
+                        NULL,
+                        sizeof (GthImageNavigator),
+                        0,
+                        (GInstanceInitFunc) gth_image_navigator_init
+                };
+
+                type = g_type_register_static (GTK_TYPE_HBOX,
+                                               "GthImageNavigator",
+                                               &type_info,
+                                               0);
+        }
+
+        return type;
+}
+
+
+/* -- NavigatorPopup -- */
+
+
+typedef struct {
+	GthImageViewer *viewer;
+	int             x_root, y_root;
+	GtkWidget      *popup_win;
+	GtkWidget      *preview;
+	GdkPixbuf      *pixbuf;
+	int             image_width, image_height;
+	int             window_max_width, window_max_height;
+	int             popup_x, popup_y, popup_width, popup_height;
+	GdkRectangle    visible_area;
+	double          zoom_factor;
+} NavigatorPopup;
+
+
+static void
+get_visible_area_origin_as_double (NavigatorPopup *nav_popup,
+				   int             mx,
+				   int             my,
+				   double         *x,
+				   double         *y)
+{
+	*x = MIN (mx - POPUP_BORDER, nav_popup->window_max_width);
+	*y = MIN (my - POPUP_BORDER, nav_popup->window_max_height);
+
+	if (*x - nav_popup->visible_area.width / 2.0 < 0.0)
+		*x = nav_popup->visible_area.width / 2.0;
+
+	if (*y - nav_popup->visible_area.height / 2.0 < 0.0)
+		*y = nav_popup->visible_area.height / 2.0;
+
+	if (*x + nav_popup->visible_area.width / 2.0 > nav_popup->popup_width - 0)
+		*x = nav_popup->popup_width - 0 - nav_popup->visible_area.width / 2.0;
+
+	if (*y + nav_popup->visible_area.height / 2.0 > nav_popup->popup_height - 0)
+		*y = nav_popup->popup_height - 0 - nav_popup->visible_area.height / 2.0;
+
+	*x = *x - nav_popup->visible_area.width / 2.0;
+	*y = *y - nav_popup->visible_area.height / 2.0;
+}
+
+
+static void
+update_popup_geometry (NavigatorPopup *nav_popup)
+{
+	int            zoomed_width;
+	int            zoomed_height;
+	GdkPixbuf     *image_pixbuf;
+	GtkAllocation  allocation;
+	int            scroll_offset_x;
+	int            scroll_offset_y;
+
+	zoomed_width = nav_popup->image_width * gth_image_viewer_get_zoom (nav_popup->viewer);
+	zoomed_height = nav_popup->image_height * gth_image_viewer_get_zoom (nav_popup->viewer);
+
+	nav_popup->window_max_width = MIN (zoomed_width, POPUP_MAX_WIDTH);
+	nav_popup->window_max_height = MIN (zoomed_width, POPUP_MAX_HEIGHT);
+
+	nav_popup->zoom_factor = MIN ((double) (nav_popup->window_max_width) / zoomed_width,
+				    (double) (nav_popup->window_max_height) / zoomed_height);
+
+	/* popup window size */
+
+	nav_popup->popup_width  = MAX ((int) floor (nav_popup->zoom_factor * zoomed_width + 0.5), 1);
+	nav_popup->popup_height = MAX ((int) floor (nav_popup->zoom_factor * zoomed_height + 0.5), 1);
+
+	image_pixbuf = gth_image_viewer_get_current_pixbuf (nav_popup->viewer);
+	g_return_if_fail (image_pixbuf != NULL);
+
+	if (nav_popup->pixbuf != NULL)
+		g_object_unref (nav_popup->pixbuf);
+	nav_popup->pixbuf = _gdk_pixbuf_scale_simple_safe (image_pixbuf,
+							 nav_popup->popup_width,
+							 nav_popup->popup_height,
+							 GDK_INTERP_TILES);
+
+	/* visible area size */
+
+	gtk_widget_get_allocation (GTK_WIDGET (nav_popup->viewer), &allocation);
+	nav_popup->visible_area.width = (allocation.width - GTH_IMAGE_VIEWER_FRAME_BORDER2) * nav_popup->zoom_factor;
+	nav_popup->visible_area.width = MAX (nav_popup->visible_area.width, POPUP_BORDER);
+	nav_popup->visible_area.width = MIN (nav_popup->visible_area.width, nav_popup->popup_width);
+
+	nav_popup->visible_area.height = (allocation.height - GTH_IMAGE_VIEWER_FRAME_BORDER2) * nav_popup->zoom_factor;
+	nav_popup->visible_area.height = MAX (nav_popup->visible_area.height, POPUP_BORDER);
+	nav_popup->visible_area.height = MIN (nav_popup->visible_area.height, nav_popup->popup_height);
+
+	/* visible area position */
+
+	gth_image_viewer_get_scroll_offset (nav_popup->viewer, &scroll_offset_x, &scroll_offset_y);
+	nav_popup->visible_area.x = scroll_offset_x * nav_popup->zoom_factor;
+	nav_popup->visible_area.y = scroll_offset_y * nav_popup->zoom_factor;
+
+	/* popup window position */
+
+	nav_popup->popup_x = MIN ((int) nav_popup->x_root - nav_popup->visible_area.x - POPUP_BORDER - nav_popup->visible_area.width / 2,
+				gdk_screen_width () - nav_popup->popup_width - POPUP_BORDER_2);
+	nav_popup->popup_y = MIN ((int) nav_popup->y_root - nav_popup->visible_area.y - POPUP_BORDER - nav_popup->visible_area.height / 2,
+				gdk_screen_height () - nav_popup->popup_height - POPUP_BORDER_2);
+}
+
+
+static int
+popup_window_event_cb (GtkWidget *widget,
+		       GdkEvent  *event,
+		       gpointer   data)
+{
+	NavigatorPopup  *nav_popup = data;
+	GthImageViewer  *viewer = nav_popup->viewer;
+	GdkModifierType  mask;
+	int              mx, my;
+	double           x, y;
+
+	switch (event->type) {
+	case GDK_BUTTON_RELEASE:
+		/* Release keyboard focus. */
+		gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+		gtk_grab_remove (nav_popup->popup_win);
+
+		gtk_widget_destroy (nav_popup->popup_win);
+		g_object_unref (nav_popup->pixbuf);
+		g_free (nav_popup);
+
+		return TRUE;
+
+	case GDK_MOTION_NOTIFY:
+		gdk_window_get_pointer (widget->window, &mx, &my, &mask);
+
+		get_visible_area_origin_as_double (nav_popup, mx, my, &x, &y);
+		nav_popup->visible_area.x = (int) x;
+		nav_popup->visible_area.y = (int) y;
+		gtk_widget_queue_draw (widget);
+
+		mx = (int) (x / nav_popup->zoom_factor);
+		my = (int) (y / nav_popup->zoom_factor);
+		gth_image_viewer_scroll_to (viewer, mx, my);
+
+		return TRUE;
+
+	case GDK_KEY_PRESS:
+		switch (event->key.keyval) {
+		case GDK_plus:
+		case GDK_minus:
+		case GDK_1:
+			switch (event->key.keyval) {
+			case GDK_plus:
+				gth_image_viewer_zoom_in (viewer);
+				break;
+			case GDK_minus:
+				gth_image_viewer_zoom_out (viewer);
+				break;
+			case GDK_1:
+				gth_image_viewer_set_zoom (viewer, 1.0);
+				break;
+			}
+
+			update_popup_geometry (nav_popup);
+			nav_popup->visible_area.x = MAX (nav_popup->visible_area.x, 0);
+			nav_popup->visible_area.x = MIN (nav_popup->visible_area.x, nav_popup->popup_width - nav_popup->visible_area.width);
+			nav_popup->visible_area.y = MAX (nav_popup->visible_area.y, 0);
+			nav_popup->visible_area.y = MIN (nav_popup->visible_area.y, nav_popup->popup_height - nav_popup->visible_area.height);
+			gtk_widget_queue_draw (widget);
+			break;
+
+		default:
+			break;
+		}
+		return TRUE;
+
+	default:
+		break;
+	}
+
+	return FALSE;
+}
+
+
+static void
+nav_window_grab_pointer (NavigatorPopup *nav_popup)
+{
+	GdkCursor *cursor;
+
+	gtk_grab_add (nav_popup->popup_win);
+
+	cursor = gdk_cursor_new (GDK_FLEUR);
+	gdk_pointer_grab (nav_popup->popup_win->window,
+			  TRUE,
+			  (GDK_BUTTON_RELEASE_MASK
+			   | GDK_POINTER_MOTION_HINT_MASK
+			   | GDK_BUTTON_MOTION_MASK
+			   | GDK_EXTENSION_EVENTS_ALL),
+			  nav_popup->preview->window,
+			  cursor,
+			  0);
+	gdk_cursor_unref (cursor);
+
+	/* Capture keyboard events. */
+
+	gdk_keyboard_grab (nav_popup->popup_win->window, TRUE, GDK_CURRENT_TIME);
+        gtk_widget_grab_focus (nav_popup->popup_win);
+}
+
+
+static gboolean
+navigator_popup_expose_event_cb (GtkWidget      *widget,
+				 GdkEventExpose *event,
+				 NavigatorPopup *nav_popup)
+{
+	cairo_t *cr;
+
+	if (nav_popup->pixbuf == NULL)
+		return FALSE;
+
+	cr = gdk_cairo_create (gtk_widget_get_window (widget));
+	cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+	gdk_cairo_set_source_pixbuf (cr, nav_popup->pixbuf, 0, 0);
+  	cairo_rectangle (cr, 0, 0, nav_popup->popup_width, nav_popup->popup_height);
+  	cairo_fill (cr);
+
+	if ((nav_popup->visible_area.width < nav_popup->popup_width)
+	    || (nav_popup->visible_area.height < nav_popup->popup_height))
+	{
+		cairo_save (cr);
+		cairo_set_line_width (cr, VISIBLE_AREA_BORDER);
+		cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
+		cairo_rectangle (cr,
+				 nav_popup->visible_area.x + 1.0,
+				 nav_popup->visible_area.y + 1.0,
+				 nav_popup->visible_area.width - VISIBLE_AREA_BORDER,
+				 nav_popup->visible_area.height - VISIBLE_AREA_BORDER);
+		cairo_stroke (cr);
+		cairo_restore (cr);
+	}
+
+	cairo_destroy (cr);
+
+	return TRUE;
+}
+
+
+static void
+navigator_event_area_button_press_event_cb (GtkWidget      *widget,
+					    GdkEventButton *event,
+					    GthImageViewer *viewer)
+{
+	NavigatorPopup *nav_popup;
+	GtkWidget      *out_frame;
+	GtkWidget      *in_frame;
+
+	if (gth_image_viewer_is_void (viewer))
+		return;
+
+	nav_popup = g_new0 (NavigatorPopup, 1);
+	nav_popup->viewer = viewer;
+	nav_popup->popup_win = gtk_window_new (GTK_WINDOW_POPUP);
+	gtk_window_set_wmclass (GTK_WINDOW (nav_popup->popup_win), "", "gthumb_navigator");
+
+	out_frame = gtk_frame_new (NULL);
+	gtk_frame_set_shadow_type (GTK_FRAME (out_frame), GTK_SHADOW_OUT);
+	gtk_container_add (GTK_CONTAINER (nav_popup->popup_win), out_frame);
+
+	in_frame = gtk_frame_new (NULL);
+	gtk_frame_set_shadow_type (GTK_FRAME (in_frame), GTK_SHADOW_IN);
+	gtk_container_add (GTK_CONTAINER (out_frame), in_frame);
+
+	nav_popup->preview = gtk_drawing_area_new ();
+	gtk_container_add (GTK_CONTAINER (in_frame), nav_popup->preview);
+	g_signal_connect (G_OBJECT (nav_popup->preview),
+			  "expose_event",
+			  G_CALLBACK (navigator_popup_expose_event_cb),
+			  nav_popup);
+
+	nav_popup->x_root = event->x_root;
+	nav_popup->y_root = event->y_root;
+	nav_popup->image_width = gth_image_viewer_get_image_width (viewer);
+	nav_popup->image_height = gth_image_viewer_get_image_height (viewer);
+	update_popup_geometry (nav_popup);
+
+	g_signal_connect (G_OBJECT (nav_popup->popup_win),
+			  "event",
+			  G_CALLBACK (popup_window_event_cb),
+			  nav_popup);
+
+	gtk_window_move (GTK_WINDOW (nav_popup->popup_win),
+			 nav_popup->popup_x,
+			 nav_popup->popup_y);
+
+  	gtk_window_set_default_size (GTK_WINDOW (nav_popup->popup_win),
+				     nav_popup->popup_width + POPUP_BORDER_2,
+				     nav_popup->popup_height + POPUP_BORDER_2);
+
+	gtk_widget_show_all (nav_popup->popup_win);
+
+	nav_window_grab_pointer (nav_popup);
+}
+
+
+static gboolean
+image_viewer_size_changed_cb (GtkWidget         *widget,
+			      GthImageNavigator *self)
+{
+	GtkAdjustment *vadj;
+	GtkAdjustment *hadj;
+	gboolean       hide_vscr;
+	gboolean       hide_hscr;
+
+	gth_image_viewer_get_adjustments (self->priv->viewer, &hadj, &vadj);
+
+	g_return_val_if_fail (hadj != NULL, FALSE);
+	g_return_val_if_fail (vadj != NULL, FALSE);
+
+	hide_vscr = (vadj->page_size == 0) || (vadj->upper <= vadj->page_size);
+	hide_hscr = (hadj->page_size == 0) || (hadj->upper <= hadj->page_size);
+
+	if (! self->priv->scrollbars_visible || (hide_vscr && hide_hscr)) {
+		gtk_widget_hide (self->priv->viewer_vscr);
+		gtk_widget_hide (self->priv->viewer_hscr);
+		gtk_widget_hide (self->priv->navigator_event_area);
+	}
+	else {
+		gtk_widget_show (self->priv->viewer_vscr);
+		gtk_widget_show (self->priv->viewer_hscr);
+		gtk_widget_show (self->priv->navigator_event_area);
+	}
+
+	return TRUE;
+}
+
+
+static void
+gth_image_navigator_construct (GthImageNavigator *self,
+			       GthImageViewer    *viewer)
+{
+	GtkAdjustment *vadj = NULL;
+	GtkAdjustment *hadj = NULL;
+	GtkWidget     *hbox;
+	GtkWidget     *table;
+
+	self->priv->viewer = viewer;
+	g_signal_connect (G_OBJECT (self->priv->viewer),
+			  "size_changed",
+			  G_CALLBACK (image_viewer_size_changed_cb),
+			  self);
+
+	gth_image_viewer_get_adjustments (self->priv->viewer, &hadj, &vadj);
+	self->priv->viewer_hscr = gtk_hscrollbar_new (hadj);
+	self->priv->viewer_vscr = gtk_vscrollbar_new (vadj);
+
+	self->priv->navigator_event_area = gtk_event_box_new ();
+	gtk_container_add (GTK_CONTAINER (self->priv->navigator_event_area), _gtk_image_new_from_xpm_data (nav_button_xpm));
+
+	g_signal_connect (G_OBJECT (self->priv->navigator_event_area),
+			  "button_press_event",
+			  G_CALLBACK (navigator_event_area_button_press_event_cb),
+			  self->priv->viewer);
+
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_container_add (GTK_CONTAINER (hbox), GTK_WIDGET (self->priv->viewer));
+
+	table = gtk_table_new (2, 2, FALSE);
+	gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, 0, 1,
+			  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+			  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+	gtk_table_attach (GTK_TABLE (table), self->priv->viewer_vscr, 1, 2, 0, 1,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+	gtk_table_attach (GTK_TABLE (table), self->priv->viewer_hscr, 0, 1, 1, 2,
+			  (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+	gtk_table_attach (GTK_TABLE (table), self->priv->navigator_event_area, 1, 2, 1, 2,
+			  (GtkAttachOptions) (GTK_FILL),
+			  (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+	gtk_widget_show_all (hbox);
+	gtk_widget_show (table);
+
+	gtk_container_add (GTK_CONTAINER (self), table);
+}
+
+
+GtkWidget *
+gth_image_navigator_new (GthImageViewer *viewer)
+{
+	GthImageNavigator *self;
+
+	g_return_val_if_fail (viewer != NULL, NULL);
+
+	self = g_object_new (GTH_TYPE_IMAGE_NAVIGATOR, NULL);
+	gth_image_navigator_construct (self, viewer);
+
+	return (GtkWidget*) self;
+}
+
+
+void
+gth_image_navigator_set_scrollbars_visible (GthImageNavigator *self,
+				            gboolean           visible)
+{
+	self->priv->scrollbars_visible = visible;
+	image_viewer_size_changed_cb (NULL, self);
+}
diff --git a/gthumb/gth-image-navigator.h b/gthumb/gth-image-navigator.h
new file mode 100644
index 0000000..70a79fd
--- /dev/null
+++ b/gthumb/gth-image-navigator.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2006-2009 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_IMAGE_NAVIGATOR_H
+#define GTH_IMAGE_NAVIGATOR_H
+
+#include <gtk/gtk.h>
+#include "gth-image-viewer.h"
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_IMAGE_NAVIGATOR            (gth_image_navigator_get_type ())
+#define GTH_IMAGE_NAVIGATOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigator))
+#define GTH_IMAGE_NAVIGATOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigatorClass))
+#define GTH_IS_IMAGE_NAVIGATOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_IMAGE_NAVIGATOR))
+#define GTH_IS_IMAGE_NAVIGATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_IMAGE_NAVIGATOR))
+#define GTH_IMAGE_NAVIGATOR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_IMAGE_NAVIGATOR, GthImageNavigatorClass))
+
+typedef struct _GthImageNavigator        GthImageNavigator;
+typedef struct _GthImageNavigatorClass   GthImageNavigatorClass;
+typedef struct _GthImageNavigatorPrivate GthImageNavigatorPrivate;
+
+struct _GthImageNavigator {
+	GtkHBox __parent;
+	GthImageNavigatorPrivate *priv;
+};
+
+struct _GthImageNavigatorClass {
+	GtkHBoxClass __parent;
+};
+
+GType        gth_image_navigator_get_type               (void);
+GtkWidget *  gth_image_navigator_new                    (GthImageViewer    *viewer);
+void         gth_image_navigator_set_scrollbars_visible (GthImageNavigator *window,
+						         gboolean           visible);
+
+G_END_DECLS
+
+#endif /* GTH_IMAGE_NAVIGATOR_H */
diff --git a/gthumb/gth-image-selector.c b/gthumb/gth-image-selector.c
index 17ab49e..91bc706 100644
--- a/gthumb/gth-image-selector.c
+++ b/gthumb/gth-image-selector.c
@@ -35,6 +35,7 @@
 #define STEP_INCREMENT 20.0  /* scroll increment. */
 #define SCROLL_TIMEOUT 30    /* autoscroll timeout in milliseconds */
 #define GOLDEN_RATIO   1.6180339887
+#define GOLDER_RATIO_FACTOR (GOLDEN_RATIO / (1.0 + 2.0 * GOLDEN_RATIO))
 
 
 typedef struct {
@@ -206,7 +207,6 @@ struct _GthImageSelectorPrivate {
 	gboolean         active;
 
 	GdkRectangle     drag_start_selection_area;
-	GdkGC           *selection_gc;
 	GdkRectangle     selection_area;
 	GdkRectangle     selection;
 
@@ -512,15 +512,6 @@ gth_image_selector_realize (GthImageViewerTool *base)
 
 	widget = (GtkWidget *) self->priv->viewer;
 
-	self->priv->selection_gc = gdk_gc_new (widget->window);
-	gdk_gc_copy (self->priv->selection_gc, widget->style->white_gc);
-	gdk_gc_set_line_attributes (self->priv->selection_gc,
-				    1,
-				    GDK_LINE_SOLID,
-				    GDK_CAP_BUTT,
-				    GDK_JOIN_MITER);
-	gdk_gc_set_function (self->priv->selection_gc, GDK_INVERT);
-
 	if (self->priv->type == GTH_SELECTOR_TYPE_REGION)
 		self->priv->default_cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_CROSSHAIR /*GDK_LEFT_PTR*/);
 	else if (self->priv->type == GTH_SELECTOR_TYPE_POINT)
@@ -552,11 +543,6 @@ gth_image_selector_unrealize (GthImageViewerTool *base)
 		self->priv->default_cursor = NULL;
 	}
 
-	if (self->priv->selection_gc != NULL) {
-		g_object_unref (self->priv->selection_gc);
-		self->priv->selection_gc = NULL;
-	}
-
 	free_event_area_list (self);
 }
 
@@ -588,9 +574,11 @@ gth_image_selector_unmap (GthImageViewerTool *base)
 
 static void
 paint_background (GthImageSelector *self,
-		  GdkEventExpose   *event)
+		  GdkEventExpose   *event,
+		  cairo_t          *cr)
 {
 	gth_image_viewer_paint_region (self->priv->viewer,
+				       cr,
 				       self->priv->background,
 				       self->priv->viewer->x_offset - self->priv->viewer->image_area.x,
 				       self->priv->viewer->y_offset - self->priv->viewer->image_area.y,
@@ -602,19 +590,17 @@ paint_background (GthImageSelector *self,
 
 static void
 paint_selection (GthImageSelector *self,
-		 GdkEventExpose   *event)
+		 GdkEventExpose   *event,
+		 cairo_t          *cr)
 {
 	GdkRectangle selection_area;
-	GdkRectangle paint_area;
 
 	selection_area = self->priv->selection_area;
 	selection_area.x += self->priv->viewer->image_area.x - self->priv->viewer->x_offset;
 	selection_area.y += self->priv->viewer->image_area.y - self->priv->viewer->y_offset;
 
-	if (! gdk_rectangle_intersect (&selection_area, &event->area, &paint_area))
-		return;
-
 	gth_image_viewer_paint_region (self->priv->viewer,
+				       cr,
 				       self->priv->pixbuf,
 				       self->priv->viewer->x_offset - self->priv->viewer->image_area.x,
 				       self->priv->viewer->y_offset - self->priv->viewer->image_area.y,
@@ -622,26 +608,37 @@ paint_selection (GthImageSelector *self,
 				       event->region,
 				       GDK_INTERP_TILES);
 
-	gdk_gc_set_clip_region (self->priv->selection_gc, event->region);
+	cairo_save (cr);
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 2)
+	cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
+	cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+#else
+	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+#endif
+
+
+	gdk_cairo_region (cr, event->region);
+	gdk_cairo_rectangle (cr, &selection_area);
+	cairo_clip (cr);
 
 	if (self->priv->grid_type != GTH_GRID_NONE) {
 		int grid_x0, grid_x1, grid_x2, grid_x3;
 	        int grid_y0, grid_y1, grid_y2, grid_y3;
 		int x_delta, y_delta;
 
-		grid_x0 = paint_area.x;
-		grid_x3 = paint_area.x + paint_area.width;
+		grid_x0 = selection_area.x;
+		grid_x3 = selection_area.x + selection_area.width;
 
-                grid_y0 = paint_area.y;
-                grid_y3 = paint_area.y + paint_area.height;
+                grid_y0 = selection_area.y;
+                grid_y3 = selection_area.y + selection_area.height;
 
 		if (self->priv->grid_type == GTH_GRID_THIRDS) {
-			x_delta = paint_area.width / 3;
-			y_delta = paint_area.height /3;
+			x_delta = selection_area.width / 3;
+			y_delta = selection_area.height /3;
 		}
 		else if (self->priv->grid_type == GTH_GRID_GOLDEN) {
-			x_delta = paint_area.width * (GOLDEN_RATIO / (1.0 + 2.0 * GOLDEN_RATIO));
-			y_delta = paint_area.height * (GOLDEN_RATIO / (1.0 + 2.0 * GOLDEN_RATIO));
+			x_delta = selection_area.width * GOLDER_RATIO_FACTOR;
+			y_delta = selection_area.height * GOLDER_RATIO_FACTOR;
 		}
 
 		grid_x1 = grid_x0 + x_delta;
@@ -649,39 +646,37 @@ paint_selection (GthImageSelector *self,
                 grid_y1 = grid_y0 + y_delta;
                 grid_y2 = grid_y3 - y_delta;
 
-		gdk_draw_line (GTK_WIDGET (self->priv->viewer)->window,
-			       self->priv->selection_gc,
-			       grid_x1, grid_y0,
-			       grid_x1, grid_y3);
-	        gdk_draw_line (GTK_WIDGET (self->priv->viewer)->window,
-       		               self->priv->selection_gc,
- 			       grid_x2, grid_y0,
-			       grid_x2, grid_y3);
-        	gdk_draw_line (GTK_WIDGET (self->priv->viewer)->window,
-       	        	       self->priv->selection_gc,
-                               grid_x0, grid_y1,
-                               grid_x3, grid_y1);
-	        gdk_draw_line (GTK_WIDGET (self->priv->viewer)->window,
-       		               self->priv->selection_gc,
-                               grid_x0, grid_y2,
-                               grid_x3, grid_y2);
+		cairo_move_to (cr, grid_x1 + 0.5, grid_y0 + 0.5);
+		cairo_line_to (cr, grid_x1 + 0.5, grid_y3 + 0.5);
+
+		cairo_move_to (cr, grid_x2 + 0.5, grid_y0 + 0.5);
+		cairo_line_to (cr, grid_x2 + 0.5, grid_y3 + 0.5);
+
+		cairo_move_to (cr, grid_x0 + 0.5, grid_y1 + 0.5);
+		cairo_line_to (cr, grid_x3 + 0.5, grid_y1 + 0.5);
+
+		cairo_move_to (cr, grid_x0 + 0.5, grid_y2 + 0.5);
+		cairo_line_to (cr, grid_x3 + 0.5, grid_y2 + 0.5);
 	}
 
-	gdk_draw_rectangle (GTK_WIDGET (self->priv->viewer)->window,
-			    self->priv->selection_gc,
-			    FALSE,
-			    selection_area.x,
-			    selection_area.y,
-			    selection_area.width,
-			    selection_area.height);
+	cairo_rectangle (cr,
+			 selection_area.x + 0.5,
+			 selection_area.y + 0.5,
+			 selection_area.width,
+			 selection_area.height);
+	cairo_stroke (cr);
+
+	cairo_restore (cr);
 }
 
 
 static void
 paint_image (GthImageSelector *self,
-	     GdkEventExpose   *event)
+	     GdkEventExpose   *event,
+	     cairo_t          *cr)
 {
 	gth_image_viewer_paint_region (self->priv->viewer,
+				       cr,
 				       self->priv->pixbuf,
 				       self->priv->viewer->x_offset - self->priv->viewer->image_area.x,
 				       self->priv->viewer->y_offset - self->priv->viewer->image_area.y,
@@ -693,7 +688,8 @@ paint_image (GthImageSelector *self,
 
 static void
 gth_image_selector_expose (GthImageViewerTool *base,
-			   GdkEventExpose     *event)
+			   GdkEventExpose     *event,
+			   cairo_t            *cr)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 
@@ -701,11 +697,11 @@ gth_image_selector_expose (GthImageViewerTool *base,
 		return;
 
 	if (self->priv->mask_visible) {
-		paint_background (self, event);
-		paint_selection (self, event);
+		paint_background (self, event, cr);
+		paint_selection (self, event, cr);
 	}
 	else
-		paint_image (self, event);
+		paint_image (self, event, cr);
 }
 
 
diff --git a/gthumb/gth-image-viewer-tool.c b/gthumb/gth-image-viewer-tool.c
index be6c7f1..e41e437 100644
--- a/gthumb/gth-image-viewer-tool.c
+++ b/gthumb/gth-image-viewer-tool.c
@@ -88,9 +88,10 @@ gth_image_viewer_tool_size_allocate (GthImageViewerTool *self,
 
 void
 gth_image_viewer_tool_expose (GthImageViewerTool *self,
-			      GdkEventExpose     *event)
+			      GdkEventExpose     *event,
+			      cairo_t            *cr)
 {
-	GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->expose (self, event);
+	GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->expose (self, event, cr);
 }
 
 
diff --git a/gthumb/gth-image-viewer-tool.h b/gthumb/gth-image-viewer-tool.h
index c69cfcf..8a3374d 100644
--- a/gthumb/gth-image-viewer-tool.h
+++ b/gthumb/gth-image-viewer-tool.h
@@ -45,7 +45,8 @@ struct _GthImageViewerToolIface {
 	void      (*size_allocate)  (GthImageViewerTool   *self,
 				     GtkAllocation        *allocation);
 	void      (*expose)         (GthImageViewerTool   *self,
-				     GdkEventExpose       *event);
+				     GdkEventExpose       *event,
+				     cairo_t              *cr);
 	gboolean  (*button_press)   (GthImageViewerTool   *self,
 				     GdkEventButton       *event);
 	gboolean  (*button_release) (GthImageViewerTool   *self,
@@ -64,7 +65,8 @@ void       gth_image_viewer_tool_unrealize        (GthImageViewerTool *self);
 void       gth_image_viewer_tool_size_allocate    (GthImageViewerTool *self,
 						   GtkAllocation      *allocation);
 void       gth_image_viewer_tool_expose           (GthImageViewerTool *self,
-						   GdkEventExpose     *event);
+						   GdkEventExpose     *event,
+						   cairo_t            *cr);
 gboolean   gth_image_viewer_tool_button_press     (GthImageViewerTool *self,
 						   GdkEventButton     *event);
 gboolean   gth_image_viewer_tool_button_release   (GthImageViewerTool *self,
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index 553d548..f9aa6fe 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -717,13 +717,24 @@ gth_image_viewer_expose (GtkWidget      *widget,
 			 GdkEventExpose *event)
 {
 	GthImageViewer *viewer;
+	cairo_t        *cr;
+	GtkStyle       *style;
 	int             gdk_width;
 	int             gdk_height;
 
 	viewer = GTH_IMAGE_VIEWER (widget);
 
+	cr = gdk_cairo_create (gtk_widget_get_window (widget));
+
+	cairo_set_line_width (cr, 0.5);
+	cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+	gdk_cairo_region (cr, event->region);
+	cairo_clip (cr);
+
 	/* Draw the background. */
 
+	style = gtk_widget_get_style (widget);
 	gdk_width = widget->allocation.width - viewer->priv->frame_border2;
 	gdk_height = widget->allocation.height - viewer->priv->frame_border2;
 
@@ -732,74 +743,62 @@ gth_image_viewer_expose (GtkWidget      *widget,
 	    || (viewer->image_area.width < gdk_width)
 	    || (viewer->image_area.height < gdk_height))
 	{
-		int    rx, ry, rw, rh;
-		GdkGC *gc;
+		int rx, ry, rw, rh;
 
 		if (viewer->priv->black_bg)
-			gc = widget->style->black_gc;
+			cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
 		else
-			gc = widget->style->bg_gc[GTK_STATE_NORMAL];
+			gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
 
 		if (gth_image_viewer_get_current_pixbuf (viewer) == NULL) {
-			gdk_draw_rectangle (widget->window,
-					    gc,
-					    TRUE,
-					    0, 0,
-					    widget->allocation.width,
-					    widget->allocation.height);
+			cairo_rectangle (cr,
+					 0 + 0.5,
+					 0 + 0.5,
+					 widget->allocation.width + 0.5,
+					 widget->allocation.height + 0.5);
 		}
 		else {
 			/* If an image is present draw in four phases to avoid
 			 * flickering. */
 
 			/* Top rectangle. */
+
 			rx = 0;
 			ry = 0;
 			rw = widget->allocation.width;
 			rh = viewer->image_area.y;
 			if ((rw > 0) && (rh > 0))
-				gdk_draw_rectangle (widget->window,
-						    gc,
-						    TRUE,
-						    rx, ry,
-						    rw, rh);
+				cairo_rectangle (cr, rx + 0.5, ry + 0.5, rw + 0.5, rh + 0.5);
 
 			/* Bottom rectangle. */
+
 			rx = 0;
 			ry = viewer->image_area.y + viewer->image_area.height;
 			rw = widget->allocation.width;
 			rh = widget->allocation.height - viewer->image_area.y - viewer->image_area.height;
 			if ((rw > 0) && (rh > 0))
-				gdk_draw_rectangle (widget->window,
-						    gc,
-						    TRUE,
-						    rx, ry,
-						    rw, rh);
+				cairo_rectangle (cr, rx + 0.5, ry + 0.5, rw + 0.5, rh + 0.5);
 
 			/* Left rectangle. */
+
 			rx = 0;
 			ry = viewer->image_area.y - 1;
 			rw = viewer->image_area.x;
 			rh = viewer->image_area.height + 2;
 			if ((rw > 0) && (rh > 0))
-				gdk_draw_rectangle (widget->window,
-						    gc,
-						    TRUE,
-						    rx, ry,
-						    rw, rh);
+				cairo_rectangle (cr, rx + 0.5, ry + 0.5, rw + 0.5, rh + 0.5);
 
 			/* Right rectangle. */
+
 			rx = viewer->image_area.x + viewer->image_area.width;
 			ry = viewer->image_area.y - 1;
 			rw = widget->allocation.width - viewer->image_area.x - viewer->image_area.width;
 			rh = viewer->image_area.height + 2;
 			if ((rw > 0) && (rh > 0))
-				gdk_draw_rectangle (widget->window,
-						    gc,
-						    TRUE,
-						    rx, ry,
-						    rw, rh);
+				cairo_rectangle (cr, rx + 0.5, ry + 0.5, rw + 0.5, rh + 0.5);
 		}
+
+		cairo_fill (cr);
 	}
 
 	/* Draw the frame. */
@@ -807,58 +806,43 @@ gth_image_viewer_expose (GtkWidget      *widget,
 	if ((viewer->priv->frame_border > 0)
 	    && (gth_image_viewer_get_current_pixbuf (viewer) != NULL))
 	{
-		int    x1, y1, x2, y2;
-		GdkGC *gc;
 
-		if (viewer->priv->black_bg)
-			gc = widget->style->black_gc;
-		else
-			gc = widget->style->light_gc[GTK_STATE_NORMAL];
-			/*gc = widget->style->dark_gc[GTK_STATE_NORMAL];*/
-
-		x1 = viewer->image_area.x + viewer->image_area.width;
-		y1 = viewer->image_area.y - 1;
-		x2 = viewer->image_area.x + viewer->image_area.width;
-		y2 = viewer->image_area.y + viewer->image_area.height;
-		gdk_draw_line (widget->window,
-			       gc,
-			       x1, y1,
-			       x2, y2);
-
-		x1 = viewer->image_area.x - 1;
-		y1 = viewer->image_area.y + viewer->image_area.height;
-		x2 = viewer->image_area.x + viewer->image_area.width;
-		y2 = viewer->image_area.y + viewer->image_area.height;
-		gdk_draw_line (widget->window,
-			       gc,
-			       x1, y1,
-			       x2, y2);
+		/* bottom and right side */
 
 		if (viewer->priv->black_bg)
-			gc = widget->style->black_gc;
+			cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
 		else
-			gc = widget->style->dark_gc[GTK_STATE_NORMAL];
-
-		x1 = viewer->image_area.x - 1;
-		y1 = viewer->image_area.y - 1;
-		x2 = viewer->image_area.x - 1;
-		y2 = viewer->image_area.y + viewer->image_area.height;
-		gdk_draw_line (widget->window,
-			       gc,
-			       x1, y1,
-			       x2, y2);
-
-		x1 = viewer->image_area.x - 1;
-		y1 = viewer->image_area.y - 1;
-		x2 = viewer->image_area.x + viewer->image_area.width;
-		y2 = viewer->image_area.y - 1;
-		gdk_draw_line (widget->window,
-			       gc,
-			       x1, y1,
-			       x2, y2);
+			gdk_cairo_set_source_color (cr, &style->light[GTK_STATE_NORMAL]);
+
+		cairo_move_to (cr,
+			       viewer->image_area.x + viewer->image_area.width + 0.5,
+			       viewer->image_area.y - 1 + 0.5);
+		cairo_line_to (cr,
+			       viewer->image_area.x + viewer->image_area.width + 0.5,
+			       viewer->image_area.y + viewer->image_area.height + 0.5);
+		cairo_line_to (cr,
+			       viewer->image_area.x - 1 + 0.5,
+			       viewer->image_area.y + viewer->image_area.height + 0.5);
+		cairo_stroke (cr);
+
+		/* top and left side */
+
+		if (! viewer->priv->black_bg)
+			gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
+
+		cairo_move_to (cr,
+			       viewer->image_area.x - 1 + 0.5,
+			       viewer->image_area.y + viewer->image_area.height + 0.5);
+		cairo_line_to (cr,
+			       viewer->image_area.x - 1 + 0.5,
+			       viewer->image_area.y - 1 + 0.5);
+		cairo_line_to (cr,
+			       viewer->image_area.x + viewer->image_area.width + 0.5,
+			       viewer->image_area.y - 1 + 0.5);
+		cairo_stroke (cr);
 	}
 
-	gth_image_viewer_tool_expose (viewer->priv->tool, event);
+	gth_image_viewer_tool_expose (viewer->priv->tool, event, cr);
 
 	/* Draw the focus. */
 
@@ -882,6 +866,8 @@ gth_image_viewer_expose (GtkWidget      *widget,
 
 	queue_frame_change (viewer);
 
+	cairo_destroy (cr);
+
 	return FALSE;
 }
 
@@ -1028,9 +1014,9 @@ scroll_to (GthImageViewer *viewer,
 	}
 
 	if ((delta_x != 0) || (delta_y != 0)) {
-		GdkGC *gc = GTK_WIDGET (viewer)->style->black_gc;
-		int    src_x, dest_x;
-		int    src_y, dest_y;
+		int      src_x, dest_x;
+		int      src_y, dest_y;
+		cairo_t *cr;
 
 		if (delta_x < 0) {
 			src_x = 0;
@@ -1050,23 +1036,21 @@ scroll_to (GthImageViewer *viewer,
 			dest_y = 0;
 		}
 
-		gc = gdk_gc_new (drawable);
-		gdk_gc_set_exposures (gc, TRUE);
-
 		dest_x += viewer->priv->frame_border;
 		dest_y += viewer->priv->frame_border;
 		src_x += viewer->priv->frame_border;
 		src_y += viewer->priv->frame_border;
 
-		gdk_draw_drawable (drawable,
-				   gc,
-				   drawable,
-				   src_x, src_y,
-				   dest_x, dest_y,
-				   gdk_width - abs (delta_x),
-				   gdk_height - abs (delta_y));
+		cr = gdk_cairo_create (drawable);
+		gdk_cairo_set_source_pixmap (cr, drawable, dest_x - src_x, dest_y - src_y);
+		cairo_rectangle (cr,
+				 dest_x,
+				 dest_y,
+				 gdk_width - abs (delta_x),
+				 gdk_height - abs (delta_y));
+		cairo_fill (cr);
 
-		g_object_unref (gc);
+		cairo_destroy (cr);
 	}
 
 	viewer->x_offset = *x_offset;
@@ -1712,6 +1696,7 @@ gth_image_viewer_instance_init (GthImageViewer *viewer)
 	GTK_WIDGET_SET_FLAGS (viewer, GTK_CAN_FOCUS);
 
 	viewer->priv = GTH_IMAGE_VIEWER_GET_PRIVATE (viewer);
+	gtk_widget_set_double_buffered (GTK_WIDGET (viewer), TRUE);
 
 	/* Initialize data. */
 
@@ -2588,6 +2573,7 @@ gth_image_viewer_is_frame_visible (GthImageViewer *viewer)
 
 void
 gth_image_viewer_paint (GthImageViewer *viewer,
+			cairo_t        *cr,
 			GdkPixbuf      *pixbuf,
 			int             src_x,
 			int             src_y,
@@ -2597,11 +2583,9 @@ gth_image_viewer_paint (GthImageViewer *viewer,
 			int             height,
 			int             interp_type)
 {
-	double         zoom_level;
-	int            bits_per_sample;
-	GdkColorspace  color_space;
-	guchar        *pixels;
-	int            rowstride;
+	double        zoom_level;
+	int           bits_per_sample;
+	GdkColorspace color_space;
 
 	zoom_level = viewer->priv->zoom_level;
 
@@ -2629,62 +2613,42 @@ gth_image_viewer_paint (GthImageViewer *viewer,
 		viewer->priv->paint_bps = bits_per_sample;
 	}
 
-	if ((zoom_level == 1.0) && ! gdk_pixbuf_get_has_alpha (pixbuf) && (bits_per_sample == 8)) {
-		rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-		pixels = gdk_pixbuf_get_pixels (pixbuf) + (src_y * rowstride) + (src_x * gdk_pixbuf_get_n_channels (pixbuf));
-	}
-	else {
-		if (gdk_pixbuf_get_has_alpha (pixbuf))
-			gdk_pixbuf_composite_color (pixbuf,
-						    viewer->priv->paint_pixbuf,
-						    0, 0,
-						    width, height,
-						    (double) -src_x,
-						    (double) -src_y,
-						    zoom_level,
-						    zoom_level,
-						    interp_type,
-						    255,
-						    src_x, src_y,
-						    viewer->priv->check_size,
-						    viewer->priv->check_color1,
-						    viewer->priv->check_color2);
-		else
-			gdk_pixbuf_scale (pixbuf,
-					  viewer->priv->paint_pixbuf,
-					  0, 0,
-					  width, height,
-					  (double) -src_x,
-					  (double) -src_y,
-					  zoom_level,
-					  zoom_level,
-					  interp_type);
-
-		rowstride = gdk_pixbuf_get_rowstride (viewer->priv->paint_pixbuf);
-		pixels = gdk_pixbuf_get_pixels (viewer->priv->paint_pixbuf);
-	}
-
-	gdk_draw_rgb_image_dithalign (GTK_WIDGET (viewer)->window,
-				      GTK_WIDGET (viewer)->style->black_gc,
-				      dest_x, dest_y,
-				      width, height,
-				      GDK_RGB_DITHER_MAX,
-				      pixels,
-				      rowstride,
-				      dest_x, dest_y);
+	if (gdk_pixbuf_get_has_alpha (pixbuf))
+		gdk_pixbuf_composite_color (pixbuf,
+					    viewer->priv->paint_pixbuf,
+					    0, 0,
+					    width, height,
+					    (double) -src_x,
+					    (double) -src_y,
+					    zoom_level,
+					    zoom_level,
+					    interp_type,
+					    255,
+					    src_x, src_y,
+					    viewer->priv->check_size,
+					    viewer->priv->check_color1,
+					    viewer->priv->check_color2);
+	else
+		gdk_pixbuf_scale (pixbuf,
+				  viewer->priv->paint_pixbuf,
+				  0, 0,
+				  width, height,
+				  (double) -src_x,
+				  (double) -src_y,
+				  zoom_level,
+				  zoom_level,
+				  interp_type);
 
-#if 0
-	gdk_draw_rectangle (GTK_WIDGET (viewer)->window,
-			    GTK_WIDGET (viewer)->style->black_gc,
-			    FALSE,
-			    dest_x, dest_y,
-			    width, height);
-#endif
+	cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+	gdk_cairo_set_source_pixbuf (cr, viewer->priv->paint_pixbuf, dest_x, dest_y);
+  	cairo_rectangle (cr, dest_x, dest_y, width, height);
+  	cairo_fill (cr);
 }
 
 
 void
 gth_image_viewer_paint_region (GthImageViewer *viewer,
+			       cairo_t        *cr,
 			       GdkPixbuf      *pixbuf,
 			       int             src_x,
 			       int             src_y,
@@ -2696,12 +2660,19 @@ gth_image_viewer_paint_region (GthImageViewer *viewer,
 	int           n_rects;
 	int           i;
 
+	cairo_save (cr);
+	gdk_cairo_region (cr, region);
+	cairo_clip (cr);
+	gdk_cairo_rectangle (cr, pixbuf_area);
+	cairo_clip (cr);
+
 	gdk_region_get_rectangles (region, &rects, &n_rects);
 	for (i = 0; i < n_rects; i++) {
 		GdkRectangle paint_area;
 
 		if (gdk_rectangle_intersect (pixbuf_area, &rects[i], &paint_area))
 			gth_image_viewer_paint (viewer,
+						cr,
 						pixbuf,
 						src_x + paint_area.x,
 						src_y + paint_area.y,
@@ -2712,6 +2683,8 @@ gth_image_viewer_paint_region (GthImageViewer *viewer,
 						interp_type);
 	}
 
+	cairo_restore (cr);
+
 	g_free (rects);
 }
 
diff --git a/gthumb/gth-image-viewer.h b/gthumb/gth-image-viewer.h
index 5d48f67..6690176 100644
--- a/gthumb/gth-image-viewer.h
+++ b/gthumb/gth-image-viewer.h
@@ -266,6 +266,7 @@ gboolean       gth_image_viewer_is_frame_visible         (GthImageViewer     *vi
 /*< protected, used by the tools >*/
 
 void           gth_image_viewer_paint                    (GthImageViewer     *viewer,
+							  cairo_t            *cr,
 							  GdkPixbuf          *pixbuf,
 							  int                 src_x,
 							  int                 src_y,
@@ -275,6 +276,7 @@ void           gth_image_viewer_paint                    (GthImageViewer     *vi
 							  int                 height,
 							  int                 interp_type);
 void           gth_image_viewer_paint_region             (GthImageViewer     *viewer,
+							  cairo_t            *cr,
 							  GdkPixbuf          *pixbuf,
 							  int                 src_x,
 							  int                 src_y,
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1da6a5c..3655100 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -639,6 +639,8 @@ gthumb/gth-image-history.c
 gthumb/gth-image-history.h
 gthumb/gth-image-loader.c
 gthumb/gth-image-loader.h
+gthumb/gth-image-navigator.c
+gthumb/gth-image-navigator.h
 gthumb/gth-image-preloader.c
 gthumb/gth-image-preloader.h
 gthumb/gth-image-selector.c
@@ -670,8 +672,6 @@ gthumb/gth-monitor.c
 gthumb/gth-monitor.h
 gthumb/gth-multipage.c
 gthumb/gth-multipage.h
-gthumb/gth-nav-window.c
-gthumb/gth-nav-window.h
 gthumb/gth-overwrite-dialog.c
 gthumb/gth-overwrite-dialog.h
 gthumb/gth-pixbuf-list-task.c



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