mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-28 05:16:01 +01:00
Add option to ignore images while recoloring
Ideally we would handle this differently. See the TODO entry in the render function. But the patch is a start. Thanks to carlos for the patch. Closes: #398 Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
parent
50ea97468c
commit
9a06b5f61e
6 changed files with 122 additions and 3 deletions
17
callbacks.c
17
callbacks.c
|
@ -510,6 +510,23 @@ cb_setting_recolor_keep_hue_change(girara_session_t* session, const char* name,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
cb_setting_recolor_keep_reverse_video_change(girara_session_t* session, const char* 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);
|
||||
g_return_if_fail(name != NULL);
|
||||
zathura_t* zathura = session->global.data;
|
||||
|
||||
const bool bool_value = *((bool*) value);
|
||||
|
||||
if (zathura->sync.render_thread != NULL && zathura_renderer_recolor_reverse_video_enabled(zathura->sync.render_thread) != bool_value) {
|
||||
zathura_renderer_enable_recolor_reverse_video(zathura->sync.render_thread, bool_value);
|
||||
render_all(zathura);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
cb_unknown_command(girara_session_t* session, const char* input)
|
||||
|
|
11
callbacks.h
11
callbacks.h
|
@ -176,6 +176,17 @@ void cb_setting_recolor_change(girara_session_t* session, const char* name,
|
|||
void cb_setting_recolor_keep_hue_change(girara_session_t* session, const char* name,
|
||||
girara_setting_type_t type, void* value, void* data);
|
||||
|
||||
/**
|
||||
* Emitted when the 'recolor-reverse-video' setting is changed
|
||||
*
|
||||
* @param session Girara session
|
||||
* @param name Name of the setting ("recolor")
|
||||
* @param type Type of the setting (BOOLEAN)
|
||||
* @param value New value
|
||||
* @param data Custom data
|
||||
*/
|
||||
void cb_setting_recolor_keep_reverse_video_change(girara_session_t* session,
|
||||
const char* name, girara_setting_type_t type, void* value, void* data);
|
||||
|
||||
/**
|
||||
* Unknown command handler which is used to handle the strict numeric goto
|
||||
|
|
2
config.c
2
config.c
|
@ -186,6 +186,8 @@ config_load_default(zathura_t* zathura)
|
|||
bool_value = false;
|
||||
girara_setting_add(gsession, "recolor-keephue", &bool_value, BOOLEAN, false, _("When recoloring keep original hue and adjust lightness only"), cb_setting_recolor_keep_hue_change, NULL);
|
||||
bool_value = false;
|
||||
girara_setting_add(gsession, "recolor-reverse-video", &bool_value, BOOLEAN, false, _("When recoloring keep original image colors"), cb_setting_recolor_keep_reverse_video_change, NULL);
|
||||
bool_value = false;
|
||||
girara_setting_add(gsession, "scroll-wrap", &bool_value, BOOLEAN, false, _("Wrap scrolling"), NULL, NULL);
|
||||
bool_value = false;
|
||||
girara_setting_add(gsession, "scroll-page-aware", &bool_value, BOOLEAN, false, _("Page aware scrolling"), NULL, NULL);
|
||||
|
|
80
render.c
80
render.c
|
@ -43,6 +43,7 @@ typedef struct private_s {
|
|||
struct {
|
||||
bool enabled;
|
||||
bool hue;
|
||||
bool reverse_video;
|
||||
|
||||
GdkRGBA light;
|
||||
GdkRGBA dark;
|
||||
|
@ -107,6 +108,7 @@ zathura_renderer_init(ZathuraRenderer* renderer)
|
|||
/* recolor */
|
||||
priv->recolor.enabled = false;
|
||||
priv->recolor.hue = true;
|
||||
priv->recolor.reverse_video = false;
|
||||
|
||||
/* page cache */
|
||||
priv->page_cache.size = 0;
|
||||
|
@ -336,6 +338,21 @@ zathura_renderer_enable_recolor_hue(ZathuraRenderer* renderer, bool enable)
|
|||
GET_PRIVATE(renderer)->recolor.hue = enable;
|
||||
}
|
||||
|
||||
bool
|
||||
zathura_renderer_recolor_reverse_video_enabled(ZathuraRenderer* renderer)
|
||||
{
|
||||
g_return_val_if_fail(ZATHURA_IS_RENDERER(renderer), false);
|
||||
|
||||
return GET_PRIVATE(renderer)->recolor.reverse_video;
|
||||
}
|
||||
|
||||
void
|
||||
zathura_renderer_enable_recolor_reverse_video(ZathuraRenderer* renderer, bool enable)
|
||||
{
|
||||
g_return_if_fail(ZATHURA_IS_RENDERER(renderer));
|
||||
|
||||
GET_PRIVATE(renderer)->recolor.reverse_video = enable;
|
||||
}
|
||||
void
|
||||
zathura_renderer_set_recolor_colors(ZathuraRenderer* renderer,
|
||||
const GdkRGBA* light, const GdkRGBA* dark)
|
||||
|
@ -563,8 +580,8 @@ colorumax(const double* h, double l, double l1, double l2)
|
|||
}
|
||||
|
||||
static void
|
||||
recolor(private_t* priv, unsigned int page_width, unsigned int page_height,
|
||||
cairo_surface_t* surface)
|
||||
recolor(private_t* priv, zathura_page_t* page, unsigned int page_width,
|
||||
unsigned int page_height, cairo_surface_t* surface)
|
||||
{
|
||||
/* uses a representation of a rgb color as follows:
|
||||
- a lightness scalar (between 0,1), which is a weighted average of r, g, b,
|
||||
|
@ -574,6 +591,12 @@ recolor(private_t* priv, unsigned int page_width, unsigned int page_height,
|
|||
in the boundary of the rgb cube.
|
||||
*/
|
||||
|
||||
/* TODO: split handling of image handling off
|
||||
* Ideally we would create a mask surface for the location of the images and
|
||||
* we would blit the the recolored and unmodified surfaces together to get the
|
||||
* same effect.
|
||||
*/
|
||||
|
||||
const int rowstride = cairo_image_surface_get_stride(surface);
|
||||
unsigned char* image = cairo_image_surface_get_data(surface);
|
||||
|
||||
|
@ -591,10 +614,54 @@ recolor(private_t* priv, unsigned int page_width, unsigned int page_height,
|
|||
rgb2.blue - rgb1.blue
|
||||
};
|
||||
|
||||
girara_list_t* images = NULL;
|
||||
girara_list_t* rectangles = NULL;
|
||||
bool found_images = false;
|
||||
|
||||
/* If in reverse video mode retrieve images */
|
||||
if (priv->recolor.reverse_video == true) {
|
||||
images = zathura_page_images_get(page, NULL);
|
||||
found_images = (images != NULL);
|
||||
|
||||
rectangles = girara_list_new();
|
||||
if (rectangles == NULL) {
|
||||
found_images = false;
|
||||
girara_warning("Failed to retrieve images.\n");
|
||||
}
|
||||
|
||||
if (found_images == true) {
|
||||
/* Get images bounding boxes */
|
||||
GIRARA_LIST_FOREACH(images, zathura_image_t*, iter, image_it)
|
||||
zathura_rectangle_t* rect = g_try_malloc(sizeof(zathura_rectangle_t));
|
||||
if (rect == NULL) {
|
||||
break;
|
||||
}
|
||||
*rect = recalc_rectangle(page, image_it->position);
|
||||
girara_list_append(rectangles, rect);
|
||||
GIRARA_LIST_FOREACH_END(images, zathura_image_t*, iter, image_it);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int y = 0; y < page_height; y++) {
|
||||
unsigned char* data = image + y * rowstride;
|
||||
|
||||
for (unsigned int x = 0; x < page_width; x++, data += 4) {
|
||||
/* Check if the pixel belongs to an image when in reverse video mode*/
|
||||
if (priv->recolor.reverse_video == true && found_images == true){
|
||||
bool inside_image = false;
|
||||
GIRARA_LIST_FOREACH(rectangles, zathura_rectangle_t*, iter, rect_it)
|
||||
if (rect_it->x1 <= x && rect_it->x2 >= x &&
|
||||
rect_it->y1 <= y && rect_it->y2 >= y) {
|
||||
inside_image = true;
|
||||
break;
|
||||
}
|
||||
GIRARA_LIST_FOREACH_END(rectangles, zathura_rectangle_t*, iter, rect_it);
|
||||
/* If it's inside and image don't recolor */
|
||||
if (inside_image == true) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Careful. data color components blue, green, red. */
|
||||
const double rgb[3] = {
|
||||
(double) data[2] / 256.,
|
||||
|
@ -640,6 +707,13 @@ recolor(private_t* priv, unsigned int page_width, unsigned int page_height,
|
|||
}
|
||||
}
|
||||
|
||||
if (images != NULL) {
|
||||
girara_list_free(images);
|
||||
}
|
||||
if (rectangles != NULL) {
|
||||
girara_list_free(rectangles);
|
||||
}
|
||||
|
||||
#undef rgb1
|
||||
#undef rgb2
|
||||
}
|
||||
|
@ -708,7 +782,7 @@ render(render_job_t* job, ZathuraRenderRequest* request, ZathuraRenderer* render
|
|||
|
||||
/* recolor */
|
||||
if (priv->recolor.enabled == true) {
|
||||
recolor(priv, page_width, page_height, surface);
|
||||
recolor(priv, page, page_width, page_height, surface);
|
||||
}
|
||||
|
||||
emit_completed_signal_t* ecs = g_try_malloc0(sizeof(emit_completed_signal_t));
|
||||
|
|
13
render.h
13
render.h
|
@ -71,6 +71,19 @@ bool zathura_renderer_recolor_hue_enabled(ZathuraRenderer* renderer);
|
|||
*/
|
||||
void zathura_renderer_enable_recolor_hue(ZathuraRenderer* renderer,
|
||||
bool enable);
|
||||
/**
|
||||
* Return whether images should be recolored while recoloring.
|
||||
* @param renderer a renderer object
|
||||
* @returns true if images should be recolored, false otherwise
|
||||
*/
|
||||
bool zathura_renderer_recolor_reverse_video_enabled(ZathuraRenderer* renderer);
|
||||
/**
|
||||
* Enable/disable recoloring of images while recoloring.
|
||||
* @param renderer a renderer object
|
||||
* @param enable or disable images recoloring
|
||||
*/
|
||||
void zathura_renderer_enable_recolor_reverse_video(ZathuraRenderer* renderer,
|
||||
bool enable);
|
||||
/**
|
||||
* Set light and dark colors for recoloring.
|
||||
* @param renderer a renderer object
|
||||
|
|
|
@ -744,6 +744,8 @@ document_open(zathura_t* zathura, const char* path, const char* password,
|
|||
zathura_renderer_enable_recolor(zathura->sync.render_thread, recolor);
|
||||
girara_setting_get(zathura->ui.session, "recolor-keephue", &recolor);
|
||||
zathura_renderer_enable_recolor_hue(zathura->sync.render_thread, recolor);
|
||||
girara_setting_get(zathura->ui.session, "recolor-reverse-video", &recolor);
|
||||
zathura_renderer_enable_recolor_reverse_video(zathura->sync.render_thread, recolor);
|
||||
|
||||
/* get view port size */
|
||||
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(
|
||||
|
|
Loading…
Reference in a new issue