Merge branch 'feature/redo-page-refresh' into develop

Conflicts:
	links.c
This commit is contained in:
Sebastian Ramacher 2013-10-31 04:35:30 +01:00
commit 1241afbe89
18 changed files with 987 additions and 801 deletions

View file

@ -2,6 +2,144 @@
#include "adjustment.h"
#include "utils.h"
#include <math.h>
double
page_calc_height_width(zathura_document_t* document, double height, double width,
unsigned int* page_height, unsigned int* page_width, bool rotate)
{
g_return_val_if_fail(document != NULL && page_height != NULL && page_width != NULL, 0.0);
double scale = zathura_document_get_scale(document);
double real_scale;
if (rotate && zathura_document_get_rotation(document) % 180) {
*page_width = round(height * scale);
*page_height = round(width * scale);
real_scale = MAX(*page_width / height, *page_height / width);
} else {
*page_width = round(width * scale);
*page_height = round(height * scale);
real_scale = MAX(*page_width / width, *page_height / height);
}
return real_scale;
}
void
page_calc_position(zathura_document_t* document, double x, double y,
double *xn, double *yn) {
g_return_if_fail(document != NULL && xn != NULL && yn != NULL);
unsigned int rot = zathura_document_get_rotation(document);
if (rot == 90) {
*xn = 1 - y;
*yn = x;
}else if (rot == 180) {
*xn = 1 - x;
*yn = 1 - y;
} else if (rot == 270) {
*xn = y;
*yn = 1 - x;
} else {
*xn = x;
*yn = y;
}
}
unsigned int
position_to_page_number(zathura_document_t* document,
double pos_x, double pos_y){
g_return_val_if_fail(document != NULL, 0);
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);
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 = (npag + c0 - 1 + ncol - 1) / ncol; /* number of rows */
unsigned int pad = zathura_document_get_page_padding(document);
unsigned int col = floor(pos_x * (double)doc_width / (double)(cell_width + pad));
unsigned int row = floor(pos_y * (double)doc_height / (double)(cell_height + pad));
return ncol * (row % nrow) + (col % ncol) - (c0 - 1);
}
void
page_number_to_position(zathura_document_t* document, unsigned int page_number,
double xalign, double yalign, double *pos_x, double *pos_y) {
g_return_if_fail(document != NULL);
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 = (npag + c0 - 1 + ncol - 1) / ncol; /* number of rows */
/* 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);
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);
/* 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;
if (cell_width > view_width) {
shift_x = 0.5 + (xalign - 0.5) * ((double)cell_width - (double)view_width) / (double)cell_width;
}
if (cell_height > view_height) {
shift_y = 0.5 + (yalign - 0.5) * ((double)cell_height - (double)view_height) / (double)cell_height;
}
/* compute the position */
*pos_x = ((double)col + shift_x) / (double)ncol;
*pos_y = ((double)row + shift_y) / (double)nrow;
}
bool
page_is_visible(zathura_document_t *document, unsigned int page_number) {
g_return_val_if_fail(document != NULL, false);
/* position at the center of the viewport */
double pos_x = zathura_document_get_position_x(document);
double pos_y = zathura_document_get_position_y(document);
/* 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);
unsigned int cell_width, cell_height;
zathura_document_get_cell_size(document, &cell_height, &cell_width);
unsigned int doc_width, doc_height;
zathura_document_get_document_size(document, &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);
}
GtkAdjustment*
zathura_adjustment_clone(GtkAdjustment* adjustment)

View file

@ -4,8 +4,73 @@
#define ZATHURA_ADJUSTMENT_H
#include <gtk/gtk.h>
#include <stdbool.h>
#include "document.h"
/* Clone a GtkAdjustment
/**
* Calculate the page size according to the corrent scaling and rotation if
* desired.
*
* @param document the document
* @param height width the original height and width
* @return page_height page_width the scaled and rotated height and width
* @param rotate honor page's rotation
* @return real scale after rounding
*/
double page_calc_height_width(zathura_document_t* document, double height, double width,
unsigned int* page_height, unsigned int* page_width, bool rotate);
/**
* Calculate a page relative position after a rotation. The positions x y are
* relative to a page, i.e. 0=top of page, 1=bottom of page. They are NOT
* relative to the entire document.
*
* @param document the document
* @param x y the x y coordinates on the unrotated page
* @param xn yn the x y coordinates after rotation
*/
void page_calc_position(zathura_document_t* document, double x, double y,
double *xn, double *yn);
/**
* Converts a relative position within the document to a page number.
*
* @param document The document
* @param pos_x pos_y the 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);
/**
* Converts a page number to a position in units relative to the document
*
* We can specify where to aliwn the viewport and the page. For instance, xalign
* = 0 means align them on the left margin, xalign = 0.5 means centered, and
* xalign = 1.0 align them on the right margin.
*
* 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 page_number the given page number
* @param xalign yalign where to align the viewport and the page
* @return pos_x 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, double *pos_x, double *pos_y);
/**
* Checks whether a given page falls within the viewport
*
* @param document The document
* @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);
/**
* Clone a GtkAdjustment
*
* Creates a new adjustment with the same value, lower and upper bounds, step
* and page increments and page_size as the original adjustment.

View file

@ -25,14 +25,14 @@ zathura_bookmark_add(zathura_t* zathura, const gchar* id, unsigned int page)
g_return_val_if_fail(zathura && zathura->document && zathura->bookmarks.bookmarks, NULL);
g_return_val_if_fail(id, NULL);
double x = zathura_adjustment_get_ratio(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
double y = zathura_adjustment_get_ratio(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
double position_x = zathura_document_get_position_x(zathura->document);
double position_y = zathura_document_get_position_y(zathura->document);
zathura_bookmark_t* old = zathura_bookmark_get(zathura, id);
if (old != NULL) {
old->page = page;
old->x = x;
old->y = y;
old->x = position_x;
old->y = position_y;
if (zathura->database != NULL) {
const char* path = zathura_document_get_path(zathura->document);
@ -52,8 +52,8 @@ zathura_bookmark_add(zathura_t* zathura, const gchar* id, unsigned int page)
bookmark->id = g_strdup(id);
bookmark->page = page;
bookmark->x = x;
bookmark->y = y;
bookmark->x = position_x;
bookmark->y = position_y;
girara_list_append(zathura->bookmarks.bookmarks, bookmark);
if (zathura->database != NULL) {

View file

@ -8,6 +8,7 @@
#include <gtk/gtk.h>
#include <string.h>
#include <glib/gi18n.h>
#include <math.h>
#include "callbacks.h"
#include "links.h"
@ -48,78 +49,89 @@ cb_buffer_changed(girara_session_t* session)
}
}
void
cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpointer data)
{
zathura_t* zathura = data;
if (zathura == NULL || zathura->document == NULL || zathura->ui.page_widget == NULL) {
return;
}
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
/* current adjustment values */
const GdkRectangle view_rect = {
.x = 0,
.y = 0,
.width = gtk_adjustment_get_page_size(view_hadjustment),
.height = gtk_adjustment_get_page_size(view_vadjustment)
};
int page_padding = 1;
girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
const GdkRectangle center = {
.x = (view_rect.width + 1) / 2,
.y = (view_rect.height + 1) / 2,
.width = (2 * page_padding) + 1,
.height = (2 * page_padding) + 1
};
static void
update_visible_pages(zathura_t* zathura) {
const unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
const double scale = zathura_document_get_scale(zathura->document);
bool updated = false;
/* find page that fits */
for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
GdkRectangle page_rect = {
.width = zathura_page_get_width(page) * scale,
.height = zathura_page_get_height(page) * scale
};
GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
ZathuraPage* zathura_page_widget = ZATHURA_PAGE(page_widget);
gtk_widget_translate_coordinates(page_widget, zathura->ui.session->gtk.view,
0, 0, &page_rect.x, &page_rect.y);
if (gdk_rectangle_intersect(&view_rect, &page_rect, NULL) == TRUE) {
if (page_is_visible(zathura->document, page_id) == true) {
/* make page visible */
if (zathura_page_get_visibility(page) == false) {
zathura_page_set_visibility(page, true);
zathura_page_widget_update_view_time(zathura_page_widget);
zathura_renderer_page_cache_add(zathura->sync.render_thread, zathura_page_get_index(page));
}
if (zathura->global.update_page_number == true && updated == false
&& gdk_rectangle_intersect(&center, &page_rect, NULL) == TRUE) {
zathura_document_set_current_page_number(zathura->document, page_id);
updated = true;
}
} else {
/* make page invisible */
if (zathura_page_get_visibility(page) == true) {
zathura_page_set_visibility(page, false);
/* If a page becomes invisible, abort the render request. */
zathura_page_widget_abort_render_request(zathura_page_widget);
}
/* reset current search result */
girara_list_t* results = NULL;
g_object_get(page_widget, "search-results", &results, NULL);
if (results != NULL) {
g_object_set(page_widget, "search-current", 0, NULL);
}
}
}
}
void
cb_view_hadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)
{
zathura_t* zathura = data;
if (zathura == NULL || zathura->document == NULL) {
return;
}
/* Do nothing in index mode */
if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
return;
}
update_visible_pages(zathura);
double position_x = zathura_adjustment_get_ratio(adjustment);
double position_y = zathura_document_get_position_y(zathura->document);
unsigned int page_id = position_to_page_number(zathura->document, position_x, position_y);
zathura_document_set_position_x(zathura->document, position_x);
zathura_document_set_position_y(zathura->document, position_y);
zathura_document_set_current_page_number(zathura->document, page_id);
statusbar_page_number_update(zathura);
}
void
cb_view_vadjustment_value_changed(GtkAdjustment* adjustment, gpointer data)
{
zathura_t* zathura = data;
if (zathura == NULL || zathura->document == NULL) {
return;
}
/* Do nothing in index mode */
if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
return;
}
update_visible_pages(zathura);
double position_x = zathura_document_get_position_x(zathura->document);
double position_y = zathura_adjustment_get_ratio(adjustment);
unsigned int page_id = position_to_page_number(zathura->document, position_x, position_y);
zathura_document_set_position_x(zathura->document, position_x);
zathura_document_set_position_y(zathura->document, position_y);
zathura_document_set_current_page_number(zathura->document, page_id);
statusbar_page_number_update(zathura);
}
@ -133,29 +145,23 @@ cb_view_hadjustment_changed(GtkAdjustment* adjustment, gpointer data)
zathura_adjust_mode_t adjust_mode =
zathura_document_get_adjust_mode(zathura->document);
gdouble lower, upper, page_size, value, ratio;
bool zoom_center = false;
switch (adjust_mode) {
center:
case ZATHURA_ADJUST_BESTFIT:
case ZATHURA_ADJUST_WIDTH:
lower = gtk_adjustment_get_lower(adjustment);
upper = gtk_adjustment_get_upper(adjustment);
page_size = gtk_adjustment_get_page_size(adjustment);
value = ((upper - lower) - page_size) / 2.0;
zathura_adjustment_set_value(adjustment, value);
break;
default:
girara_setting_get(zathura->ui.session, "zoom-center", &zoom_center);
if (zoom_center) {
goto center;
}
ratio = zathura_adjustment_get_ratio(zathura->ui.hadjustment);
zathura_adjustment_set_value_from_ratio(adjustment, ratio);
break;
/* Do nothing in index mode */
if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
return;
}
/* Don't scroll we're focusing the inputbar. */
if (adjust_mode == ZATHURA_ADJUST_INPUTBAR) {
return;
}
/* save the viewport size */
unsigned int view_width = (unsigned int)floor(gtk_adjustment_get_page_size(adjustment));
zathura_document_set_viewport_width(zathura->document, view_width);
/* reset the adjustment, in case bounds have changed */
double ratio = zathura_document_get_position_x(zathura->document);
zathura_adjustment_set_value_from_ratio(adjustment, ratio);
}
void
@ -167,93 +173,71 @@ cb_view_vadjustment_changed(GtkAdjustment* adjustment, gpointer data)
zathura_adjust_mode_t adjust_mode =
zathura_document_get_adjust_mode(zathura->document);
/* Do nothing in index mode */
if (girara_mode_get(zathura->ui.session) == zathura->modes.index) {
return;
}
/* Don't scroll we're focusing the inputbar. */
if (adjust_mode == ZATHURA_ADJUST_INPUTBAR) {
return;
}
double ratio = zathura_adjustment_get_ratio(zathura->ui.vadjustment);
/* save the viewport size */
unsigned int view_height = (unsigned int)floor(gtk_adjustment_get_page_size(adjustment));
zathura_document_set_viewport_height(zathura->document, view_height);
/* reset the adjustment, in case bounds have changed */
double ratio = zathura_document_get_position_y(zathura->document);
zathura_adjustment_set_value_from_ratio(adjustment, ratio);
}
void
cb_adjustment_track_value(GtkAdjustment* adjustment, gpointer data)
cb_refresh_view(GtkWidget* GIRARA_UNUSED(view), gpointer data)
{
GtkAdjustment* tracker = data;
gdouble lower = gtk_adjustment_get_lower(adjustment);
gdouble upper = gtk_adjustment_get_upper(adjustment);
if (lower != gtk_adjustment_get_lower(tracker) ||
upper != gtk_adjustment_get_upper(tracker)) {
zathura_t* zathura = data;
if (zathura == NULL || zathura->document == NULL) {
return;
}
gdouble value = gtk_adjustment_get_value(adjustment);
gtk_adjustment_set_value(tracker, value);
unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
if (page == NULL) {
return;
}
GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
GtkAdjustment* hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
double position_x = zathura_document_get_position_x(zathura->document);
double position_y = zathura_document_get_position_y(zathura->document);
zathura_adjustment_set_value_from_ratio(vadj, position_y);
zathura_adjustment_set_value_from_ratio(hadj, position_x);
statusbar_page_number_update(zathura);
}
void
cb_adjustment_track_bounds(GtkAdjustment* adjustment, gpointer data)
{
GtkAdjustment* tracker = data;
gdouble value = gtk_adjustment_get_value(adjustment);
gdouble lower = gtk_adjustment_get_lower(adjustment);
gdouble upper = gtk_adjustment_get_upper(adjustment);
gdouble page_size = gtk_adjustment_get_page_size(adjustment);
gtk_adjustment_set_value(tracker, value);
gtk_adjustment_set_lower(tracker, lower);
gtk_adjustment_set_upper(tracker, upper);
gtk_adjustment_set_page_size(tracker, page_size);
}
void
cb_pages_per_row_value_changed(girara_session_t* session, const char* UNUSED(name), girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
cb_page_layout_value_changed(girara_session_t* session, const char* UNUSED(name), girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
{
g_return_if_fail(value != NULL);
g_return_if_fail(session != NULL);
g_return_if_fail(session->global.data != NULL);
zathura_t* zathura = session->global.data;
int pages_per_row = *(int*) value;
if (pages_per_row < 1) {
pages_per_row = 1;
}
unsigned int first_page_column = 1;
girara_setting_get(session, "first-page-column", &first_page_column);
page_widget_set_mode(zathura, pages_per_row, first_page_column);
if (zathura->document != NULL) {
unsigned int current_page = zathura_document_get_current_page_number(zathura->document);
page_set_delayed(zathura, current_page);
}
}
void
cb_first_page_column_value_changed(girara_session_t* session, const char* UNUSED(name), girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
{
g_return_if_fail(value != NULL);
g_return_if_fail(session != NULL);
g_return_if_fail(session->global.data != NULL);
zathura_t* zathura = session->global.data;
int first_page_column = *(int*) value;
if (first_page_column < 1) {
first_page_column = 1;
}
unsigned int pages_per_row = 1;
girara_setting_get(session, "pages-per-row", &pages_per_row);
page_widget_set_mode(zathura, pages_per_row, first_page_column);
unsigned int first_page_column = 1;
girara_setting_get(session, "first-page-column", &first_page_column);
if (zathura->document != NULL) {
unsigned int current_page = zathura_document_get_current_page_number(zathura->document);
page_set_delayed(zathura, current_page);
}
unsigned int page_padding = 1;
girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
page_widget_set_mode(zathura, page_padding, pages_per_row, first_page_column);
zathura_document_set_page_layout(zathura->document, page_padding, pages_per_row, first_page_column);
}
void
@ -461,23 +445,19 @@ error_ret:
}
bool
cb_view_resized(GtkWidget* UNUSED(widget), GtkAllocation* allocation, zathura_t* zathura)
cb_view_resized(GtkWidget* UNUSED(widget), GtkAllocation* UNUSED(allocation), zathura_t* zathura)
{
if (zathura == NULL || zathura->document == NULL) {
return false;
}
static int height = -1;
static int width = -1;
/* adjust the scale according to settings. If nothing needs to be resized,
it does not trigger the resize event.
/* adjust only if the allocation changed */
if (width != allocation->width || height != allocation->height) {
girara_argument_t argument = { zathura_document_get_adjust_mode(zathura->document), NULL };
sc_adjust_window(zathura->ui.session, &argument, NULL, 0);
width = allocation->width;
height = allocation->height;
}
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;
}

View file

@ -27,6 +27,15 @@ gboolean cb_destroy(GtkWidget* widget, zathura_t* zathura);
*/
void cb_buffer_changed(girara_session_t* session);
/**
* This function gets called when the value of the horizontal scrollbars
* changes (e.g.: by scrolling, moving to another page)
*
* @param adjustment The hadjustment of the page view
* @param data NULL
*/
void cb_view_hadjustment_value_changed(GtkAdjustment *adjustment, gpointer data);
/**
* This function gets called when the value of the vertical scrollbars
* changes (e.g.: by scrolling, moving to another page)
@ -40,9 +49,7 @@ void cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data)
* This function gets called when the bounds or the page_size of the horizontal
* scrollbar change (e.g. when the zoom level is changed).
*
* It adjusts the value of the horizontal scrollbar, possibly based on its
* previous adjustment, stored in the tracking adjustment
* zathura->ui.hadjustment.
* It adjusts the value of the horizontal scrollbar
*
* @param adjustment The horizontal adjustment of a gtkScrolledWindow
* @param data The zathura instance
@ -61,26 +68,16 @@ void cb_view_hadjustment_changed(GtkAdjustment *adjustment, gpointer data);
*/
void cb_view_vadjustment_changed(GtkAdjustment *adjustment, gpointer data);
/* This function gets called when the value of the adjustment changes.
/**
* This function gets called when the program need to refresh the document view.
*
* It updates the value of the tracking adjustment, only if the bounds of the
* adjustment have not changed (if they did change,
* cb_adjustment_track_bounds() will take care of updating everything).
* It adjusts the value of the scrollbars, triggering a redraw in the new
* position.
*
* @param adjustment The adjustment instance
* @param data The tracking adjustment instance
* @param view The view GtkWidget
* @param data The zathura instance
*/
void cb_adjustment_track_value(GtkAdjustment* adjustment, gpointer data);
/* This function gets called when the bounds or the page_size of the adjustment
* change.
*
* It updates the value, bounds and page_size of the tracking adjustment.
*
* @param adjustment The adjustment instance
* @param data The tracking adjustment instance
*/
void cb_adjustment_track_bounds(GtkAdjustment* adjustment, gpointer data);
void cb_refresh_view(GtkWidget* view, gpointer data);
/**
* This function gets called when the value of the "pages-per-row"
@ -92,19 +89,7 @@ void cb_adjustment_track_bounds(GtkAdjustment* adjustment, gpointer data);
* @param value The value
* @param data Custom data
*/
void cb_pages_per_row_value_changed(girara_session_t* session, const char* name,
girara_setting_type_t type, void* value, void* data);
/**
* This function gets called when the value of the "first-page-column"
* variable changes
*
* @param session The current girara session
* @param name The name of the row
* @param type The settings type
* @param value The value
* @param data Custom data
*/
void cb_first_page_column_value_changed(girara_session_t* session, const char* name,
void cb_page_layout_value_changed(girara_session_t* session, const char* name,
girara_setting_type_t type, void* value, void* data);
/**

View file

@ -118,15 +118,9 @@ cmd_bookmark_open(girara_session_t* session, girara_list_t* argument_list)
}
zathura_jumplist_add(zathura);
page_set(zathura, bookmark->page - 1);
if (bookmark->x != DBL_MIN && bookmark->y != DBL_MIN) {
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
zathura_adjustment_set_value_from_ratio(hadjustment, bookmark->x);
zathura_adjustment_set_value_from_ratio(vadjustment, bookmark->y);
zathura_document_set_current_page_number(zathura->document, bookmark->page - 1);
statusbar_page_number_update(zathura);
} else {
page_set(zathura, bookmark->page - 1);
position_set(zathura, bookmark->x, bookmark->y);
}
zathura_jumplist_add(zathura);

View file

@ -73,27 +73,6 @@ cb_color_change(girara_session_t* session, const char* name,
render_all(zathura);
}
static void
cb_page_padding_changed(girara_session_t* session, const char* UNUSED(name),
girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
{
g_return_if_fail(value != NULL);
g_return_if_fail(session != NULL);
g_return_if_fail(session->global.data != NULL);
zathura_t* zathura = session->global.data;
int val = *(int*) value;
if (GTK_IS_TABLE(zathura->ui.page_widget) == TRUE) {
#if (GTK_MAJOR_VERSION == 3)
gtk_grid_set_row_spacing(GTK_GRID(zathura->ui.page_widget), val);
gtk_grid_set_column_spacing(GTK_GRID(zathura->ui.page_widget), val);
#else
gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_widget), val);
gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_widget), val);
#endif
}
}
static void
cb_nohlsearch_changed(girara_session_t* session, const char* UNUSED(name),
girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
@ -149,21 +128,21 @@ config_load_default(zathura_t* zathura)
girara_mode_set(gsession, zathura->modes.normal);
/* zathura settings */
girara_setting_add(gsession, "database", "plain", STRING, true, _("Database backend"), NULL, NULL);
girara_setting_add(gsession, "database", "plain", STRING, true, _("Database backend"), NULL, NULL);
int_value = 10;
girara_setting_add(gsession, "zoom-step", &int_value, INT, false, _("Zoom step"), NULL, NULL);
girara_setting_add(gsession, "zoom-step", &int_value, INT, false, _("Zoom step"), NULL, NULL);
int_value = 1;
girara_setting_add(gsession, "page-padding", &int_value, INT, false, _("Padding between pages"), cb_page_padding_changed, NULL);
girara_setting_add(gsession, "page-padding", &int_value, INT, false, _("Padding between pages"), cb_page_layout_value_changed, NULL);
int_value = 1;
girara_setting_add(gsession, "pages-per-row", &int_value, INT, false, _("Number of pages per row"), cb_pages_per_row_value_changed, NULL);
girara_setting_add(gsession, "pages-per-row", &int_value, INT, false, _("Number of pages per row"), cb_page_layout_value_changed, NULL);
int_value = 1;
girara_setting_add(gsession, "first-page-column", &int_value, INT, false, _("Column of the first page"),cb_first_page_column_value_changed, NULL);
girara_setting_add(gsession, "first-page-column", &int_value, INT, false, _("Column of the first page"), cb_page_layout_value_changed, NULL);
float_value = 40;
girara_setting_add(gsession, "scroll-step", &float_value, FLOAT, false, _("Scroll step"), NULL, NULL);
girara_setting_add(gsession, "scroll-step", &float_value, FLOAT, false, _("Scroll step"), NULL, NULL);
float_value = 40;
girara_setting_add(gsession, "scroll-hstep", &float_value, FLOAT, false, _("Horizontal scroll step"), NULL, NULL);
girara_setting_add(gsession, "scroll-hstep", &float_value, FLOAT, false, _("Horizontal scroll step"), NULL, NULL);
float_value = 0.0;
girara_setting_add(gsession, "scroll-full-overlap", &float_value, FLOAT, false, _("Full page scroll overlap"), NULL, NULL);
girara_setting_add(gsession, "scroll-full-overlap", &float_value, FLOAT, false, _("Full page scroll overlap"), NULL, NULL);
int_value = 10;
girara_setting_add(gsession, "zoom-min", &int_value, INT, false, _("Zoom minimum"), NULL, NULL);
int_value = 1000;
@ -175,13 +154,13 @@ config_load_default(zathura_t* zathura)
girara_setting_add(gsession, "recolor-darkcolor", "#FFFFFF", STRING, false, _("Recoloring (dark color)"), cb_color_change, NULL);
girara_setting_add(gsession, "recolor-lightcolor", "#000000", STRING, false, _("Recoloring (light color)"), cb_color_change, NULL);
girara_setting_add(gsession, "highlight-color", NULL, STRING, false, _("Color for highlighting"), cb_color_change, NULL);
girara_setting_add(gsession, "highlight-color", NULL, STRING, false, _("Color for highlighting"), cb_color_change, NULL);
girara_setting_set(gsession, "highlight-color", "#9FBC00");
girara_setting_add(gsession, "highlight-active-color", NULL, STRING, false, _("Color for highlighting (active)"), cb_color_change, NULL);
girara_setting_add(gsession, "highlight-active-color", NULL, STRING, false, _("Color for highlighting (active)"), cb_color_change, NULL);
girara_setting_set(gsession, "highlight-active-color", "#00BC00");
girara_setting_add(gsession, "render-loading-bg", NULL, STRING, false, _("'Loading ...' background color"), cb_color_change, NULL);
girara_setting_add(gsession, "render-loading-bg", NULL, STRING, false, _("'Loading ...' background color"), cb_color_change, NULL);
girara_setting_set(gsession, "render-loading-bg", "#FFFFFF");
girara_setting_add(gsession, "render-loading-fg", NULL, STRING, false, _("'Loading ...' foreground color"), cb_color_change, NULL);
girara_setting_add(gsession, "render-loading-fg", NULL, STRING, false, _("'Loading ...' foreground color"), cb_color_change, NULL);
girara_setting_set(gsession, "render-loading-fg", "#000000");
bool_value = false;

View file

@ -22,6 +22,7 @@
#include <girara/session.h>
#include <girara/settings.h>
#include "adjustment.h"
#include "document.h"
#include "utils.h"
#include "zathura.h"
@ -50,6 +51,15 @@ struct zathura_document_s {
void* data; /**< Custom data */
zathura_adjust_mode_t adjust_mode; /**< Adjust mode (best-fit, width) */
int page_offset; /**< Page offset */
double cell_width; /**< width of a page cell in the document (not ransformed by scale and rotation) */
double cell_height; /**< height of a page cell in the document (not ransformed by scale and rotation) */
unsigned int view_width; /**< width of current viewport */
unsigned int view_height; /**< height of current viewport */
unsigned int pages_per_row; /**< number of pages in a row */
unsigned int first_page_column; /**< column of the first page */
unsigned int page_padding; /**< padding between pages */
double position_x; /**< X adjustment */
double position_y; /**< Y adjustment */
/**
* Document pages
@ -124,6 +134,12 @@ zathura_document_open(zathura_plugin_manager_t* plugin_manager, const char*
document->scale = 1.0;
document->plugin = plugin;
document->adjust_mode = ZATHURA_ADJUST_NONE;
document->cell_width = 0.0;
document->cell_height = 0.0;
document->view_height = 0;
document->view_width = 0;
document->position_x = 0.0;
document->position_y = 0.0;
/* open document */
zathura_plugin_functions_t* functions = zathura_plugin_get_functions(plugin);
@ -155,6 +171,15 @@ zathura_document_open(zathura_plugin_manager_t* plugin_manager, const char*
}
document->pages[page_id] = page;
/* cell_width and cell_height is the maximum of all the pages width and height */
double width = zathura_page_get_width(page);
if (document->cell_width < width)
document->cell_width = width;
double height = zathura_page_get_height(page);
if (document->cell_height < height)
document->cell_height = height;
}
return document;
@ -310,6 +335,46 @@ zathura_document_set_current_page_number(zathura_document_t* document, unsigned
document->current_page_number = current_page;
}
double
zathura_document_get_position_x(zathura_document_t* document)
{
if (document == NULL) {
return 0;
}
return document->position_x;
}
double
zathura_document_get_position_y(zathura_document_t* document)
{
if (document == NULL) {
return 0;
}
return document->position_y;
}
void
zathura_document_set_position_x(zathura_document_t* document, double position_x)
{
if (document == NULL) {
return;
}
document->position_x = position_x;
}
void
zathura_document_set_position_y(zathura_document_t* document, double position_y)
{
if (document == NULL) {
return;
}
document->position_y = position_y;
}
double
zathura_document_get_scale(zathura_document_t* document)
{
@ -400,32 +465,99 @@ zathura_document_set_page_offset(zathura_document_t* document, unsigned int page
document->page_offset = page_offset;
}
void
zathura_document_set_viewport_width(zathura_document_t* document, unsigned int width)
{
if (document == NULL) {
return;
}
document->view_width = width;
}
void
zathura_document_set_viewport_height(zathura_document_t* document, unsigned int height)
{
if (document == NULL) {
return;
}
document->view_height = height;
}
void
zathura_document_get_viewport_size(zathura_document_t* document,
unsigned int *height, unsigned int* width)
{
g_return_if_fail(document != NULL && height != NULL && width != NULL);
*height = document->view_height;
*width = document->view_width;
}
void
zathura_document_get_cell_size(zathura_document_t* document,
unsigned int* height, unsigned int* width)
{
g_return_if_fail(document != NULL && height != NULL && width != NULL);
unsigned int number_of_pages =
zathura_document_get_number_of_pages(document);
*width = 0;
*height = 0;
page_calc_height_width(document, document->cell_height, document->cell_width,
height, width, true);
/* Get the size of each cell of the table/grid, assuming it is homogeneous
* (i.e. each cell has the same dimensions. */
for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
zathura_page_t* page = zathura_document_get_page(document, page_id);
if (page == NULL)
continue;
}
unsigned int page_width = 0, page_height = 0;
page_calc_height_width(page, &page_height, &page_width, true);
void
zathura_document_get_document_size(zathura_document_t* document,
unsigned int* height, unsigned int* width)
{
g_return_if_fail(document != NULL && height != NULL && width != NULL);
if (*width < page_width)
*width = page_width;
if (*height < page_height)
*height = page_height;
unsigned int npag = zathura_document_get_number_of_pages(document);
unsigned int ncol = zathura_document_get_pages_per_row(document);
unsigned int c0 = zathura_document_get_first_page_column(document);
unsigned int nrow = (npag + c0 - 1 + ncol - 1) / ncol; /* number of rows */
unsigned int pad = zathura_document_get_page_padding(document);
unsigned int cell_height=0, cell_width=0;
zathura_document_get_cell_size(document, &cell_height, &cell_width);
*width = ncol * cell_width + (ncol - 1) * pad;
*height = nrow * cell_height + (nrow - 1) * pad;
}
void
zathura_document_set_page_layout(zathura_document_t* document, unsigned int page_padding,
unsigned int pages_per_row, unsigned int first_page_column)
{
g_return_if_fail(document != NULL);
document->page_padding = page_padding;
document->pages_per_row = pages_per_row;
document->first_page_column = first_page_column;
}
unsigned int
zathura_document_get_page_padding(zathura_document_t* document)
{
if (document == NULL) {
return 0;
}
return document->page_padding;
}
unsigned int
zathura_document_get_pages_per_row(zathura_document_t* document)
{
if (document == NULL) {
return 0;
}
return document->pages_per_row;
}
unsigned int
zathura_document_get_first_page_column(zathura_document_t* document)
{
if (document == NULL) {
return 0;
}
return document->first_page_column;
}
zathura_error_t

View file

@ -97,6 +97,42 @@ unsigned int zathura_document_get_current_page_number(zathura_document_t* docume
void zathura_document_set_current_page_number(zathura_document_t* document, unsigned
int current_page);
/**
* Returns the X position, as a value relative to the document width (0=left,
* 1=right).
*
* @param document The document
* @return X adjustment
*/
double zathura_document_get_position_x(zathura_document_t* document);
/**
* Returns the Y position as value relative to the document height (0=top,
* 1=bottom)
*
* @param document The document
* @return Y adjustment
*/
double zathura_document_get_position_y(zathura_document_t* document);
/**
* Sets the X position as a value relative to the document width (0=left,
* 1=right)
*
* @param document The document
* @param position_x the X adjustment
*/
void zathura_document_set_position_x(zathura_document_t* document, double position_x);
/**
* Sets the Y position as a value relative to the document height (0=top,
* 1=bottom)
*
* @param document The document
* @param position_y the Y adjustment
*/
void zathura_document_set_position_y(zathura_document_t* document, double position_y);
/**
* Returns the current scale value of the document
*
@ -178,9 +214,37 @@ void* zathura_document_get_data(zathura_document_t* document);
void zathura_document_set_data(zathura_document_t* document, void* data);
/**
* Computes the size of a cell in the document's layout table, assuming that
* the table is homogeneous (i.e. every cell has the same dimensions). It takes
* the current scale into account.
* Sets the width of the viewport in pixels.
*
* @param[in] document The document instance
* @param[in] width The width of the viewport
*/
void
zathura_document_set_viewport_width(zathura_document_t* document, unsigned int width);
/**
* Sets the height of the viewport in pixels.
*
* @param[in] document The document instance
* @param[in] height The height of the viewport
*/
void
zathura_document_set_viewport_height(zathura_document_t* document, unsigned int height);
/**
* Return the size of the viewport in pixels.
*
* @param[in] document The document instance
* @param[out] height,width The width and height of the viewport
*/
void
zathura_document_get_viewport_size(zathura_document_t* document,
unsigned int *height, unsigned int* width);
/**
* Return the size of a cell from the document's layout table in pixels. Assumes
* that the table is homogeneous (i.e. every cell has the same dimensions). It
* takes the current scale into account.
*
* @param[in] document The document instance
* @param[out] height,width The computed height and width of the cell
@ -188,6 +252,52 @@ void zathura_document_set_data(zathura_document_t* document, void* data);
void zathura_document_get_cell_size(zathura_document_t* document,
unsigned int* height, unsigned int* width);
/**
* Compute the size of the entire document to be displayed in pixels. Takes into
* account the scale, the layout of the pages, and the padding between them. It
* should be equal to the allocation of zathura->ui.page_widget once it's shown.
*
* @param[in] document The document
* @param[out] height,width The height and width of the document
*/
void zathura_document_get_document_size(zathura_document_t* document,
unsigned int* height, unsigned int* width);
/**
* Sets the layout of the pages in the document
*
* @param[in] document The document instance
* @param[in] page_padding pixels of padding between pages
* @param[in] pages_per_row number of pages per row
* @param[in] first_page_column column of the first page (first column is 1)
*/
void zathura_document_set_page_layout(zathura_document_t* document, unsigned int page_padding,
unsigned int pages_per_row, unsigned int first_page_column);
/**
* Returns the padding in pixels betwen pages
*
* @param document The document
* @return The padding in pixels between pages
*/
unsigned int zathura_document_get_page_padding(zathura_document_t* document);
/**
* Returns the number of pages per row
*
* @param document The document
* @return The number of pages per row
*/
unsigned int zathura_document_get_pages_per_row(zathura_document_t* document);
/**
* Returns the column for the first page (first column = 1)
*
* @param document The document
* @return The column for the first page
*/
unsigned int zathura_document_get_first_page_column(zathura_document_t* document);
/**
* Save the document
*

57
links.c
View file

@ -6,10 +6,12 @@
#include <girara/session.h>
#include <girara/settings.h>
#include "adjustment.h"
#include "links.h"
#include "zathura.h"
#include "document.h"
#include "utils.h"
#include "page.h"
struct zathura_link_s {
zathura_rectangle_t position; /**< Position of the link */
@ -140,34 +142,51 @@ zathura_link_evaluate(zathura_t* zathura, zathura_link_t* link)
return;
}
page_offset_t offset;
page_calculate_offset(zathura, page, &offset);
/* compute the position with the page aligned to the top and left
of the viewport */
double pos_x = 0;
double pos_y = 0;
page_number_to_position(zathura->document, link->target.page_number,
0.0, 0.0, &pos_x, &pos_y);
if (link->target.destination_type == ZATHURA_LINK_DESTINATION_XYZ) {
if (link->target.left != -1) {
offset.x += link->target.left * zathura_document_get_scale(zathura->document);
}
/* correct to place the target position at the top of the viewport */
/* NOTE: link->target is in page units, needs to be scaled and rotated */
unsigned int cell_height = 0;
unsigned int cell_width = 0;
zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
if (link->target.top != -1) {
offset.y += link->target.top * zathura_document_get_scale(zathura->document);
}
}
unsigned int doc_height = 0;
unsigned int doc_width = 0;
zathura_document_get_document_size(zathura->document, &doc_height, &doc_width);
zathura_jumplist_add(zathura);
/* jump to the page */
page_set(zathura, link->target.page_number);
/* move to the target position */
bool link_hadjust = true;
girara_setting_get(zathura->ui.session, "link-hadjust", &link_hadjust);
if (link_hadjust == true) {
position_set(zathura, offset.x, offset.y);
/* scale and rotate */
double scale = zathura_document_get_scale(zathura->document);
double shiftx = link->target.left * scale / (double)cell_width;
double shifty = link->target.top * scale / (double)cell_height;
page_calc_position(zathura->document, shiftx, shifty, &shiftx, &shifty);
/* shift the position or set to auto */
if (link->target.destination_type == ZATHURA_LINK_DESTINATION_XYZ &&
link->target.left != -1 && link_hadjust == true) {
pos_x += shiftx / (double)doc_width;
} else {
position_set(zathura, -1, offset.y);
pos_x = -1; /* -1 means automatic */
}
if (link->target.destination_type == ZATHURA_LINK_DESTINATION_XYZ &&
link->target.top != -1) {
pos_y += shifty / (double)doc_height;
} else {
pos_y = -1; /* -1 means automatic */
}
/* move to position */
zathura_jumplist_add(zathura);
zathura_document_set_current_page_number(zathura->document, link->target.page_number);
position_set(zathura, pos_x, pos_y);
zathura_jumplist_add(zathura);
}
break;

23
marks.c
View file

@ -23,7 +23,8 @@ struct zathura_mark_s {
int key; /**> Marks key */
double position_x; /**> Horizontal adjustment */
double position_y; /**> Vertical adjustment */
float scale; /**> Zoom level */
unsigned int page; /**> Page number */
double scale; /**> Zoom level */
};
bool
@ -196,21 +197,16 @@ mark_add(zathura_t* zathura, int key)
return;
}
GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view);
GtkAdjustment* v_adjustment = gtk_scrolled_window_get_vadjustment(window);
GtkAdjustment* h_adjustment = gtk_scrolled_window_get_hadjustment(window);
unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
double position_x = zathura_document_get_position_x(zathura->document);
double position_y = zathura_document_get_position_y(zathura->document);
if (v_adjustment == NULL || h_adjustment == NULL) {
return;
}
double position_x = gtk_adjustment_get_value(h_adjustment);
double position_y = gtk_adjustment_get_value(v_adjustment);
float scale = zathura_document_get_scale(zathura->document);
double scale = zathura_document_get_scale(zathura->document);
/* search for existing mark */
GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark)
if (mark->key == key) {
mark->page = page_id;
mark->position_x = position_x;
mark->position_y = position_y;
mark->scale = scale;
@ -222,6 +218,7 @@ mark_add(zathura_t* zathura, int key)
zathura_mark_t* mark = g_malloc0(sizeof(zathura_mark_t));
mark->key = key;
mark->page = page_id;
mark->position_x = position_x;
mark->position_y = position_y;
mark->scale = scale;
@ -243,12 +240,10 @@ mark_evaluate(zathura_t* zathura, int key)
render_all(zathura);
zathura_jumplist_add(zathura);
page_set(zathura, mark->page);
position_set(zathura, mark->position_x, mark->position_y);
zathura_jumplist_add(zathura);
cb_view_vadjustment_value_changed(NULL, zathura);
zathura->global.update_page_number = true;
return;
}
GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark);

View file

@ -4,7 +4,9 @@
#include <girara/datastructures.h>
#include <girara/utils.h>
#include "glib-compat.h"
#include "render.h"
#include "adjustment.h"
#include "zathura.h"
#include "document.h"
#include "page.h"
@ -600,8 +602,14 @@ render(ZathuraRenderRequest* request, ZathuraRenderer* renderer)
/* create cairo surface */
unsigned int page_width = 0;
unsigned int page_height = 0;
const double real_scale = page_calc_height_width(page, &page_height,
&page_width, false);
zathura_document_t* document = zathura_page_get_document(page);
double height = zathura_page_get_height(page);
double width = zathura_page_get_width(page);
const double real_scale = page_calc_height_width(document, height, width,
&page_height, &page_width, false);
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
page_width, page_height);
@ -705,7 +713,9 @@ render_all(zathura_t* zathura)
zathura_page_t* page = zathura_document_get_page(zathura->document,
page_id);
unsigned int page_height = 0, page_width = 0;
page_calc_height_width(page, &page_height, &page_width, true);
double height = zathura_page_get_height(page);
double width = zathura_page_get_width(page);
page_calc_height_width(zathura->document, height, width, &page_height, &page_width, true);
GtkWidget* widget = zathura_page_get_widget(zathura, page);
gtk_widget_set_size_request(widget, page_width, page_height);

