Distinguish zoom and scale, always apply DPI correction on scale

Replace scale with zoom in most cases. Scale means pixels per point, as
before. The zoom is the screen-size / document-size ratio: a zoom of 1
means that the document should have the same size on screen as on paper.

This fixes many issues with the previous DPI changes, e.g. with link and
search rectangles.
This commit is contained in:
Jeremie Knuesel 2018-02-12 10:31:13 +01:00
parent 9bfefaf905
commit d625c0d9bd
14 changed files with 106 additions and 86 deletions

View file

@ -14,13 +14,6 @@ page_calc_height_width(zathura_document_t* document, double height,
double scale = zathura_document_get_scale(document);
/* If monitor DPI information is available, use it to match 100% zoom to physical page size */
double dpi = zathura_document_get_viewport_dpi(document);
if (fabs(dpi) != DBL_EPSILON) {
/* real scale = 1 means: 1 point = 1 pixel, and there are 72 points in one inch */
scale *= dpi / 72.0;
}
if (rotate == true && zathura_document_get_rotation(document) % 180 != 0) {
*page_width = round(height * scale);
*page_height = round(width * scale);

View file

@ -24,7 +24,7 @@
#define KEY_PAGE "page"
#define KEY_OFFSET "offset"
#define KEY_SCALE "scale"
#define KEY_ZOOM "zoom"
#define KEY_ROTATE "rotate"
#define KEY_PAGES_PER_ROW "pages-per-row"
#define KEY_FIRST_PAGE_COLUMN "first-page-column"
@ -550,7 +550,7 @@ plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t*
g_key_file_set_integer(priv->history, name, KEY_PAGE, file_info->current_page);
g_key_file_set_integer(priv->history, name, KEY_OFFSET, file_info->page_offset);
g_key_file_set_double (priv->history, name, KEY_SCALE, file_info->scale);
g_key_file_set_double (priv->history, name, KEY_ZOOM, file_info->zoom);
g_key_file_set_integer(priv->history, name, KEY_ROTATE, file_info->rotation);
g_key_file_set_integer(priv->history, name, KEY_PAGES_PER_ROW, file_info->pages_per_row);
g_key_file_set_string(priv->history, name, KEY_FIRST_PAGE_COLUMN, file_info->first_page_column_list);
@ -586,7 +586,7 @@ plain_get_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t*
file_info->current_page = g_key_file_get_integer(priv->history, name, KEY_PAGE, NULL);
file_info->page_offset = g_key_file_get_integer(priv->history, name, KEY_OFFSET, NULL);
file_info->scale = g_key_file_get_double (priv->history, name, KEY_SCALE, NULL);
file_info->zoom = g_key_file_get_double (priv->history, name, KEY_ZOOM, NULL);
file_info->rotation = g_key_file_get_integer(priv->history, name, KEY_ROTATE, NULL);
/* the following flags got introduced at a later point */

View file

@ -147,7 +147,7 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path)
"file TEXT PRIMARY KEY,"
"page INTEGER,"
"offset INTEGER,"
"scale FLOAT,"
"zoom FLOAT,"
"rotation INTEGER,"
"pages_per_row INTEGER,"
"first_page_column TEXT,"
@ -640,7 +640,7 @@ sqlite_set_fileinfo(zathura_database_t* db, const char* file,
zathura_sqldatabase_private_t* priv = ZATHURA_SQLDATABASE_GET_PRIVATE(db);
static const char SQL_FILEINFO_SET[] =
"REPLACE INTO fileinfo (file, page, offset, scale, rotation, pages_per_row, first_page_column, position_x, position_y, time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now'));";
"REPLACE INTO fileinfo (file, page, offset, zoom, rotation, pages_per_row, first_page_column, position_x, position_y, time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, DATETIME('now'));";
sqlite3_stmt* stmt = prepare_statement(priv->session, SQL_FILEINFO_SET);
if (stmt == NULL) {
@ -650,7 +650,7 @@ sqlite_set_fileinfo(zathura_database_t* db, const char* file,
if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK ||
sqlite3_bind_int(stmt, 2, file_info->current_page) != SQLITE_OK ||
sqlite3_bind_int(stmt, 3, file_info->page_offset) != SQLITE_OK ||
sqlite3_bind_double(stmt, 4, file_info->scale) != SQLITE_OK ||
sqlite3_bind_double(stmt, 4, file_info->zoom) != SQLITE_OK ||
sqlite3_bind_int(stmt, 5, file_info->rotation) != SQLITE_OK ||
sqlite3_bind_int(stmt, 6, file_info->pages_per_row) != SQLITE_OK ||
sqlite3_bind_text(stmt, 7, file_info->first_page_column_list, -1, NULL)
@ -679,7 +679,7 @@ sqlite_get_fileinfo(zathura_database_t* db, const char* file,
zathura_sqldatabase_private_t* priv = ZATHURA_SQLDATABASE_GET_PRIVATE(db);
static const char SQL_FILEINFO_GET[] =
"SELECT page, offset, scale, rotation, pages_per_row, first_page_column, position_x, position_y FROM fileinfo WHERE file = ?;";
"SELECT page, offset, zoom, rotation, pages_per_row, first_page_column, position_x, position_y FROM fileinfo WHERE file = ?;";
sqlite3_stmt* stmt = prepare_statement(priv->session, SQL_FILEINFO_GET);
if (stmt == NULL) {
@ -700,7 +700,7 @@ sqlite_get_fileinfo(zathura_database_t* db, const char* file,
file_info->current_page = sqlite3_column_int(stmt, 0);
file_info->page_offset = sqlite3_column_int(stmt, 1);
file_info->scale = sqlite3_column_double(stmt, 2);
file_info->zoom = sqlite3_column_double(stmt, 2);
file_info->rotation = sqlite3_column_int(stmt, 3);
file_info->pages_per_row = sqlite3_column_int(stmt, 4);
file_info->first_page_column_list = g_strdup((const char*) sqlite3_column_text(stmt, 5));

View file

@ -12,7 +12,7 @@
typedef struct zathura_fileinfo_s {
unsigned int current_page;
unsigned int page_offset;
double scale;
double zoom;
unsigned int rotation;
unsigned int pages_per_row;
char* first_page_column_list;

View file

@ -28,7 +28,7 @@ struct zathura_document_s {
const char* password; /**< Password of the document */
unsigned int current_page_number; /**< Current page number */
unsigned int number_of_pages; /**< Number of pages */
double scale; /**< Scale value */
double zoom; /**< Zoom value */
unsigned int rotate; /**< Rotation */
void* data; /**< Custom data */
zathura_adjust_mode_t adjust_mode; /**< Adjust mode (best-fit, width) */
@ -128,7 +128,7 @@ zathura_document_open(zathura_t* zathura, const char* path, const char* uri,
g_object_unref(gf);
}
document->password = password;
document->scale = 1.0;
document->zoom = 1.0;
document->plugin = plugin;
document->adjust_mode = ZATHURA_ADJUST_NONE;
document->cell_width = 0.0;
@ -390,6 +390,26 @@ zathura_document_set_position_y(zathura_document_t* document, double position_y)
document->position_y = position_y;
}
double
zathura_document_get_zoom(zathura_document_t* document)
{
if (document == NULL) {
return 0;
}
return document->zoom;
}
void
zathura_document_set_zoom(zathura_document_t* document, double zoom)
{
if (document == NULL) {
return;
}
document->zoom = zoom;
}
double
zathura_document_get_scale(zathura_document_t* document)
{
@ -397,17 +417,15 @@ zathura_document_get_scale(zathura_document_t* document)
return 0;
}
return document->scale;
}
void
zathura_document_set_scale(zathura_document_t* document, double scale)
{
if (document == NULL) {
return;
/* If monitor DPI information is available, use it to match 100% zoom to
* physical page size */
if (document->view_dpi > DBL_EPSILON) {
/* scale 1 means: 1 point = 1 pixel, and there are 72 points in one inch */
return document->zoom * document->view_dpi / 72.0;
}
document->scale = scale;
/* No DPI information -> scale == zoom */
return document->zoom;
}
unsigned int

View file

@ -142,7 +142,16 @@ void zathura_document_set_position_x(zathura_document_t* document, double positi
void zathura_document_set_position_y(zathura_document_t* document, double position_y);
/**
* Returns the current scale value of the document
* Returns the current zoom value of the document
*
* @param document The document
* @return The current zoom value
*/
double zathura_document_get_zoom(zathura_document_t* document);
/**
* Returns the current scale value of the document (based on zoom and screen
* DPI)
*
* @param document The document
* @return The current scale value
@ -150,12 +159,12 @@ void zathura_document_set_position_y(zathura_document_t* document, double positi
double zathura_document_get_scale(zathura_document_t* document);
/**
* Sets the new scale value of the document
* Sets the new zoom value of the document
*
* @param document The document
* @param scale The new scale value
* @param zoom The new zoom value
*/
void zathura_document_set_scale(zathura_document_t* document, double scale);
void zathura_document_set_zoom(zathura_document_t* document, double zoom);
/**
* Returns the rotation value of zathura (0..360)

View file

@ -134,9 +134,9 @@ zathura_link_evaluate(zathura_t* zathura, zathura_link_t* link)
switch (link->type) {
case ZATHURA_LINK_GOTO_DEST:
if (link->target.destination_type != ZATHURA_LINK_DESTINATION_UNKNOWN) {
if (link->target.scale >= DBL_EPSILON && link_zoom) {
zathura_document_set_scale(zathura->document,
zathura_correct_scale_value(zathura->ui.session, link->target.scale));
if (link->target.zoom >= DBL_EPSILON && link_zoom) {
zathura_document_set_zoom(zathura->document,
zathura_correct_zoom_value(zathura->ui.session, link->target.zoom));
render_all(zathura);
}

View file

@ -24,7 +24,7 @@ struct zathura_mark_s {
double position_x; /**> Horizontal adjustment */
double position_y; /**> Vertical adjustment */
unsigned int page; /**> Page number */
double scale; /**> Zoom level */
double zoom; /**> Zoom level */
};
bool
@ -202,7 +202,7 @@ mark_add(zathura_t* zathura, int key)
double position_x = zathura_document_get_position_x(zathura->document);
double position_y = zathura_document_get_position_y(zathura->document);
double scale = zathura_document_get_scale(zathura->document);
double zoom = zathura_document_get_zoom(zathura->document);
/* search for existing mark */
GIRARA_LIST_FOREACH_BODY_WITH_ITER(zathura->global.marks, zathura_mark_t*, iter, mark,
@ -210,7 +210,7 @@ mark_add(zathura_t* zathura, int key)
mark->page = page_id;
mark->position_x = position_x;
mark->position_y = position_y;
mark->scale = scale;
mark->zoom = zoom;
girara_list_iterator_free(iter);
return;
}
@ -226,7 +226,7 @@ mark_add(zathura_t* zathura, int key)
mark->page = page_id;
mark->position_x = position_x;
mark->position_y = position_y;
mark->scale = scale;
mark->zoom = zoom;
girara_list_append(zathura->global.marks, mark);
}
@ -241,8 +241,8 @@ mark_evaluate(zathura_t* zathura, int key)
/* search for existing mark */
GIRARA_LIST_FOREACH_BODY(zathura->global.marks, zathura_mark_t*, mark,
if (mark != NULL && mark->key == key) {
zathura_document_set_scale(zathura->document,
zathura_correct_scale_value(zathura->ui.session, mark->scale));
zathura_document_set_zoom(zathura->document,
zathura_correct_zoom_value(zathura->ui.session, mark->zoom));
render_all(zathura);
zathura_jumplist_add(zathura);

View file

@ -690,9 +690,9 @@ zathura_page_widget_redraw_canvas(ZathuraPage* pageview)
}
/* smaller than max to be replaced by actual renders */
#define THUMBNAIL_INITIAL_SCALE 0.5
#define THUMBNAIL_INITIAL_ZOOM 0.5
/* small enough to make bilinear downscaling fast */
#define THUMBNAIL_MAX_SCALE 0.5
#define THUMBNAIL_MAX_ZOOM 0.5
static bool
surface_small_enough(cairo_surface_t* surface, size_t max_size, cairo_surface_t* old)
@ -712,7 +712,7 @@ surface_small_enough(cairo_surface_t* surface, size_t max_size, cairo_surface_t*
const unsigned int width_old = cairo_image_surface_get_width(old);
const unsigned int height_old = cairo_image_surface_get_height(old);
const size_t old_size = width_old * height_old;
if (new_size < old_size && new_size >= old_size * THUMBNAIL_MAX_SCALE * THUMBNAIL_MAX_SCALE) {
if (new_size < old_size && new_size >= old_size * THUMBNAIL_MAX_ZOOM * THUMBNAIL_MAX_ZOOM) {
return false;
}
}
@ -725,9 +725,9 @@ draw_thumbnail_image(cairo_surface_t* surface, size_t max_size)
{
unsigned int width = cairo_image_surface_get_width(surface);
unsigned int height = cairo_image_surface_get_height(surface);
double scale = sqrt((double)max_size / (width * height)) * THUMBNAIL_INITIAL_SCALE;
if (scale > THUMBNAIL_MAX_SCALE) {
scale = THUMBNAIL_MAX_SCALE;
double scale = sqrt((double)max_size / (width * height)) * THUMBNAIL_INITIAL_ZOOM;
if (scale > THUMBNAIL_MAX_ZOOM) {
scale = THUMBNAIL_MAX_ZOOM;
}
width = width * scale;
height = height * scale;

View file

@ -1304,8 +1304,8 @@ sc_toggle_presentation(girara_session_t* session, girara_argument_t*
/* set full screen */
gtk_window_unfullscreen(GTK_WINDOW(session->gtk.window));
/* reset scale */
zathura_document_set_scale(zathura->document, zathura->shortcut.toggle_presentation_mode.zoom);
/* reset zoom */
zathura_document_set_zoom(zathura->document, zathura->shortcut.toggle_presentation_mode.zoom);
render_all(zathura);
refresh_view(zathura);
@ -1326,7 +1326,7 @@ sc_toggle_presentation(girara_session_t* session, girara_argument_t*
girara_setting_set(session, "pages-per-row", &int_value);
/* back up zoom */
zathura->shortcut.toggle_presentation_mode.zoom = zathura_document_get_scale(zathura->document);
zathura->shortcut.toggle_presentation_mode.zoom = zathura_document_get_zoom(zathura->document);
/* adjust window */
girara_argument_t argument = { ZATHURA_ADJUST_BESTFIT, NULL };
@ -1379,37 +1379,37 @@ sc_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t*
const int nt = (t == 0) ? 1 : t;
const double zoom_step = 1.0 + value / 100.0 * nt;
const double old_zoom = zathura_document_get_scale(zathura->document);
const double old_zoom = zathura_document_get_zoom(zathura->document);
/* specify new zoom value */
if (argument->n == ZOOM_IN) {
girara_debug("Increasing zoom by %f.", zoom_step - 1.0);
zathura_document_set_scale(zathura->document, old_zoom * zoom_step);
zathura_document_set_zoom(zathura->document, old_zoom * zoom_step);
} else if (argument->n == ZOOM_OUT) {
girara_debug("Decreasing zoom by %f.", zoom_step - 1.0);
zathura_document_set_scale(zathura->document, old_zoom / zoom_step);
zathura_document_set_zoom(zathura->document, old_zoom / zoom_step);
} else if (argument->n == ZOOM_SPECIFIC) {
if (t == 0) {
girara_debug("Setting zoom to 1.");
zathura_document_set_scale(zathura->document, 1.0);
zathura_document_set_zoom(zathura->document, 1.0);
} else {
girara_debug("Setting zoom to %f.", t / 100.0);
zathura_document_set_scale(zathura->document, t / 100.0);
zathura_document_set_zoom(zathura->document, t / 100.0);
}
} else if (argument->n == ZOOM_SMOOTH) {
const double dy = (event != NULL) ? event->y : 1.0;
girara_debug("Increasing zoom by %f.", zoom_step * dy - 1.0);
zathura_document_set_scale(zathura->document, old_zoom + zoom_step * dy);
zathura_document_set_zoom(zathura->document, old_zoom + zoom_step * dy);
} else {
girara_debug("Setting zoom to 1.");
zathura_document_set_scale(zathura->document, 1.0);
zathura_document_set_zoom(zathura->document, 1.0);
}
/* zoom limitations */
const double scale = zathura_document_get_scale(zathura->document);
zathura_document_set_scale(zathura->document, zathura_correct_scale_value(session, scale));
const double zoom = zathura_document_get_zoom(zathura->document);
zathura_document_set_zoom(zathura->document, zathura_correct_zoom_value(session, zoom));
const double new_zoom = zathura_document_get_scale(zathura->document);
const double new_zoom = zathura_document_get_zoom(zathura->document);
if (fabs(new_zoom - old_zoom) <= DBL_EPSILON) {
girara_debug("New and old zoom level are too close: %f vs. %f, diff = %f", new_zoom, old_zoom, fabs(new_zoom - old_zoom));
return false;

View file

@ -179,7 +179,7 @@ typedef struct zathura_link_target_s
double right; /**< Right coordinate */
double top; /**< Top coordinate */
double bottom; /**< Bottom coordinate */
double scale; /**< Scale */
double zoom; /**< Scale */
} zathura_link_target_t;
/**

View file

@ -21,10 +21,10 @@
#include "content-type.h"
double
zathura_correct_scale_value(girara_session_t* session, const double scale)
zathura_correct_zoom_value(girara_session_t* session, const double zoom)
{
if (session == NULL) {
return scale;
return zoom;
}
/* zoom limitations */
@ -36,12 +36,12 @@ zathura_correct_scale_value(girara_session_t* session, const double scale)
const double zoom_min = zoom_min_int * 0.01;
const double zoom_max = zoom_max_int * 0.01;
if (scale < zoom_min) {
if (zoom < zoom_min) {
return zoom_min;
} else if (scale > zoom_max) {
} else if (zoom > zoom_max) {
return zoom_max;
} else {
return scale;
return zoom;
}
}

View file

@ -96,16 +96,16 @@ char* zathura_get_version_string(zathura_t* zathura, bool markup);
GdkAtom* get_selection(zathura_t* zathura);
/**
* Returns the valid scale value which needs to lie in the interval of zoom_min
* Returns the valid zoom value which needs to lie in the interval of zoom_min
* and zoom_max specified in the girara session
*
* @param[in] session The session
* @param[in] scale The proposed scale value
* @param[in] zoom The proposed zoom value
*
* @return The corrected scale value
* @return The corrected zoom value
*/
double zathura_correct_scale_value(girara_session_t* session, const double
scale);
double zathura_correct_zoom_value(girara_session_t* session, const double
zoom);
/**

View file

@ -873,7 +873,7 @@ document_open(zathura_t* zathura, const char* path, const char* uri, const char*
zathura_fileinfo_t file_info = {
.current_page = 0,
.page_offset = 0,
.scale = 1,
.zoom = 1,
.rotation = 0,
.pages_per_row = 0,
.first_page_column_list = NULL,
@ -888,12 +888,12 @@ document_open(zathura_t* zathura, const char* path, const char* uri, const char*
/* set page offset */
zathura_document_set_page_offset(document, file_info.page_offset);
/* check for valid scale value */
if (file_info.scale <= DBL_EPSILON) {
file_info.scale = 1;
/* check for valid zoom value */
if (file_info.zoom <= DBL_EPSILON) {
file_info.zoom = 1;
}
zathura_document_set_scale(document,
zathura_correct_scale_value(zathura->ui.session, file_info.scale));
zathura_document_set_zoom(document,
zathura_correct_zoom_value(zathura->ui.session, file_info.zoom));
/* check current page number */
/* if it wasn't specified on the command-line, get it from file_info */
@ -1264,7 +1264,7 @@ save_fileinfo_to_db(zathura_t* zathura)
zathura_fileinfo_t file_info = {
.current_page = zathura_document_get_current_page_number(zathura->document),
.page_offset = zathura_document_get_page_offset(zathura->document),
.scale = zathura_document_get_scale(zathura->document),
.zoom = zathura_document_get_zoom(zathura->document),
.rotation = zathura_document_get_rotation(zathura->document),
.pages_per_row = 1,
.first_page_column_list = "1:2",
@ -1558,31 +1558,31 @@ adjust_view(zathura_t* zathura)
double page_ratio = (double)cell_height / (double)document_width;
double view_ratio = (double)view_height / (double)view_width;
double scale = zathura_document_get_scale(zathura->document);
double newscale = scale;
double zoom = zathura_document_get_zoom(zathura->document);
double newzoom = zoom;
if (adjust_mode == ZATHURA_ADJUST_WIDTH ||
(adjust_mode == ZATHURA_ADJUST_BESTFIT && page_ratio < view_ratio)) {
newscale *= (double)view_width / (double)document_width;
newzoom *= (double)view_width / (double)document_width;
} else if (adjust_mode == ZATHURA_ADJUST_BESTFIT) {
newscale *= (double)view_height / (double)cell_height;
newzoom *= (double)view_height / (double)cell_height;
} else {
goto error_ret;
}
/* save new scale and recompute cell size */
zathura_document_set_scale(zathura->document, newscale);
/* save new zoom and recompute cell size */
zathura_document_set_zoom(zathura->document, newzoom);
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 the change in zoom changes page cell dimensions by at least one pixel, render */
if (abs((int)new_cell_width - (int)cell_width) > 1 ||
abs((int)new_cell_height - (int)cell_height) > 1) {
render_all(zathura);
refresh_view(zathura);
} else {
/* otherwise set the old scale and leave */
zathura_document_set_scale(zathura->document, scale);
/* otherwise set the old zoom and leave */
zathura_document_set_zoom(zathura->document, zoom);
}
error_ret: