Separating the bisection code a little bit more from the jump list is
properly a code idea. I took the opportunity to rewrite it a little bit
and came up with the attached patch. What do you think of it?
* It moves some state to zathura_t: start and end denote the range that
is bisected. last_jump is used to determine if this is a new
bisection or if one is continued.
* sc_bisect now determines first if we continue or start a bisection.
If it's a new bisection, it gets the previous two jump list entries
to determine the bounds.
* Then it calculates the new position based on the current page and the
bisection range.
I have tried a few bisection sequences and probably broke some cases
that I didn't think of, so I appreciate feedback. Also, the code to
detect the start of a new bisect run is a bit hacky and could use some
improvement.
Cheers
--
Sebastian Ramacher
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;
- } else {
- return false;
- }
+ 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;
- cur_page = zathura_document_get_current_page_number(zathura->document);
+ /* check if we have previous jumps */
+ if (zathura_jumplist_has_previous(zathura) == true) {
+ zathura_jumplist_backward(zathura);
+ jump = zathura_jumplist_current(zathura);
- 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;
- }
+ unsigned int prev_page = 0;
+ unsigned int prev_page2 = num_pages - 1;
+ if (jump != NULL) {
+ prev_page = jump->page;
+ }
- 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;
+ 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;
+ }
+ }
}
- zathura_jumplist_forward(zathura);
}
- zathura_jumplist_forward(zathura);
+ } else {
+ return false;
+ }
+
+ 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..18d3132 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; /**< */
+ unsigned int start; /**< Bisection range - start */
+ unsigned int end; /**< Bisection range - end */
+ } bisect;
};
/**
_______________________________________________
zathura mailing list
[email protected]
http://lists.pwmt.org/mailman/listinfo/zathura