mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2025-01-01 07:26:01 +01:00
Merge branch 'knuesel/zathura-feature/hidpi' into develop
This commit is contained in:
commit
19645cf608
9 changed files with 152 additions and 6 deletions
|
@ -26,7 +26,7 @@ GLIB_MIN_VERSION = 2.50
|
||||||
GLIB_PKG_CONFIG_NAME = glib-2.0
|
GLIB_PKG_CONFIG_NAME = glib-2.0
|
||||||
# GTK
|
# GTK
|
||||||
GTK_VERSION_CHECK ?= 1
|
GTK_VERSION_CHECK ?= 1
|
||||||
GTK_MIN_VERSION = 3.6
|
GTK_MIN_VERSION = 3.10
|
||||||
GTK_PKG_CONFIG_NAME = gtk+-3.0
|
GTK_PKG_CONFIG_NAME = gtk+-3.0
|
||||||
|
|
||||||
# pkg-config binary
|
# pkg-config binary
|
||||||
|
|
|
@ -216,6 +216,29 @@ cb_refresh_view(GtkWidget* GIRARA_UNUSED(view), gpointer data)
|
||||||
statusbar_page_number_update(zathura);
|
statusbar_page_number_update(zathura);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cb_scale_factor(GObject* object, GParamSpec* UNUSED(pspec), gpointer data)
|
||||||
|
{
|
||||||
|
zathura_t* zathura = data;
|
||||||
|
if (zathura == NULL || zathura->document == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int new_factor = gtk_widget_get_scale_factor(GTK_WIDGET(object));
|
||||||
|
if (new_factor == 0) {
|
||||||
|
girara_debug("Ignoring new device scale factor = 0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zathura_device_factors_t current = zathura_document_get_device_factors(zathura->document);
|
||||||
|
if (fabs(new_factor - current.x) >= DBL_EPSILON ||
|
||||||
|
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);
|
||||||
|
render_all(zathura);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cb_page_layout_value_changed(girara_session_t* session, const char* name, girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
|
cb_page_layout_value_changed(girara_session_t* session, const char* name, girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,6 +79,18 @@ void cb_view_vadjustment_changed(GtkAdjustment *adjustment, gpointer data);
|
||||||
*/
|
*/
|
||||||
void cb_refresh_view(GtkWidget* view, gpointer data);
|
void cb_refresh_view(GtkWidget* view, gpointer data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function gets called when the view widget scale factor changes (e.g.
|
||||||
|
* when moving from a regular to a HiDPI screen).
|
||||||
|
*
|
||||||
|
* It records the new value and triggers a re-rendering of the document.
|
||||||
|
*
|
||||||
|
* @param object The view widget
|
||||||
|
* @param pspec The GParamSpec for the scale-factor property
|
||||||
|
* @param gpointer The zathura instance
|
||||||
|
*/
|
||||||
|
void cb_scale_factor(GObject* object, GParamSpec* pspec, gpointer data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function gets called when the value of the "pages-per-row"
|
* This function gets called when the value of the "pages-per-row"
|
||||||
* variable changes
|
* variable changes
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <girara/datastructures.h>
|
#include <girara/datastructures.h>
|
||||||
#include <girara/utils.h>
|
#include <girara/utils.h>
|
||||||
|
@ -36,6 +37,7 @@ struct zathura_document_s {
|
||||||
double cell_height; /**< height of a page cell in the document (not ransformed by scale and rotation) */
|
double cell_height; /**< height of a page cell in the document (not ransformed by scale and rotation) */
|
||||||
unsigned int view_width; /**< width of current viewport */
|
unsigned int view_width; /**< width of current viewport */
|
||||||
unsigned int view_height; /**< height 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) */
|
||||||
unsigned int pages_per_row; /**< number of pages in a row */
|
unsigned int pages_per_row; /**< number of pages in a row */
|
||||||
unsigned int first_page_column; /**< column of the first page */
|
unsigned int first_page_column; /**< column of the first page */
|
||||||
unsigned int page_padding; /**< padding between pages */
|
unsigned int page_padding; /**< padding between pages */
|
||||||
|
@ -132,6 +134,8 @@ zathura_document_open(zathura_t* zathura, const char* path, const char* uri,
|
||||||
document->cell_height = 0.0;
|
document->cell_height = 0.0;
|
||||||
document->view_height = 0;
|
document->view_height = 0;
|
||||||
document->view_width = 0;
|
document->view_width = 0;
|
||||||
|
document->device_factors.x = 1.0;
|
||||||
|
document->device_factors.y = 1.0;
|
||||||
document->position_x = 0.0;
|
document->position_x = 0.0;
|
||||||
document->position_y = 0.0;
|
document->position_y = 0.0;
|
||||||
|
|
||||||
|
@ -500,6 +504,34 @@ zathura_document_get_viewport_size(zathura_document_t* document,
|
||||||
*width = document->view_width;
|
*width = document->view_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zathura_document_set_device_factors(zathura_document_t* document,
|
||||||
|
double x_factor, double y_factor)
|
||||||
|
{
|
||||||
|
if (document == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fabs(x_factor) < DBL_EPSILON || fabs(y_factor) < DBL_EPSILON) {
|
||||||
|
girara_debug("Ignoring new device factors %f and %f: too small",
|
||||||
|
x_factor, y_factor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
document->device_factors.x = x_factor;
|
||||||
|
document->device_factors.y = y_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
zathura_device_factors_t
|
||||||
|
zathura_document_get_device_factors(zathura_document_t* document)
|
||||||
|
{
|
||||||
|
if (document == NULL) {
|
||||||
|
/* The function is guaranteed to not return zero values */
|
||||||
|
return (zathura_device_factors_t){1.0, 1.0};
|
||||||
|
}
|
||||||
|
|
||||||
|
return document->device_factors;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zathura_document_get_cell_size(zathura_document_t* document,
|
zathura_document_get_cell_size(zathura_document_t* document,
|
||||||
unsigned int* height, unsigned int* width)
|
unsigned int* height, unsigned int* width)
|
||||||
|
|
|
@ -249,6 +249,24 @@ void
|
||||||
zathura_document_get_viewport_size(zathura_document_t* document,
|
zathura_document_get_viewport_size(zathura_document_t* document,
|
||||||
unsigned int *height, unsigned int* width);
|
unsigned int *height, unsigned int* width);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* the screen.
|
||||||
|
*
|
||||||
|
* @param[in] x_factor,yfactor The x and y scale factors
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
zathura_document_set_device_factors(zathura_document_t* document,
|
||||||
|
double x_factor, double y_factor);
|
||||||
|
/**
|
||||||
|
* Return the current device scale factors (guaranteed to be non-zero).
|
||||||
|
*
|
||||||
|
* @return The x and y device scale factors
|
||||||
|
*/
|
||||||
|
zathura_device_factors_t
|
||||||
|
zathura_document_get_device_factors(zathura_document_t* document);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the size of a cell from the document's layout table in pixels. Assumes
|
* Return the size of a cell from the document's layout table in pixels. Assumes
|
||||||
* that the table is homogeneous (i.e. every cell has the same dimensions). It
|
* that the table is homogeneous (i.e. every cell has the same dimensions). It
|
||||||
|
|
|
@ -409,6 +409,30 @@ 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)
|
||||||
|
{
|
||||||
|
zathura_device_factors_t factors;
|
||||||
|
cairo_surface_get_device_scale(surface, &factors.x, &factors.y);
|
||||||
|
|
||||||
|
if (fabs(factors.x) < DBL_EPSILON) {
|
||||||
|
factors.x = 1.0;
|
||||||
|
}
|
||||||
|
if (fabs(factors.y) < DBL_EPSILON) {
|
||||||
|
factors.y = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
static gboolean
|
||||||
zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo)
|
zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo)
|
||||||
{
|
{
|
||||||
|
@ -445,8 +469,13 @@ zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo)
|
||||||
} else {
|
} else {
|
||||||
const unsigned int height = cairo_image_surface_get_height(priv->thumbnail);
|
const unsigned int height = cairo_image_surface_get_height(priv->thumbnail);
|
||||||
const unsigned int width = cairo_image_surface_get_width(priv->thumbnail);
|
const unsigned int width = cairo_image_surface_get_width(priv->thumbnail);
|
||||||
const unsigned int pheight = (rotation % 180 ? page_width : page_height);
|
unsigned int pheight = (rotation % 180 ? page_width : page_height);
|
||||||
const unsigned int pwidth = (rotation % 180 ? page_height : page_width);
|
unsigned int pwidth = (rotation % 180 ? page_height : page_width);
|
||||||
|
|
||||||
|
/* note: this always returns 1 and 1 if Cairo too old for device scale API */
|
||||||
|
zathura_device_factors_t device = get_safe_device_factors(priv->thumbnail);
|
||||||
|
pwidth *= device.x;
|
||||||
|
pheight *= device.y;
|
||||||
|
|
||||||
cairo_scale(cairo, pwidth / (double)width, pheight / (double)height);
|
cairo_scale(cairo, pwidth / (double)width, pheight / (double)height);
|
||||||
cairo_set_source_surface(cairo, priv->thumbnail, 0, 0);
|
cairo_set_source_surface(cairo, priv->thumbnail, 0, 0);
|
||||||
|
@ -625,8 +654,14 @@ draw_thumbnail_image(cairo_surface_t* surface, size_t max_size)
|
||||||
width = width * scale;
|
width = width * scale;
|
||||||
height = height * scale;
|
height = height * scale;
|
||||||
|
|
||||||
|
/* note: this always returns 1 and 1 if Cairo too old for device scale API */
|
||||||
|
zathura_device_factors_t device = get_safe_device_factors(surface);
|
||||||
|
const unsigned int user_width = width / device.x;
|
||||||
|
const unsigned int user_height = height / device.y;
|
||||||
|
|
||||||
|
/* create thumbnail surface, taking width and height as device sizes */
|
||||||
cairo_surface_t *thumbnail;
|
cairo_surface_t *thumbnail;
|
||||||
thumbnail = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR, width, height);
|
thumbnail = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR, user_width, user_height);
|
||||||
if (thumbnail == NULL) {
|
if (thumbnail == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -732,20 +732,30 @@ render(render_job_t* job, ZathuraRenderRequest* request, ZathuraRenderer* render
|
||||||
unsigned int page_width = 0;
|
unsigned int page_width = 0;
|
||||||
unsigned int page_height = 0;
|
unsigned int page_height = 0;
|
||||||
|
|
||||||
|
/* page size in points */
|
||||||
zathura_document_t* document = zathura_page_get_document(page);
|
zathura_document_t* document = zathura_page_get_document(page);
|
||||||
const double height = zathura_page_get_height(page);
|
const double height = zathura_page_get_height(page);
|
||||||
const double width = zathura_page_get_width(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 */
|
||||||
const double real_scale = page_calc_height_width(document, height, width,
|
const double real_scale = page_calc_height_width(document, height, width,
|
||||||
&page_height, &page_width,
|
&page_height, &page_width,
|
||||||
false);
|
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,
|
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
|
||||||
page_width, page_height);
|
page_width, page_height);
|
||||||
if (surface == NULL) {
|
if (surface == NULL) {
|
||||||
return false;
|
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) {
|
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
|
||||||
cairo_surface_destroy(surface);
|
cairo_surface_destroy(surface);
|
||||||
return false;
|
return false;
|
||||||
|
@ -759,11 +769,11 @@ render(render_job_t* job, ZathuraRenderRequest* request, ZathuraRenderer* render
|
||||||
|
|
||||||
cairo_save(cairo);
|
cairo_save(cairo);
|
||||||
cairo_set_source_rgb(cairo, 1, 1, 1);
|
cairo_set_source_rgb(cairo, 1, 1, 1);
|
||||||
cairo_rectangle(cairo, 0, 0, page_width, page_height);
|
cairo_paint(cairo);
|
||||||
cairo_fill(cairo);
|
|
||||||
cairo_restore(cairo);
|
cairo_restore(cairo);
|
||||||
cairo_save(cairo);
|
cairo_save(cairo);
|
||||||
|
|
||||||
|
/* apply scale (used by e.g. Poppler as pixels per point) */
|
||||||
if (fabs(real_scale - 1.0f) > FLT_EPSILON) {
|
if (fabs(real_scale - 1.0f) > FLT_EPSILON) {
|
||||||
cairo_scale(cairo, real_scale, real_scale);
|
cairo_scale(cairo, real_scale, real_scale);
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,4 +271,13 @@ void zathura_document_information_entry_free(zathura_document_information_entry_
|
||||||
*/
|
*/
|
||||||
typedef struct zathura_content_type_context_s zathura_content_type_context_t;
|
typedef struct zathura_content_type_context_s zathura_content_type_context_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device scaling structure.
|
||||||
|
*/
|
||||||
|
typedef struct zathura_device_factors_s
|
||||||
|
{
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
} zathura_device_factors_t;
|
||||||
|
|
||||||
#endif // TYPES_H
|
#endif // TYPES_H
|
||||||
|
|
|
@ -153,6 +153,9 @@ init_ui(zathura_t* zathura)
|
||||||
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view), "refresh-view",
|
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view), "refresh-view",
|
||||||
G_CALLBACK(cb_refresh_view), zathura);
|
G_CALLBACK(cb_refresh_view), zathura);
|
||||||
|
|
||||||
|
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view),
|
||||||
|
"notify::scale-factor", G_CALLBACK(cb_scale_factor), zathura);
|
||||||
|
|
||||||
/* page view */
|
/* page view */
|
||||||
zathura->ui.page_widget = gtk_grid_new();
|
zathura->ui.page_widget = gtk_grid_new();
|
||||||
gtk_grid_set_row_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE);
|
gtk_grid_set_row_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE);
|
||||||
|
@ -956,6 +959,10 @@ 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));
|
const unsigned int view_height = (unsigned int)floor(gtk_adjustment_get_page_size(vadjustment));
|
||||||
zathura_document_set_viewport_height(zathura->document, view_height);
|
zathura_document_set_viewport_height(zathura->document, view_height);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
/* create blank pages */
|
/* create blank pages */
|
||||||
zathura->pages = calloc(number_of_pages, sizeof(GtkWidget*));
|
zathura->pages = calloc(number_of_pages, sizeof(GtkWidget*));
|
||||||
if (zathura->pages == NULL) {
|
if (zathura->pages == NULL) {
|
||||||
|
|
Loading…
Reference in a new issue