Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 83 additions & 39 deletions zathura/adjustment.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* SPDX-License-Identifier: Zlib */

#include "adjustment.h"
#include "utils.h"
#include "document-widget.h"
#include "zathura.h"

#include <math.h>

Expand All @@ -11,8 +12,6 @@ double page_calc_height_width(zathura_document_t* document, double height, doubl

double scale = zathura_document_get_scale(document);

// TODO this just set all pages to the maximum.
// needs to adjust cell size based on the page size itself.
if (rotate == true && zathura_document_get_rotation(document) % 180 != 0) {
*page_width = round(height * scale);
*page_height = round(width * scale);
Expand Down Expand Up @@ -45,32 +44,44 @@ void page_calc_position(zathura_document_t* document, double x, double y, double
}
}

unsigned int position_to_page_number(zathura_document_t* document, double pos_x, double pos_y) {
unsigned int position_to_page_number(zathura_t* zathura, double pos_x, double pos_y) {
g_return_val_if_fail(zathura != NULL, 0);

zathura_document_t* document = zathura_get_document(zathura);
g_return_val_if_fail(document != NULL, 0);

ZathuraDocument* doc_widget = ZATHURA_DOCUMENT(zathura->ui.document_widget);

unsigned int doc_width, doc_height;
zathura_document_get_document_size(document, &doc_height, &doc_width);

unsigned int cell_width, cell_height;
zathura_document_get_cell_size(document, &cell_height, &cell_width);

zathura_document_widget_get_document_size(doc_widget, &doc_height, &doc_width);

unsigned int c0 = zathura_document_get_first_page_column(document);
unsigned int npag = zathura_document_get_number_of_pages(document);
unsigned int ncol = zathura_document_get_pages_per_row(document);
unsigned int nrow = 0;
unsigned int v_padding = zathura_document_get_page_v_padding(document);
unsigned int h_padding = zathura_document_get_page_h_padding(document);

if (c0 == 1) {
/* There is no offset, so this is easy. */
nrow = (npag + ncol - 1) / ncol;
} else {
/* If there is a offset, we handle the first row extra. */
nrow = 1 + (npag - (ncol - c0 - 1) + (ncol - 1)) / ncol;
unsigned int nrow = (npag + c0 - 1 + ncol - 1) / ncol;

// This could be done using binary search if linear is too slow
unsigned int row = 0;
for (unsigned int i = 0; i < nrow; i++) {
unsigned int row_pos, row_height;
zathura_document_widget_get_row(doc_widget, i, &row_pos, &row_height);

if (pos_y * doc_height <= row_pos + row_height) {
row = i;
break;
}
}

unsigned int col = floor(pos_x * (double)doc_width / (double)(cell_width + h_padding));
unsigned int row = floor(pos_y * (double)doc_height / (double)(cell_height + v_padding));
unsigned int col = 0;
for (unsigned int i = 0; i < ncol; i++) {
unsigned int col_pos, col_width;
zathura_document_widget_get_col(doc_widget, i, &col_pos, &col_width);

if (pos_x * doc_width <= col_pos + col_width) {
col = i;
break;
}
}

unsigned int page = ncol * (row % nrow) + (col % ncol);
if (page < c0 - 1) {
Expand All @@ -80,26 +91,28 @@ unsigned int position_to_page_number(zathura_document_t* document, double pos_x,
}
}

void page_number_to_position(zathura_document_t* document, unsigned int page_number, double xalign, double yalign,
void page_number_to_position(zathura_t* zathura, unsigned int page_number, double xalign, double yalign,
double* pos_x, double* pos_y) {
g_return_if_fail(document != NULL);
g_return_if_fail(zathura != NULL);

unsigned int c0 = zathura_document_get_first_page_column(document);
unsigned int ncol = zathura_document_get_pages_per_row(document);
zathura_document_t* document = zathura_get_document(zathura);
g_return_if_fail(document != NULL);

/* row and column for page_number indexed from 0 */
unsigned int row = (page_number + c0 - 1) / ncol;
unsigned int col = (page_number + c0 - 1) % ncol;

/* sizes of page cell, viewport and document */
unsigned int cell_height = 0, cell_width = 0;
zathura_document_get_cell_size(document, &cell_height, &cell_width);
zathura_document_widget_get_cell_size(ZATHURA_DOCUMENT(zathura->ui.document_widget), page_number,
&cell_height, &cell_width);

unsigned int cell_pos_x = 0, cell_pos_y = 0;
zathura_document_widget_get_cell_pos(ZATHURA_DOCUMENT(zathura->ui.document_widget), page_number,
&cell_pos_x, &cell_pos_y);

unsigned int view_height = 0, view_width = 0;
zathura_document_get_viewport_size(document, &view_height, &view_width);

unsigned int doc_height = 0, doc_width = 0;
zathura_document_get_document_size(document, &doc_height, &doc_width);
zathura_document_widget_get_document_size(ZATHURA_DOCUMENT(zathura->ui.document_widget), &doc_height, &doc_width);

/* compute the shift to align to the viewport. If the page fits to viewport, just center it. */
double shift_x = 0.5, shift_y = 0.5;
Expand All @@ -111,15 +124,15 @@ void page_number_to_position(zathura_document_t* document, unsigned int page_num
shift_y = 0.5 + (yalign - 0.5) * ((double)cell_height - (double)view_height) / (double)cell_height;
}

const unsigned int v_padding = zathura_document_get_page_v_padding(document);
const unsigned int h_padding = zathura_document_get_page_h_padding(document);

/* compute the position */
*pos_x = ((double)col * (cell_width + h_padding) + shift_x * cell_width) / (double) doc_width;
*pos_y = ((double)row * (cell_height + v_padding) + shift_y * cell_height) / (double) doc_height;
*pos_x = ((double)cell_pos_x + shift_x * cell_width) / (double) doc_width;
*pos_y = ((double)cell_pos_y + shift_y * cell_height) / (double) doc_height;
}

bool page_is_visible(zathura_document_t* document, unsigned int page_number) {
bool page_is_visible(zathura_t* zathura, unsigned int page_number) {
g_return_val_if_fail(zathura != NULL, false);
zathura_document_t* document = zathura_get_document(zathura);

g_return_val_if_fail(document != NULL, false);

/* position at the center of the viewport */
Expand All @@ -128,17 +141,48 @@ bool page_is_visible(zathura_document_t* document, unsigned int page_number) {

/* get the center of page page_number */
double page_x, page_y;
page_number_to_position(document, page_number, 0.5, 0.5, &page_x, &page_y);
page_number_to_position(zathura, page_number, 0.5, 0.5, &page_x, &page_y);

unsigned int cell_width, cell_height;
zathura_document_get_cell_size(document, &cell_height, &cell_width);
zathura_document_widget_get_cell_size(ZATHURA_DOCUMENT(zathura->ui.document_widget), page_number,
&cell_height, &cell_width);

unsigned int doc_width, doc_height;
zathura_document_get_document_size(document, &doc_height, &doc_width);
zathura_document_widget_get_document_size(ZATHURA_DOCUMENT(zathura->ui.document_widget), &doc_height, &doc_width);

unsigned int view_width, view_height;
zathura_document_get_viewport_size(document, &view_height, &view_width);

return (fabs(pos_x - page_x) < 0.5 * (double)(view_width + cell_width) / (double)doc_width &&
fabs(pos_y - page_y) < 0.5 * (double)(view_height + cell_height) / (double)doc_height);
}

gdouble zathura_adjustment_get_ratio(GtkAdjustment* adjustment) {
gdouble lower = gtk_adjustment_get_lower(adjustment);
gdouble upper = gtk_adjustment_get_upper(adjustment);
gdouble page_size = gtk_adjustment_get_page_size(adjustment);
gdouble value = gtk_adjustment_get_value(adjustment);

return (value - lower + page_size / 2.0) / (upper - lower);
}

void zathura_adjustment_set_value(GtkAdjustment* adjustment, gdouble value) {
const gdouble lower = gtk_adjustment_get_lower(adjustment);
const gdouble upper_m_size = gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size(adjustment);

gtk_adjustment_set_value(adjustment, MAX(lower, MIN(upper_m_size, value)));
}

void zathura_adjustment_set_value_from_ratio(GtkAdjustment* adjustment, gdouble ratio) {
if (ratio == 0.0) {
return;
}

gdouble lower = gtk_adjustment_get_lower(adjustment);
gdouble upper = gtk_adjustment_get_upper(adjustment);
gdouble page_size = gtk_adjustment_get_page_size(adjustment);

gdouble value = (upper - lower) * ratio + lower - page_size / 2.0;

zathura_adjustment_set_value(adjustment, value);
}
16 changes: 10 additions & 6 deletions zathura/adjustment.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ void page_calc_position(zathura_document_t* document, double x, double y, double
/**
* Converts a relative position within the document to a page number.
*
* @param document The document
* @param zathura The zathura instance
* @param pos_x the x position relative to the document
* @param pos_y the y position relative to the document
* @return page sitting in that position
*/
unsigned int position_to_page_number(zathura_document_t* document, double pos_x, double pos_y);
unsigned int position_to_page_number(zathura_t* zathura, double pos_x, double pos_y);

/**
* Converts a page number to a position in units relative to the document
Expand All @@ -55,23 +55,27 @@ unsigned int position_to_page_number(zathura_document_t* document, double pos_x,
* The return value is the position in in units relative to the document (0=top
* 1=bottom) of the point thet will lie at the center of the viewport.
*
* @param document The document
* @param zathura The zathura instance
* @param page_number the given page number
* @param xalign where to align the viewport and the page
* @param yalign where to align the viewport and the page
* @param pos_x position that will lie at the center of the viewport.
* @param pos_y position that will lie at the center of the viewport.
*/
void page_number_to_position(zathura_document_t* document, unsigned int page_number, double xalign, double yalign,
void page_number_to_position(zathura_t* zathura, unsigned int page_number, double xalign, double yalign,
double* pos_x, double* pos_y);

/**
* Checks whether a given page falls within the viewport
*
* @param document The document
* @param zathura The zathura instance
* @param page_number the page number
* @return true if the page intersects the viewport
*/
bool page_is_visible(zathura_document_t* document, unsigned int page_number);
bool page_is_visible(zathura_t* zathura, unsigned int page_number);

gdouble zathura_adjustment_get_ratio(GtkAdjustment* adjustment);
void zathura_adjustment_set_value(GtkAdjustment* adjustment, gdouble value);
void zathura_adjustment_set_value_from_ratio(GtkAdjustment* adjustment, gdouble ratio);

#endif /* ZATHURA_ADJUSTMENT_H */
40 changes: 15 additions & 25 deletions zathura/callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void update_visible_pages(zathura_t* zathura) {
GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
ZathuraPage* zathura_page_widget = ZATHURA_PAGE(page_widget);

if (page_is_visible(document, page_id) == true) {
if (page_is_visible(zathura, page_id) == true) {
/* make page visible */
if (zathura_page_get_visibility(page) == false) {
zathura_page_set_visibility(page, true);
Expand Down Expand Up @@ -98,9 +98,9 @@ void cb_view_hadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)
update_visible_pages(zathura);

zathura_document_t* document = zathura_get_document(zathura);
const double position_x = zathura_document_widget_get_ratio(zathura, adjustment, true);
const double position_x = zathura_adjustment_get_ratio(adjustment);
const double position_y = zathura_document_get_position_y(document);
unsigned int page_id = position_to_page_number(document, position_x, position_y);
unsigned int page_id = position_to_page_number(zathura, position_x, position_y);

zathura_document_set_position_x(document, position_x);
zathura_document_set_position_y(document, position_y);
Expand All @@ -124,8 +124,8 @@ void cb_view_vadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)

zathura_document_t* document = zathura_get_document(zathura);
const double position_x = zathura_document_get_position_x(document);
const double position_y = zathura_document_widget_get_ratio(zathura, adjustment, false);
const unsigned int page_id = position_to_page_number(document, position_x, position_y);
const double position_y = zathura_adjustment_get_ratio(adjustment);
const unsigned int page_id = position_to_page_number(zathura, position_x, position_y);

zathura_document_set_position_x(document, position_x);
zathura_document_set_position_y(document, position_y);
Expand Down Expand Up @@ -160,7 +160,7 @@ static void cb_view_adjustment_changed(GtkAdjustment* adjustment, zathura_t* zat
const double ratio =
width == true ? zathura_document_get_position_x(document) : zathura_document_get_position_y(document);

zathura_document_widget_set_value_from_ratio(zathura, adjustment, ratio, width);
zathura_adjustment_set_value_from_ratio(adjustment, ratio);
}

void cb_view_hadjustment_changed(GtkAdjustment* adjustment, gpointer data) {
Expand Down Expand Up @@ -205,8 +205,8 @@ void cb_refresh_view(GtkWidget* GIRARA_UNUSED(view), gpointer data) {
const double position_x = zathura_document_get_position_x(document);
const double position_y = zathura_document_get_position_y(document);

zathura_document_widget_set_value_from_ratio(zathura, vadj, position_y, false);
zathura_document_widget_set_value_from_ratio(zathura, hadj, position_x, true);
zathura_adjustment_set_value_from_ratio(vadj, position_y);
zathura_adjustment_set_value_from_ratio(hadj, position_x);

statusbar_page_number_update(zathura);
}
Expand Down Expand Up @@ -324,7 +324,13 @@ void cb_page_layout_value_changed(girara_session_t* session, const char* name, g

zathura_document_set_page_layout(zathura_get_document(zathura), page_v_padding, page_h_padding, pages_per_row,
first_page_column);
zathura_document_widget_set_mode(zathura, page_right_to_left);

g_auto(GValue) page_right_to_left_value = G_VALUE_INIT;
g_value_init(&page_right_to_left_value, G_TYPE_BOOLEAN);
g_value_set_boolean(&page_right_to_left_value, page_right_to_left);
g_object_set_property(G_OBJECT(zathura->ui.document_widget), "pages-right-to-left", &page_right_to_left_value);

zathura_document_widget_refresh_layout(ZATHURA_DOCUMENT(zathura->ui.document_widget));
}

void cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path, GtkTreeViewColumn* UNUSED(column), void* data) {
Expand Down Expand Up @@ -500,22 +506,6 @@ gboolean cb_password_dialog(GtkEntry* entry, void* data) {
return false;
}

gboolean cb_view_resized(GtkWidget* UNUSED(widget), GtkAllocation* UNUSED(allocation), zathura_t* zathura) {
if (zathura_has_document(zathura) == false) {
return false;
}

/* adjust the scale according to settings. If nothing needs to be resized,
it does not trigger the resize event.

The right viewport size is already in the document object, due to a
previous call to adjustment_changed. We don't want to use the allocation in
here, because we would have to subtract scrollbars, etc. */
adjust_view(zathura);

return false;
}

void cb_setting_recolor_change(girara_session_t* session, const char* name, girara_setting_type_t UNUSED(type),
const void* value, void* UNUSED(data)) {
g_return_if_fail(value != NULL);
Expand Down
10 changes: 0 additions & 10 deletions zathura/callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,16 +199,6 @@ void cb_file_monitor(ZathuraFileMonitor* monitor, girara_session_t* session);
*/
gboolean cb_password_dialog(GtkEntry* entry, void* dialog);

/**
* Emitted when the view has been resized
*
* @param widget View
* @param allocation Allocation
* @param zathura Zathura session
* @return true if signal has been handled successfully
*/
gboolean cb_view_resized(GtkWidget* widget, GtkAllocation* allocation, zathura_t* zathura);

/**
* Emitted when the 'recolor' setting is changed
*
Expand Down
Loading