? attachment.cgi?id=38720
? attachment.cgi?id=38922
? attachment.cgi?id=38944
? attachment.cgi?id=39274
? attachment.cgi?id=39609
Index: backend/ev-jobs.c
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-jobs.c,v
retrieving revision 1.3
diff -u -p -r1.3 ev-jobs.c
--- backend/ev-jobs.c	31 Mar 2005 15:34:34 -0000	1.3
+++ backend/ev-jobs.c	4 Apr 2005 03:56:54 -0000
@@ -211,6 +211,7 @@ ev_job_render_run (EvJobRender *job)
 	job->pixbuf = ev_document_render_pixbuf (EV_JOB (job)->document);
 	if (job->include_links)
 		job->link_mapping = ev_document_get_links (EV_JOB (job)->document);
+
 	EV_JOB (job)->finished = TRUE;
 
 	g_mutex_unlock (EV_DOC_MUTEX);
Index: backend/ev-page-cache.c
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-page-cache.c,v
retrieving revision 1.5
diff -u -p -r1.5 ev-page-cache.c
--- backend/ev-page-cache.c	1 Apr 2005 07:03:05 -0000	1.5
+++ backend/ev-page-cache.c	4 Apr 2005 03:56:54 -0000
@@ -24,6 +24,10 @@ struct _EvPageCache
 	gint uniform_width;
 	gint uniform_height;
 
+	gint max_width_page_width;
+	gint max_width_page_height;
+	gint max_height_page_width;
+	gint max_height_page_height;
 	EvPageCacheInfo *size_cache;
 };
 
