mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-28 20:46: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
|
bool
|
||||||
cb_unknown_command(girara_session_t* session, const char* input)
|
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,
|
void cb_setting_recolor_keep_hue_change(girara_session_t* session, const char* name,
|
||||||
girara_setting_type_t type, void* value, void* data);
|
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
|
* 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;
|
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);
|
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;
|
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);
|
girara_setting_add(gsession, "scroll-wrap", &bool_value, BOOLEAN, false, _("Wrap scrolling"), NULL, NULL);
|
||||||
bool_value = false;
|
bool_value = false;
|
||||||
girara_setting_add(gsession, "scroll-page-aware", &bool_value, BOOLEAN, false, _("Page aware scrolling"), NULL, NULL);
|
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 {
|
struct {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
bool hue;
|
bool hue;
|
||||||
|
bool reverse_video;
|
||||||
|
|
||||||
GdkRGBA light;
|
GdkRGBA light;
|
||||||
GdkRGBA dark;
|
GdkRGBA dark;
|
||||||
|
@ -107,6 +108,7 @@ zathura_renderer_init(ZathuraRenderer* renderer)
|
||||||
/* recolor */
|
/* recolor */
|
||||||
priv->recolor.enabled = false;
|
priv->recolor.enabled = false;
|
||||||
priv->recolor.hue = true;
|
priv->recolor.hue = true;
|
||||||
|
priv->recolor.reverse_video = false;
|
||||||
|
|
||||||
/* page cache */
|
/* page cache */
|
||||||
priv->page_cache.size = 0;
|
priv->page_cache.size = 0;
|
||||||
|
@ -336,6 +338,21 @@ zathura_renderer_enable_recolor_hue(ZathuraRenderer* renderer, bool enable)
|
||||||
GET_PRIVATE(renderer)->recolor.hue = 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
|
void
|
||||||
zathura_renderer_set_recolor_colors(ZathuraRenderer* renderer,
|
zathura_renderer_set_recolor_colors(ZathuraRenderer* renderer,
|
||||||
const GdkRGBA* light, const GdkRGBA* dark)
|
const GdkRGBA* light, const GdkRGBA* dark)
|
||||||
|
@ -563,8 +580,8 @@ colorumax(const double* h, double l, double l1, double l2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recolor(private_t* priv, unsigned int page_width, unsigned int page_height,
|
recolor(private_t* priv, zathura_page_t* page, unsigned int page_width,
|
||||||
cairo_surface_t* surface)
|
unsigned int page_height, cairo_surface_t* surface)
|
||||||
{
|
{
|
||||||
/* uses a representation of a rgb color as follows:
|
/* 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 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.
|
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);
|
const int rowstride = cairo_image_surface_get_stride(surface);
|
||||||
unsigned char* image = cairo_image_surface_get_data(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
|
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++) {
|
for (unsigned int y = 0; y < page_height; y++) {
|
||||||
unsigned char* data = image + y * rowstride;
|
unsigned char* data = image + y * rowstride;
|
||||||
|
|
||||||
for (unsigned int x = 0; x < page_width; x++, data += 4) {
|
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. */
|
/* Careful. data color components blue, green, red. */
|
||||||
const double rgb[3] = {
|
const double rgb[3] = {
|
||||||
(double) data[2] / 256.,
|
(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 rgb1
|
||||||
#undef rgb2
|
#undef rgb2
|
||||||
}
|
}
|
||||||
|
@ -708,7 +782,7 @@ render(render_job_t* job, ZathuraRenderRequest* request, ZathuraRenderer* render
|
||||||
|
|
||||||
/* recolor */
|
/* recolor */
|
||||||
if (priv->recolor.enabled == true) {
|
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));
|
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,
|
void zathura_renderer_enable_recolor_hue(ZathuraRenderer* renderer,
|
||||||
bool enable);
|
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.
|
* Set light and dark colors for recoloring.
|
||||||
* @param renderer a renderer object
|
* @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);
|
zathura_renderer_enable_recolor(zathura->sync.render_thread, recolor);
|
||||||
girara_setting_get(zathura->ui.session, "recolor-keephue", &recolor);
|
girara_setting_get(zathura->ui.session, "recolor-keephue", &recolor);
|
||||||
zathura_renderer_enable_recolor_hue(zathura->sync.render_thread, 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 */
|
/* get view port size */
|
||||||
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(
|
GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(
|
||||||
|
|
Loading…
Reference in a new issue