gthumb r2368 - in trunk: . libgthumb src



Author: mjc
Date: Thu Jul 31 17:49:56 2008
New Revision: 2368
URL: http://svn.gnome.org/viewvc/gthumb?rev=2368&view=rev

Log:
2008-07-31  Michael J. Chudobiak  <mjc svn gnome org>

        * libgthumb/gth-nav-window.c: (size_changed_cb):
        Remove assumptions about GtkAdjustment->lower being 0

        * libgthumb/nav-window.c: (nav_window_events), (update_view):
        * libgthumb/image-viewer-image.c, libgthumb/image-viewer-image.h:
        Adjust [xy]-offset scales such that an offset of (0,0)
        will draw the image in the center of the widget even if
        widget is bigger or smaller than the image itself (important
        when there are two images with different sizes  on the screen at
        once).

        * libgthumb/image-viewer-image.c, libgthumb/image-viewer-image.h:
        Have image paint itself to a cairo buffer to be used
        by a transition or directly by the widget.

        Removed the "repainted" signal as it is no longer needed
        as scrolling triggers an "exposed" event that takes care
        of it for gth-fullscreen.

        * src/gth-fullscreeen.c:
        No longer connect to the "repainted" event.

        Patch by Geoffrey Antos <dynamotwain aim com>. Bug #501512.



Modified:
   trunk/ChangeLog
   trunk/libgthumb/gth-nav-window.c
   trunk/libgthumb/image-viewer-image.c
   trunk/libgthumb/image-viewer-image.h
   trunk/libgthumb/image-viewer.c
   trunk/libgthumb/nav-window.c
   trunk/src/gth-fullscreen.c

Modified: trunk/libgthumb/gth-nav-window.c
==============================================================================
--- trunk/libgthumb/gth-nav-window.c	(original)
+++ trunk/libgthumb/gth-nav-window.c	Thu Jul 31 17:49:56 2008
@@ -113,8 +113,8 @@
 	g_return_val_if_fail (hadj != NULL, FALSE);
 	g_return_val_if_fail (vadj != NULL, FALSE);
 
-	hide_vscr = (vadj->upper <= vadj->page_size);
-	hide_hscr = (hadj->upper <= hadj->page_size);
+	hide_vscr = (vadj->upper - vadj->lower <= vadj->page_size + 1e-6);
+	hide_hscr = (hadj->upper - hadj->lower <= hadj->page_size + 1e-6);
 
 	if (hide_vscr && hide_hscr) {
 		gtk_widget_hide (priv->viewer_vscr); 

Modified: trunk/libgthumb/image-viewer-image.c
==============================================================================
--- trunk/libgthumb/image-viewer-image.c	(original)
+++ trunk/libgthumb/image-viewer-image.c	Thu Jul 31 17:49:56 2008
@@ -25,6 +25,8 @@
 #include "image-viewer.h"
 #include "image-viewer-image.h"
 
+#define FLOAT_EQUAL(a,b) (fabs ((a) - (b)) < 1e-6)
+
 #define MINIMUM_DELAY   10    /* When an animation frame has a 0 milli seconds
 			       * delay use this delay instead. */
 
@@ -57,6 +59,8 @@
 
 	gdouble                x_offset;           /* Scroll offsets. */
 	gdouble                y_offset;
+
+	cairo_surface_t       *buffer;
 };
 
 enum {
@@ -64,6 +68,8 @@
 	LAST_SIGNAL
 };
 
+cairo_surface_t*               pixbuf_to_surface (GdkPixbuf *pixbuf);
+
 static guint image_viewer_image_signals[LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE(ImageViewerImage, image_viewer_image, G_TYPE_OBJECT)
@@ -99,7 +105,6 @@
 image_viewer_image_init (ImageViewerImage *self)
 {
 	ImageViewerImagePrivate  *priv = IMAGE_VIEWER_IMAGE_GET_PRIVATE (self);
-	/* do stuff */
 
 	priv->viewer = NULL;
 	priv->is_animation = FALSE;
@@ -114,10 +119,12 @@
 	priv->static_pixbuf = NULL;
 
 	priv->zoom_level = 1.0;
-	priv->fit = GTH_FIT_SIZE_IF_LARGER;
+	priv->fit = GTH_FIT_NONE;
 
 	priv->x_offset = 0;
 	priv->y_offset = 0;
+
+	priv->buffer = NULL;
 }
 
 static void
@@ -159,6 +166,11 @@
 		priv->file = NULL;
 	}
 
+	if (priv->buffer != NULL) {
+		cairo_surface_destroy (priv->buffer);
+		priv->buffer = NULL;
+	}
+
         /* Chain up */
 	G_OBJECT_CLASS (image_viewer_image_parent_class)->finalize (object);
 }
@@ -187,6 +199,14 @@
 	GdkPixbufAnimationIter  *iter = priv->iter;
 	priv->anim_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (iter);
 	priv->frame_delay = gdk_pixbuf_animation_iter_get_delay_time (iter);
+
+	if (priv->buffer != NULL)
+	{
+		cairo_surface_destroy (priv->buffer);
+	}
+
+	priv->buffer = pixbuf_to_surface (priv->anim_pixbuf);
+
 	gtk_widget_queue_draw (GTK_WIDGET (priv->viewer));
 }
 
@@ -229,33 +249,37 @@
 	return FALSE;
 }
 