@@ -94,7 +98,10 @@ _ev_page_cache_new (EvDocument *document
 	gint i;
 
 	page_cache = (EvPageCache *) g_object_new (EV_TYPE_PAGE_CACHE, NULL);
-
+	page_cache->max_width_page_width = 0;
+	page_cache->max_width_page_height = 0;
+	page_cache->max_height_page_width = 0;
+	page_cache->max_height_page_height = 0;
 	g_mutex_lock (EV_DOC_MUTEX);
 
 	/* We read page information out of the document */
@@ -111,6 +118,17 @@ _ev_page_cache_new (EvDocument *document
 		gint page_height = 0;
 
 		ev_document_get_page_size (document, i, &page_width, &page_height);
+
+		if (page_width > page_cache->max_width_page_width) {
+			page_cache->max_width_page_width = page_width;
+			page_cache->max_width_page_height = page_height;
+		}
+
+		if (page_height > page_cache->max_height_page_height) {
+			page_cache->max_height_page_width = page_width;
+			page_cache->max_height_page_height = page_height;
+		}
+
 		page_cache->page_labels[i] = ev_document_get_page_label (document, i);
 
 		if (i == 0) {
@@ -272,6 +290,35 @@ ev_page_cache_get_size (EvPageCache *pag
 		*height = (*height) * scale;
 
 }
+
+/* Note that these aren't necessarily from the same page.
+ */
+void
+ev_page_cache_get_max_width_size (EvPageCache *page_cache,
+				  gint        *width,
+				  gint        *height)
+{
+	g_return_if_fail (EV_IS_PAGE_CACHE (page_cache));
+
+	if (width)
+		*width = page_cache->max_width_page_width;
+	if (height)
+		*height = page_cache->max_width_page_height;
+}
+
+void
+ev_page_cache_get_max_height_size (EvPageCache *page_cache,
+				   gint        *width,
+				   gint        *height)
+{
+	g_return_if_fail (EV_IS_PAGE_CACHE (page_cache));
+
+	if (width)
+		*width = page_cache->max_height_page_width;
+	if (height)
+		*height = page_cache->max_height_page_height;
+}
+
 gchar *
 ev_page_cache_get_page_label (EvPageCache *page_cache,
 			      gint         page)
Index: backend/ev-page-cache.h
===================================================================
RCS file: /cvs/gnome/evince/backend/ev-page-cache.h,v
retrieving revision 1.4
diff -u -p -r1.4 ev-page-cache.h
--- backend/ev-page-cache.h	1 Apr 2005 07:03:05 -0000	1.4
+++ backend/ev-page-cache.h	4 Apr 2005 03:56:54 -0000
@@ -39,6 +39,12 @@ void           ev_page_cache_get_size   
 					       gfloat       scale,
 					       gint        *width,
 					       gint        *height);
+void           ev_page_cache_get_max_width_size (EvPageCache  *page_cache,
+						 gint         *width,
+						 gint         *height);
+void           ev_page_cache_get_max_height_size (EvPageCache  *page_cache,
+						  gint         *width,
+						  gint         *height);
 char          *ev_page_cache_get_page_label  (EvPageCache  *page_cache,
 					      gint          page);
 /* Navigation */
@@ -49,8 +55,8 @@ gboolean       ev_page_cache_set_page_la
 					       const char  *page_label);
 void           ev_page_cache_set_link         (EvPageCache *page_cache,
 					       EvLink      *link);
-gboolean       ev_page_cache_next_page        (EvPageCache *page_cache);         
-gboolean       ev_page_cache_prev_page        (EvPageCache *page_cache);         
+gboolean       ev_page_cache_next_page        (EvPageCache *page_cache);
+gboolean       ev_page_cache_prev_page        (EvPageCache *page_cache);
 
 G_END_DECLS
 
Index: shell/ev-view.c
===================================================================
RCS file: /cvs/gnome/evince/shell/ev-view.c,v
retrieving revision 1.70
diff -u -p -r1.70 ev-view.c
--- shell/ev-view.c	3 Apr 2005 00:01:47 -0000	1.70
+++ shell/ev-view.c	4 Apr 2005 03:56:55 -0000
@@ -131,12 +131,56 @@ struct _EvViewClass {
 static void ev_view_set_scroll_adjustments (EvView         *view,
 					    GtkAdjustment  *hadjustment,
 					    GtkAdjustment  *vadjustment);
+static int  get_full_width_at_scale (EvView *view, double scale);
 
 G_DEFINE_TYPE (EvView, ev_view, GTK_TYPE_WIDGET)
 
 /*** Helper functions ***/
 
 static void
+update_page_range_from_adjustments (EvView *view)
+{
+	gint x_offset;
+	int i;
+	gint start_page = 0;
+	gint end_page = -1;
+	gboolean found_page = FALSE;
+
+	if (view->document == NULL)
+		return;
+
+	x_offset = view->spacing;
+	for (i = 0; i < ev_page_cache_get_n_pages (view->page_cache); i ++) {
+		gint width, height;
+		GtkBorder border;
+
+		ev_page_cache_get_size (view->page_cache, i,
+					view->scale,
+					&width, &height);
+		ev_document_misc_get_page_border_size (width, height, &border);
+
+		if (!found_page) {
+			/* check for the start */
+			if (x_offset + width + border.left > view->hadjustment->value) {
+				start_page = i;
+				found_page = TRUE;
+			}
+		}
+		/* See if we're over the edge. */
+		if (found_page) {
+			if (x_offset > view->hadjustment->value + view->hadjustment->page_size) {
+				break;
+			}
+		}
+
+		end_page++;
+		x_offset += (width + border.left + border.right + view->spacing);
+	}
+
+	ev_pixbuf_cache_set_page_range (view->pixbuf_cache, start_page, end_page, view->scale);
+}
+
+static void
 view_update_adjustments (EvView *view)
 {
 	int old_x = view->scroll_x;
@@ -152,8 +196,10 @@ view_update_adjustments (EvView *view)
 	else
 		view->scroll_y = 0;
 
+	
 	if (GTK_WIDGET_REALIZED (view) &&
 	    (view->scroll_x != old_x || view->scroll_y != old_y)) {
+		update_page_range_from_adjustments (view);
 		gdk_window_move (view->bin_window, - view->scroll_x, - view->scroll_y);
 		gdk_window_process_updates (view->bin_window, TRUE);
 	}
@@ -288,8 +334,6 @@ ev_view_size_request (GtkWidget      *wi
 		      GtkRequisition *requisition)
 {
 	EvView *view = EV_VIEW (widget);
-	GtkBorder border;
-	gint width, height;
 
 	if (!GTK_WIDGET_REALIZED (widget))
 		return;
@@ -300,30 +344,14 @@ ev_view_size_request (GtkWidget      *wi
 		return;
 	}
 
-	ev_page_cache_get_size (view->page_cache,
-				view->current_page,
-				view->scale,
-				&width, &height);
+	/* Calculate the width */
+	requisition->height = 0;
+	requisition->width = get_full_width_at_scale (view, view->scale);
 
 	ev_pixbuf_cache_set_page_range (view->pixbuf_cache,
 					view->current_page,
 					view->current_page,
 					view->scale);
-	ev_document_misc_get_page_border_size (width, height, &border);
-
-	if (view->width >= 0) {
-		requisition->width = 0;
-	} else {
-		requisition->width = width + border.left + border.right +
-				     view->spacing * 2;
-	}
-
-	if (view->height >= 0) {
-		requisition->height = 0;
-	} else {
-		requisition->height = height + border.top + border.bottom +
-				      view->spacing * 2;
-	}
 }
 
 static void
@@ -418,6 +446,7 @@ ev_view_unrealize (GtkWidget *widget)
 	GTK_WIDGET_CLASS (ev_view_parent_class)->unrealize (widget);
 }
 
+#if 0
 static guint32
 ev_gdk_color_to_rgb (const GdkColor *color)
 {
@@ -428,6 +457,7 @@ ev_gdk_color_to_rgb (const GdkColor *col
   return result;
 }
 
+
 static void
 draw_rubberband (GtkWidget *widget, GdkWindow *window,
 		 const GdkRectangle *rect, guchar alpha)
@@ -493,29 +523,26 @@ highlight_find_results (EvView *view)
 				 &rectangle, alpha);
         }
 }
