void zathura_document_get_cell_size(zathura_document_t* document, unsigned int* height, unsigned int* width) { g_return_if_fail(document != NULL && height != NULL && width != NULL); unsigned int number_of_pages = zathura_document_get_number_of_pages(document); *width = 0; *height = 0; /* Get the size of each cell of the table/grid, assuming it is homogeneous * (i.e. each cell has the same dimensions. */ for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { zathura_page_t* page = zathura_document_get_page(document, page_id); if (page == NULL) continue; unsigned int page_width = 0, page_height = 0; page_calc_height_width(page, &page_height, &page_width, true); if (*width < page_width) *width = page_width; if (*height < page_height) *height = page_height; } }
void zathura_document_get_cell_size(zathura_document_t* document, unsigned int* height, unsigned int* width) { g_return_if_fail(document != NULL && height != NULL && width != NULL); page_calc_height_width(document, document->cell_height, document->cell_width, height, width, true); }
void render_all(zathura_t* zathura) { if (zathura == NULL || zathura->document == NULL) { return; } /* unmark all pages */ unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); 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); unsigned int page_height = 0, page_width = 0; page_calc_height_width(page, &page_height, &page_width, true); GtkWidget* widget = zathura_page_get_widget(zathura, page); gtk_widget_set_size_request(widget, page_width, page_height); gtk_widget_queue_resize(widget); } }
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; }