View file

@ -102,103 +102,8 @@ sc_adjust_window(girara_session_t* session, girara_argument_t* argument,
zathura_t* zathura = session->global.data;
g_return_val_if_fail(argument != NULL, false);
unsigned int pages_per_row = 1;
girara_setting_get(session, "pages-per-row", &pages_per_row);
unsigned int first_page_column = 1;
girara_setting_get(session, "first-page-column", &first_page_column);
int padding = 1;
girara_setting_get(zathura->ui.session, "page-padding", &padding);
if (zathura->ui.page_widget == NULL || zathura->document == NULL) {
goto error_ret;
}
zathura_document_set_adjust_mode(zathura->document, argument->n);
if (argument->n == ZATHURA_ADJUST_NONE) {
/* there is nothing todo */
goto error_ret;
}
/* get window size */
GtkAllocation allocation;
gtk_widget_get_allocation(session->gtk.view, &allocation);
unsigned int width = allocation.width;
unsigned int height = allocation.height;
/* scrollbar spacing */
gint spacing;
gtk_widget_style_get(session->gtk.view, "scrollbar_spacing", &spacing, NULL);
width -= spacing;
/* correct view size */
if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == true) {
gtk_widget_get_allocation(session->gtk.inputbar, &allocation);
height += allocation.height;
}
double scale = 1.0;
unsigned int cell_height = 0, cell_width = 0;
unsigned int document_height = 0, document_width = 0;
zathura_document_set_scale(zathura->document, scale);
zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
zathura_get_document_size(zathura, cell_height, cell_width,
&document_height, &document_width);
double page_ratio = (double)cell_height / (double)document_width;
double window_ratio = (double)height / (double)width;
if (argument->n == ZATHURA_ADJUST_WIDTH ||
(argument->n == ZATHURA_ADJUST_BESTFIT && page_ratio < window_ratio)) {
scale = (double)(width - (pages_per_row - 1) * padding) /
(double)(pages_per_row * cell_width);
zathura_document_set_scale(zathura->document, scale);
bool show_vscrollbar = false;
girara_setting_get(session, "show-v-scrollbar", &show_vscrollbar);
if (show_vscrollbar) {
/* If the document is taller than the view, there's a vertical
* scrollbar; we need to substract its width from the view's width. */
zathura_get_document_size(zathura, cell_height, cell_width,
&document_height, &document_width);
if (height < document_height) {
GtkWidget* vscrollbar = gtk_scrolled_window_get_vscrollbar(
GTK_SCROLLED_WINDOW(session->gtk.view));
if (vscrollbar != NULL) {
int scroll_width;
#if (GTK_MAJOR_VERSION == 3)
gtk_widget_get_preferred_width(GTK_WIDGET(vscrollbar), NULL, &scroll_width);
#else
GtkRequisition requisition;
gtk_widget_get_requisition(vscrollbar, &requisition);
scroll_width = requisition.width;
#endif
if (0 < scroll_width && (unsigned int)scroll_width < width) {
width -= scroll_width;
scale = (double)(width - (pages_per_row - 1) * padding) /
(double)(pages_per_row * cell_width);
zathura_document_set_scale(zathura->document, scale);
}
}
}
}
}
else if (argument->n == ZATHURA_ADJUST_BESTFIT) {
scale = (double)height / (double)cell_height;
zathura_document_set_scale(zathura->document, scale);
}
else {
goto error_ret;
}
/* re-render all pages */
render_all(zathura);
error_ret:
adjust_view(zathura);
return false;
}
@ -400,7 +305,6 @@ sc_mouse_scroll(girara_session_t* session, girara_argument_t* argument, girara_e
gtk_adjustment_get_value(x_adj) - (event->x - x));
zathura_adjustment_set_value(y_adj,
gtk_adjustment_get_value(y_adj) - (event->y - y));
zathura->global.update_page_number = true;
break;
/* unhandled events */
@ -570,7 +474,7 @@ sc_rotate(girara_session_t* session, girara_argument_t* argument,
/* render all pages again */
render_all(zathura);
page_set_delayed(zathura, page_number);
page_set(zathura, page_number);
return false;
}
@ -591,18 +495,14 @@ sc_scroll(girara_session_t* session, girara_argument_t* argument,
t = 1;
}
GtkAdjustment* adjustment = NULL;
if ( (argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
(argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
} else {
adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
}
unsigned int view_width=0, view_height=0;
zathura_document_get_viewport_size(zathura->document, &view_height, &view_width);
gdouble view_size = gtk_adjustment_get_page_size(adjustment);
gdouble value = gtk_adjustment_get_value(adjustment);
gdouble max = gtk_adjustment_get_upper(adjustment) - view_size;
zathura->global.update_page_number = true;
unsigned int cell_width=0, cell_height=0;
zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
unsigned int doc_width=0, doc_height=0;
zathura_document_get_document_size(zathura->document, &doc_height, &doc_width);
float scroll_step = 40;
girara_setting_get(session, "scroll-step", &scroll_step);
@ -622,108 +522,111 @@ sc_scroll(girara_session_t* session, girara_argument_t* argument,
int padding = 1;
girara_setting_get(session, "page-padding", &padding);
gdouble new_value;
double pos_x = zathura_document_get_position_x(zathura->document);
double pos_y = zathura_document_get_position_y(zathura->document);
double page_id = zathura_document_get_current_page_number(zathura->document);
double direction = 1.0;
/* if TOP or BOTTOM, go there and we are done */
if (argument->n == TOP) {
position_set(zathura, -1, 0);
return false;
} else if (argument->n == BOTTOM) {
position_set(zathura, -1, 1.0);
return false;
}
/* compute the direction of scrolling */
if ( (argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
(argument->n == UP) || (argument->n == FULL_UP) || (argument->n == HALF_UP)) {
direction = -1.0;
} else {
direction = 1.0;
}
double vstep = (double)(cell_height + padding) / (double)doc_height;
double hstep = (double)(cell_width + padding) / (double)doc_width;
/* compute new position */
switch(argument->n) {
case FULL_UP:
case FULL_LEFT:
new_value = value - (1.0 - scroll_full_overlap) * view_size - padding;
break;
case FULL_DOWN:
pos_y += direction * (1.0 - scroll_full_overlap) * vstep;
break;
case FULL_LEFT:
case FULL_RIGHT:
new_value = value + (1.0 - scroll_full_overlap) * view_size + padding;
pos_x += direction * (1.0 - scroll_full_overlap) * hstep;
break;
case HALF_UP:
case HALF_LEFT:
new_value = value - ((view_size + padding) / 2);
break;
case HALF_DOWN:
pos_y += direction * 0.5 * vstep;
break;
case HALF_LEFT:
case HALF_RIGHT:
new_value = value + ((view_size + padding) / 2);
break;
case LEFT:
new_value = value - scroll_hstep * t;
pos_x += direction * 0.5 * hstep;
break;
case UP:
new_value = value - scroll_step * t;
break;
case RIGHT:
new_value = value + scroll_hstep * t;
break;
case DOWN:
new_value = value + scroll_step * t;
pos_y += direction * t * scroll_step / (double)doc_height;
break;
case TOP:
new_value = 0;
case LEFT:
case RIGHT:
pos_x += direction * t * scroll_hstep / (double)doc_width;
break;
case BOTTOM:
new_value = max;
break;
default:
new_value = value;
}
if (scroll_wrap == true) {
if (new_value < 0)
new_value = max;
else if (new_value > max)
new_value = 0;
/* handle boundaries */
double end_x = 0.5 * (double)view_width / (double)doc_width;
double end_y = 0.5 * (double)view_height / (double)doc_height;
double new_x = scroll_wrap ? 1.0 - end_x : end_x;
double new_y = scroll_wrap ? 1.0 - end_y : end_y;
if (pos_x < end_x) {
pos_x = new_x;
} else if (pos_x > 1.0 - end_x) {
pos_x = 1 - new_x;
}
if (scroll_page_aware == true) {
int page_offset;
double page_size;
if (pos_y < end_y) {
pos_y = new_y;
} else if (pos_y > 1.0 - end_y) {
pos_y = 1 - new_y;
}
{
unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
page_offset_t offset;
page_calculate_offset(zathura, page, &offset);
/* snap to the border if we change page */
double dummy;
unsigned int new_page_id = position_to_page_number(zathura->document, pos_x, pos_y);
if (scroll_page_aware == true && page_id != new_page_id) {
switch(argument->n) {
case FULL_LEFT:
case HALF_LEFT:
page_number_to_position(zathura->document, new_page_id, 1.0, 0.0, &pos_x, &dummy);
break;
double scale = zathura_document_get_scale(zathura->document);
case FULL_RIGHT:
case HALF_RIGHT:
page_number_to_position(zathura->document, new_page_id, 0.0, 0.0, &pos_x, &dummy);
break;
if ((argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
(argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
page_offset = offset.x;
page_size = zathura_page_get_width(page) * scale;
} else {
page_offset = offset.y;
page_size = zathura_page_get_height(page) * scale;
}
case FULL_UP:
case HALF_UP:
page_number_to_position(zathura->document, new_page_id, 0.0, 1.0, &dummy, &pos_y);
break;
page_offset -= padding / 2;
page_size += padding;
}
if ((argument->n == FULL_DOWN) || (argument->n == HALF_DOWN) ||
(argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
if ((page_offset > value) &&
(page_offset < value + view_size)) {
new_value = page_offset;
} else if ((page_offset <= value) &&
(page_offset + page_size < value + view_size)) {
new_value = page_offset + page_size + 1;
} else if ((page_offset <= value) &&
(page_offset + page_size < new_value + view_size)) {
new_value = page_offset + page_size - view_size + 1;
}
} else if ((argument->n == FULL_UP) || (argument->n == HALF_UP) ||
(argument->n == FULL_LEFT) || (argument->n == HALF_LEFT)) {
if ((page_offset + 1 >= value) &&
(page_offset < value + view_size)) {
new_value = page_offset - view_size;
} else if ((page_offset <= value) &&
(page_offset + page_size + 1 < value + view_size)) {
new_value = page_offset + page_size - view_size;
} else if ((page_offset <= value) &&
(page_offset > new_value)) {
new_value = page_offset;
}
case FULL_DOWN:
case HALF_DOWN:
page_number_to_position(zathura->document, new_page_id, 0.0, 0.0, &dummy, &pos_y);
break;
}
}
zathura_adjustment_set_value(adjustment, new_value);
position_set(zathura, pos_x, pos_y);
return false;
}
@ -743,10 +646,9 @@ sc_jumplist(girara_session_t* session, girara_argument_t* argument,
return true;
}
GtkAdjustment* hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
double x = zathura_adjustment_get_ratio(hadj);
double y = zathura_adjustment_get_ratio(vadj);
double x = zathura_document_get_position_x(zathura->document);
double y = zathura_document_get_position_y(zathura->document);
zathura_jump_t* jump = NULL;
zathura_jump_t* prev_jump = zathura_jumplist_current(zathura);
bool go_to_current = false;
@ -786,11 +688,9 @@ sc_jumplist(girara_session_t* session, girara_argument_t* argument,
}
if (jump != NULL) {
zathura_adjustment_set_value_from_ratio(hadj, jump->x);
zathura_adjustment_set_value_from_ratio(vadj, jump->y);
zathura_document_set_current_page_number(zathura->document, jump->page);
statusbar_page_number_update(zathura);
}
page_set(zathura, jump->page);
position_set(zathura, jump->x, jump->y);
}
return false;
}
@ -1011,26 +911,35 @@ sc_search(girara_session_t* session, girara_argument_t* argument,
zathura_rectangle_t* rect = girara_list_nth(results, target_idx);
zathura_rectangle_t rectangle = recalc_rectangle(target_page, *rect);
page_offset_t offset;
page_calculate_offset(zathura, target_page, &offset);
zathura_jumplist_add(zathura);
if (zathura_page_get_index(target_page) != cur_page) {
page_set(zathura, zathura_page_get_index(target_page));
}
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
int y = offset.y - gtk_adjustment_get_page_size(view_vadjustment) / 2 + rectangle.y1;
zathura_adjustment_set_value(view_vadjustment, y);
bool search_hadjust = true;
girara_setting_get(session, "search-hadjust", &search_hadjust);
/* compute the position of the center of the page */
double pos_x = 0;
double pos_y = 0;
page_number_to_position(zathura->document, zathura_page_get_index(target_page),
0.5, 0.5, &pos_x, &pos_y);
/* correction to center the current result */
/* NOTE: rectangle is in viewport units, already scaled and rotated */
unsigned int cell_height = 0;
unsigned int cell_width = 0;
zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
unsigned int doc_height = 0;
unsigned int doc_width = 0;
zathura_document_get_document_size(zathura->document, &doc_height, &doc_width);
pos_y += (rectangle.y1 - (double)cell_height/2) / (double)doc_height;
if (search_hadjust == true) {
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
int x = offset.x - gtk_adjustment_get_page_size(view_hadjustment) / 2 + rectangle.x1;
zathura_adjustment_set_value(view_hadjustment, x);
pos_x += (rectangle.x1 - (double)cell_width/2) / (double)doc_width;
}
/* move to position */
zathura_jumplist_add(zathura);
position_set(zathura, pos_x, pos_y);
zathura_jumplist_add(zathura);
}
@ -1208,24 +1117,14 @@ sc_toggle_index(girara_session_t* session, girara_argument_t* UNUSED(argument),
gtk_widget_show(treeview);
}
static double vvalue = 0;
static double hvalue = 0;
if (gtk_widget_get_visible(GTK_WIDGET(zathura->ui.index))) {
girara_set_view(session, zathura->ui.page_widget_alignment);
gtk_widget_hide(GTK_WIDGET(zathura->ui.index));
girara_mode_set(zathura->ui.session, zathura->modes.normal);
/* reset adjustment */
position_set_delayed(zathura, hvalue, vvalue);
/* refresh view */
refresh_view(zathura);
} else {
/* save adjustment */
GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
vvalue = gtk_adjustment_get_value(vadjustment);
hvalue = gtk_adjustment_get_value(hadjustment);
/* save current position to the jumplist */
zathura_jumplist_add(zathura);
@ -1315,7 +1214,7 @@ sc_toggle_fullscreen(girara_session_t* session, girara_argument_t*
/* reset scale */
zathura_document_set_scale(zathura->document, zoom);
render_all(zathura);
page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document));
refresh_view(zathura);
/* setm ode */
girara_mode_set(session, zathura->modes.normal);
@ -1343,7 +1242,7 @@ sc_toggle_fullscreen(girara_session_t* session, girara_argument_t*
/* set full screen */
gtk_window_fullscreen(GTK_WINDOW(session->gtk.window));
page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document));
refresh_view(zathura);
/* setm ode */
girara_mode_set(session, zathura->modes.fullscreen);
@ -1420,6 +1319,7 @@ sc_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t*
}
render_all(zathura);
refresh_view(zathura);
return false;
}

View file

@ -97,7 +97,7 @@ synctex_record_hits(zathura_t* zathura, int page_idx, girara_list_t* hits, bool
g_object_set(page_widget, "search-results", hits, NULL);
if (first) {
page_set_delayed(zathura, zathura_page_get_index(page));
page_set(zathura, zathura_page_get_index(page));
g_object_set(page_widget, "search-current", 0, NULL);
}
}

65
utils.c
View file

@ -240,71 +240,6 @@ error_ret:
return rectangle;
}
double
page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned int* page_width, bool rotate)
{
g_return_val_if_fail(page != NULL && page_height != NULL && page_width != NULL, 0.0);
zathura_document_t* document = zathura_page_get_document(page);
if (document == NULL) {
return 0.0;
}
double height = zathura_page_get_height(page);
double width = zathura_page_get_width(page);
double scale = zathura_document_get_scale(document);
double real_scale;
if (rotate && zathura_document_get_rotation(document) % 180) {
*page_width = ceil(height * scale);
*page_height = ceil(width * scale);
real_scale = MAX(*page_width / height, *page_height / width);
} else {
*page_width = ceil(width * scale);
*page_height = ceil(height * scale);
real_scale = MAX(*page_width / width, *page_height / height);
}
return real_scale;
}
void
zathura_get_document_size(zathura_t* zathura,
unsigned int cell_height, unsigned int cell_width,
unsigned int* height, unsigned int* width)
{
g_return_if_fail(zathura != NULL && zathura->document != NULL &&
height != NULL && width != NULL);
unsigned int pages_per_row = 1;
girara_setting_get(zathura->ui.session, "pages-per-row", &pages_per_row);
if (pages_per_row == 0)
pages_per_row = 1;
unsigned int first_page_column = 1;
girara_setting_get(zathura->ui.session, "first-page-column", &first_page_column);
if (first_page_column < 1)
first_page_column = 1;
if (first_page_column > pages_per_row)
first_page_column = (first_page_column - 1) % pages_per_row + 1;
int padding = 1;
girara_setting_get(zathura->ui.session, "page-padding", &padding);
double scale = zathura_document_get_scale(zathura->document);
cell_height = ceil(cell_height * scale);
cell_width = ceil(cell_width * scale);
*width = pages_per_row * cell_width + (pages_per_row - 1) * padding;
unsigned int effective_number_of_pages =
zathura_document_get_number_of_pages(zathura->document) +
first_page_column - 1;
unsigned int rows = effective_number_of_pages / pages_per_row +
(effective_number_of_pages % pages_per_row ? 1 : 0);
*height = rows * cell_height + (rows - 1) * padding;
}
GtkWidget*
zathura_page_get_widget(zathura_t* zathura, zathura_page_t* page)
{

31
utils.h
View file

@ -86,35 +86,6 @@ zathura_rectangle_t rotate_rectangle(zathura_rectangle_t rectangle, unsigned int
*/
zathura_rectangle_t recalc_rectangle(zathura_page_t* page, zathura_rectangle_t rectangle);
/**
* Calculate the page size according to the corrent scaling and rotation if
* desired.
* @param page the page
* @param page_height the resulting page height
* @param page_width the resultung page width
* @param rotate honor page's rotation
* @return real scale after rounding
*/
double
page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned int* page_width, bool rotate);
/**
* Compute the size of the entire document to be displayed (in pixels), taking
* into account the scale, the layout of the pages, and the padding between
* them. It should be equal to the allocation of zathura->ui.page_widget once
* it's shown.
*
* @param[in] zathura The zathura instance
* @param[in] cell_height,cell_width The height and width of a cell containing
* a single page; it should be obtained
* using zathura_document_get_cell_size()
* with the document scale set to 1.0
* @param[out] height,width The height and width of the document
*/
void zathura_get_document_size(zathura_t* zathura,
unsigned int cell_height, unsigned int cell_width,
unsigned int* height, unsigned int* width);
/**
* Returns the page widget of the page
*
@ -138,7 +109,7 @@ void document_draw_search_results(zathura_t* zathura, bool value);
*
* @param zathura The zathura instance
* @param markup Enable markup
* @return Version string
* @return Version string
*/
char* zathura_get_version_string(zathura_t* zathura, bool markup);

353
zathura.c
View file

@ -42,16 +42,6 @@ typedef struct zathura_document_info_s {
int page_number;
} zathura_document_info_t;
typedef struct page_set_delayed_s {
zathura_t* zathura;
unsigned int page;
} page_set_delayed_t;
typedef struct position_set_delayed_s {
zathura_t* zathura;
double position_x;
double position_y;
} position_set_delayed_t;
static gboolean document_info_open(gpointer data);
static void zathura_jumplist_reset_current(zathura_t* zathura);
@ -65,7 +55,6 @@ zathura_create(void)
zathura_t* zathura = g_malloc0(sizeof(zathura_t));
/* global settings */
zathura->global.update_page_number = true;
zathura->global.search_direction = FORWARD;
/* plugins */
@ -141,6 +130,21 @@ zathura_init(zathura_t* zathura)
zathura->ui.session->events.buffer_changed = cb_buffer_changed;
zathura->ui.session->events.unknown_command = cb_unknown_command;
/* zathura signals */
zathura->signals.refresh_view = g_signal_new("refresh-view",
GTK_TYPE_WIDGET,
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
g_cclosure_marshal_generic,
G_TYPE_NONE,
1,
G_TYPE_POINTER);
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view), "refresh-view",
G_CALLBACK(cb_refresh_view), zathura);
/* page view */
#if (GTK_MAJOR_VERSION == 3)
zathura->ui.page_widget = gtk_grid_new();
@ -155,37 +159,23 @@ zathura_init(zathura_t* zathura)
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "size-allocate", G_CALLBACK(cb_view_resized), zathura);
/* Setup hadjustment tracker */
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(
GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
zathura->ui.hadjustment = zathura_adjustment_clone(hadjustment);
g_object_ref_sink(zathura->ui.hadjustment);
GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
/* Connect hadjustment signals */
g_signal_connect(G_OBJECT(hadjustment), "value-changed",
G_CALLBACK(cb_view_vadjustment_value_changed), zathura);
g_signal_connect(G_OBJECT(hadjustment), "value-changed",
G_CALLBACK(cb_adjustment_track_value), zathura->ui.hadjustment);
G_CALLBACK(cb_view_hadjustment_value_changed), zathura);
g_signal_connect(G_OBJECT(hadjustment), "changed",
G_CALLBACK(cb_view_hadjustment_changed), zathura);
g_signal_connect(G_OBJECT(hadjustment), "changed",
G_CALLBACK(cb_adjustment_track_bounds), zathura->ui.hadjustment);
/* Setup vadjustment tracker */
GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(
GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
zathura->ui.vadjustment = zathura_adjustment_clone(vadjustment);
g_object_ref_sink(zathura->ui.vadjustment);
GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
/* Connect vadjustment signals */
g_signal_connect(G_OBJECT(vadjustment), "value-changed",
G_CALLBACK(cb_view_vadjustment_value_changed), zathura);
g_signal_connect(G_OBJECT(vadjustment), "value-changed",
G_CALLBACK(cb_adjustment_track_value), zathura->ui.vadjustment);
g_signal_connect(G_OBJECT(vadjustment), "changed",
G_CALLBACK(cb_view_vadjustment_changed), zathura);
g_signal_connect(G_OBJECT(vadjustment), "changed",
G_CALLBACK(cb_adjustment_track_bounds), zathura->ui.vadjustment);
/* page view alignment */
zathura->ui.page_widget_alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
@ -225,18 +215,6 @@ zathura_init(zathura_t* zathura)
/* signals */
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), zathura);
/* set page padding */
int page_padding = 1;
girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
#if (GTK_MAJOR_VERSION == 3)
gtk_grid_set_row_spacing(GTK_GRID(zathura->ui.page_widget), page_padding);
gtk_grid_set_column_spacing(GTK_GRID(zathura->ui.page_widget), page_padding);
#else
gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding);
gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding);
#endif
/* database */
char* database = NULL;
girara_setting_get(zathura->ui.session, "database", &database);
@ -304,13 +282,6 @@ zathura_free(zathura_t* zathura)
girara_session_destroy(zathura->ui.session);
}
if (zathura->ui.hadjustment != NULL) {
g_object_unref(G_OBJECT(zathura->ui.hadjustment));
}
if (zathura->ui.vadjustment != NULL) {
g_object_unref(G_OBJECT(zathura->ui.vadjustment));
}
/* stdin support */
if (zathura->stdin_support.file != NULL) {
g_unlink(zathura->stdin_support.file);
@ -745,7 +716,10 @@ document_open(zathura_t* zathura, const char* path, const char* password,
/* set widget size */
unsigned int page_height = 0;
unsigned int page_width = 0;
page_calc_height_width(page, &page_height, &page_width, true);
double height = zathura_page_get_height(page);
double width = zathura_page_get_width(page);
page_calc_height_width(zathura->document, height, width, &page_height, &page_width, true);
gtk_widget_set_size_request(page_widget, page_width, page_height);
@ -756,8 +730,12 @@ document_open(zathura_t* zathura, const char* path, const char* password,
}
/* view mode */
int pages_per_row = 1;
int first_page_column = 1;
unsigned int pages_per_row = 1;
unsigned int first_page_column = 1;
unsigned int page_padding = 1;
girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
if (file_info.pages_per_row > 0) {
pages_per_row = file_info.pages_per_row;
} else {
@ -772,7 +750,9 @@ document_open(zathura_t* zathura, const char* path, const char* password,
girara_setting_set(zathura->ui.session, "pages-per-row", &pages_per_row);
girara_setting_set(zathura->ui.session, "first-page-column", &first_page_column);
page_widget_set_mode(zathura, pages_per_row, first_page_column);
page_widget_set_mode(zathura, page_padding, pages_per_row, first_page_column);
zathura_document_set_page_layout(zathura->document, page_padding, pages_per_row, first_page_column);
girara_set_view(zathura->ui.session, zathura->ui.page_widget_alignment);
@ -799,16 +779,14 @@ document_open(zathura_t* zathura, const char* path, const char* password,
g_free(file_uri);
/* adjust window */
girara_argument_t argument = { zathura_document_get_adjust_mode(document), NULL };
sc_adjust_window(zathura->ui.session, &argument, NULL, 0);
/* adjust_view and set position*/
adjust_view(zathura);
/* set position */
page_set(zathura, zathura_document_get_current_page_number(document));
if (file_info.position_x != 0 || file_info.position_y != 0) {
position_set_delayed(zathura, file_info.position_x, file_info.position_y);
} else {
page_set_delayed(zathura, zathura_document_get_current_page_number(document));
cb_view_vadjustment_value_changed(NULL, zathura);
position_set(zathura, file_info.position_x, file_info.position_y);
}
return true;
@ -936,12 +914,8 @@ document_close(zathura_t* zathura, bool keep_monitor)
girara_setting_get(zathura->ui.session, "first-page-column", &(file_info.first_page_column));
/* get position */
GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view);
GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window);
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window);
file_info.position_x = gtk_adjustment_get_value(hadjustment);
file_info.position_y = gtk_adjustment_get_value(vadjustment);
file_info.position_x = zathura_document_get_position_x(zathura->document);
file_info.position_y = zathura_document_get_position_y(zathura->document);
/* save file info */
zathura_db_set_fileinfo(zathura->database, path, &file_info);
@ -991,31 +965,6 @@ document_close(zathura_t* zathura, bool keep_monitor)
return true;
}
static gboolean
page_set_delayed_impl(gpointer data)
{
page_set_delayed_t* p = data;
page_set(p->zathura, p->page);
g_free(p);
return FALSE;
}
bool
page_set_delayed(zathura_t* zathura, unsigned int page_id)
{
if (zathura == NULL || zathura->document == NULL ||
(page_id >= zathura_document_get_number_of_pages(zathura->document))) {
return false;
}
page_set_delayed_t* p = g_malloc(sizeof(page_set_delayed_t));
p->zathura = zathura;
p->page = page_id;
gdk_threads_add_idle(page_set_delayed_impl, p);
return true;
}
bool
page_set(zathura_t* zathura, unsigned int page_id)
{
@ -1023,33 +972,17 @@ page_set(zathura_t* zathura, unsigned int page_id)
goto error_out;
}
/* render page */
zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
if (page == NULL) {
goto error_out;
}
zathura_document_set_current_page_number(zathura->document, page_id);
zathura->global.update_page_number = false;
page_offset_t offset;
page_calculate_offset(zathura, page, &offset);
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
zathura_adjustment_set_value(view_hadjustment, offset.x);
zathura_adjustment_set_value(view_vadjustment, offset.y);
/* refresh horizontal adjustment, to honor zoom-center */
cb_view_hadjustment_changed(view_hadjustment, zathura);
statusbar_page_number_update(zathura);
return true;
/* negative position means auto */
return position_set(zathura, -1, -1);
error_out:
return false;
}
@ -1089,7 +1022,8 @@ statusbar_page_number_update(zathura_t* zathura)
}
void
page_widget_set_mode(zathura_t* zathura, unsigned int pages_per_row, unsigned int first_page_column)
page_widget_set_mode(zathura_t* zathura, unsigned int page_padding,
unsigned int pages_per_row, unsigned int first_page_column)
{
/* show at least one page */
if (pages_per_row == 0) {
@ -1100,7 +1034,6 @@ page_widget_set_mode(zathura_t* zathura, unsigned int pages_per_row, unsigned in
if (first_page_column < 1) {
first_page_column = 1;
}
if (first_page_column > pages_per_row) {
first_page_column = ((first_page_column - 1) % pages_per_row) + 1;
}
@ -1112,9 +1045,18 @@ page_widget_set_mode(zathura_t* zathura, unsigned int pages_per_row, unsigned in
gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_widget), remove_page_from_table, (gpointer)0);
unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
#if (GTK_MAJOR_VERSION == 3)
gtk_grid_set_row_spacing(GTK_GRID(zathura->ui.page_widget), page_padding);
gtk_grid_set_column_spacing(GTK_GRID(zathura->ui.page_widget), page_padding);
#else
gtk_table_resize(GTK_TABLE(zathura->ui.page_widget), ceil((number_of_pages + first_page_column - 1) / pages_per_row), pages_per_row);
gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding);
gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding);
unsigned int ncol = pages_per_row;
unsigned int nrow = (number_of_pages + first_page_column - 1 + ncol - 1) / ncol;
gtk_table_resize(GTK_TABLE(zathura->ui.page_widget), nrow, ncol);
#endif
for (unsigned int i = 0; i < number_of_pages; i++) {
@ -1133,94 +1075,126 @@ page_widget_set_mode(zathura_t* zathura, unsigned int pages_per_row, unsigned in
gtk_widget_show_all(zathura->ui.page_widget);
}
static gboolean
position_set_delayed_impl(gpointer data)
{
position_set_delayed_t* p = (position_set_delayed_t*) data;
GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(p->zathura->ui.session->gtk.view);
GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window);
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window);
/* negative values mean: don't set the position */
if (p->position_x >= 0) {
zathura_adjustment_set_value(hadjustment, p->position_x);
}
if (p->position_y >= 0) {
zathura_adjustment_set_value(vadjustment, p->position_y);
}
g_free(p);
return FALSE;
}
void
position_set_delayed(zathura_t* zathura, double position_x, double position_y)
{
g_return_if_fail(zathura != NULL);
position_set_delayed_t* p = g_malloc0(sizeof(position_set_delayed_t));
p->zathura = zathura;
p->position_x = position_x;
p->position_y = position_y;
gdk_threads_add_idle(position_set_delayed_impl, p);
}
void
bool
position_set(zathura_t* zathura, double position_x, double position_y)
{
g_return_if_fail(zathura != NULL);
GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view);
GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window);
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window);
/* negative values mean: don't set the position */
if (position_x >= 0) {
zathura_adjustment_set_value(hadjustment, position_x);
if (zathura == NULL || zathura->document == NULL) {
goto error_out;
}
if (position_y >= 0) {
zathura_adjustment_set_value(vadjustment, position_y);
double comppos_x, comppos_y;
unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
/* xalign = 0.5: center horizontally (with the page, not the document) */
/* yalign = 0.0: align page an viewport edges at the top */
page_number_to_position(zathura->document, page_id, 0.5, 0.0, &comppos_x, &comppos_y);
/* automatic horizontal adjustment */
zathura_adjust_mode_t adjust_mode = zathura_document_get_adjust_mode(zathura->document);
/* negative position_x mean: use the computed value */
if (position_x < 0) {
position_x = comppos_x;
bool zoom_center = false;
girara_setting_get(zathura->ui.session, "zoom-center", &zoom_center);
/* center horizontally */
if (adjust_mode == ZATHURA_ADJUST_BESTFIT ||
adjust_mode == ZATHURA_ADJUST_WIDTH ||
zoom_center) {
position_x = 0.5;
}
}
if (position_y < 0) {
position_y = comppos_y;
}
/* set the position */
zathura_document_set_position_x(zathura->document, position_x);
zathura_document_set_position_y(zathura->document, position_y);
/* trigger a 'change' event for both adjustments */
refresh_view(zathura);
return true;
error_out:
return false;
}
static void
zathura_jumplist_hide_inputbar(zathura_t* zathura)
{
g_return_if_fail(zathura != NULL && zathura->ui.session->gtk.inputbar != NULL);
girara_argument_t arg = { GIRARA_HIDE, NULL };
girara_isc_completion(zathura->ui.session, &arg, NULL, 0);
void
refresh_view(zathura_t* zathura) {
g_return_if_fail(zathura != NULL);
if (zathura->ui.session->global.autohide_inputbar == true) {
/* XXX: This is a workaround for incremental-search. We should revisit this
* when we drop GTK+3 support and the inputbar is placed in a GtkOverlay
* widget. */
char *input = gtk_editable_get_chars(GTK_EDITABLE(zathura->ui.session->gtk.inputbar_entry), 0, -1);
bool res = false;
/* emit a custom refresh-view signal */
g_signal_emit(zathura->ui.session->gtk.view, zathura->signals.refresh_view,
0, zathura);
}
girara_setting_get(zathura->ui.session, "incremental-search", &res);
if ((*input == '/' || *input == '?') && res == true) {
g_free(input);
bool
adjust_view(zathura_t* zathura) {
g_return_val_if_fail(zathura != NULL, false);
return;
}
/* </workaround> */
gtk_widget_hide(zathura->ui.session->gtk.inputbar);
if (zathura->ui.page_widget == NULL || zathura->document == NULL) {
goto error_ret;
}
/* we want to do it immediately */
/* XXX: ... and we want this to go away */
while (gtk_events_pending()) {
gtk_main_iteration();
zathura_adjust_mode_t adjust_mode = zathura_document_get_adjust_mode(zathura->document);
if (adjust_mode == ZATHURA_ADJUST_NONE) {
/* there is nothing todo */
goto error_ret;
}
unsigned int cell_height = 0, cell_width = 0;
unsigned int document_height = 0, document_width = 0;
unsigned int view_height = 0, view_width = 0;
zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
zathura_document_get_document_size(zathura->document, &document_height, &document_width);
zathura_document_get_viewport_size(zathura->document, &view_height, &view_width);
double scale = zathura_document_get_scale(zathura->document);
if (view_height == 0 || view_width == 0 || cell_height == 0 || cell_width == 0) {
goto error_ret;
}
double page_ratio = (double)cell_height / (double)document_width;
double view_ratio = (double)view_height / (double)view_width;
double newscale = scale;
if (adjust_mode == ZATHURA_ADJUST_WIDTH ||
(adjust_mode == ZATHURA_ADJUST_BESTFIT && page_ratio < view_ratio)) {
newscale = scale * (double)view_width / (double)document_width;
} else if (adjust_mode == ZATHURA_ADJUST_BESTFIT) {
newscale = scale * (double)view_height / (double)cell_height;
} else {
goto error_ret;
}
/* save new scale and recompute cell size */
zathura_document_set_scale(zathura->document, newscale);
unsigned int new_cell_height = 0, new_cell_width = 0;
zathura_document_get_cell_size(zathura->document, &new_cell_height, &new_cell_width);
/* if the change in scale changes page cell dimensions by at least one pixel, render */
if (abs(new_cell_width - cell_width) > 1 ||
abs(new_cell_height - cell_height) > 1) {
render_all(zathura);
refresh_view(zathura);
/* otherwise set the old scale and leave */
} else {
zathura_document_set_scale(zathura->document, scale);
}
error_ret:
return false;
}
bool
@ -1321,12 +1295,11 @@ zathura_jumplist_trim(zathura_t* zathura)
void
zathura_jumplist_add(zathura_t* zathura)
{
g_return_if_fail(zathura != NULL && zathura->jumplist.list != NULL);
zathura_jumplist_hide_inputbar(zathura);
g_return_if_fail(zathura != NULL && zathura->document != NULL && zathura->jumplist.list != NULL);
unsigned int pagenum = zathura_document_get_current_page_number(zathura->document);
double x = zathura_adjustment_get_ratio(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
double y = zathura_adjustment_get_ratio(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
double x = zathura_document_get_position_x(zathura->document);
double y = zathura_document_get_position_y(zathura->document);
if (zathura->jumplist.size != 0) {
zathura_jumplist_reset_current(zathura);
@ -1375,7 +1348,7 @@ zathura_jumplist_load(zathura_t* zathura, const char* file)
static void
zathura_jumplist_save(zathura_t* zathura)
{
g_return_if_fail(zathura != NULL);
g_return_if_fail(zathura != NULL && zathura->document != NULL);
zathura_jump_t* cur = zathura_jumplist_current(zathura);
@ -1383,7 +1356,7 @@ zathura_jumplist_save(zathura_t* zathura)
if (cur) {
cur->page = pagenum;
cur->x = zathura_adjustment_get_ratio(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
cur->y = zathura_adjustment_get_ratio(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)));
cur->x = zathura_document_get_position_x(zathura->document);
cur->y = zathura_document_get_position_y(zathura->document);
}
}

View file

@ -69,9 +69,6 @@ struct zathura_s
GtkWidget *page_widget_alignment;
GtkWidget *page_widget; /**< Widget that contains all rendered pages */
GtkWidget *index; /**< Widget to show the index of the document */
GtkAdjustment *hadjustment; /**< Tracking hadjustment */
GtkAdjustment *vadjustment; /**< Tracking vadjustment */
} ui;
struct
@ -104,7 +101,6 @@ struct zathura_s
struct
{
bool update_page_number; /**< Update current page number */
int search_direction; /**< Current search direction (FORWARD or BACKWARD) */
girara_list_t* marks; /**< Marker */
char** arguments; /**> Arguments that were passed at startup */
@ -132,6 +128,11 @@ struct zathura_s
unsigned int max_size;
} jumplist;
struct
{
guint refresh_view;
} signals;
struct
{
gchar* file;
@ -295,40 +296,39 @@ bool document_close(zathura_t* zathura, bool keep_monitor);
bool page_set(zathura_t* zathura, unsigned int page_id);
/**
* Opens the page with the given number (delayed)
* Moves to the given position
*
* @param zathura The zathura session
* @param page_id The id of the page that should be set
* @param zathura Zathura session
* @param position_x X coordinate
* @param position_y Y coordinate
* @return If no error occured true, otherwise false, is returned.
*/
bool page_set_delayed(zathura_t* zathura, unsigned int page_id);
bool position_set(zathura_t* zathura, double position_x, double position_y);
/**
* Moves to the given position
* Refresh the page view
*
* @param zathura Zathura session
* @param position_x X coordinate
* @param position_y Y coordinate
*/
void position_set_delayed(zathura_t* zathura, double position_x, double position_y);
void refresh_view(zathura_t* zathura);
/**
* Moves to the given position
* Recompute the scale according to settings
*
* @param zathura Zathura session
* @param position_x X coordinate
* @param position_y Y coordinate
*/
void position_set(zathura_t* zathura, double position_x, double position_y);
bool adjust_view(zathura_t* zathura);
/**
* Builds the box structure to show the rendered pages
*
* @param zathura The zathura session
* @param page_padding padding in pixels between pages
* @param pages_per_row Number of shown pages per row
* @param first_page_column Column on which first page start
*/
void page_widget_set_mode(zathura_t* zathura, unsigned int pages_per_row, unsigned int first_page_column);
void page_widget_set_mode(zathura_t* zathura, unsigned int page_padding,
unsigned int pages_per_row, unsigned int first_page_column);
/**
* Updates the page number in the statusbar. Note that 1 will be added to the