+#endif
 
-
+/* Draws one page with an upper-left corner at x/y
+ */
 static void
-expose_bin_window (GtkWidget      *widget,
-		   GdkEventExpose *event)
+expose_one_page (EvView *view,
+		 gint    x_offset,
+		 gint    y_offset,
+		 gint    page)
 {
-	EvView *view = EV_VIEW (widget);
-	GtkBorder border;
 	gint width, height;
+	GtkBorder border;
 	GdkRectangle area;
-	int x_offset, y_offset;
 	GdkPixbuf *scaled_image;
 	GdkPixbuf *current_pixbuf;
 
-	if (view->document == NULL)
-		return;
-
-	ev_view_get_offsets (view, &x_offset, &y_offset);
 	ev_page_cache_get_size (view->page_cache,
-				view->current_page,
+				page,
 				view->scale,
 				&width, &height);
-
 	ev_document_misc_get_page_border_size (width, height, &border);
 
 	/* Paint the frame */
@@ -523,15 +550,9 @@ expose_bin_window (GtkWidget      *widge
 	area.y = y_offset;
 	area.width = width + border.left + border.right;
 	area.height = height + border.top + border.bottom;
-	ev_document_misc_paint_one_page (view->bin_window, widget, &area, &border);
-
-	/* Render the document itself */
-	LOG ("Render area %d %d %d %d - Offset %d %d",
-	     event->area.x, event->area.y,
-             event->area.width, event->area.height,
-	     x_offset, y_offset);
+	ev_document_misc_paint_one_page (view->bin_window, GTK_WIDGET (view), &area, &border);
 
-	current_pixbuf = ev_pixbuf_cache_get_pixbuf (view->pixbuf_cache, view->current_page);
+	current_pixbuf = ev_pixbuf_cache_get_pixbuf (view->pixbuf_cache, page);
 
 	if (current_pixbuf == NULL)
 		scaled_image = NULL;
@@ -554,19 +575,38 @@ expose_bin_window (GtkWidget      *widge
 				 0, 0);
 		g_object_unref (scaled_image);
 	}
+}
 
