bool sc_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(zathura->document != NULL, false); zathura_document_set_adjust_mode(zathura->document, ZATHURA_ADJUST_NONE); /* retrieve zoom step value */ int value = 1; girara_setting_get(zathura->ui.session, "zoom-step", &value); 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); /* 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); } 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); } else if (argument->n == ZOOM_SPECIFIC) { if (t == 0) { girara_debug("Setting zoom to 1."); zathura_document_set_scale(zathura->document, 1.0); } else { girara_debug("Setting zoom to %f.", t / 100.0); zathura_document_set_scale(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); } else { girara_debug("Setting zoom to 1."); zathura_document_set_scale(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 new_zoom = zathura_document_get_scale(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; } girara_debug("Re-rendering with new zoom level %f.", new_zoom); render_all(zathura); refresh_view(zathura); return false; }
bool sc_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int t) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(zathura->document != NULL, false); zathura_document_set_adjust_mode(zathura->document, ZATHURA_ADJUST_NONE); /* retreive zoom step value */ int value = 1; girara_setting_get(zathura->ui.session, "zoom-step", &value); int nt = (t == 0) ? 1 : t; float zoom_step = value / 100.0f * nt; float old_zoom = zathura_document_get_scale(zathura->document); /* specify new zoom value */ if (argument->n == ZOOM_IN) { zathura_document_set_scale(zathura->document, old_zoom + zoom_step); } else if (argument->n == ZOOM_OUT) { zathura_document_set_scale(zathura->document, old_zoom - zoom_step); } else if (argument->n == ZOOM_SPECIFIC) { if (t == 0) { zathura_document_set_scale(zathura->document, 1.0f); } else { zathura_document_set_scale(zathura->document, t / 100.0f); } } else { zathura_document_set_scale(zathura->document, 1.0f); } /* zoom limitations */ int zoom_min_int = 10; int zoom_max_int = 1000; girara_setting_get(session, "zoom-min", &zoom_min_int); girara_setting_get(session, "zoom-max", &zoom_max_int); float zoom_min = zoom_min_int * 0.01f; float zoom_max = zoom_max_int * 0.01f; float scale = zathura_document_get_scale(zathura->document); if (scale < zoom_min) { zathura_document_set_scale(zathura->document, zoom_min); } else if (scale > zoom_max) { zathura_document_set_scale(zathura->document, zoom_max); } /* keep position */ readjust_view_after_zooming(zathura, old_zoom, true); render_all(zathura); return false; }
bool sc_jumplist(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t)) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(zathura->document != NULL, false); zathura_jump_t* jump = NULL; switch(argument->n) { case FORWARD: zathura_jumplist_save(zathura); zathura_jumplist_forward(zathura); jump = zathura_jumplist_current(zathura); break; case BACKWARD: zathura_jumplist_save(zathura); zathura_jumplist_backward(zathura); jump = zathura_jumplist_current(zathura); break; } if (jump != NULL) { page_set(zathura, jump->page); const double s = zathura_document_get_scale(zathura->document); position_set_delayed(zathura, jump->x * s, jump->y * s); } return false; }
double page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned int* page_width, bool rotate) { g_return_val_if_fail(page != NULL && page_height != NULL && page_width != NULL, 0.0); zathura_document_t* document = zathura_page_get_document(page); if (document == NULL) { return 0.0; } double height = zathura_page_get_height(page); double width = zathura_page_get_width(page); double scale = zathura_document_get_scale(document); double real_scale; if (rotate && zathura_document_get_rotation(document) % 180) { *page_width = ceil(height * scale); *page_height = ceil(width * scale); real_scale = MAX(*page_width / height, *page_height / width); } else { *page_width = ceil(width * scale); *page_height = ceil(height * scale); real_scale = MAX(*page_width / width, *page_height / height); } return real_scale; }
zathura_rectangle_t recalc_rectangle(zathura_page_t* page, zathura_rectangle_t rectangle) { if (page == NULL) { goto error_ret; } zathura_document_t* document = zathura_page_get_document(page); if (document == NULL) { goto error_ret; } double page_height = zathura_page_get_height(page); double page_width = zathura_page_get_width(page); double scale = zathura_document_get_scale(document); zathura_rectangle_t tmp = rotate_rectangle(rectangle, zathura_document_get_rotation(document), page_height, page_width); tmp.x1 *= scale; tmp.x2 *= scale; tmp.y1 *= scale; tmp.y2 *= scale; return tmp; error_ret: return rectangle; }
void cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpointer data) { zathura_t* zathura = data; if (zathura == NULL || zathura->document == NULL || zathura->ui.page_widget == NULL) { return; } GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); GdkRectangle view_rect; /* get current adjustment values */ view_rect.y = 0; view_rect.height = gtk_adjustment_get_page_size(view_vadjustment); view_rect.x = 0; view_rect.width = gtk_adjustment_get_page_size(view_hadjustment); int page_padding = 1; girara_setting_get(zathura->ui.session, "page-padding", &page_padding); GdkRectangle center; center.x = (view_rect.width + 1) / 2; center.y = (view_rect.height + 1) / 2; center.height = center.width = (2 * page_padding) + 1; unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); double scale = zathura_document_get_scale(zathura->document); bool updated = false; /* find page that fits */ for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); GdkRectangle page_rect; GtkWidget* page_widget = zathura_page_get_widget(zathura, page); gtk_widget_translate_coordinates(page_widget, zathura->ui.session->gtk.view, 0, 0, &page_rect.x, &page_rect.y); page_rect.width = zathura_page_get_width(page) * scale; page_rect.height = zathura_page_get_height(page) * scale; if (gdk_rectangle_intersect(&view_rect, &page_rect, NULL) == TRUE) { zathura_page_set_visibility(page, true); if (zathura->global.update_page_number == true && updated == false && gdk_rectangle_intersect(¢er, &page_rect, NULL) == TRUE) { zathura_document_set_current_page_number(zathura->document, page_id); updated = true; } } else { zathura_page_set_visibility(page, false); } zathura_page_widget_update_view_time(ZATHURA_PAGE(page_widget)); } statusbar_page_number_update(zathura); }
double page_calc_height_width(zathura_document_t* document, double height, double width, unsigned int* page_height, unsigned int* page_width, bool rotate) { g_return_val_if_fail(document != NULL && page_height != NULL && page_width != NULL, 0.0); double scale = zathura_document_get_scale(document); if (rotate && zathura_document_get_rotation(document) % 180) { *page_width = round(height * scale); *page_height = round(width * scale); scale = MAX(*page_width / height, *page_height / width); } else { *page_width = round(width * scale); *page_height = round(height * scale); scale = MAX(*page_width / width, *page_height / height); } return scale; }
void mark_add(zathura_t* zathura, int key) { if (zathura == NULL || zathura->document == NULL || zathura->global.marks == NULL) { return; } GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view); GtkAdjustment* v_adjustment = gtk_scrolled_window_get_vadjustment(window); GtkAdjustment* h_adjustment = gtk_scrolled_window_get_hadjustment(window); if (v_adjustment == NULL || h_adjustment == NULL) { return; } double position_x = gtk_adjustment_get_value(h_adjustment); double position_y = gtk_adjustment_get_value(v_adjustment); float scale = zathura_document_get_scale(zathura->document); /* search for existing mark */ GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark) if (mark->key == key) { mark->position_x = position_x; mark->position_y = position_y; mark->scale = scale; return; } GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark); /* add new mark */ zathura_mark_t* mark = g_malloc0(sizeof(zathura_mark_t)); mark->key = key; mark->position_x = position_x; mark->position_y = position_y; mark->scale = scale; girara_list_append(zathura->global.marks, mark); }
void mark_evaluate(zathura_t* zathura, int key) { if (zathura == NULL || zathura->global.marks == NULL) { return; } /* search for existing mark */ GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark) if (mark != NULL && mark->key == key) { double old_scale = zathura_document_get_scale(zathura->document); zathura_document_set_scale(zathura->document, mark->scale); readjust_view_after_zooming(zathura, old_scale, true); render_all(zathura); position_set_delayed(zathura, mark->position_x, mark->position_y); cb_view_vadjustment_value_changed(NULL, zathura); zathura->global.update_page_number = true; return; } GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark); }
void zathura_get_document_size(zathura_t* zathura, unsigned int cell_height, unsigned int cell_width, unsigned int* height, unsigned int* width) { g_return_if_fail(zathura != NULL && zathura->document != NULL && height != NULL && width != NULL); unsigned int pages_per_row = 1; girara_setting_get(zathura->ui.session, "pages-per-row", &pages_per_row); if (pages_per_row == 0) pages_per_row = 1; unsigned int first_page_column = 1; girara_setting_get(zathura->ui.session, "first-page-column", &first_page_column); if (first_page_column < 1) first_page_column = 1; if (first_page_column > pages_per_row) first_page_column = (first_page_column - 1) % pages_per_row + 1; int padding = 1; girara_setting_get(zathura->ui.session, "page-padding", &padding); double scale = zathura_document_get_scale(zathura->document); cell_height = ceil(cell_height * scale); cell_width = ceil(cell_width * scale); *width = pages_per_row * cell_width + (pages_per_row - 1) * padding; unsigned int effective_number_of_pages = zathura_document_get_number_of_pages(zathura->document) + first_page_column - 1; unsigned int rows = effective_number_of_pages / pages_per_row + (effective_number_of_pages % pages_per_row ? 1 : 0); *height = rows * cell_height + (rows - 1) * padding; }
bool sc_toggle_presentation(girara_session_t* session, girara_argument_t* UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t)) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL) { girara_notify(session, GIRARA_WARNING, _("No document opened.")); return false; } const girara_mode_t old_mode = girara_mode_get(session); if (old_mode == zathura->modes.presentation) { /* reset pages per row */ girara_setting_set(session, "pages-per-row", &zathura->shortcut.toggle_presentation_mode.pages); /* reset first page column */ if (zathura->shortcut.toggle_presentation_mode.first_page_column_list != NULL) { girara_setting_set(session, "first-page-column", zathura->shortcut.toggle_presentation_mode.first_page_column_list); } /* show status bar */ gtk_widget_show(GTK_WIDGET(session->gtk.statusbar)); /* 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); render_all(zathura); refresh_view(zathura); /* set mode */ girara_mode_set(session, zathura->modes.normal); } else if (old_mode == zathura->modes.normal) { /* backup pages per row */ girara_setting_get(session, "pages-per-row", &zathura->shortcut.toggle_presentation_mode.pages); /* backup first page column */ g_free(zathura->shortcut.toggle_presentation_mode.first_page_column_list); zathura->shortcut.toggle_presentation_mode.first_page_column_list = NULL; /* this will leak. we need to move the values somewhere else */ girara_setting_get(session, "first-page-column", &zathura->shortcut.toggle_presentation_mode.first_page_column_list); /* set single view */ int int_value = 1; girara_setting_set(session, "pages-per-row", &int_value); /* back up zoom */ zathura->shortcut.toggle_presentation_mode.zoom = zathura_document_get_scale(zathura->document); /* adjust window */ girara_argument_t argument = { ZATHURA_ADJUST_BESTFIT, NULL }; sc_adjust_window(session, &argument, NULL, 0); /* hide status and inputbar */ gtk_widget_hide(GTK_WIDGET(session->gtk.inputbar)); gtk_widget_hide(GTK_WIDGET(session->gtk.statusbar)); /* set full screen */ gtk_window_fullscreen(GTK_WINDOW(session->gtk.window)); refresh_view(zathura); /* set mode */ girara_mode_set(session, zathura->modes.presentation); } return false; }
bool sc_adjust_window(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t)) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; g_return_val_if_fail(argument != NULL, false); unsigned int pages_per_row = 1; girara_setting_get(session, "pages-per-row", &pages_per_row); unsigned int first_page_column = 1; girara_setting_get(session, "first-page-column", &first_page_column); int padding = 1; girara_setting_get(zathura->ui.session, "page-padding", &padding); if (zathura->ui.page_widget == NULL || zathura->document == NULL) { goto error_ret; } float old_zoom = zathura_document_get_scale(zathura->document); zathura_document_set_adjust_mode(zathura->document, argument->n); if (argument->n == ZATHURA_ADJUST_NONE) { /* there is nothing todo */ goto error_ret; } /* get window size */ GtkAllocation allocation; gtk_widget_get_allocation(session->gtk.view, &allocation); unsigned int width = allocation.width; unsigned int height = allocation.height; /* scrollbar spacing */ gint spacing; gtk_widget_style_get(session->gtk.view, "scrollbar_spacing", &spacing, NULL); width -= spacing; /* correct view size */ if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == true) { gtk_widget_get_allocation(session->gtk.inputbar, &allocation); height += allocation.height; } double scale = 1.0; unsigned int cell_height = 0, cell_width = 0; unsigned int document_height = 0, document_width = 0; zathura_document_set_scale(zathura->document, scale); zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width); zathura_get_document_size(zathura, cell_height, cell_width, &document_height, &document_width); double page_ratio = (double)cell_height / (double)document_width; double window_ratio = (double)height / (double)width; if (argument->n == ZATHURA_ADJUST_WIDTH || (argument->n == ZATHURA_ADJUST_BESTFIT && page_ratio < window_ratio)) { scale = (double)(width - (pages_per_row - 1) * padding) / (double)(pages_per_row * cell_width); zathura_document_set_scale(zathura->document, scale); bool show_scrollbars = false; girara_setting_get(session, "show-scrollbars", &show_scrollbars); if (show_scrollbars) { /* If the document is taller than the view, there's a vertical * scrollbar; we need to substract its width from the view's width. */ zathura_get_document_size(zathura, cell_height, cell_width, &document_height, &document_width); if (height < document_height) { GtkWidget* vscrollbar = gtk_scrolled_window_get_vscrollbar( GTK_SCROLLED_WINDOW(session->gtk.view)); if (vscrollbar != NULL) { GtkRequisition requisition; gtk_widget_get_requisition(vscrollbar, &requisition); if (0 < requisition.width && (unsigned)requisition.width < width) { width -= requisition.width; scale = (double)(width - (pages_per_row - 1) * padding) / (double)(pages_per_row * cell_width); zathura_document_set_scale(zathura->document, scale); } } } } } else if (argument->n == ZATHURA_ADJUST_BESTFIT) { scale = (double)height / (double)cell_height; zathura_document_set_scale(zathura->document, scale); } else { goto error_ret; } /* keep position */ readjust_view_after_zooming(zathura, old_zoom, false); /* re-render all pages */ render_all(zathura); error_ret: return false; }
zathura_image_buffer_t* djvu_page_render(zathura_page_t* page, void* UNUSED(data), zathura_error_t* error) { if (page == NULL) { if (error != NULL) { *error = ZATHURA_ERROR_INVALID_ARGUMENTS; } return NULL; } zathura_document_t* document = zathura_page_get_document(page); if (document == NULL) { return NULL; } /* calculate sizes */ unsigned int page_width = zathura_document_get_scale(document) * zathura_page_get_width(page); unsigned int page_height = zathura_document_get_scale(document) * zathura_page_get_height(page); if (page_width == 0 || page_height == 0) { if (error != NULL) { *error = ZATHURA_ERROR_UNKNOWN; } goto error_out; } /* init ddjvu render data */ djvu_document_t* djvu_document = zathura_document_get_data(document); ddjvu_page_t* djvu_page = ddjvu_page_create_by_pageno( djvu_document->document, zathura_page_get_index(page)); if (djvu_page == NULL) { if (error != NULL) { *error = ZATHURA_ERROR_UNKNOWN; } goto error_out; } while (!ddjvu_page_decoding_done(djvu_page)) { handle_messages(djvu_document, true); } ddjvu_rect_t rrect = { 0, 0, page_width, page_height }; ddjvu_rect_t prect = { 0, 0, page_width, page_height }; zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height); if (image_buffer == NULL) { if (error != NULL) { *error = ZATHURA_ERROR_OUT_OF_MEMORY; } goto error_free; } /* set rotation */ ddjvu_page_set_rotation(djvu_page, DDJVU_ROTATE_0); /* render page */ ddjvu_page_render(djvu_page, DDJVU_RENDER_COLOR, &prect, &rrect, djvu_document->format, 3 * page_width, (char*) image_buffer->data); return image_buffer; error_free: ddjvu_page_release(djvu_page); zathura_image_buffer_free(image_buffer); error_out: return NULL; }
bool sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t)) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL) { girara_notify(session, GIRARA_WARNING, _("No document opened.")); return false; } static bool fullscreen = false; static int pages_per_row = 1; static int first_page_column = 1; static double zoom = 1.0; if (fullscreen == true) { /* reset pages per row */ girara_setting_set(session, "pages-per-row", &pages_per_row); /* reset first page column */ girara_setting_set(session, "first-page-column", &first_page_column); /* show status bar */ gtk_widget_show(GTK_WIDGET(session->gtk.statusbar)); /* set full screen */ gtk_window_unfullscreen(GTK_WINDOW(session->gtk.window)); /* reset scale */ zathura_document_set_scale(zathura->document, zoom); render_all(zathura); page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document)); /* setm ode */ girara_mode_set(session, zathura->modes.normal); } else { /* backup pages per row */ girara_setting_get(session, "pages-per-row", &pages_per_row); /* backup first page column */ girara_setting_get(session, "first-page-column", &first_page_column); /* set single view */ int int_value = 1; girara_setting_set(session, "pages-per-row", &int_value); /* back up zoom */ zoom = zathura_document_get_scale(zathura->document); /* adjust window */ girara_argument_t argument = { ZATHURA_ADJUST_BESTFIT, NULL }; sc_adjust_window(session, &argument, NULL, 0); /* hide status and inputbar */ gtk_widget_hide(GTK_WIDGET(session->gtk.inputbar)); gtk_widget_hide(GTK_WIDGET(session->gtk.statusbar)); /* set full screen */ gtk_window_fullscreen(GTK_WINDOW(session->gtk.window)); page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document)); /* setm ode */ girara_mode_set(session, zathura->modes.fullscreen); } fullscreen = fullscreen ? false : true; return false; }
void cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpointer data) { zathura_t* zathura = data; if (zathura == NULL || zathura->document == NULL || zathura->ui.page_widget == NULL) { return; } GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); /* current adjustment values */ GdkRectangle view_rect = { .x = 0, .y = 0, .width = gtk_adjustment_get_page_size(view_hadjustment), .height = gtk_adjustment_get_page_size(view_vadjustment) }; int page_padding = 1; girara_setting_get(zathura->ui.session, "page-padding", &page_padding); GdkRectangle center = { .x = (view_rect.width + 1) / 2, .y = (view_rect.height + 1) / 2, .width = (2 * page_padding) + 1, .height = (2 * page_padding) + 1 }; unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); double scale = zathura_document_get_scale(zathura->document); bool updated = false; /* find page that fits */ for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); GdkRectangle page_rect = { .width = zathura_page_get_width(page) * scale, .height = zathura_page_get_height(page) * scale }; GtkWidget* page_widget = zathura_page_get_widget(zathura, page); gtk_widget_translate_coordinates(page_widget, zathura->ui.session->gtk.view, 0, 0, &page_rect.x, &page_rect.y); if (gdk_rectangle_intersect(&view_rect, &page_rect, NULL) == TRUE) { zathura_page_set_visibility(page, true); if (zathura->global.update_page_number == true && updated == false && gdk_rectangle_intersect(¢er, &page_rect, NULL) == TRUE) { zathura_document_set_current_page_number(zathura->document, page_id); updated = true; } } else { zathura_page_set_visibility(page, false); } zathura_page_widget_update_view_time(ZATHURA_PAGE(page_widget)); } statusbar_page_number_update(zathura); } void cb_pages_per_row_value_changed(girara_session_t* session, const char* UNUSED(name), girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data)) { g_return_if_fail(value != NULL); g_return_if_fail(session != NULL); g_return_if_fail(session->global.data != NULL); zathura_t* zathura = session->global.data; int pages_per_row = *(int*) value; if (pages_per_row < 1) { pages_per_row = 1; } unsigned int first_page_column = 1; girara_setting_get(session, "first-page-column", &first_page_column); page_widget_set_mode(zathura, pages_per_row, first_page_column); if (zathura->document != NULL) { unsigned int current_page = zathura_document_get_current_page_number(zathura->document); page_set_delayed(zathura, current_page); } }
bool sc_scroll(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t)) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; g_return_val_if_fail(argument != NULL, false); if (zathura->document == NULL) { return false; } GtkAdjustment* adjustment = NULL; if ( (argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) || (argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) { adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view)); } else { adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view)); } gdouble view_size = gtk_adjustment_get_page_size(adjustment); gdouble value = gtk_adjustment_get_value(adjustment); gdouble max = gtk_adjustment_get_upper(adjustment) - view_size; zathura->global.update_page_number = true; float scroll_step = 40; girara_setting_get(session, "scroll-step", &scroll_step); float scroll_hstep = -1; girara_setting_get(session, "scroll-hstep", &scroll_hstep); if (scroll_hstep < 0) { scroll_hstep = scroll_step; } float scroll_full_overlap = 0.0; girara_setting_get(session, "scroll-full-overlap", &scroll_full_overlap); bool scroll_page_aware = false; girara_setting_get(session, "scroll-page-aware", &scroll_page_aware); bool scroll_wrap = false; girara_setting_get(session, "scroll-wrap", &scroll_wrap); int padding = 1; girara_setting_get(session, "page-padding", &padding); gdouble new_value; switch(argument->n) { case FULL_UP: case FULL_LEFT: new_value = value - (1.0 - scroll_full_overlap) * view_size - padding; break; case FULL_DOWN: case FULL_RIGHT: new_value = value + (1.0 - scroll_full_overlap) * view_size + padding; break; case HALF_UP: case HALF_LEFT: new_value = value - ((view_size + padding) / 2); break; case HALF_DOWN: case HALF_RIGHT: new_value = value + ((view_size + padding) / 2); break; case LEFT: new_value = value - scroll_hstep; break; case UP: new_value = value - scroll_step; break; case RIGHT: new_value = value + scroll_hstep; break; case DOWN: new_value = value + scroll_step; break; case TOP: new_value = 0; break; case BOTTOM: new_value = max; break; default: new_value = value; } if (scroll_wrap == true) { if (new_value < 0) new_value = max; else if (new_value > max) new_value = 0; } if (scroll_page_aware == true) { int page_offset; double page_size; { unsigned int page_id = zathura_document_get_current_page_number(zathura->document); zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); page_offset_t offset; page_calculate_offset(zathura, page, &offset); double scale = zathura_document_get_scale(zathura->document); if ((argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) || (argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) { page_offset = offset.x; page_size = zathura_page_get_width(page) * scale; } else { page_offset = offset.y; page_size = zathura_page_get_height(page) * scale; } page_offset -= padding / 2; page_size += padding; } if ((argument->n == FULL_DOWN) || (argument->n == HALF_DOWN) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) { if ((page_offset > value) && (page_offset < value + view_size)) { new_value = page_offset; } else if ((page_offset <= value) && (page_offset + page_size < value + view_size)) { new_value = page_offset + page_size + 1; } else if ((page_offset <= value) && (page_offset + page_size < new_value + view_size)) { new_value = page_offset + page_size - view_size + 1; } } else if ((argument->n == FULL_UP) || (argument->n == HALF_UP) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT)) { if ((page_offset + 1 >= value) && (page_offset < value + view_size)) { new_value = page_offset - view_size; } else if ((page_offset <= value) && (page_offset + page_size + 1 < value + view_size)) { new_value = page_offset + page_size - view_size; } else if ((page_offset <= value) && (page_offset > new_value)) { new_value = page_offset; } } } set_adjustment(adjustment, new_value); return false; }
static bool render(zathura_t* zathura, zathura_page_t* page) { if (zathura == NULL || page == NULL || zathura->sync.render_thread->about_to_close == true) { return false; } /* create cairo surface */ unsigned int page_width = 0; unsigned int page_height = 0; page_calc_height_width(page, &page_height, &page_width, false); cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height); if (surface == NULL) { return false; } cairo_t* cairo = cairo_create(surface); if (cairo == NULL) { cairo_surface_destroy(surface); return false; } cairo_save(cairo); cairo_set_source_rgb(cairo, 1, 1, 1); cairo_rectangle(cairo, 0, 0, page_width, page_height); cairo_fill(cairo); cairo_restore(cairo); cairo_save(cairo); double scale = zathura_document_get_scale(zathura->document); if (fabs(scale - 1.0f) > FLT_EPSILON) { cairo_scale(cairo, scale, scale); } render_lock(zathura->sync.render_thread); if (zathura_page_render(page, cairo, false) != ZATHURA_ERROR_OK) { render_unlock(zathura->sync.render_thread); cairo_destroy(cairo); cairo_surface_destroy(surface); return false; } render_unlock(zathura->sync.render_thread); cairo_restore(cairo); cairo_destroy(cairo); const int rowstride = cairo_image_surface_get_stride(surface); unsigned char* image = cairo_image_surface_get_data(surface); /* recolor */ /* uses a representation of a rgb color as follows: - a lightness scalar (between 0,1), which is a weighted average of r, g, b, - a hue vector, which indicates a radian direction from the grey axis, inside the equal lightness plane. - a saturation scalar between 0,1. It is 0 when grey, 1 when the color is in the boundary of the rgb cube. */ if (zathura->global.recolor == true) { /* RGB weights for computing lightness. Must sum to one */ double a[] = {0.30, 0.59, 0.11}; double l1, l2, l, s, u, t; double h[3]; double rgb1[3], rgb2[3], rgb[3]; color2double(&zathura->ui.colors.recolor_dark_color, rgb1); color2double(&zathura->ui.colors.recolor_light_color, rgb2); l1 = (a[0]*rgb1[0] + a[1]*rgb1[1] + a[2]*rgb1[2]); l2 = (a[0]*rgb2[0] + a[1]*rgb2[1] + a[2]*rgb2[2]); for (unsigned int y = 0; y < page_height; y++) { unsigned char* data = image + y * rowstride; for (unsigned int x = 0; x < page_width; x++) { /* Careful. data color components blue, green, red. */ rgb[0] = (double) data[2] / 256.; rgb[1] = (double) data[1] / 256.; rgb[2] = (double) data[0] / 256.; /* compute h, s, l data */ l = a[0]*rgb[0] + a[1]*rgb[1] + a[2]*rgb[2]; h[0] = rgb[0] - l; h[1] = rgb[1] - l; h[2] = rgb[2] - l; /* u is the maximum possible saturation for given h and l. s is a rescaled saturation between 0 and 1 */ u = colorumax(h, l, 0, 1); if (u == 0) { s = 0; } else { s = 1/u; } /* Interpolates lightness between light and dark colors. white goes to light, and black goes to dark. */ t = l; l = t * (l2 - l1) + l1; if (zathura->global.recolor_keep_hue == true) { /* adjusting lightness keeping hue of current color. white and black go to grays of same ligtness as light and dark colors. */ u = colorumax(h, l, l1, l2); data[2] = (unsigned char)round(255.*(l + s*u * h[0])); data[1] = (unsigned char)round(255.*(l + s*u * h[1])); data[0] = (unsigned char)round(255.*(l + s*u * h[2])); } else { /* Linear interpolation between dark and light with color ligtness as a parameter */ data[2] = (unsigned char)round(255.*(t * (rgb2[0] - rgb1[0]) + rgb1[0])); data[1] = (unsigned char)round(255.*(t * (rgb2[1] - rgb1[1]) + rgb1[1])); data[0] = (unsigned char)round(255.*(t * (rgb2[2] - rgb1[2]) + rgb1[2])); } data += 4; } } } if (zathura->sync.render_thread->about_to_close == false) { /* update the widget */ gdk_threads_enter(); GtkWidget* widget = zathura_page_get_widget(zathura, page); zathura_page_widget_update_surface(ZATHURA_PAGE(widget), surface); gdk_threads_leave(); } else { cairo_surface_destroy(surface); } return true; }