From ff679a310bcb0894eadbf36ce4bcd71fc8b8fe9e Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Sun, 11 Feb 2018 15:00:47 +0100 Subject: [PATCH 01/17] Comment fixes --- zathura/adjustment.h | 2 +- zathura/document.c | 4 ++-- zathura/page-widget.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/zathura/adjustment.h b/zathura/adjustment.h index 0ae967c..a1c3da4 100644 --- a/zathura/adjustment.h +++ b/zathura/adjustment.h @@ -8,7 +8,7 @@ #include "document.h" /** - * Calculate the page size according to the corrent scaling and rotation if + * Calculate the page size according to the current scaling and rotation if * desired. * * @param document the document diff --git a/zathura/document.c b/zathura/document.c index bf6539d..b33d186 100644 --- a/zathura/document.c +++ b/zathura/document.c @@ -33,8 +33,8 @@ 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) */ + double cell_width; /**< width of a page cell in the document (not transformed by scale and rotation) */ + double cell_height; /**< height of a page cell in the document (not transformed by scale and rotation) */ unsigned int view_width; /**< width of current viewport */ unsigned int view_height; /**< height of current viewport */ zathura_device_factors_t device_factors; /**< x and y device scale factors (for e.g. HiDPI) */ diff --git a/zathura/page-widget.c b/zathura/page-widget.c index 606268f..b933d4a 100644 --- a/zathura/page-widget.c +++ b/zathura/page-widget.c @@ -317,8 +317,8 @@ set_font_from_property(cairo_t* cairo, zathura_t* zathura, cairo_font_weight_t w const char* family = pango_font_description_get_family(descr); /* get font size: can be points or absolute. - * absolute units: value = 10*PANGO_SCALE = 10 (unscaled) device units (logical pixels) - * point units: value = 10*PANGO_SCALE = 10 points = 10*(font dpi config / 72) device units */ + * absolute units: example: value 10*PANGO_SCALE = 10 (unscaled) device units (logical pixels) + * point units: example: value 10*PANGO_SCALE = 10 points = 10*(font dpi config / 72) device units */ double size = pango_font_description_get_size(descr) / PANGO_SCALE; /* convert point size to device units */ From 553a8ff4283b9a784c6edcb39954a0ac96defd3d Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Sun, 11 Feb 2018 15:03:57 +0100 Subject: [PATCH 02/17] Store monitor DPI in document structure --- zathura/document.c | 20 +++++++++++++++ zathura/document.h | 18 +++++++++++++ zathura/zathura.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ zathura/zathura.h | 7 ++++++ 4 files changed, 108 insertions(+) diff --git a/zathura/document.c b/zathura/document.c index b33d186..d998e0f 100644 --- a/zathura/document.c +++ b/zathura/document.c @@ -37,6 +37,7 @@ struct zathura_document_s { double cell_height; /**< height of a page cell in the document (not transformed by scale and rotation) */ unsigned int view_width; /**< width of current viewport */ unsigned int view_height; /**< height of current viewport */ + double view_dpi; /**cell_height = 0.0; document->view_height = 0; document->view_width = 0; + document->view_dpi = 0.0; document->device_factors.x = 1.0; document->device_factors.y = 1.0; document->position_x = 0.0; @@ -495,6 +497,15 @@ zathura_document_set_viewport_height(zathura_document_t* document, unsigned int document->view_height = height; } +void +zathura_document_set_viewport_dpi(zathura_document_t* document, double dpi) +{ + if (document == NULL) { + return; + } + document->view_dpi = dpi; +} + void zathura_document_get_viewport_size(zathura_document_t* document, unsigned int *height, unsigned int* width) @@ -504,6 +515,15 @@ zathura_document_get_viewport_size(zathura_document_t* document, *width = document->view_width; } +double +zathura_document_get_viewport_dpi(zathura_document_t* document) +{ + if (document == NULL) { + return 0.0; + } + return document->view_dpi; +} + void zathura_document_set_device_factors(zathura_document_t* document, double x_factor, double y_factor) diff --git a/zathura/document.h b/zathura/document.h index a993411..d3b0b12 100644 --- a/zathura/document.h +++ b/zathura/document.h @@ -239,6 +239,15 @@ zathura_document_set_viewport_width(zathura_document_t* document, unsigned int w void zathura_document_set_viewport_height(zathura_document_t* document, unsigned int height); +/** + * Sets the viewport DPI (value based on the physical resolution of the monitor). + * + * @param[in] document The document instance + * @param[in] height The viewport DPI + */ +void +zathura_document_set_viewport_dpi(zathura_document_t* document, double dpi); + /** * Return the size of the viewport in pixels. * @@ -249,6 +258,15 @@ void zathura_document_get_viewport_size(zathura_document_t* document, unsigned int *height, unsigned int* width); +/** + * Return the size of the viewport in pixels. + * + * @param[in] document The document instance + * @return The viewport DPI (value based on the physical resolution of the monitor) + */ +double +zathura_document_get_viewport_dpi(zathura_document_t* document); + /** * Set the device scale factors (e.g. for HiDPI). These are generally integers * and equal for x and y. These scaling factors are only used when rendering to diff --git a/zathura/zathura.c b/zathura/zathura.c index c134fcb..e4c5f45 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -18,6 +18,10 @@ #include #include +#ifdef GDK_WINDOWING_WAYLAND +#include +#endif + #ifdef G_OS_UNIX #include #include @@ -134,6 +138,63 @@ create_directories(zathura_t* zathura) } } +void +zathura_update_view_dpi(zathura_t* zathura) +{ + if (zathura == NULL) { + return; + } + + /* get view widget GdkMonitor */ + GdkWindow* window = gtk_widget_get_window (zathura->ui.session->gtk.view); // NULL if not realized + if (window == NULL) { + return; + } + GdkDisplay* display = gtk_widget_get_display(zathura->ui.session->gtk.view); + if (display == NULL) { + return; + } + GdkMonitor* monitor = gdk_display_get_monitor_at_window(display, window); + if (monitor == NULL) { + return; + } + + /* physical width of monitor */ + int width_mm = gdk_monitor_get_width_mm(monitor); + + /* size of monitor in pixels */ + GdkRectangle monitor_geom; + gdk_monitor_get_geometry(monitor, &monitor_geom); + + /* calculate dpi, knowing that 1 inch = 25.4 mm */ + double dpi = 0.0; + if (width_mm == 0) { + girara_debug("cannot calculate DPI: monitor has zero width"); + } else { + dpi = monitor_geom.width * 25.4 / width_mm; + } + +#ifdef GDK_WINDOWING_WAYLAND + /* work around apparend bug in GDK: on Wayland, monitor geometry doesn't + * return values in application pixels as documented, but in device pixels. + * */ + if (GDK_IS_WAYLAND_DISPLAY(display)) + { + girara_debug("on Wayland, correcting DPI for device scale factor"); + /* not using the cached value for the scale factor here to avoid issues + * if this function is called before the cached value is updated */ + int device_factor = gtk_widget_get_scale_factor(zathura->ui.session->gtk.view); + if (device_factor != 0) { + dpi /= device_factor; + } + } +#endif + + girara_debug("monitor width: %d mm, pixels: %d, dpi: %f", width_mm, monitor_geom.width, dpi); + + zathura_document_set_viewport_dpi(zathura->document, dpi); +} + static bool init_ui(zathura_t* zathura) { @@ -962,6 +1023,8 @@ document_open(zathura_t* zathura, const char* path, const char* uri, const char* const unsigned int view_height = (unsigned int)floor(gtk_adjustment_get_page_size(vadjustment)); zathura_document_set_viewport_height(zathura->document, view_height); + zathura_update_view_dpi(zathura); + /* get initial device scale */ int device_factor = gtk_widget_get_scale_factor(zathura->ui.session->gtk.view); zathura_document_set_device_factors(zathura->document, device_factor, device_factor); diff --git a/zathura/zathura.h b/zathura/zathura.h index 84e0cb6..03785d0 100644 --- a/zathura/zathura.h +++ b/zathura/zathura.h @@ -287,6 +287,13 @@ void zathura_set_plugin_dir(zathura_t* zathura, const char* dir); */ void zathura_set_argv(zathura_t* zathura, char** argv); +/** + * Calculate and store the monitor DPI for the view widget + * + * @param zathura The zathura session + */ +void zathura_update_view_dpi(zathura_t* zathura); + /** * Opens a file * From fc5a344dc1b3704b95326b60b31fca4e58404157 Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Sun, 11 Feb 2018 15:05:42 +0100 Subject: [PATCH 03/17] Use signals to detect DPI change --- zathura/callbacks.c | 39 +++++++++++++++++++++++++++++++++++++++ zathura/callbacks.h | 24 ++++++++++++++++++++++++ zathura/zathura.c | 6 ++++++ 3 files changed, 69 insertions(+) diff --git a/zathura/callbacks.c b/zathura/callbacks.c index c7ba706..bd25819 100644 --- a/zathura/callbacks.c +++ b/zathura/callbacks.c @@ -216,6 +216,44 @@ cb_refresh_view(GtkWidget* GIRARA_UNUSED(view), gpointer data) statusbar_page_number_update(zathura); } +void +cb_monitors_changed(GdkScreen* screen, gpointer data) +{ + girara_debug("signal received"); + + zathura_t* zathura = data; + if (screen == NULL || zathura == NULL) { + return; + } + + zathura_update_view_dpi(zathura); +} + +void +cb_widget_screen_changed(GtkWidget* widget, GdkScreen* UNUSED(previous_screen), gpointer data) +{ + girara_debug("signal received"); + + zathura_t* zathura = data; + if (widget == NULL || zathura == NULL) { + return; + } + + if (gtk_widget_has_screen(widget)) { + GdkScreen* screen = gtk_widget_get_screen(widget); + + /* disconnect signal on previous screen */ + g_signal_handlers_disconnect_matched(screen, G_SIGNAL_MATCH_FUNC, 0, 0, + NULL, (gpointer) cb_monitors_changed, zathura); + + /* connect to new screen */ + g_signal_connect(G_OBJECT(screen), + "monitors-changed", G_CALLBACK(cb_monitors_changed), zathura); + } + + zathura_update_view_dpi(zathura); +} + void cb_scale_factor(GObject* object, GParamSpec* UNUSED(pspec), gpointer data) { @@ -235,6 +273,7 @@ cb_scale_factor(GObject* object, GParamSpec* UNUSED(pspec), gpointer data) fabs(new_factor - current.y) >= DBL_EPSILON) { zathura_document_set_device_factors(zathura->document, new_factor, new_factor); girara_debug("New device scale factor: %d", new_factor); + zathura_update_view_dpi(zathura); render_all(zathura); } } diff --git a/zathura/callbacks.h b/zathura/callbacks.h index 95ee0fe..ab0210c 100644 --- a/zathura/callbacks.h +++ b/zathura/callbacks.h @@ -79,6 +79,30 @@ void cb_view_vadjustment_changed(GtkAdjustment *adjustment, gpointer data); */ void cb_refresh_view(GtkWidget* view, gpointer data); +/** + * This function gets called when the monitors associated with the GdkScreen + * change. + * + * It udpates the stored value for the monitor DPI. + * + * @param screen The GDK screen + * @param gpointer The zathura instance + */ +void cb_monitors_changed(GdkScreen* screen, gpointer data); + +/** + * This function gets called when the screen associated with the view widget + * changes. + * + * It udpates updates the connection on the monitors-changed ignal and the + * stored value for the monitor DPI. + * + * @param widget The view widget + * @param previous_screen The widget's previous screen + * @param gpointer The zathura instance + */ +void cb_widget_screen_changed(GtkWidget* widget, GdkScreen* previous_screen, gpointer data); + /** * This function gets called when the view widget scale factor changes (e.g. * when moving from a regular to a HiDPI screen). diff --git a/zathura/zathura.c b/zathura/zathura.c index e4c5f45..1e7fc67 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -217,6 +217,9 @@ init_ui(zathura_t* zathura) g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view), "notify::scale-factor", G_CALLBACK(cb_scale_factor), zathura); + g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view), + "screen-changed", G_CALLBACK(cb_widget_screen_changed), zathura); + /* page view */ zathura->ui.page_widget = gtk_grid_new(); gtk_grid_set_row_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); @@ -1025,6 +1028,9 @@ document_open(zathura_t* zathura, const char* path, const char* uri, const char* zathura_update_view_dpi(zathura); + /* call screen-changed callback to connect monitors-changed signal on initial screen */ + cb_widget_screen_changed(zathura->ui.session->gtk.view, NULL, zathura); + /* get initial device scale */ int device_factor = gtk_widget_get_scale_factor(zathura->ui.session->gtk.view); zathura_document_set_device_factors(zathura->document, device_factor, device_factor); From 250547cabd9d1ecbd1699f341ee9f7a7396977d8 Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Sun, 11 Feb 2018 15:08:12 +0100 Subject: [PATCH 04/17] Use DPI to scale documents to physical size --- zathura/adjustment.c | 8 ++++++++ zathura/render.c | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/zathura/adjustment.c b/zathura/adjustment.c index 9a10da5..4ae7161 100644 --- a/zathura/adjustment.c +++ b/zathura/adjustment.c @@ -13,6 +13,14 @@ page_calc_height_width(zathura_document_t* document, double height, g_return_val_if_fail(document != NULL && page_height != NULL && page_width != NULL, 0.0); 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); diff --git a/zathura/render.c b/zathura/render.c index 5953de0..e586f3d 100644 --- a/zathura/render.c +++ b/zathura/render.c @@ -740,7 +740,11 @@ render(render_job_t* job, ZathuraRenderRequest* request, ZathuraRenderer* render const double height = zathura_page_get_height(page); const double width = zathura_page_get_width(page); - /* page size in user pixels base on document zoom: 100% results in 1 pixel per point */ + /* page size in user pixels based on document zoom: if DPI information is + * available, 100% results in 72 documents points per inch of screen (i.e. + * document size on screen matching the physical paper size). If DPI + * information is unavailable, the page size in pixels will be 1 pixel per + * document point. */ const double real_scale = page_calc_height_width(document, height, width, &page_height, &page_width, false); From 9bfefaf905290877e070e9860959614f40225f31 Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Sun, 11 Feb 2018 14:48:04 +0100 Subject: [PATCH 05/17] Check GTK+ version for monitor methods --- zathura/zathura.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/zathura/zathura.c b/zathura/zathura.c index 1e7fc67..c73674d 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -154,6 +154,10 @@ zathura_update_view_dpi(zathura_t* zathura) if (display == NULL) { return; } + + double dpi = 0.0; + +#if GTK_CHECK_VERSION(3,22,0) GdkMonitor* monitor = gdk_display_get_monitor_at_window(display, window); if (monitor == NULL) { return; @@ -167,12 +171,12 @@ zathura_update_view_dpi(zathura_t* zathura) gdk_monitor_get_geometry(monitor, &monitor_geom); /* calculate dpi, knowing that 1 inch = 25.4 mm */ - double dpi = 0.0; if (width_mm == 0) { girara_debug("cannot calculate DPI: monitor has zero width"); } else { dpi = monitor_geom.width * 25.4 / width_mm; } +#endif #ifdef GDK_WINDOWING_WAYLAND /* work around apparend bug in GDK: on Wayland, monitor geometry doesn't From d625c0d9bde6a1da664ff14e203f926240195d8d Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Mon, 12 Feb 2018 10:31:13 +0100 Subject: [PATCH 06/17] 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. --- zathura/adjustment.c | 7 ------- zathura/database-plain.c | 6 +++--- zathura/database-sqlite.c | 10 +++++----- zathura/database.h | 2 +- zathura/document.c | 40 ++++++++++++++++++++++++++++----------- zathura/document.h | 17 +++++++++++++---- zathura/links.c | 6 +++--- zathura/marks.c | 12 ++++++------ zathura/page-widget.c | 12 ++++++------ zathura/shortcuts.c | 26 ++++++++++++------------- zathura/types.h | 2 +- zathura/utils.c | 10 +++++----- zathura/utils.h | 10 +++++----- zathura/zathura.c | 32 +++++++++++++++---------------- 14 files changed, 106 insertions(+), 86 deletions(-) diff --git a/zathura/adjustment.c b/zathura/adjustment.c index 4ae7161..b4d70a7 100644 --- a/zathura/adjustment.c +++ b/zathura/adjustment.c @@ -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); diff --git a/zathura/database-plain.c b/zathura/database-plain.c index 17c8438..254a626 100644 --- a/zathura/database-plain.c +++ b/zathura/database-plain.c @@ -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 */ diff --git a/zathura/database-sqlite.c b/zathura/database-sqlite.c index 4d1b146..c75a575 100644 --- a/zathura/database-sqlite.c +++ b/zathura/database-sqlite.c @@ -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)); diff --git a/zathura/database.h b/zathura/database.h index 7c76407..1211a3d 100644 --- a/zathura/database.h +++ b/zathura/database.h @@ -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; diff --git a/zathura/document.c b/zathura/document.c index d998e0f..7eca627 100644 --- a/zathura/document.c +++ b/zathura/document.c @@ -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 diff --git a/zathura/document.h b/zathura/document.h index d3b0b12..629083d 100644 --- a/zathura/document.h +++ b/zathura/document.h @@ -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) diff --git a/zathura/links.c b/zathura/links.c index 47030e2..293691c 100644 --- a/zathura/links.c +++ b/zathura/links.c @@ -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); } diff --git a/zathura/marks.c b/zathura/marks.c index 0433c7f..12eee4f 100644 --- a/zathura/marks.c +++ b/zathura/marks.c @@ -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); diff --git a/zathura/page-widget.c b/zathura/page-widget.c index b933d4a..5c1fc4b 100644 --- a/zathura/page-widget.c +++ b/zathura/page-widget.c @@ -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; diff --git a/zathura/shortcuts.c b/zathura/shortcuts.c index ae3a469..58e4fcb 100644 --- a/zathura/shortcuts.c +++ b/zathura/shortcuts.c @@ -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; diff --git a/zathura/types.h b/zathura/types.h index 0cf1f9b..bf9b2b1 100644 --- a/zathura/types.h +++ b/zathura/types.h @@ -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; /** diff --git a/zathura/utils.c b/zathura/utils.c index 9aeaff3..f9b1e57 100644 --- a/zathura/utils.c +++ b/zathura/utils.c @@ -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; } } diff --git a/zathura/utils.h b/zathura/utils.h index 135eb2e..088b214 100644 --- a/zathura/utils.h +++ b/zathura/utils.h @@ -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); /** diff --git a/zathura/zathura.c b/zathura/zathura.c index c73674d..8439714 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -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: From b4eca29d3ac2956016032d02e2cc8933171f844d Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Mon, 12 Feb 2018 10:55:05 +0100 Subject: [PATCH 07/17] Replace monitor "dpi" with "ppi" This should avoid some confusion with the font DPI --- zathura/callbacks.c | 6 +++--- zathura/callbacks.h | 4 ++-- zathura/document.c | 22 +++++++++++----------- zathura/document.h | 28 +++++++++++++++------------- zathura/render.c | 6 +++--- zathura/zathura.c | 20 ++++++++++---------- zathura/zathura.h | 4 ++-- 7 files changed, 46 insertions(+), 44 deletions(-) diff --git a/zathura/callbacks.c b/zathura/callbacks.c index bd25819..04106c1 100644 --- a/zathura/callbacks.c +++ b/zathura/callbacks.c @@ -226,7 +226,7 @@ cb_monitors_changed(GdkScreen* screen, gpointer data) return; } - zathura_update_view_dpi(zathura); + zathura_update_view_ppi(zathura); } void @@ -251,7 +251,7 @@ cb_widget_screen_changed(GtkWidget* widget, GdkScreen* UNUSED(previous_screen), "monitors-changed", G_CALLBACK(cb_monitors_changed), zathura); } - zathura_update_view_dpi(zathura); + zathura_update_view_ppi(zathura); } void @@ -273,7 +273,7 @@ cb_scale_factor(GObject* object, GParamSpec* UNUSED(pspec), gpointer data) fabs(new_factor - current.y) >= DBL_EPSILON) { zathura_document_set_device_factors(zathura->document, new_factor, new_factor); girara_debug("New device scale factor: %d", new_factor); - zathura_update_view_dpi(zathura); + zathura_update_view_ppi(zathura); render_all(zathura); } } diff --git a/zathura/callbacks.h b/zathura/callbacks.h index ab0210c..ba49f9d 100644 --- a/zathura/callbacks.h +++ b/zathura/callbacks.h @@ -83,7 +83,7 @@ void cb_refresh_view(GtkWidget* view, gpointer data); * This function gets called when the monitors associated with the GdkScreen * change. * - * It udpates the stored value for the monitor DPI. + * It udpates the stored value for the monitor PPI. * * @param screen The GDK screen * @param gpointer The zathura instance @@ -95,7 +95,7 @@ void cb_monitors_changed(GdkScreen* screen, gpointer data); * changes. * * It udpates updates the connection on the monitors-changed ignal and the - * stored value for the monitor DPI. + * stored value for the monitor PPI. * * @param widget The view widget * @param previous_screen The widget's previous screen diff --git a/zathura/document.c b/zathura/document.c index 7eca627..d315273 100644 --- a/zathura/document.c +++ b/zathura/document.c @@ -37,7 +37,7 @@ struct zathura_document_s { double cell_height; /**< height of a page cell in the document (not transformed by scale and rotation) */ unsigned int view_width; /**< width of current viewport */ unsigned int view_height; /**< height of current viewport */ - double view_dpi; /**cell_height = 0.0; document->view_height = 0; document->view_width = 0; - document->view_dpi = 0.0; + document->view_ppi = 0.0; document->device_factors.x = 1.0; document->device_factors.y = 1.0; document->position_x = 0.0; @@ -417,14 +417,14 @@ zathura_document_get_scale(zathura_document_t* document) return 0; } - /* If monitor DPI information is available, use it to match 100% zoom to + /* If monitor PPI 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; + if (document->view_ppi > DBL_EPSILON) { + /* scale = pixels per point, and there are 72 points in one inch */ + return document->zoom * document->view_ppi / 72.0; } - /* No DPI information -> scale == zoom */ + /* No PPI information -> scale == zoom */ return document->zoom; } @@ -516,12 +516,12 @@ zathura_document_set_viewport_height(zathura_document_t* document, unsigned int } void -zathura_document_set_viewport_dpi(zathura_document_t* document, double dpi) +zathura_document_set_viewport_ppi(zathura_document_t* document, double ppi) { if (document == NULL) { return; } - document->view_dpi = dpi; + document->view_ppi = ppi; } void @@ -534,12 +534,12 @@ zathura_document_get_viewport_size(zathura_document_t* document, } double -zathura_document_get_viewport_dpi(zathura_document_t* document) +zathura_document_get_viewport_ppi(zathura_document_t* document) { if (document == NULL) { return 0.0; } - return document->view_dpi; + return document->view_ppi; } void diff --git a/zathura/document.h b/zathura/document.h index 629083d..a4a66dd 100644 --- a/zathura/document.h +++ b/zathura/document.h @@ -151,7 +151,7 @@ double zathura_document_get_zoom(zathura_document_t* document); /** * Returns the current scale value of the document (based on zoom and screen - * DPI) + * PPI) * * @param document The document * @return The current scale value @@ -248,15 +248,6 @@ zathura_document_set_viewport_width(zathura_document_t* document, unsigned int w void zathura_document_set_viewport_height(zathura_document_t* document, unsigned int height); -/** - * Sets the viewport DPI (value based on the physical resolution of the monitor). - * - * @param[in] document The document instance - * @param[in] height The viewport DPI - */ -void -zathura_document_set_viewport_dpi(zathura_document_t* document, double dpi); - /** * Return the size of the viewport in pixels. * @@ -268,13 +259,24 @@ zathura_document_get_viewport_size(zathura_document_t* document, unsigned int *height, unsigned int* width); /** - * Return the size of the viewport in pixels. + Sets the viewport PPI (pixels per inch: the resolution of the monitor, after + scaling with the device factor). * * @param[in] document The document instance - * @return The viewport DPI (value based on the physical resolution of the monitor) + * @param[in] height The viewport PPI + */ +void +zathura_document_set_viewport_ppi(zathura_document_t* document, double ppi); + +/** + * Return the viewport PPI (pixels per inch: the resolution of the monitor, + * after scaling with the device factor). + * + * @param[in] document The document instance + * @return The viewport PPI */ double -zathura_document_get_viewport_dpi(zathura_document_t* document); +zathura_document_get_viewport_ppi(zathura_document_t* document); /** * Set the device scale factors (e.g. for HiDPI). These are generally integers diff --git a/zathura/render.c b/zathura/render.c index e586f3d..a250efc 100644 --- a/zathura/render.c +++ b/zathura/render.c @@ -740,9 +740,9 @@ render(render_job_t* job, ZathuraRenderRequest* request, ZathuraRenderer* render const double height = zathura_page_get_height(page); const double width = zathura_page_get_width(page); - /* page size in user pixels based on document zoom: if DPI information is - * available, 100% results in 72 documents points per inch of screen (i.e. - * document size on screen matching the physical paper size). If DPI + /* page size in user pixels based on document zoom: if PPI information is + * available, 100% zoom results in 72 documents points per inch of screen + * (i.e. document size on screen matching the physical paper size). If PPI * information is unavailable, the page size in pixels will be 1 pixel per * document point. */ const double real_scale = page_calc_height_width(document, height, width, diff --git a/zathura/zathura.c b/zathura/zathura.c index 8439714..d24a95d 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -139,7 +139,7 @@ create_directories(zathura_t* zathura) } void -zathura_update_view_dpi(zathura_t* zathura) +zathura_update_view_ppi(zathura_t* zathura) { if (zathura == NULL) { return; @@ -155,7 +155,7 @@ zathura_update_view_dpi(zathura_t* zathura) return; } - double dpi = 0.0; + double ppi = 0.0; #if GTK_CHECK_VERSION(3,22,0) GdkMonitor* monitor = gdk_display_get_monitor_at_window(display, window); @@ -170,11 +170,11 @@ zathura_update_view_dpi(zathura_t* zathura) GdkRectangle monitor_geom; gdk_monitor_get_geometry(monitor, &monitor_geom); - /* calculate dpi, knowing that 1 inch = 25.4 mm */ + /* calculate ppi, knowing that 1 inch = 25.4 mm */ if (width_mm == 0) { - girara_debug("cannot calculate DPI: monitor has zero width"); + girara_debug("cannot calculate PPI: monitor has zero width"); } else { - dpi = monitor_geom.width * 25.4 / width_mm; + ppi = monitor_geom.width * 25.4 / width_mm; } #endif @@ -184,19 +184,19 @@ zathura_update_view_dpi(zathura_t* zathura) * */ if (GDK_IS_WAYLAND_DISPLAY(display)) { - girara_debug("on Wayland, correcting DPI for device scale factor"); + girara_debug("on Wayland, correcting PPI for device scale factor"); /* not using the cached value for the scale factor here to avoid issues * if this function is called before the cached value is updated */ int device_factor = gtk_widget_get_scale_factor(zathura->ui.session->gtk.view); if (device_factor != 0) { - dpi /= device_factor; + ppi /= device_factor; } } #endif - girara_debug("monitor width: %d mm, pixels: %d, dpi: %f", width_mm, monitor_geom.width, dpi); + girara_debug("monitor width: %d mm, pixels: %d, ppi: %f", width_mm, monitor_geom.width, ppi); - zathura_document_set_viewport_dpi(zathura->document, dpi); + zathura_document_set_viewport_ppi(zathura->document, ppi); } static bool @@ -1030,7 +1030,7 @@ document_open(zathura_t* zathura, const char* path, const char* uri, const char* const unsigned int view_height = (unsigned int)floor(gtk_adjustment_get_page_size(vadjustment)); zathura_document_set_viewport_height(zathura->document, view_height); - zathura_update_view_dpi(zathura); + zathura_update_view_ppi(zathura); /* call screen-changed callback to connect monitors-changed signal on initial screen */ cb_widget_screen_changed(zathura->ui.session->gtk.view, NULL, zathura); diff --git a/zathura/zathura.h b/zathura/zathura.h index 03785d0..e05be81 100644 --- a/zathura/zathura.h +++ b/zathura/zathura.h @@ -288,11 +288,11 @@ void zathura_set_plugin_dir(zathura_t* zathura, const char* dir); void zathura_set_argv(zathura_t* zathura, char** argv); /** - * Calculate and store the monitor DPI for the view widget + * Calculate and store the monitor PPI for the view widget * * @param zathura The zathura session */ -void zathura_update_view_dpi(zathura_t* zathura); +void zathura_update_view_ppi(zathura_t* zathura); /** * Opens a file From 55055758facab7d5abff680ffc78d0a39bae003c Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Mon, 12 Feb 2018 11:05:23 +0100 Subject: [PATCH 08/17] Assume PPI=100 (typical value) if info unavailable --- zathura/document.c | 13 ++++++------- zathura/document.h | 2 +- zathura/render.c | 6 ++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/zathura/document.c b/zathura/document.c index d315273..7023d2d 100644 --- a/zathura/document.c +++ b/zathura/document.c @@ -417,15 +417,14 @@ zathura_document_get_scale(zathura_document_t* document) return 0; } - /* If monitor PPI information is available, use it to match 100% zoom to - * physical page size */ - if (document->view_ppi > DBL_EPSILON) { - /* scale = pixels per point, and there are 72 points in one inch */ - return document->zoom * document->view_ppi / 72.0; + double ppi = document->view_ppi; + if (ppi < DBL_EPSILON) { + /* No PPI information -> use a typical value */ + ppi = 100; } - /* No PPI information -> scale == zoom */ - return document->zoom; + /* scale = pixels per point, and there are 72 points in one inch */ + return document->zoom * ppi / 72.0; } unsigned int diff --git a/zathura/document.h b/zathura/document.h index a4a66dd..42d7e77 100644 --- a/zathura/document.h +++ b/zathura/document.h @@ -154,7 +154,7 @@ double zathura_document_get_zoom(zathura_document_t* document); * PPI) * * @param document The document - * @return The current scale value + * @return The current scale value, in pixels per point */ double zathura_document_get_scale(zathura_document_t* document); diff --git a/zathura/render.c b/zathura/render.c index a250efc..0a85f45 100644 --- a/zathura/render.c +++ b/zathura/render.c @@ -741,10 +741,8 @@ render(render_job_t* job, ZathuraRenderRequest* request, ZathuraRenderer* render const double width = zathura_page_get_width(page); /* page size in user pixels based on document zoom: if PPI information is - * available, 100% zoom results in 72 documents points per inch of screen - * (i.e. document size on screen matching the physical paper size). If PPI - * information is unavailable, the page size in pixels will be 1 pixel per - * document point. */ + * correct, 100% zoom will result in 72 documents points per inch of screen + * (i.e. document size on screen matching the physical paper size). */ const double real_scale = page_calc_height_width(document, height, width, &page_height, &page_width, false); From f6dd3682a8b369687138cd430be157d11c9f28ba Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Mon, 12 Feb 2018 11:05:46 +0100 Subject: [PATCH 09/17] Fix compilation for GTK+ < 3.22 --- zathura/zathura.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zathura/zathura.c b/zathura/zathura.c index d24a95d..3afb68b 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -176,7 +176,6 @@ zathura_update_view_ppi(zathura_t* zathura) } else { ppi = monitor_geom.width * 25.4 / width_mm; } -#endif #ifdef GDK_WINDOWING_WAYLAND /* work around apparend bug in GDK: on Wayland, monitor geometry doesn't @@ -195,6 +194,7 @@ zathura_update_view_ppi(zathura_t* zathura) #endif girara_debug("monitor width: %d mm, pixels: %d, ppi: %f", width_mm, monitor_geom.width, ppi); +#endif zathura_document_set_viewport_ppi(zathura->document, ppi); } From 1a12214a8c2ddd4e785918e4b19d282fa2ba0357 Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Mon, 12 Feb 2018 14:50:14 +0100 Subject: [PATCH 10/17] Bump GTK+ to 3.22 --- README | 2 +- config.mk | 2 +- zathura/zathura.c | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README b/README index 046596f..87e16d4 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ girara user interface library and several document libraries. Requirements ------------ -gtk3 (>= 3.10) +gtk3 (>= 3.22) glib (>= 2.50) girara (>= 0.2.8) sqlite3 (optional, >= 3.5.9) diff --git a/config.mk b/config.mk index 5f0a99a..e7d174c 100644 --- a/config.mk +++ b/config.mk @@ -26,7 +26,7 @@ GLIB_MIN_VERSION = 2.50 GLIB_PKG_CONFIG_NAME = glib-2.0 # GTK GTK_VERSION_CHECK ?= 1 -GTK_MIN_VERSION = 3.10 +GTK_MIN_VERSION = 3.22 GTK_PKG_CONFIG_NAME = gtk+-3.0 # pkg-config binary diff --git a/zathura/zathura.c b/zathura/zathura.c index 3afb68b..299b5bd 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -157,7 +157,6 @@ zathura_update_view_ppi(zathura_t* zathura) double ppi = 0.0; -#if GTK_CHECK_VERSION(3,22,0) GdkMonitor* monitor = gdk_display_get_monitor_at_window(display, window); if (monitor == NULL) { return; @@ -194,7 +193,6 @@ zathura_update_view_ppi(zathura_t* zathura) #endif girara_debug("monitor width: %d mm, pixels: %d, ppi: %f", width_mm, monitor_geom.width, ppi); -#endif zathura_document_set_viewport_ppi(zathura->document, ppi); } From 4f3837c372c73dac31ab7995c59aa0f3069c15b4 Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Mon, 12 Feb 2018 15:18:18 +0100 Subject: [PATCH 11/17] Remove Cairo 1.14 version checks They're no longer needed since GTK+ 3.22 depends on Cairo >= 1.14 --- zathura/page-widget.c | 8 -------- zathura/render.c | 6 ++---- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/zathura/page-widget.c b/zathura/page-widget.c index 5c1fc4b..0f95d2e 100644 --- a/zathura/page-widget.c +++ b/zathura/page-widget.c @@ -496,7 +496,6 @@ zathura_page_widget_get_property(GObject* object, guint prop_id, GValue* value, } } -#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,14,0) static zathura_device_factors_t get_safe_device_factors(cairo_surface_t* surface) { @@ -512,13 +511,6 @@ get_safe_device_factors(cairo_surface_t* surface) return factors; } -#else -static zathura_device_factors_t -get_safe_device_factors(cairo_surface_t* UNUSED(surface)) -{ - return (zathura_device_factors_t){1.0, 1.0}; -} -#endif static gboolean zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) diff --git a/zathura/render.c b/zathura/render.c index 0a85f45..1d7636c 100644 --- a/zathura/render.c +++ b/zathura/render.c @@ -747,20 +747,18 @@ render(render_job_t* job, ZathuraRenderRequest* request, ZathuraRenderer* render &page_height, &page_width, false); -#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,14,0) zathura_device_factors_t device_factors = zathura_document_get_device_factors(document); page_width *= device_factors.x; page_height *= device_factors.y; -#endif cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height); if (surface == NULL) { return false; } -#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,14,0) + cairo_surface_set_device_scale(surface, device_factors.x, device_factors.y); -#endif + if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy(surface); return false; From 09d8a37c8e661c299c6aa8af63c6e69d27b5f02d Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Tue, 13 Feb 2018 20:00:56 +0100 Subject: [PATCH 12/17] Add zoom column to sqlite database if missing --- zathura/database-sqlite.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/zathura/database-sqlite.c b/zathura/database-sqlite.c index c75a575..b744f72 100644 --- a/zathura/database-sqlite.c +++ b/zathura/database-sqlite.c @@ -184,6 +184,10 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path) static const char SQL_FILEINFO_ALTER3[] = "ALTER TABLE fileinfo ADD COLUMN time TIMESTAMP;"; + /* update fileinfo table (part 4) */ + static const char SQL_FILEINFO_ALTER4[] = + "ALTER TABLE fileinfo ADD COLUMN zoom FLOAT;"; + /* update bookmark table */ static const char SQL_BOOKMARK_ALTER[] = "ALTER TABLE bookmarks ADD COLUMN hadj_ratio FLOAT;" @@ -234,6 +238,15 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path) } } + ret1 = check_column(session, "fileinfo", "zoom", &res1); + + if (ret1 == true && res1 == false) { + girara_debug("old database table layout detected; updating ..."); + if (sqlite3_exec(session, SQL_FILEINFO_ALTER4, NULL, 0, NULL) != SQLITE_OK) { + girara_warning("failed to update database table layout"); + } + } + ret1 = check_column(session, "bookmarks", "hadj_ratio", &res1); ret2 = check_column(session, "bookmarks", "vadj_ratio", &res2); From 8b93be947168b5c7a16b921b2c2c65e2395d94de Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Thu, 15 Feb 2018 18:07:20 +0100 Subject: [PATCH 13/17] Add scale/zoom union in link target scale is now deprecated and plugins should use zoom instead --- zathura/links.c | 2 +- zathura/types.h | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/zathura/links.c b/zathura/links.c index 293691c..47c6c38 100644 --- a/zathura/links.c +++ b/zathura/links.c @@ -114,7 +114,7 @@ zathura_link_target_t zathura_link_get_target(zathura_link_t* link) { if (link == NULL) { - zathura_link_target_t target = { 0, NULL, 0, 0, 0, 0, 0, 0 }; + zathura_link_target_t target = { 0, NULL, 0, 0, 0, 0, 0, { 0 } }; return target; } diff --git a/zathura/types.h b/zathura/types.h index bf9b2b1..006890b 100644 --- a/zathura/types.h +++ b/zathura/types.h @@ -179,7 +179,10 @@ typedef struct zathura_link_target_s double right; /**< Right coordinate */ double top; /**< Top coordinate */ double bottom; /**< Bottom coordinate */ - double zoom; /**< Scale */ + union { + double scale; /**< @deprecated Scale */ + double zoom; /**< Zoom */ + }; } zathura_link_target_t; /** From af90d4050d1148e4f9d039b5dfef464e28bda37f Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Fri, 16 Feb 2018 16:42:33 +0100 Subject: [PATCH 14/17] Store monitors-changed handler for disconnection --- zathura/callbacks.c | 16 +++++++++------- zathura/zathura.c | 3 +++ zathura/zathura.h | 2 ++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/zathura/callbacks.c b/zathura/callbacks.c index 04106c1..4499cdb 100644 --- a/zathura/callbacks.c +++ b/zathura/callbacks.c @@ -230,24 +230,26 @@ cb_monitors_changed(GdkScreen* screen, gpointer data) } void -cb_widget_screen_changed(GtkWidget* widget, GdkScreen* UNUSED(previous_screen), gpointer data) +cb_widget_screen_changed(GtkWidget* widget, GdkScreen* previous_screen, gpointer data) { - girara_debug("signal received"); + girara_debug("called"); zathura_t* zathura = data; if (widget == NULL || zathura == NULL) { return; } + /* disconnect previous screen handler if present */ + if (previous_screen != NULL && zathura->signals.monitors_changed_handler > 0) { + g_signal_handler_disconnect(previous_screen, zathura->signals.monitors_changed_handler); + zathura->signals.monitors_changed_handler = 0; + } + if (gtk_widget_has_screen(widget)) { GdkScreen* screen = gtk_widget_get_screen(widget); - /* disconnect signal on previous screen */ - g_signal_handlers_disconnect_matched(screen, G_SIGNAL_MATCH_FUNC, 0, 0, - NULL, (gpointer) cb_monitors_changed, zathura); - /* connect to new screen */ - g_signal_connect(G_OBJECT(screen), + zathura->signals.monitors_changed_handler = g_signal_connect(G_OBJECT(screen), "monitors-changed", G_CALLBACK(cb_monitors_changed), zathura); } diff --git a/zathura/zathura.c b/zathura/zathura.c index 299b5bd..d2e2442 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -222,6 +222,9 @@ init_ui(zathura_t* zathura) g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view), "screen-changed", G_CALLBACK(cb_widget_screen_changed), zathura); + /* initialize the screen-changed handler to 0 (i.e. invalid) */ + zathura->signals.monitors_changed_handler = 0; + /* page view */ zathura->ui.page_widget = gtk_grid_new(); gtk_grid_set_row_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); diff --git a/zathura/zathura.h b/zathura/zathura.h index e05be81..22077cc 100644 --- a/zathura/zathura.h +++ b/zathura/zathura.h @@ -163,6 +163,8 @@ struct zathura_s #ifdef G_OS_UNIX guint sigterm; #endif + + gulong monitors_changed_handler; /**< Signal handler for monitors-changed */ } signals; struct From 1e170f0cab55ae2217d236aaf64b92e9b59cfaf4 Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Fri, 23 Feb 2018 15:02:06 +0100 Subject: [PATCH 15/17] Indentation fix --- zathura/zathura.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/zathura/zathura.c b/zathura/zathura.c index d2e2442..d67eabe 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -177,19 +177,19 @@ zathura_update_view_ppi(zathura_t* zathura) } #ifdef GDK_WINDOWING_WAYLAND - /* work around apparend bug in GDK: on Wayland, monitor geometry doesn't - * return values in application pixels as documented, but in device pixels. - * */ - if (GDK_IS_WAYLAND_DISPLAY(display)) - { - girara_debug("on Wayland, correcting PPI for device scale factor"); - /* not using the cached value for the scale factor here to avoid issues - * if this function is called before the cached value is updated */ - int device_factor = gtk_widget_get_scale_factor(zathura->ui.session->gtk.view); - if (device_factor != 0) { - ppi /= device_factor; - } + /* work around apparent bug in GDK: on Wayland, monitor geometry doesn't + * return values in application pixels as documented, but in device pixels. + * */ + if (GDK_IS_WAYLAND_DISPLAY(display)) + { + /* not using the cached value for the scale factor here to avoid issues + * if this function is called before the cached value is updated */ + int device_factor = gtk_widget_get_scale_factor(zathura->ui.session->gtk.view); + girara_debug("on Wayland, correcting PPI for device scale factor = %d", device_factor); + if (device_factor != 0) { + ppi /= device_factor; } + } #endif girara_debug("monitor width: %d mm, pixels: %d, ppi: %f", width_mm, monitor_geom.width, ppi); From 8e3f05612112fd78df0aaeabb67214bc84549a6c Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Fri, 23 Feb 2018 15:26:43 +0100 Subject: [PATCH 16/17] If new PPI is significantly different, yes render and refresh --- zathura/zathura.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/zathura/zathura.c b/zathura/zathura.c index d67eabe..1e5fe9d 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -192,9 +192,13 @@ zathura_update_view_ppi(zathura_t* zathura) } #endif - girara_debug("monitor width: %d mm, pixels: %d, ppi: %f", width_mm, monitor_geom.width, ppi); - - zathura_document_set_viewport_ppi(zathura->document, ppi); + double current_ppi = zathura_document_get_viewport_ppi(zathura->document); + if (fabs(ppi - current_ppi) > DBL_EPSILON) { + girara_debug("monitor width: %d mm, pixels: %d, ppi: %f", width_mm, monitor_geom.width, ppi); + zathura_document_set_viewport_ppi(zathura->document, ppi); + render_all(zathura); + refresh_view(zathura); + } } static bool From 063b234a2a7b23c0cdad151324abfeeae1ae5751 Mon Sep 17 00:00:00 2001 From: Jeremie Knuesel Date: Fri, 23 Feb 2018 15:28:22 +0100 Subject: [PATCH 17/17] Listen on configure event for PPI changes This allows detection of a PPI change due to the window moving to another monitor --- zathura/callbacks.c | 11 +++++++++++ zathura/callbacks.h | 22 +++++++++++++++++++--- zathura/render.c | 6 ++++-- zathura/zathura.c | 3 +++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/zathura/callbacks.c b/zathura/callbacks.c index 4499cdb..63024da 100644 --- a/zathura/callbacks.c +++ b/zathura/callbacks.c @@ -256,6 +256,17 @@ cb_widget_screen_changed(GtkWidget* widget, GdkScreen* previous_screen, gpointer zathura_update_view_ppi(zathura); } +void +cb_widget_configured(GtkWidget* UNUSED(widget), GdkEvent* UNUSED(event), gpointer data) +{ + zathura_t* zathura = data; + if (zathura == NULL) { + return; + } + + zathura_update_view_ppi(zathura); +} + void cb_scale_factor(GObject* object, GParamSpec* UNUSED(pspec), gpointer data) { diff --git a/zathura/callbacks.h b/zathura/callbacks.h index ba49f9d..bee54e0 100644 --- a/zathura/callbacks.h +++ b/zathura/callbacks.h @@ -83,7 +83,8 @@ void cb_refresh_view(GtkWidget* view, gpointer data); * This function gets called when the monitors associated with the GdkScreen * change. * - * It udpates the stored value for the monitor PPI. + * It checks for a change of monitor PPI, storing the new value and triggering + * a refresh if appropriate. * * @param screen The GDK screen * @param gpointer The zathura instance @@ -94,8 +95,9 @@ void cb_monitors_changed(GdkScreen* screen, gpointer data); * This function gets called when the screen associated with the view widget * changes. * - * It udpates updates the connection on the monitors-changed ignal and the - * stored value for the monitor PPI. + * It updates the connection on the monitors-changed signal and checks for a + * change of monitor PPI, storing the new value and triggering a refresh if + * appropriate. * * @param widget The view widget * @param previous_screen The widget's previous screen @@ -103,6 +105,20 @@ void cb_monitors_changed(GdkScreen* screen, gpointer data); */ void cb_widget_screen_changed(GtkWidget* widget, GdkScreen* previous_screen, gpointer data); +/** + * This function gets called when the main window's size, position or stacking + * changes. + * + * It checks for a change of monitor PPI (due to the window moving between + * different monitors), storing the new value and triggering a refresh if + * appropriate. + * + * @param widget The main window widget + * @param event The configure event + * @param gpointer The zathura instance + */ +void cb_widget_configured(GtkWidget* widget, GdkEvent* event, gpointer data); + /** * This function gets called when the view widget scale factor changes (e.g. * when moving from a regular to a HiDPI screen). diff --git a/zathura/render.c b/zathura/render.c index 1d7636c..e7ddc6c 100644 --- a/zathura/render.c +++ b/zathura/render.c @@ -868,8 +868,10 @@ render_all(zathura_t* zathura) girara_debug("Queuing resize for page %u to %u x %u (%f x %f).", page_id, page_width, page_height, width, height); GtkWidget* widget = zathura_page_get_widget(zathura, page); - gtk_widget_set_size_request(widget, page_width, page_height); - gtk_widget_queue_resize(widget); + if (widget != NULL) { + gtk_widget_set_size_request(widget, page_width, page_height); + gtk_widget_queue_resize(widget); + } } } diff --git a/zathura/zathura.c b/zathura/zathura.c index 1e5fe9d..4516dfe 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -226,6 +226,9 @@ init_ui(zathura_t* zathura) g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view), "screen-changed", G_CALLBACK(cb_widget_screen_changed), zathura); + g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), + "configure-event", G_CALLBACK(cb_widget_configured), zathura); + /* initialize the screen-changed handler to 0 (i.e. invalid) */ zathura->signals.monitors_changed_handler = 0;