mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-29 13:35:59 +01:00
3d96d44095
Closes: #404 Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
193 lines
6.3 KiB
C
193 lines
6.3 KiB
C
/* See LICENSE file for license and copyright information */
|
|
|
|
#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);
|
|
if (rotate && zathura_document_get_rotation(document) % 180) {
|
|
*page_width = round(height * scale);
|
|
*page_height = round(width * scale);
|
|
scale = MAX(*page_width / height, *page_height / width);
|
|
} else {
|
|
*page_width = round(width * scale);
|
|
*page_height = round(height * scale);
|
|
scale = MAX(*page_width / width, *page_height / height);
|
|
}
|
|
|
|
return 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);
|
|
|
|
const 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 = 0;
|
|
unsigned int pad = zathura_document_get_page_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 col = floor(pos_x * (double)doc_width / (double)(cell_width + pad));
|
|
unsigned int row = floor(pos_y * (double)doc_height / (double)(cell_height + pad));
|
|
|
|
unsigned int page = ncol * (row % nrow) + (col % ncol);
|
|
if (page < c0 - 1) {
|
|
return 0;
|
|
} else {
|
|
return MIN(page - (c0 - 1), npag - 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);
|
|
}
|
|
|
|
void
|
|
zathura_adjustment_set_value(GtkAdjustment* adjustment, gdouble value)
|
|
{
|
|
gtk_adjustment_set_value(adjustment,
|
|
MAX(gtk_adjustment_get_lower(adjustment),
|
|
MIN(gtk_adjustment_get_upper(adjustment) -
|
|
gtk_adjustment_get_page_size(adjustment),
|
|
value)));
|
|
}
|
|
|
|
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_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);
|
|
}
|