-	if (EV_IS_DOCUMENT_FIND (view->document)) {
-		highlight_find_results (view);
-	}
+static void
+expose_bin_window (GtkWidget      *widget,
+		   GdkEventExpose *event)
+{
+	EvView *view = EV_VIEW (widget);
+	int i, x_offset;
 
-	if (view->has_selection) {
-		GdkRectangle rubberband;
+	if (view->document == NULL)
+		return;
 
-		doc_rect_to_view_rect (view, &view->selection, &rubberband);
-		if (rubberband.width > 0 && rubberband.height > 0) {
-			draw_rubberband (widget, view->bin_window,
-					 &rubberband, 0x40);
-		}
+	x_offset = view->spacing;
+	for (i = 0; i < ev_page_cache_get_n_pages (view->page_cache); i ++) {
+		gint width, height;
+		GtkBorder border;
+		GdkRectangle area, unused;
+
+		ev_page_cache_get_size (view->page_cache, i,
+					view->scale,
+					&width, &height);
+		ev_document_misc_get_page_border_size (width, height, &border);
+
+		area.x = x_offset;
+		area.y = view->spacing;
+		area.width = width + border.left + border.right;
+		area.height = height + border.top + border.bottom;
+		if (gdk_rectangle_intersect (&area,
+					     &event->area,
+					     &unused))
+			expose_one_page (view, x_offset, view->spacing, i);
+		x_offset +=area.width + view->spacing;
 	}
 }
 
@@ -1353,6 +1393,7 @@ static void
 job_finished_cb (EvPixbufCache *pixbuf_cache,
 		 EvView        *view)
 {
+	/* FIXME: Should queue a draw of just the visible page */
 	gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
@@ -1504,20 +1545,50 @@ ev_view_zoom_out (EvView *view)
 	ev_view_zoom (view, ZOOM_OUT_FACTOR, TRUE);
 }
 
+static int
+get_full_width_at_scale (EvView *view, double scale)
+{
+	int i;
+	gint width, height;
+	gint total_width;
+	GtkBorder border;
+
+	total_width = 0;
+	for (i = 0; i < ev_page_cache_get_n_pages (view->page_cache); i++) {
+		ev_page_cache_get_size (view->page_cache, i,
+					scale, &width, &height);
+		ev_document_misc_get_page_border_size (width, height, &border);
+		total_width += width + border.left + border.right;
+	}
+
+	total_width += view->spacing * (ev_page_cache_get_n_pages (view->page_cache) + 1);
+
+	return total_width;
+}
+
 static double
 size_to_zoom_factor (EvView *view, int width, int height)
 {
 	int doc_width, doc_height;
 	double scale, scale_w, scale_h;
+	int max_width, max_height;
 	GtkBorder border;
 
 	doc_width = doc_height = 0;
 	scale = scale_w = scale_h = 1.0;
+
 	ev_page_cache_get_size (view->page_cache,
 				view->current_page,
 				view->scale,
 				&doc_width,
 				&doc_height);
+
+	/* Quick hack to test continuous scrolling */
+	if (width == -1 && height >= 0) {
+		ev_page_cache_get_max_height_size (view->page_cache, &max_width, &max_height);
+		ev_document_misc_get_page_border_size (max_width, max_height, &border);
+		return height / (double)(max_height + border.top + border.bottom + 2*view->spacing);
+	}
 
 	/* FIXME: The border size isn't constant.  Ugh.  Still, if we have extra
 	 * space, we just cut it from the border */
Index: shell/ev-window.c
===================================================================
RCS file: /cvs/gnome/evince/shell/ev-window.c,v
retrieving revision 1.87
diff -u -p -r1.87 ev-window.c
--- shell/ev-window.c	3 Apr 2005 00:01:47 -0000	1.87
+++ shell/ev-window.c	4 Apr 2005 03:56:55 -0000
@@ -1545,7 +1545,7 @@ static void
 update_view_size (EvWindow *window)
 {
 	int width, height;
-	GtkRequisition vsb_requisition;
+	GtkRequisition sb_requisition;
 	int scrollbar_spacing;
 
 	width = window->priv->scrolled_window->allocation.width;
@@ -1554,18 +1554,20 @@ update_view_size (EvWindow *window)
 	/* the scrolled window has a GTK_SHADOW_IN */
 	width -= 2 * window->priv->view->style->xthickness;
 	height -= 2 * window->priv->view->style->ythickness;
+	gtk_widget_style_get (window->priv->scrolled_window,
+			      "scrollbar_spacing", &scrollbar_spacing,
+			      NULL);
 
 	if (window->priv->sizing_mode == EV_SIZING_BEST_FIT) {
+		gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->priv->scrolled_window)->hscrollbar,
+					 &sb_requisition);
 		ev_view_set_size (EV_VIEW (window->priv->view),
-				  MAX (1, width), MAX (1, height));
+				  -1, height - sb_requisition.height - scrollbar_spacing);
 	} else if (window->priv->sizing_mode == EV_SIZING_FIT_WIDTH) {
 		gtk_widget_size_request (GTK_SCROLLED_WINDOW (window->priv->scrolled_window)->vscrollbar,
-					 &vsb_requisition);
-		gtk_widget_style_get (window->priv->scrolled_window,
-				      "scrollbar_spacing", &scrollbar_spacing,
-				      NULL);
+					 &sb_requisition);
 		ev_view_set_size (EV_VIEW (window->priv->view),
-				  width - vsb_requisition.width - scrollbar_spacing, -1);
+				  width - sb_requisition.width - scrollbar_spacing, -1);
 	}
 }
 
@@ -1596,7 +1598,7 @@ ev_window_set_sizing_mode (EvWindow     
 	switch (sizing_mode) {
 	case EV_SIZING_BEST_FIT:
 		g_object_set (G_OBJECT (scrolled_window),
-			      "hscrollbar-policy", GTK_POLICY_NEVER,
+			      "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
 			      "vscrollbar-policy", GTK_POLICY_NEVER,
 			      NULL);
 		g_signal_connect (scrolled_window, "size-allocate",
@@ -2419,6 +2421,6 @@ ev_window_init (EvWindow *ev_window)
 
 	/* Set it to something random to force a change */
 	ev_window->priv->sizing_mode = EV_SIZING_FREE;
-	ev_window_set_sizing_mode (ev_window,  EV_SIZING_FIT_WIDTH);
+	ev_window_set_sizing_mode (ev_window,  EV_SIZING_BEST_FIT);
 	update_action_sensitivity (ev_window);
 }
