+ for (i = dual_even_left; i < n_pages + 2; i += 2) {
+ if (uniform) {
+ uniform_height = swap ? u_width : u_height;
+ cache->dual_height_to_page[i] = ((i + dual_even_left) / 2) * uniform_height;
+ if (i + 1 < n_pages + 2)
+ cache->dual_height_to_page[i + 1] = ((i + dual_even_left) / 2) * uniform_height;
+ } else {
+ if (i + 1 < n_pages) {
+ gdouble w, h;
+
+ ev_document_get_page_size (document, i + 1, &w, &h);
+ next_page_height = swap ? w : h;
+ } else {
+ next_page_height = 0;
+ }
+
+ if (i < n_pages) {
+ gdouble w, h;
+
+ ev_document_get_page_size (document, i, &w, &h);
+ page_height = swap ? w : h;
+ } else {
+ page_height = 0;
+ }
+
+ if (i + 1 < n_pages + 2) {
+ cache->dual_height_to_page[i] = saved_height;
+ cache->dual_height_to_page[i + 1] = saved_height;
+ saved_height += MAX(page_height, next_page_height);
+ } else {
+ cache->dual_height_to_page[i] = saved_height;
+ }
+ }
+ }
+}
+
+static void
+ev_height_to_page_cache_get_height (EvHeightToPageCache *cache,
+ EvDocument *document,
+ gint page,
+ gint rotation,
+ gdouble *height,
+ gdouble *dual_height)
+{
+ if (cache->rotation != rotation)
+ build_height_to_page (cache, document, rotation);
+
+ *height = cache->height_to_page[page];
+ *dual_height = cache->dual_height_to_page[page];
+}
+
+static void
+ev_height_to_page_cache_free (EvHeightToPageCache *cache)
+{
+ if (cache->height_to_page) {
+ g_free (cache->height_to_page);
+ cache->height_to_page = NULL;
+ }
+
+ if (cache->dual_height_to_page) {
+ g_free (cache->dual_height_to_page);
+ cache->dual_height_to_page = NULL;
+ }
+ g_free (cache);
+}
+
+static EvHeightToPageCache *
+ev_view_get_height_to_page_cache (EvView *view)
+{
+ EvHeightToPageCache *cache;
+
+ if (!view->document)
+ return NULL;
+
+ cache = g_object_get_data (G_OBJECT (view->document), EV_HEIGHT_TO_PAGE_CACHE_KEY);
+ if (!cache) {
+ cache = g_new0 (EvHeightToPageCache, 1);
+ build_height_to_page (cache, view->document, view->rotation);
+ g_object_set_data_full (G_OBJECT (view->document),
+ EV_HEIGHT_TO_PAGE_CACHE_KEY,
+ cache,
+ (GDestroyNotify)ev_height_to_page_cache_free);
+ }
+
+ return cache;
+}
+
+static void
+ev_view_get_height_to_page (EvView *view,
+ gint page,
+ gint *height,
+ gint *dual_height)
+{
+ gdouble h, dh;
+
+ if (!view->height_to_page_cache)
+ return;
+
+ ev_height_to_page_cache_get_height (view->height_to_page_cache,
+ view->document,
+ page,
+ view->rotation,
+ &h, &dh);
+ if (height)
+ *height = (gint)(h * view->scale + 0.5);
+
+ if (dual_height)
+ *dual_height = (gint)(dh * view->scale + 0.5);
+}
+
+static gint
+ev_view_get_scrollbar_size (EvView *view,
+ GtkOrientation orientation)
+{
+ GtkWidget *widget = GTK_WIDGET (view);
+ GtkWidget *sb;
+ GtkWidget *swindow = gtk_widget_get_parent (GTK_WIDGET (view));
+ GtkRequisition req;
+ gint spacing;
+
+ if (!GTK_IS_SCROLLED_WINDOW (swindow))
+ return 0;