mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2025-01-15 05:26:00 +01:00
Move recolor code into separate function
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
parent
8a9bd7f512
commit
8d53833d81
1 changed files with 81 additions and 77 deletions
158
render.c
158
render.c
|
@ -430,6 +430,86 @@ emit_completed_signal(void* data)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recolor(private_t* priv, 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,
|
||||||
|
- 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const int rowstride = cairo_image_surface_get_stride(surface);
|
||||||
|
unsigned char* image = cairo_image_surface_get_data(surface);
|
||||||
|
|
||||||
|
/* RGB weights for computing lightness. Must sum to one */
|
||||||
|
static const double a[] = {0.30, 0.59, 0.11};
|
||||||
|
|
||||||
|
#define rgb1 priv->recolor.dark
|
||||||
|
#define rgb2 priv->recolor.light
|
||||||
|
const double l1 = (a[0]*rgb1[0] + a[1]*rgb1[1] + a[2]*rgb1[2]);
|
||||||
|
const double l2 = (a[0]*rgb2[0] + a[1]*rgb2[1] + a[2]*rgb2[2]);
|
||||||
|
|
||||||
|
const double rgb_diff[] = {
|
||||||
|
rgb2[0] - rgb1[0],
|
||||||
|
rgb2[1] - rgb1[1],
|
||||||
|
rgb2[2] - rgb1[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++, data += 4) {
|
||||||
|
/* Careful. data color components blue, green, red. */
|
||||||
|
const double rgb[3] = {
|
||||||
|
(double) data[2] / 256.,
|
||||||
|
(double) data[1] / 256.,
|
||||||
|
(double) data[0] / 256.
|
||||||
|
};
|
||||||
|
|
||||||
|
/* compute h, s, l data */
|
||||||
|
double l = a[0]*rgb[0] + a[1]*rgb[1] + a[2]*rgb[2];
|
||||||
|
|
||||||
|
if (priv->recolor.hue == true) {
|
||||||
|
/* adjusting lightness keeping hue of current color. white and black
|
||||||
|
* go to grays of same ligtness as light and dark colors. */
|
||||||
|
const double h[3] = {
|
||||||
|
rgb[0] - l,
|
||||||
|
rgb[1] - l,
|
||||||
|
rgb[2] - l
|
||||||
|
};
|
||||||
|
|
||||||
|
/* u is the maximum possible saturation for given h and l. s is a
|
||||||
|
* rescaled saturation between 0 and 1 */
|
||||||
|
double u = colorumax(h, l, 0, 1);
|
||||||
|
double s = 0;
|
||||||
|
if (u != 0) {
|
||||||
|
s = 1/u;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interpolates lightness between light and dark colors. white goes to
|
||||||
|
* light, and black goes to dark. */
|
||||||
|
l = l * (l2 - l1) + l1;
|
||||||
|
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.*(l * rgb_diff[0] + rgb1[0]));
|
||||||
|
data[1] = (unsigned char)round(255.*(l * rgb_diff[1] + rgb1[1]));
|
||||||
|
data[0] = (unsigned char)round(255.*(l * rgb_diff[2] + rgb1[2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef rgb1
|
||||||
|
#undef rgb2
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
render(ZathuraRenderRequest* request, ZathuraRenderer* renderer)
|
render(ZathuraRenderRequest* request, ZathuraRenderer* renderer)
|
||||||
{
|
{
|
||||||
|
@ -482,85 +562,9 @@ render(ZathuraRenderRequest* request, ZathuraRenderer* renderer)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* recolor */
|
/* 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 (priv->recolor.enabled == true) {
|
if (priv->recolor.enabled == true) {
|
||||||
const int rowstride = cairo_image_surface_get_stride(surface);
|
recolor(priv, page_width, page_height, surface);
|
||||||
unsigned char* image = cairo_image_surface_get_data(surface);
|
|
||||||
|
|
||||||
/* RGB weights for computing lightness. Must sum to one */
|
|
||||||
static const double a[] = {0.30, 0.59, 0.11};
|
|
||||||
|
|
||||||
#define rgb1 priv->recolor.dark
|
|
||||||
#define rgb2 priv->recolor.light
|
|
||||||
const double l1 = (a[0]*rgb1[0] + a[1]*rgb1[1] + a[2]*rgb1[2]);
|
|
||||||
const double l2 = (a[0]*rgb2[0] + a[1]*rgb2[1] + a[2]*rgb2[2]);
|
|
||||||
|
|
||||||
const double rgb_diff[] = {
|
|
||||||
rgb2[0] - rgb1[0],
|
|
||||||
rgb2[1] - rgb1[1],
|
|
||||||
rgb2[2] - rgb1[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++, data += 4) {
|
|
||||||
/* Careful. data color components blue, green, red. */
|
|
||||||
const double rgb[3] = {
|
|
||||||
(double) data[2] / 256.,
|
|
||||||
(double) data[1] / 256.,
|
|
||||||
(double) data[0] / 256.
|
|
||||||
};
|
|
||||||
|
|
||||||
/* compute h, s, l data */
|
|
||||||
double l = a[0]*rgb[0] + a[1]*rgb[1] + a[2]*rgb[2];
|
|
||||||
|
|
||||||
const double h[3] = {
|
|
||||||
rgb[0] - l,
|
|
||||||
rgb[1] - l,
|
|
||||||
rgb[2] - l
|
|
||||||
};
|
|
||||||
|
|
||||||
/* u is the maximum possible saturation for given h and l. s is a
|
|
||||||
* rescaled saturation between 0 and 1 */
|
|
||||||
double u = colorumax(h, l, 0, 1);
|
|
||||||
double s;
|
|
||||||
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. */
|
|
||||||
const double t = l;
|
|
||||||
l = t * (l2 - l1) + l1;
|
|
||||||
|
|
||||||
if (priv->recolor.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 * rgb_diff[0] + rgb1[0]));
|
|
||||||
data[1] = (unsigned char)round(255.*(t * rgb_diff[1] + rgb1[1]));
|
|
||||||
data[0] = (unsigned char)round(255.*(t * rgb_diff[2] + rgb1[2]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef rgb1
|
|
||||||
#undef rgb2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_completed_signal_t* ecs = g_malloc(sizeof(ecs));
|
emit_completed_signal_t* ecs = g_malloc(sizeof(ecs));
|
||||||
|
|
Loading…
Reference in a new issue