-
 static void
 clamp_offsets (ImageViewerImage *image)
 {
 	ImageViewerImagePrivate *priv = IMAGE_VIEWER_IMAGE_GET_PRIVATE (image);
+	gint                     border, border2;
 	gint                     gdk_width, gdk_height;
-	gint                     width, height, border;
+	gdouble                  width, height;
 
-	border = image_viewer_is_frame_visible (priv->viewer) ?
-		 FRAME_BORDER2 : 0;
+	if (image_viewer_is_frame_visible (priv->viewer)) {
+		border  = FRAME_BORDER;
+		border2 = FRAME_BORDER2;
+	} else {
+		border = border2 = 0;
+	}
 
-	gdk_width = GTK_WIDGET (priv->viewer)->allocation.width - border;
-	gdk_height = GTK_WIDGET (priv->viewer)->allocation.height - border;
+	gdk_width = GTK_WIDGET (priv->viewer)->allocation.width - border2;
+	gdk_height = GTK_WIDGET (priv->viewer)->allocation.height - border2;
 
 	image_viewer_image_get_zoomed_size (image, &width, &height);
 
 	if (width > gdk_width)
 		priv->x_offset = CLAMP (priv->x_offset,
-				0,
-				width - gdk_width);
+				floor (-width/2 - border),
+				floor ( width/2 + border));
 	else
 		priv->x_offset = 0;
 
 	if (height > gdk_height)
 		priv->y_offset = CLAMP (priv->y_offset,
-				0,
-				height - gdk_height);
+				floor (-height/2 - border),
+				floor ( height/2 + border));
 	else
 		priv->y_offset = 0;
 }
@@ -305,11 +329,10 @@
 {
 	ImageViewerImagePrivate *priv = IMAGE_VIEWER_IMAGE_GET_PRIVATE (image);
 	GtkWidget               *widget = GTK_WIDGET (priv->viewer);
-	GdkPixbuf               *buf;
-	gint                     gdk_width, gdk_height, border;
+	gdouble                  gdk_width, gdk_height;
+	gint                     border;
 	gdouble                  zoom_ratio;
 
-	buf = image_viewer_image_get_pixbuf (image);
 	border = image_viewer_is_frame_visible (priv->viewer) ?
 		 FRAME_BORDER2 : 0;
 
@@ -319,8 +342,8 @@
 	/* try to keep the center of the view visible. */
 
 	zoom_ratio = zoom_level / priv->zoom_level;
-	priv->x_offset = ((priv->x_offset + center_x) * zoom_ratio - gdk_width / 2);
-	priv->y_offset = ((priv->y_offset + center_y) * zoom_ratio - gdk_height / 2);
+	priv->x_offset = ((priv->x_offset - gdk_width  / 2 + center_x) * zoom_ratio);
+	priv->y_offset = ((priv->y_offset - gdk_height / 2 + center_y) * zoom_ratio);
 
 	priv->zoom_level = zoom_level;
 
@@ -400,6 +423,10 @@
 		create_first_pixbuf (image);
 		add_change_frame_timeout(image);
 	}
+	else
+	{
+		priv->buffer = pixbuf_to_surface (priv->static_pixbuf);
+	}
 
 	return image;
 }
@@ -595,8 +622,8 @@
 
 void
 image_viewer_image_get_zoomed_size (ImageViewerImage *image,
-				    gint             *width,
-				    gint             *height)
+				    gdouble          *width,
+				    gdouble          *height)
 {
 	ImageViewerImagePrivate *priv;
 	gint w, h;
@@ -608,8 +635,8 @@
 	w = image_viewer_image_get_width (image);
 	h = image_viewer_image_get_height (image);
 
-	*width  = (int) floor ((double) w * priv->zoom_level);
-	*height = (int) floor ((double) h * priv->zoom_level);
+	*width  = floor ((double) w * priv->zoom_level);
+	*height = floor ((double) h * priv->zoom_level);
 }
 
 
@@ -862,3 +889,253 @@
 	set_zoom_centered (image, get_prev_zoom (priv->zoom_level));
 }
 
