diff --git a/database-plain.c b/database-plain.c index 65ee461..804d626 100644 --- a/database-plain.c +++ b/database-plain.c @@ -19,6 +19,7 @@ #define KEY_PAGE "page" #define KEY_OFFSET "offset" #define KEY_SCALE "scale" +#define KEY_ROTATE "rotate" #define file_lock_set(fd, cmd) \ { \ @@ -226,7 +227,7 @@ zathura_db_load_bookmarks(zathura_database_t* db, const char* file) bool zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned int - page, int offset, double scale) + page, int offset, double scale, int rotation) { if (db == NULL || db->history == NULL || file == NULL) { return false; @@ -240,6 +241,7 @@ zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned int g_key_file_set_integer(db->history, file, KEY_PAGE, page); g_key_file_set_integer(db->history, file, KEY_OFFSET, offset); g_key_file_set_string (db->history, file, KEY_SCALE, tmp); + g_key_file_set_integer(db->history, file, KEY_ROTATE, rotation); g_free(tmp); @@ -250,10 +252,10 @@ zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned int bool zathura_db_get_fileinfo(zathura_database_t* db, const char* file, unsigned int* - page, int* offset, double* scale) + page, int* offset, double* scale, int* rotation) { if (db == NULL || db->history == NULL || file == NULL || page == NULL || - offset == NULL || scale == NULL) { + offset == NULL || scale == NULL || rotation == NULL) { return false; } @@ -264,6 +266,7 @@ zathura_db_get_fileinfo(zathura_database_t* db, const char* file, unsigned int* *page = g_key_file_get_integer(db->history, file, KEY_PAGE, NULL); *offset = g_key_file_get_integer(db->history, file, KEY_OFFSET, NULL); *scale = strtod(g_key_file_get_string(db->history, file, KEY_SCALE, NULL), NULL); + *rotation = g_key_file_get_integer(db->history, file, KEY_ROTATE, NULL); return true; } diff --git a/database-sqlite.c b/database-sqlite.c index 6ec5d44..3cd8e3b 100644 --- a/database-sqlite.c +++ b/database-sqlite.c @@ -41,7 +41,8 @@ zathura_db_init(const char* dir) "file TEXT PRIMARY KEY," "page INTEGER," "offset INTEGER," - "scale FLOAT);"; + "scale FLOAT," + "rotation INTEGER);"; if (sqlite3_open(path, &(db->session)) != SQLITE_OK) { girara_error("Could not open database: %s\n", path); @@ -198,12 +199,12 @@ zathura_db_load_bookmarks(zathura_database_t* db, const char* file) bool zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned int - page, int offset, double scale) + page, int offset, double scale, int rotation) { g_return_val_if_fail(db && file, false); static const char SQL_FILEINFO_SET[] = - "REPLACE INTO fileinfo (file, page, offset, scale) VALUES (?, ?, ?, ?);"; + "REPLACE INTO fileinfo (file, page, offset, scale, rotation) VALUES (?, ?, ?, ?, ?);"; sqlite3_stmt* stmt = prepare_statement(db->session, SQL_FILEINFO_SET); if (stmt == NULL) { @@ -213,7 +214,8 @@ zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned int if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK || sqlite3_bind_int(stmt, 2, page) != SQLITE_OK || sqlite3_bind_int(stmt, 3, offset) != SQLITE_OK || - sqlite3_bind_double(stmt, 4, scale) != SQLITE_OK) { + sqlite3_bind_double(stmt, 4, scale) != SQLITE_OK || + sqlite3_bind_int(stmt, 5, rotation) != SQLITE_OK) { sqlite3_finalize(stmt); girara_error("Failed to bind arguments."); return false; @@ -226,12 +228,12 @@ zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned int bool zathura_db_get_fileinfo(zathura_database_t* db, const char* file, unsigned int* - page, int* offset, double* scale) + page, int* offset, double* scale, int* rotation) { - g_return_val_if_fail(db && file && page && offset && scale, false); + g_return_val_if_fail(db && file && page && offset && scale && rotation, false); static const char SQL_FILEINFO_GET[] = - "SELECT page, offset, scale FROM fileinfo WHERE file = ?;"; + "SELECT page, offset, scale, rotation FROM fileinfo WHERE file = ?;"; sqlite3_stmt* stmt = prepare_statement(db->session, SQL_FILEINFO_GET); if (stmt == NULL) { @@ -253,6 +255,7 @@ zathura_db_get_fileinfo(zathura_database_t* db, const char* file, unsigned int* *page = sqlite3_column_int(stmt, 0); *offset = sqlite3_column_int(stmt, 1); *scale = sqlite3_column_double(stmt, 2); + *rotation = sqlite3_column_int(stmt, 3); sqlite3_finalize(stmt); return true; } diff --git a/database.h b/database.h index 54f5f2b..44172e5 100644 --- a/database.h +++ b/database.h @@ -64,10 +64,11 @@ girara_list_t* zathura_db_load_bookmarks(zathura_database_t* db, const char* * @param page The last page. * @param offset The last offset. * @param scale The last scale. + * @param rotation The last rotation. * @return true on success, false otherwise. */ bool zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned - int page, int offset, double scale); + int page, int offset, double scale, int rotation); /* Get file info (last site, ...) from the database. * @@ -76,9 +77,10 @@ bool zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned * @param page The last page. * @param offset The last offset. * @param scale The last scale. + * @param rotation The rotation. * @return true on success, false otherwise. */ bool zathura_db_get_fileinfo(zathura_database_t* db, const char* file, unsigned - int* page, int* offset, double* scale); + int* page, int* offset, double* scale, int* rotation); #endif // DATABASE_H diff --git a/document.c b/document.c index cff63b9..77eaef1 100644 --- a/document.c +++ b/document.c @@ -264,7 +264,7 @@ zathura_document_open(zathura_t* zathura, const char* path, const char* password int offset = 0; zathura_db_get_fileinfo(zathura->database, document->file_path, - &document->current_page_number, &offset, &document->scale); + &document->current_page_number, &offset, &document->scale, &document->rotate); if (document->scale <= FLT_EPSILON) { girara_warning("document info: '%s' has non positive scale", document->file_path); document->scale = 1; @@ -466,7 +466,11 @@ zathura_page_get(zathura_document_t* document, unsigned int page_id, zathura_plu page->drawing_area = zathura_page_widget_new(page); page->document = document; - gtk_widget_set_size_request(page->drawing_area, page->width * document->scale, page->height * document->scale); + unsigned int page_height = 0; + unsigned int page_width = 0; + page_calc_height_width(page, &page_height, &page_width, true); + + gtk_widget_set_size_request(page->drawing_area, page_width, page_height); } return page; diff --git a/render.c b/render.c index 2fb2bd9..2311398 100644 --- a/render.c +++ b/render.c @@ -10,22 +10,11 @@ #include "zathura.h" #include "document.h" #include "page_widget.h" +#include "utils.h" void* render_job(void* data); bool render(zathura_t* zathura, zathura_page_t* page); -static void -page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned int* page_width, bool rotate) -{ - if (rotate && page->document->rotate % 180) { - *page_width = ceil(page->height * page->document->scale); - *page_height = ceil(page->width * page->document->scale); - } else { - *page_width = ceil(page->width * page->document->scale); - *page_height = ceil(page->height * page->document->scale); - } -} - void* render_job(void* data) { diff --git a/shortcuts.c b/shortcuts.c index 1aa8eaa..c5da257 100644 --- a/shortcuts.c +++ b/shortcuts.c @@ -326,7 +326,6 @@ sc_rotate(girara_session_t* session, girara_argument_t* UNUSED(argument), zathura->document->rotate = (zathura->document->rotate + 90) % 360; /* render all pages again */ - /* XXX: we don't need to rerender, only to resize the widgets and redraw */ render_all(zathura); page_set_delayed(zathura, page_number); diff --git a/utils.c b/utils.c index 24066ed..36c9cc1 100644 --- a/utils.c +++ b/utils.c @@ -7,6 +7,7 @@ #include #include #include +#include "math.h" #include "utils.h" #include "zathura.h" @@ -189,6 +190,38 @@ page_calculate_offset(zathura_page_t* page, page_offset_t* offset) zathura->ui.page_widget, 0, 0, &(offset->x), &(offset->y)) == true); } +zathura_rectangle_t rotate_rectangle(zathura_rectangle_t rectangle, unsigned int degree, int height, int width) +{ + zathura_rectangle_t tmp; + switch (degree) { + case 90: + tmp.x1 = height - rectangle.y2; + tmp.x2 = height - rectangle.y1; + tmp.y1 = rectangle.x1; + tmp.y2 = rectangle.x2; + break; + case 180: + tmp.x1 = width - rectangle.x2; + tmp.x2 = width - rectangle.x1; + tmp.y1 = height - rectangle.y2; + tmp.y2 = height - rectangle.y1; + break; + case 270: + tmp.x1 = rectangle.y1; + tmp.x2 = rectangle.y2; + tmp.y1 = width - rectangle.x2; + tmp.y2 = width - rectangle.x1; + break; + default: + tmp.x1 = rectangle.x1; + tmp.x2 = rectangle.x2; + tmp.y1 = rectangle.y1; + tmp.y2 = rectangle.y2; + } + + return tmp; +} + zathura_rectangle_t recalc_rectangle(zathura_page_t* page, zathura_rectangle_t rectangle) { @@ -232,3 +265,17 @@ set_adjustment(GtkAdjustment* adjustment, gdouble value) { gtk_adjustment_set_value(adjustment, MAX(adjustment->lower, MIN(adjustment->upper - adjustment->page_size, value))); } + +void +page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned int* page_width, bool rotate) +{ + g_return_if_fail(page != NULL && page_height != NULL && page_width != NULL); + + if (rotate && page->document->rotate % 180) { + *page_width = ceil(page->height * page->document->scale); + *page_height = ceil(page->width * page->document->scale); + } else { + *page_width = ceil(page->width * page->document->scale); + *page_height = ceil(page->height * page->document->scale); + } +} diff --git a/utils.h b/utils.h index 796b417..38124ca 100644 --- a/utils.h +++ b/utils.h @@ -72,6 +72,16 @@ void document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_ */ void page_calculate_offset(zathura_page_t* page, page_offset_t* offset); +/** + * Rotate a rectangle by 0, 90, 180 or 270 degree + * @param rect the rectangle to rotate + * @param degree rotation degree + * @param height the height of the enclosing rectangle + * @param width the width of the enclosing rectangle + * @return the rotated rectangle + */ +zathura_rectangle_t rotate_rectangle(zathura_rectangle_t rectangle, unsigned int degree, int height, int width); + /** * Calculates the new coordinates based on the rotation and scale level of the * document for the given rectangle @@ -89,4 +99,16 @@ zathura_rectangle_t recalc_rectangle(zathura_page_t* page, zathura_rectangle_t r */ void set_adjustment(GtkAdjustment* adjust, gdouble value); +/** + * Calculate the page size according to the corrent scaling and rotation if + * desired. + * @param page the page + * @param page_height the resulting page height + * @param page_width the resultung page width + * @param rotate honor page's rotation + */ +void +page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned int* page_width, bool rotate); + + #endif // UTILS_H diff --git a/zathura.c b/zathura.c index f22e440..11cde2c 100644 --- a/zathura.c +++ b/zathura.c @@ -502,7 +502,8 @@ document_close(zathura_t* zathura) /* store last seen page */ zathura_db_set_fileinfo(zathura->database, zathura->document->file_path, zathura->document->current_page_number + 1, - /* zathura->document->offset TODO */ 0, zathura->document->scale); + /* zathura->document->offset TODO */ 0, zathura->document->scale, + zathura->document->rotate); render_free(zathura->sync.render_thread); zathura->sync.render_thread = NULL;