Decouple bisect from jumplist

Move some bisect state to zathura_t and manipulate the jumplist that much.

Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
Sebastian Ramacher 2013-07-07 00:03:52 +02:00
parent a0c8f4c4ce
commit 65da0ffa50
2 changed files with 125 additions and 85 deletions

View file

@ -19,6 +19,14 @@
#include "page-widget.h" #include "page-widget.h"
#include "adjustment.h" #include "adjustment.h"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
/* Helper function; see sc_display_link and sc_follow. */ /* Helper function; see sc_display_link and sc_follow. */
static bool static bool
draw_links(zathura_t* zathura) draw_links(zathura_t* zathura)
@ -786,123 +794,146 @@ sc_bisect(girara_session_t* session, girara_argument_t* argument,
g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(argument != NULL, false);
g_return_val_if_fail(zathura->document != NULL, false); g_return_val_if_fail(zathura->document != NULL, false);
unsigned int number_of_pages, cur_page, prev_page, prev2_page; const unsigned int num_pages = zathura_document_get_number_of_pages(zathura->document);
bool have_prev, have_prev2; const unsigned int cur_page = zathura_document_get_current_page_number(zathura->document);
zathura_jump_t* prev_jump = NULL;
zathura_jump_t* prev2_jump = NULL;
number_of_pages= zathura_document_get_number_of_pages(zathura->document);
cur_page = zathura_document_get_current_page_number(zathura->document);
prev_page = prev2_page = 0;
have_prev = have_prev2 = false;
/* process arguments */ /* process arguments */
int direction; int direction;
if (t > 0 && t <= number_of_pages) { if (t > 0 && t <= num_pages) {
/* jump to page t, and bisect between cur_page and t */ /* bisect between cur_page and t */
zathura_jumplist_add(zathura); t -= 1;
page_set(zathura, t-1); if (t == cur_page) {
zathura_jumplist_add(zathura); /* nothing to do */
if (t-1 > cur_page) { return false;
}
else if (t > cur_page) {
zathura->bisect.start = cur_page;
zathura->bisect.end = t;
direction = BACKWARD; direction = BACKWARD;
} else { } else {
zathura->bisect.start = t;
zathura->bisect.end = cur_page;
direction = FORWARD; direction = FORWARD;
} }
} else if (argument != NULL) { } else if (argument != NULL) {
direction = argument->n; direction = argument->n;
zathura_jump_t* jump = zathura_jumplist_current(zathura);
if (jump == NULL) {
girara_debug("bisecting between first and last page because there are no jumps");
zathura->bisect.start = 0;
zathura->bisect.end = num_pages - 1;
} else {
if (jump->page != cur_page || jump->page != zathura->bisect.last_jump) {
girara_debug("last jump doesn't match up, starting new bisecting");
zathura->bisect.start = 0;
zathura->bisect.end = num_pages - 1;
/* check if we have previous jumps */
if (zathura_jumplist_has_previous(zathura) == true) {
zathura_jumplist_backward(zathura);
jump = zathura_jumplist_current(zathura);
unsigned int prev_page = 0;
unsigned int prev_page2 = num_pages - 1;
if (jump != NULL) {
prev_page = jump->page;
}
prev_page2 = prev_page;
if (zathura_jumplist_has_previous(zathura) == true) {
zathura_jumplist_backward(zathura);
jump = zathura_jumplist_current(zathura);
if (jump != NULL) {
prev_page2 = jump->page;
}
zathura_jumplist_forward(zathura);
}
zathura_jumplist_forward(zathura);
if (prev_page == prev_page2) {
if (prev_page > cur_page) {
zathura->bisect.end = prev_page;
} else {
zathura->bisect.start = prev_page;
}
} else {
zathura->bisect.start = MIN(prev_page, prev_page2);
zathura->bisect.end = MAX(prev_page, prev_page2);
}
}
/* some sanity checks on new bounds */
if (cur_page < zathura->bisect.start) {
if (direction == FORWARD) {
zathura->bisect.start = cur_page;
} else {
zathura->bisect.start = cur_page;
zathura->bisect.end = 0;
}
} else if (cur_page > zathura->bisect.end) {
if (direction == BACKWARD) {
zathura->bisect.end = cur_page;
} else {
zathura->bisect.start = cur_page;
zathura->bisect.end = num_pages - 1;
}
}
}
}
} else { } else {
return false; return false;
} }
cur_page = zathura_document_get_current_page_number(zathura->document); girara_debug("bisecting between %d and %d, at %d", zathura->bisect.start, zathura->bisect.end, cur_page);
if (zathura->bisect.start == zathura->bisect.end) {
if (zathura_jumplist_has_previous(zathura)) { /* nothing to do */
/* If there is a previous jump, get its page */ return false;
zathura_jumplist_backward(zathura);
prev_jump = zathura_jumplist_current(zathura);
if (prev_jump) {
prev_page = prev_jump->page;
have_prev = true;
}
if (zathura_jumplist_has_previous(zathura)) {
/* If there is a second previous jump, get its page. */
zathura_jumplist_backward(zathura);
prev2_jump = zathura_jumplist_current(zathura);
if (prev2_jump) {
prev2_page = prev2_jump->page;
have_prev2 = true;
}
zathura_jumplist_forward(zathura);
}
zathura_jumplist_forward(zathura);
} }
/* now, we are back at the initial jump. prev_page and prev2_page contain /* now, we are back at the initial jump. prev_page and prev2_page contain
the pages for previous and second previous jump if they exist. */ the pages for previous and second previous jump if they exist. */
unsigned int next_page = cur_page;
unsigned int next_start = zathura->bisect.start;
unsigned int next_end = zathura->bisect.end;
/* bisect */ /* bisect */
switch(direction) { switch(direction) {
case FORWARD: case FORWARD:
if (have_prev && cur_page <= prev_page) { if (cur_page != zathura->bisect.end) {
/* add a new jump point */ next_page = (cur_page + zathura->bisect.end) / 2;
if (cur_page < prev_page) { if (next_page == cur_page) {
zathura_jumplist_add(zathura); ++next_page;
page_set(zathura, (cur_page + prev_page)/2);
zathura_jumplist_add(zathura);
} }
next_start = cur_page;
} else if (have_prev2 && cur_page <= prev2_page) {
/* save current position at previous jump point */
if (cur_page < prev2_page) {
zathura_jumplist_backward(zathura);
zathura_jumplist_add(zathura);
zathura_jumplist_forward(zathura);
page_set(zathura, (cur_page + prev2_page)/2);
zathura_jumplist_add(zathura);
}
} else {
/* none of prev_page or prev2_page comes after cur_page */
zathura_jumplist_add(zathura);
page_set(zathura, (cur_page + number_of_pages - 1)/2);
zathura_jumplist_add(zathura);
} }
break; break;
case BACKWARD: case BACKWARD:
if (have_prev && prev_page <= cur_page) { if (cur_page != zathura->bisect.start) {
/* add a new jump point */ next_page = (cur_page + zathura->bisect.start) / 2;
if (prev_page < cur_page) { if (next_page == cur_page) {
zathura_jumplist_add(zathura); --next_page;
page_set(zathura, (cur_page + prev_page)/2);
zathura_jumplist_add(zathura);
} }
next_end = cur_page;
} else if (have_prev2 && prev2_page <= cur_page) {
/* save current position at previous jump point */
if (prev2_page < cur_page) {
zathura_jumplist_backward(zathura);
zathura_jumplist_add(zathura);
zathura_jumplist_forward(zathura);
page_set(zathura, (cur_page + prev2_page)/2);
zathura_jumplist_add(zathura);
}
} else {
/* none of prev_page or prev2_page comes before cur_page */
zathura_jumplist_add(zathura);
page_set(zathura, cur_page/2);
zathura_jumplist_add(zathura);
} }
break; break;
} }
if (next_page == cur_page) {
/* nothing to do */
return false;
}
girara_debug("bisecting between %d and %d, jumping to %d", zathura->bisect.start, zathura->bisect.end, next_page);
zathura->bisect.last_jump = next_page;
zathura->bisect.start = next_start;
zathura->bisect.end = next_end;
page_set(zathura, next_page);
zathura_jumplist_add(zathura);
/* adjust horizontal position */ /* adjust horizontal position */
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view)); GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
cb_view_hadjustment_changed(hadjustment, zathura); cb_view_hadjustment_changed(hadjustment, zathura);

View file

@ -163,6 +163,15 @@ struct zathura_s
unsigned int size; unsigned int size;
unsigned int num_cached_pages; unsigned int num_cached_pages;
} page_cache; } page_cache;
/**
* Bisect stage
*/
struct {
unsigned int last_jump; /**< Page jumped to by bisect */
unsigned int start; /**< Bisection range - start */
unsigned int end; /**< Bisection range - end */
} bisect;
}; };
/** /**