+/* image_viewer_image_paint */
+
+cairo_surface_t*
+pixbuf_to_surface (GdkPixbuf *pixbuf)
+{
+	/* based on gdk_cairo_set_source_pixbuf */
+	gint    width = gdk_pixbuf_get_width (pixbuf);
+	gint    height = gdk_pixbuf_get_height (pixbuf);
+	guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
+	int     gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+	int     n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+	int     cairo_stride;
+	guchar *cairo_pixels;
+	cairo_format_t format;
+	cairo_surface_t *surface;
+	static const cairo_user_data_key_t key;
+	int j;
+
+	if (n_channels == 3)
+		format = CAIRO_FORMAT_RGB24;
+	else
+		format = CAIRO_FORMAT_ARGB32;
+
+	cairo_stride = cairo_format_stride_for_width (format, width);
+	/* XXX store this buffer in the struct; reuse for multiple frames of animation? */
+	cairo_pixels = g_malloc (cairo_stride * height);
+
+	surface = cairo_image_surface_create_for_data (
+			(unsigned char *)cairo_pixels,
+			format,
+			width, height, cairo_stride);
+	cairo_surface_set_user_data (surface, &key,
+			cairo_pixels, (cairo_destroy_func_t)g_free);
+
+	for (j = height; j; j--)
+	{
+		guchar *p = gdk_pixels;
+		guchar *q = cairo_pixels;
+
+		if (n_channels == 3)
+		{
+			guchar *end = p + 3 * width;
+
+			while (p < end)
+			{
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+				q[0] = p[2];
+				q[1] = p[1];
+				q[2] = p[0];
+#else	  
+				q[1] = p[0];
+				q[2] = p[1];
+				q[3] = p[2];
+#endif
+				p += 3;
+				q += 4;
+			}
+		}
+		else
+		{
+			guchar *end = p + 4 * width;
+			guint t1,t2,t3;
+
+#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END
+
+			while (p < end)
+			{
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+				MULT(q[0], p[2], p[3], t1);
+				MULT(q[1], p[1], p[3], t2);
+				MULT(q[2], p[0], p[3], t3);
+				q[3] = p[3];
+#else	  
+				q[0] = p[3];
+				MULT(q[1], p[0], p[3], t1);
+				MULT(q[2], p[1], p[3], t2);
+				MULT(q[3], p[2], p[3], t3);
+#endif
+
+				p += 4;
+				q += 4;
+			}
+
+#undef MULT
+		}
+
+		gdk_pixels += gdk_rowstride;
+		cairo_pixels += 4 * width;
+	}
+
+	return surface;
+}
+
+
+static cairo_surface_t*
+checker_pattern (int width, int height, double color1, double color2)
+{
+	cairo_surface_t *surface;
+	cairo_t         *cr;
+
+	surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+					      width * 2, height *2);
+	cr = cairo_create (surface);
+
+	cairo_set_source_rgb (cr, color1, color1, color1);
+	cairo_paint (cr);
+
+	cairo_set_source_rgb (cr, color2, color2, color2);
+	cairo_rectangle (cr, 0,     0,      width, height);
+	cairo_rectangle (cr, width, height, width, height);
+	cairo_fill (cr);
+	cairo_destroy (cr);
+
+	return surface;
+}
+
+
+void
+image_viewer_image_paint (ImageViewerImage *image,
+			  cairo_t          *cr)
+{
+	ImageViewerImagePrivate *priv;
+	GdkPixbuf               *pixbuf;
+	GtkStyle                *style;
+
+	gint                     border, border2;
+	gdouble                  gdk_width, gdk_height;
+	gdouble                  src_x, src_y;
+	gdouble                  width, height;
+	GthTranspType            transp_type;
+	GthZoomQuality           zoom_quality;
+	cairo_filter_t           filter;
+	cairo_matrix_t           matrix;
+	cairo_pattern_t         *pattern;	
+
+	g_return_if_fail (image != NULL);
+
+	priv   = IMAGE_VIEWER_IMAGE_GET_PRIVATE (image);
+	pixbuf = image_viewer_image_get_pixbuf (image);
+	style  = GTK_WIDGET (priv->viewer)->style;
+
+	if (image_viewer_is_frame_visible (priv->viewer)) {
+		border  = FRAME_BORDER;
+		border2 = FRAME_BORDER2;
+	} else {
+		border = border2 = 0;
+	}
+
+	gdk_width = GTK_WIDGET (priv->viewer)->allocation.width - border2;
+	gdk_height = GTK_WIDGET (priv->viewer)->allocation.height - border2;
+
+	image_viewer_image_get_zoomed_size (image, &width, &height);
+
+	transp_type = image_viewer_get_transp_type (priv->viewer);
+
+	zoom_quality = image_viewer_get_zoom_quality (priv->viewer);
+	if (zoom_quality == GTH_ZOOM_QUALITY_LOW)
+		filter = CAIRO_FILTER_FAST;
+	else
+		filter = CAIRO_FILTER_GOOD;
+/*		filter = CAIRO_FILTER_BEST;*/
+
+	if (FLOAT_EQUAL (priv->zoom_level, 1.0))
+		filter = CAIRO_FILTER_FAST;
+
+	src_x = floor ((gdk_width  - width)  / 2 - priv->x_offset + border);
+	src_y = floor ((gdk_height - height) / 2 - priv->y_offset + border);
+
+	cairo_save (cr);
+
+	if (image_viewer_image_get_has_alpha (image) &&
+			transp_type != GTH_TRANSP_TYPE_NONE) {
+		cairo_surface_t *checker;
+		int              check_size;
+		GthCheckType     check_type;
+		double           color1, color2;
+
+		switch (transp_type) {
+		case GTH_TRANSP_TYPE_NONE:
+			g_assert_not_reached ();
+			break;
+
+		case GTH_TRANSP_TYPE_BLACK:
+			color1 = color2 = 0;
+			break;
+
+		case GTH_TRANSP_TYPE_WHITE:
+			color1 = color2 = 1;
+			break;
+
+		case GTH_TRANSP_TYPE_CHECKED:
+			check_type = image_viewer_get_check_type (priv->viewer);
+			switch (check_type) {
+			case GTH_CHECK_TYPE_DARK:
+				color1 = 0;
+				color2 = 0.2;
+				break;
+
+			case GTH_CHECK_TYPE_MIDTONE:
+				color1 = 0.4;
+				color2 = 0.6;
+				break;
+
+			case GTH_CHECK_TYPE_LIGHT:
+				color1 = 0.8;
+				color2 = 1;
+				break;
+			}
+			break;
+		}
+
+		check_size = (int) image_viewer_get_check_size (priv->viewer);
+
+		checker = checker_pattern (check_size, check_size, color1, color2);
+		cairo_set_source_surface (cr, checker, -src_x, -src_y);
+		cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+		cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+		cairo_rectangle (cr, src_x, src_y, width, height);
+		cairo_fill (cr);
+		cairo_surface_destroy (checker);
+	}
+
+	pattern = cairo_pattern_create_for_surface (priv->buffer);
+	cairo_matrix_init_scale (&matrix, 1/priv->zoom_level, 1/priv->zoom_level);
+	cairo_matrix_translate (&matrix, -src_x, -src_y);
+	cairo_pattern_set_matrix (pattern, &matrix);
+	cairo_pattern_set_filter (pattern, filter);
+
+	cairo_set_source (cr, pattern);
+	cairo_pattern_destroy(pattern);
+	cairo_paint (cr);
+
+	if(border != 0) {
+		cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+		cairo_set_line_width (cr, 1);
+		gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
+		cairo_move_to (cr, src_x - border, src_y + height + border);
+		cairo_line_to (cr, src_x - border, src_y - border);
+		cairo_line_to (cr, src_x + width + border, src_y - border);
+		cairo_stroke (cr);
+		gdk_cairo_set_source_color (cr, &style->light[GTK_STATE_NORMAL]);
+		cairo_move_to (cr, src_x + width, src_y);
+		cairo_line_to (cr, src_x + width, src_y + height);
+		cairo_line_to (cr, src_x, src_y + height);
+		cairo_stroke (cr);
+	}
+
+	cairo_restore (cr);
+
+}

