diff --git a/shortcuts.c b/shortcuts.c index bfb4cf3..44295a3 100644 --- a/shortcuts.c +++ b/shortcuts.c @@ -19,6 +19,14 @@ #include "page-widget.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. */ static bool 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(zathura->document != NULL, false); - unsigned int number_of_pages, cur_page, prev_page, prev2_page; - bool have_prev, have_prev2; - - 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; + const unsigned int num_pages = zathura_document_get_number_of_pages(zathura->document); + const unsigned int cur_page = zathura_document_get_current_page_number(zathura->document); /* process arguments */ int direction; - if (t > 0 && t <= number_of_pages) { - /* jump to page t, and bisect between cur_page and t */ - zathura_jumplist_add(zathura); - page_set(zathura, t-1); - zathura_jumplist_add(zathura); - if (t-1 > cur_page) { + if (t > 0 && t <= num_pages) { + /* bisect between cur_page and t */ + t -= 1; + if (t == cur_page) { + /* nothing to do */ + return false; + } + else if (t > cur_page) { + zathura->bisect.start = cur_page; + zathura->bisect.end = t; direction = BACKWARD; } else { + zathura->bisect.start = t; + zathura->bisect.end = cur_page; direction = FORWARD; } - } else if (argument != NULL) { 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 { return false; } - cur_page = zathura_document_get_current_page_number(zathura->document); - - if (zathura_jumplist_has_previous(zathura)) { - /* If there is a previous jump, get its page */ - 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); + girara_debug("bisecting between %d and %d, at %d", zathura->bisect.start, zathura->bisect.end, cur_page); + if (zathura->bisect.start == zathura->bisect.end) { + /* nothing to do */ + return false; } /* 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. */ + unsigned int next_page = cur_page; + unsigned int next_start = zathura->bisect.start; + unsigned int next_end = zathura->bisect.end; + /* bisect */ switch(direction) { case FORWARD: - if (have_prev && cur_page <= prev_page) { - /* add a new jump point */ - if (cur_page < prev_page) { - zathura_jumplist_add(zathura); - page_set(zathura, (cur_page + prev_page)/2); - zathura_jumplist_add(zathura); + if (cur_page != zathura->bisect.end) { + next_page = (cur_page + zathura->bisect.end) / 2; + if (next_page == cur_page) { + ++next_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); + next_start = cur_page; } break; case BACKWARD: - if (have_prev && prev_page <= cur_page) { - /* add a new jump point */ - if (prev_page < cur_page) { - zathura_jumplist_add(zathura); - page_set(zathura, (cur_page + prev_page)/2); - zathura_jumplist_add(zathura); + if (cur_page != zathura->bisect.start) { + next_page = (cur_page + zathura->bisect.start) / 2; + if (next_page == cur_page) { + --next_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); + next_end = cur_page; } 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 */ GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view)); cb_view_hadjustment_changed(hadjustment, zathura); diff --git a/zathura.h b/zathura.h index ac22636..cafbc34 100644 --- a/zathura.h +++ b/zathura.h @@ -163,6 +163,15 @@ struct zathura_s unsigned int size; unsigned int num_cached_pages; } 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; }; /**