Modified: trunk/libgthumb/image-viewer-image.h
==============================================================================
--- trunk/libgthumb/image-viewer-image.h	(original)
+++ trunk/libgthumb/image-viewer-image.h	Thu Jul 31 17:49:56 2008
@@ -74,8 +74,11 @@
 gint              image_viewer_image_get_y_offset             (ImageViewerImage *image);
 gdouble           image_viewer_image_get_zoom_level           (ImageViewerImage *image);
 void              image_viewer_image_get_zoomed_size          (ImageViewerImage *image,
-							       gint             *width,
-							       gint             *height);
+							       gdouble          *width,
+							       gdouble          *height);
+
+void              image_viewer_image_paint                    (ImageViewerImage *image,
+							       cairo_t          *cr);
 
 void              image_viewer_image_scroll_relative          (ImageViewerImage *image,
 							       gdouble           delta_x,

Modified: trunk/libgthumb/image-viewer.c
==============================================================================
--- trunk/libgthumb/image-viewer.c	(original)
+++ trunk/libgthumb/image-viewer.c	Thu Jul 31 17:49:56 2008
@@ -52,7 +52,7 @@
 			       * smaller than this value. */
 #define STEP_INCREMENT  20.0  /* Scroll increment. */
 
-#define FLOAT_EQUAL(a,b) (fabs (a - b) < 1e-6)
+#define FLOAT_EQUAL(a,b) (fabs ((a) - (b)) < 1e-6)
 
 typedef struct _ImageViewerPrivate ImageViewerPrivate;
 
@@ -72,8 +72,6 @@
 	GthTranspType    transp_type;
 	GthCheckType     check_type;
 	gint             check_size;
-	guint32          check_color1;
-	guint32          check_color2;
 
 	GdkCursor       *cursor;
 	GdkCursor       *cursor_void;
@@ -92,12 +90,6 @@
 	gint             drag_realx;
 	gint             drag_realy;
 
-	GdkPixbuf       *area_pixbuf;
-	gint             area_max_width;
-	gint             area_max_height;
-        int              area_bps;
-	GdkColorspace    area_color_space;
-
 	GtkAdjustment   *vadj, *hadj;
 
 	gboolean         black_bg;
@@ -105,9 +97,6 @@
 	gboolean         skip_zoom_change;
 	gboolean         skip_size_change;
 
-	gboolean         next_scroll_repaint; /* used in fullscreen mode to
-					       * delete the comment before
-					       * scrolling. */
 	gboolean         reset_scrollbars;	
 };
 
@@ -122,7 +111,6 @@
 	SET_ZOOM,
 	SET_FIT_MODE,
 	ZOOM_CHANGED,
-	REPAINTED,
 	MOUSE_WHEEL_SCROLL,
 	SCROLL,
 	LAST_SIGNAL
@@ -161,8 +149,6 @@
 					       GdkEventFocus    *event);
 static gint     image_viewer_scroll_event     (GtkWidget        *widget,
 					       GdkEventScroll   *event);
-static void     image_viewer_style_set        (GtkWidget        *widget,
-					       GtkStyle         *previous_style);
 static void     scroll_relative               (ImageViewer      *viewer,
 					       gdouble           delta_x,
 					       gdouble           delta_y);
@@ -295,15 +281,6 @@
 			      g_cclosure_marshal_VOID__VOID,
 			      G_TYPE_NONE,
 			      0);
-	image_viewer_signals[REPAINTED] =
-		g_signal_new ("repainted",
-			      G_TYPE_FROM_CLASS (klass),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (ImageViewerClass, repainted),
-			      NULL, NULL,
-			      g_cclosure_marshal_VOID__VOID,
-			      G_TYPE_NONE,
-			      0);
         image_viewer_signals[MOUSE_WHEEL_SCROLL] =
 		g_signal_new ("mouse_wheel_scroll",
 			      G_TYPE_FROM_CLASS (klass),
@@ -349,7 +326,6 @@
 	widget_class->motion_notify_event = image_viewer_motion_notify;
 
 	widget_class->scroll_event = image_viewer_scroll_event;
-	widget_class->style_set    = image_viewer_style_set;
 
 	klass->clicked        = NULL;
 	klass->image_loaded   = NULL;
@@ -478,9 +454,9 @@
 	gdouble              x_ofs, y_ofs;
 
 	g_return_val_if_fail (priv->image != NULL, FALSE);
-	
-	x_ofs = GTK_ADJUSTMENT (adj)->value
-		- image_viewer_image_get_x_offset (priv->image);
+
+	x_ofs = floor (adj->value + adj->page_size / 2) -
+		image_viewer_image_get_x_offset (priv->image);
 	y_ofs = 0;
 	scroll_relative_no_scrollbar (viewer, x_ofs, y_ofs);
 
@@ -494,12 +470,12 @@
 {
 	ImageViewerPrivate  *priv = IMAGE_VIEWER_GET_PRIVATE (viewer);
 	gdouble              x_ofs, y_ofs;
-
-	g_return_val_if_fail (priv->image != NULL, FALSE);
 	
+	g_return_val_if_fail (priv->image != NULL, FALSE);
+
 	x_ofs = 0;
-	y_ofs = GTK_ADJUSTMENT (adj)->value
-		- image_viewer_image_get_y_offset (priv->image);
+	y_ofs = floor (adj->value + adj->page_size / 2) -
+		image_viewer_image_get_y_offset (priv->image);
 	scroll_relative_no_scrollbar (viewer, x_ofs, y_ofs);
 
 	return FALSE;
@@ -512,14 +488,12 @@
 	ImageViewerPrivate  *priv = IMAGE_VIEWER_GET_PRIVATE (viewer);
 
 	GTK_WIDGET_SET_FLAGS (viewer, GTK_CAN_FOCUS);
-	GTK_WIDGET_UNSET_FLAGS (viewer, GTK_DOUBLE_BUFFERED);
+	/*GTK_WIDGET_UNSET_FLAGS (viewer, GTK_DOUBLE_BUFFERED);*/
 
 	/* Initialize data. */
 
 	priv->check_type = GTH_CHECK_TYPE_MIDTONE;
 	priv->check_size = GTH_CHECK_SIZE_LARGE;
-	priv->check_color1 = COLOR_GRAY_66;
-	priv->check_color2 = COLOR_GRAY_99;
 
 	priv->rendering = FALSE;
 	priv->cursor_visible = TRUE;
@@ -546,7 +520,6 @@
 
 	priv->skip_zoom_change = FALSE;
 	priv->skip_size_change = FALSE;
-	priv->next_scroll_repaint = FALSE;
 
 	priv->dragging = FALSE;
 	priv->double_click = FALSE;
@@ -554,12 +527,6 @@
 
 	priv->black_bg = FALSE;
 
-	priv->area_pixbuf = NULL;
-	priv->area_max_width = 0;
-	priv->area_max_height = 0;
-	priv->area_bps = 0;
-	priv->area_color_space = GDK_COLORSPACE_RGB;
-
 	priv->cursor = NULL;
 	priv->cursor_void = NULL;
 
@@ -586,112 +553,14 @@
 }
 
 
-static void
-paint (ImageViewer *viewer,
-       gint         src_x,
-       gint         src_y,
-       gint         dest_x,
-       gint         dest_y,
-       gint         width,
-       gint         height,
-       gint         interp_type)
-{
-	ImageViewerPrivate *priv = IMAGE_VIEWER_GET_PRIVATE (viewer);
-	GdkPixbuf          *pixbuf;
-	double              zoom_level;
-	int                 bits_per_sample;
-	GdkColorspace       color_space;
-
-	pixbuf = image_viewer_get_current_pixbuf (viewer);
-	zoom_level = image_viewer_image_get_zoom_level (priv->image);
-
-	color_space = gdk_pixbuf_get_colorspace (pixbuf);
-	bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
-
-	if ((priv->area_pixbuf == NULL)
-	    || (priv->area_max_width < width)
-	    || (priv->area_max_height < height)
-	    || (priv->area_bps != bits_per_sample)
-	    || (priv->area_color_space != color_space)) {
-		if (priv->area_pixbuf != NULL)
-			g_object_unref (priv->area_pixbuf);
-		priv->area_pixbuf = gdk_pixbuf_new (color_space,
-						      FALSE,
-						      bits_per_sample,
-						      width,
-						      height);
-		g_return_if_fail (priv->area_pixbuf != NULL);
-
-		priv->area_max_width = width;
-		priv->area_max_height = height;
-		priv->area_color_space = color_space;
-		priv->area_bps = bits_per_sample;
-	}
-
-	if (gdk_pixbuf_get_has_alpha (pixbuf))
-		gdk_pixbuf_composite_color (pixbuf,
-					    priv->area_pixbuf,
-					    0, 0,
-					    width, height,
-					    (double) -src_x,
-					    (double) -src_y,
-					    zoom_level,
-					    zoom_level,
-					    interp_type,
-					    255,
-					    src_x, src_y,
-					    priv->check_size,
-					    priv->check_color1,
-					    priv->check_color2);
-	else {
-		gdk_pixbuf_scale (pixbuf,
-				  priv->area_pixbuf,
-				  0, 0,
-				  width, height,
-				  (double) -src_x,
-				  (double) -src_y,
-				  zoom_level,
-				  zoom_level,
-				  interp_type);
-	}
-
-	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,
-				      gdk_pixbuf_get_pixels (priv->area_pixbuf),
-				      gdk_pixbuf_get_rowstride (priv->area_pixbuf),
-				      dest_x, dest_y);
-
-#if 0
-	gdk_draw_rectangle (GTK_WIDGET (viewer)->window,
-			    GTK_WIDGET (viewer)->style->black_gc,
-			    FALSE,
-			    dest_x, dest_y,
-			    width, height);
-#endif
-}
-
-
 static gint
 image_viewer_expose (GtkWidget      *widget,
 		     GdkEventExpose *event)
 {
 	ImageViewer        *viewer;
 	ImageViewerPrivate *priv;
-	gdouble              src_x, src_y;    /* Start to draw the image from this
-					* point. */
-	int           pixbuf_width;    /* Zoomed size of the image. */
-	int           pixbuf_height;
-	GdkRectangle  image_area;      /* Inside this rectangle there is the
-					* visible part of the image. */
-	GdkRectangle  paint_area;      /* The intersection between image_area
-					* and event->area. */
-	int           gdk_width;
-	int           gdk_height;
-	int           alloc_width;
-	int           alloc_height;
+	int                 gdk_width,   gdk_height;
+	int                 alloc_width, alloc_height;
 
 	viewer = IMAGE_VIEWER (widget);
 	priv = IMAGE_VIEWER_GET_PRIVATE (viewer);
@@ -701,187 +570,26 @@
 
 	priv->rendering = TRUE;
 
-	if (priv->image != NULL) {
-		image_viewer_image_get_zoomed_size (priv->image,
-						    &pixbuf_width,
-						    &pixbuf_height);
-		image_viewer_image_get_scroll_offsets (priv->image,
-						       &src_x,
-						       &src_y);
-	} else {
-		pixbuf_width = pixbuf_height = 0;
-		src_x = src_y = 0;
-	}
-	
 	alloc_width  = widget->allocation.width;
 	alloc_height = widget->allocation.height;
 	gdk_width    = alloc_width - priv->frame_border2;
 	gdk_height   = alloc_height - priv->frame_border2;
 
-	image_area.x      = MAX (priv->frame_border, (gdk_width - pixbuf_width) / 2);
-	image_area.y      = MAX (priv->frame_border, (gdk_height - pixbuf_height) / 2);
-	image_area.width  = MIN (pixbuf_width, gdk_width);
-	image_area.height = MIN (pixbuf_height, gdk_height);
-
-	/* Draw the background. */
-
-	if ((image_area.x > priv->frame_border)
-	    || (image_area.y > priv->frame_border)
-	    || (image_area.width < gdk_width)
-	    || (image_area.height < gdk_height)) {
-		int    rx, ry, rw, rh;
-		GdkGC *gc;
-
-		if (priv->black_bg)
-			gc = widget->style->black_gc;
-		else
-			gc = widget->style->bg_gc[GTK_STATE_NORMAL];
-
-		if (priv->image == NULL) {
-			gdk_draw_rectangle (widget->window,
-					    gc,
-					    TRUE,
-					    0, 0,
-					    alloc_width, alloc_height);
-
-		} else {
-			/* If an image is present draw in four phases to avoid
-			 * flickering. */
-
-			/* Top rectangle. */
-			rx = 0;
-			ry = 0;
-			rw = alloc_width;
-			rh = image_area.y;
-			if ((rw > 0) && (rh > 0))
-				gdk_draw_rectangle (widget->window,
-						    gc,
-						    TRUE,
-						    rx, ry,
-						    rw, rh);
-
-			/* Bottom rectangle. */
-			rx = 0;
-			ry = image_area.y + image_area.height;
-			rw = alloc_width;
-			rh = alloc_height - image_area.y - image_area.height;
-			if ((rw > 0) && (rh > 0))
-				gdk_draw_rectangle (widget->window,
-						    gc,
-						    TRUE,
-						    rx, ry,
-						    rw, rh);
-
-			/* Left rectangle. */
-			rx = 0;
-			ry = image_area.y - 1;
-			rw = image_area.x;
-			rh = image_area.height + 2;
-			if ((rw > 0) && (rh > 0))
-				gdk_draw_rectangle (widget->window,
-						    gc,
-						    TRUE,
-						    rx, ry,
-						    rw, rh);
-
-			/* Right rectangle. */
-			rx = image_area.x + image_area.width;
-			ry = image_area.y - 1;
-			rw = alloc_width - image_area.x - image_area.width;
-			rh = image_area.height + 2;
-			if ((rw > 0) && (rh > 0))
-				gdk_draw_rectangle (widget->window,
-						    gc,
-						    TRUE,
-						    rx, ry,
-						    rw, rh);
-		}
-	}
+	if (priv->image != NULL)
+	{
+		cairo_t *cr;
+		cr = gdk_cairo_create (GTK_WIDGET (viewer)->window);
 
-	/* Draw the frame. */
+		/* Only actually paint the regions that need redrawn */
+		gdk_cairo_region (cr, event->region);
+		cairo_clip (cr);
 
-	if ((priv->frame_border > 0) && (priv->image != NULL)) {
-		int    x1, y1, x2, y2;
-		GdkGC *gc;
-
-		if (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 = image_area.x + image_area.width;
-		y1 = image_area.y - 1;
-		x2 = image_area.x + image_area.width;
-		y2 = image_area.y + image_area.height;
-		gdk_draw_line (widget->window,
-			       gc,
-			       x1, y1,
-			       x2, y2);
-
-		x1 = image_area.x - 1;
-		y1 = image_area.y + image_area.height;
-		x2 = image_area.x + image_area.width;
-		y2 = image_area.y + image_area.height;
-		gdk_draw_line (widget->window,
-			       gc,
-			       x1, y1,
-			       x2, y2);
-
-		if (priv->black_bg)
-			gc = widget->style->black_gc;
-		else
-			gc = widget->style->dark_gc[GTK_STATE_NORMAL];
-
-		x1 = image_area.x - 1;
-		y1 = image_area.y - 1;
-		x2 = image_area.x - 1;
-		y2 = image_area.y + image_area.height;
-		gdk_draw_line (widget->window,
-			       gc,
-			       x1, y1,
-			       x2, y2);
-
-		x1 = image_area.x - 1;
-		y1 = image_area.y - 1;
-		x2 = image_area.x + image_area.width;
-		y2 = image_area.y - 1;
-		gdk_draw_line (widget->window,
-			       gc,
-			       x1, y1,
-			       x2, y2);
-	}
-
-	if ((priv->image != NULL)
-	    && gdk_rectangle_intersect (&event->area,
-					&image_area,
-					&paint_area)) {
-		int interp_type;
-
-		if (priv->zoom_quality == GTH_ZOOM_QUALITY_LOW)
-			interp_type = GDK_INTERP_NEAREST;
-		else
-			interp_type = GDK_INTERP_BILINEAR;
-/*			interp_type = GDK_INTERP_TILES;*/
-/*			interp_type = GDK_INTERP_HYPER;*/
-
-		if (FLOAT_EQUAL (
-			image_viewer_image_get_zoom_level (priv->image),
-			1.0))
-			interp_type = GDK_INTERP_NEAREST;
-
-		src_x += paint_area.x - image_area.x;
-		src_y += paint_area.y - image_area.y;
-
-		paint (viewer,
-		       src_x,
-		       src_y,
-		       paint_area.x,
-		       paint_area.y,
-		       paint_area.width,
-		       paint_area.height,
-		       interp_type);
+		/* Paint the image */
+		image_viewer_image_paint (priv->image, cr);
+
+		cairo_destroy (cr);
 	}
+
 	priv->rendering = FALSE;
 
 	/* Draw the focus. */
@@ -965,13 +673,9 @@
 			      gdouble      delta_y)
 {
 	ImageViewerPrivate *priv     = IMAGE_VIEWER_GET_PRIVATE (viewer);
-	gint                gdk_width, gdk_height;
 
 	image_viewer_image_scroll_relative (priv->image, delta_x, delta_y);
 
-	gdk_width  = GTK_WIDGET (viewer)->allocation.width - priv->frame_border2;
-	gdk_height = GTK_WIDGET (viewer)->allocation.height - priv->frame_border2;
-
 	gtk_widget_queue_draw (GTK_WIDGET (viewer));
 }
 
@@ -1143,22 +847,16 @@
 		priv->vadj = NULL;
 	}
 
-	if (priv->area_pixbuf != NULL) {
+	/*if (priv->area_pixbuf != NULL) {
 		g_object_unref (priv->area_pixbuf);
 		priv->area_pixbuf = NULL;
-	}
+	}*/
 
         /* Chain up */
 	G_OBJECT_CLASS (image_viewer_parent_class)->finalize (object);
 }
 
 
-static int
-to_255 (int v)
-{
-	return v * 255 / 65535;
-}
-
 
 static void
 image_viewer_realize (GtkWidget *widget)
@@ -1206,20 +904,6 @@
 	priv->cursor = cursor_get (widget->window, CURSOR_HAND_OPEN);
 	priv->cursor_void = cursor_get (widget->window, CURSOR_VOID);
 	gdk_window_set_cursor (widget->window, priv->cursor);
-
-	if (priv->transp_type == GTH_TRANSP_TYPE_NONE) {
-		GdkColor color;
-		guint    base_color;
-
-		color = GTK_WIDGET (viewer)->style->bg[GTK_STATE_NORMAL];
-		base_color = (0xFF000000
-			      | (to_255 (color.red) << 16)
-			      | (to_255 (color.green) << 8)
-			      | (to_255 (color.blue) << 0));
-
-		priv->check_color1 = base_color;
-		priv->check_color2 = base_color;
-	}
 }
 
 
@@ -1267,7 +951,7 @@
 {
 	ImageViewer        *viewer = IMAGE_VIEWER (widget);
 	ImageViewerPrivate *priv = IMAGE_VIEWER_GET_PRIVATE (viewer);
-	gint                gdk_width, gdk_height;
+	gdouble             gdk_width, gdk_height;
 
 	widget->allocation = *allocation;
 	gdk_width = allocation->width - priv->frame_border2;
@@ -1276,7 +960,7 @@
 	/* If a fit type is active update the zoom level. */
 
 	if (priv->image != NULL) {
-		gint       width, height;
+		gdouble    width, height;
 		gdouble	   off_x, off_y;
 
 		/* Re-fit the image to the new widget size if a fit-mode is active */
@@ -1287,23 +971,24 @@
 
 		image_viewer_image_get_zoomed_size (priv->image, &width, &height);
 
-		if ((width != priv->hadj->upper) || (height != priv->vadj->upper))
+		if (!FLOAT_EQUAL(width,  priv->hadj->upper - priv->hadj->lower) ||
+		    !FLOAT_EQUAL(height, priv->vadj->upper - priv->vadj->lower))
 			gth_iviewer_size_changed (GTH_IVIEWER (viewer));
 
 		/* Change adjustment values. */
 
-		priv->hadj->lower          = 0.0;
-		priv->hadj->upper          = width;
-		priv->hadj->value          = off_x;
+		priv->hadj->lower          = floor (-width / 2 - priv->frame_border);
+		priv->hadj->upper          = floor ( width / 2 + priv->frame_border);
+		priv->hadj->value          = floor (off_x - gdk_width / 2);
 		priv->hadj->step_increment = STEP_INCREMENT;
-		priv->hadj->page_increment = gdk_width / 2;
+		priv->hadj->page_increment = floor (gdk_width / 2);
 		priv->hadj->page_size      = gdk_width;
 
-		priv->vadj->lower          = 0.0;
-		priv->vadj->upper          = height;
-		priv->vadj->value          = off_y;
+		priv->vadj->lower          = floor (-height / 2 - priv->frame_border);
+		priv->vadj->upper          = floor ( height / 2 + priv->frame_border);
+		priv->vadj->value          = floor ( off_y - gdk_height / 2);
 		priv->vadj->step_increment = STEP_INCREMENT;
-		priv->vadj->page_increment = gdk_height / 2;
+		priv->vadj->page_increment = floor (gdk_height / 2);
 		priv->vadj->page_size      = gdk_height;
 	} else {
 		priv->hadj->lower     = 0.0;
@@ -2083,86 +1768,17 @@
 }
 
 
-static void
-image_viewer_style_set (GtkWidget *widget,
-			GtkStyle  *previous_style)
-{
-	ImageViewer        *viewer = IMAGE_VIEWER (widget);
-	ImageViewerPrivate *priv = IMAGE_VIEWER_GET_PRIVATE (viewer);
-
-	GTK_WIDGET_CLASS (image_viewer_parent_class)->style_set (widget, previous_style);
-
-	if (priv->transp_type == GTH_TRANSP_TYPE_NONE) {
-		GdkColor color;
-		guint    base_color;
-
-		color = GTK_WIDGET (viewer)->style->bg[GTK_STATE_NORMAL];
-		base_color = (0xFF000000
-			      | (to_255 (color.red) << 16)
-			      | (to_255 (color.green) << 8)
-			      | (to_255 (color.blue) << 0));
-
-		priv->check_color1 = base_color;
-		priv->check_color2 = base_color;
-	}
-}
-
-
 void
 image_viewer_set_transp_type (ImageViewer   *viewer,
 			      GthTranspType  transp_type)
 {
 	ImageViewerPrivate *priv;
-	GdkColor color;
-	guint    base_color;
 
 	g_return_if_fail (viewer != NULL);
 
 	priv = IMAGE_VIEWER_GET_PRIVATE (viewer);
 
 	priv->transp_type = transp_type;
-
-	color = GTK_WIDGET (viewer)->style->bg[GTK_STATE_NORMAL];
-	base_color = (0xFF000000
-		      | (to_255 (color.red) << 16)
-		      | (to_255 (color.green) << 8)
-		      | (to_255 (color.blue) << 0));
-
-	switch (transp_type) {
-	case GTH_TRANSP_TYPE_BLACK:
-		priv->check_color1 = COLOR_GRAY_00;
-		priv->check_color2 = COLOR_GRAY_00;
-		break;
-
-	case GTH_TRANSP_TYPE_NONE:
-		priv->check_color1 = base_color;
-		priv->check_color2 = base_color;
-		break;
-
-	case GTH_TRANSP_TYPE_WHITE:
-		priv->check_color1 = COLOR_GRAY_FF;
-		priv->check_color2 = COLOR_GRAY_FF;
-		break;
-
-	case GTH_TRANSP_TYPE_CHECKED:
-		switch (priv->check_type) {
-		case GTH_CHECK_TYPE_DARK:
-			priv->check_color1 = COLOR_GRAY_00;
-			priv->check_color2 = COLOR_GRAY_33;
-			break;
-
-		case GTH_CHECK_TYPE_MIDTONE:
-			priv->check_color1 = COLOR_GRAY_66;
-			priv->check_color2 = COLOR_GRAY_99;
-			break;
-
-		case GTH_CHECK_TYPE_LIGHT:
-			priv->check_color1 = COLOR_GRAY_CC;
-			priv->check_color2 = COLOR_GRAY_FF;
-			break;
-		}
-		break;
-	}
 }
 
 
@@ -2518,13 +2134,22 @@
 				   gboolean     set_black)
 {
 	ImageViewerPrivate *priv;
+	GtkWidget          *widget;
 
 	g_return_if_fail (IS_IMAGE_VIEWER (viewer));
 
-	priv = IMAGE_VIEWER_GET_PRIVATE (viewer);
+	priv   = IMAGE_VIEWER_GET_PRIVATE (viewer);
+	widget = GTK_WIDGET (viewer);
 
 	priv->black_bg = set_black;
-	gtk_widget_queue_draw (GTK_WIDGET (viewer));
+
+	if (set_black) {
+		gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &widget->style->black);
+	} else {
+		gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, NULL);
+	}
+
+	gtk_widget_queue_draw (widget);
 }
 
 

Modified: trunk/libgthumb/nav-window.c
==============================================================================
--- trunk/libgthumb/nav-window.c	(original)
+++ trunk/libgthumb/nav-window.c	Thu Jul 31 17:49:56 2008
@@ -174,8 +174,8 @@
 	nav_win->sqr_height = MIN (nav_win->sqr_height, popup_height); 
 
 	gth_iviewer_get_scroll_offset (viewer, &x_offset, &y_offset);
-	nav_win->sqr_x = x_offset * factor;
-	nav_win->sqr_y = y_offset * factor;
+	nav_win->sqr_x = x_offset * factor + popup_width / 2;
+	nav_win->sqr_y = y_offset * factor + popup_width / 2;
 
 	/* Popup window position. */
 
@@ -267,8 +267,8 @@
 		my = (int) y;
 		nav_window_draw_sqr (nav_win, TRUE, mx, my);
 
-		mx = (int) (x / nav_win->factor);
-		my = (int) (y / nav_win->factor);
+		mx = (int) ((x - nav_win->popup_width  / 2) / nav_win->factor);
+		my = (int) ((y - nav_win->popup_height / 2) / nav_win->factor);
 		gth_iviewer_scroll_to (viewer, mx, my);
 
 		return TRUE;

Modified: trunk/src/gth-fullscreen.c
==============================================================================
--- trunk/src/gth-fullscreen.c	(original)
+++ trunk/src/gth-fullscreen.c	Thu Jul 31 17:49:56 2008
@@ -1281,15 +1281,6 @@
 }
 
 
-static gboolean
-fs_repainted_cb (GtkWidget     *widget,
-		 GthFullscreen *fullscreen)
-{
-	fullscreen->priv->comment_visible = FALSE;
-	return TRUE;
-}
-
-
 static int
 image_button_release_cb (GtkWidget      *widget,
 			 GdkEventButton *event,
@@ -1630,10 +1621,6 @@
 				"expose_event",
 				G_CALLBACK (fs_expose_event_cb),
 				fullscreen);
-	g_signal_connect_after (G_OBJECT (priv->viewer),
-				"repainted",
-				G_CALLBACK (fs_repainted_cb),
-				fullscreen);
 	g_signal_connect_swapped (G_OBJECT (priv->viewer),
 				  "clicked",
 				  G_CALLBACK (load_next_image),



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