From 61de1fe7e510fdd425686c478439209f6f7a4b73 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 20 Aug 2014 11:33:55 +0200 Subject: Add full-page color tinting option and key binding to X11 viewer. win32 supports tinting, but cannot change the color from the default. --- docs/man/mupdf.1 | 6 ++++++ include/mupdf/fitz/pixmap.h | 9 +++++++++ platform/x11/pdfapp.c | 10 ++++++++++ platform/x11/pdfapp.h | 1 + platform/x11/x11_main.c | 18 ++++++++++++++++- source/fitz/pixmap.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 1 deletion(-) diff --git a/docs/man/mupdf.1 b/docs/man/mupdf.1 index 5831c0cc..44a6a600 100644 --- a/docs/man/mupdf.1 +++ b/docs/man/mupdf.1 @@ -29,6 +29,10 @@ The default value is 72. .B \-b bits Changes the anti-aliasing quality, specified as a number of bits between 0 (off) and 8 (best). The default value is 8. +.TP +.B \-C RRGGBB +Sets the full-page tint using hexadecimal color syntax. The default value +is FFFAF0. .SH MOUSE BEHAVIOR @@ -120,6 +124,8 @@ Toggle presentation mode. .B c Toggle between color and grayscale rendering. .TP +.B C +Toggle full-page color tinting. .B i Toggle between normal and inverted color rendering. .TP diff --git a/include/mupdf/fitz/pixmap.h b/include/mupdf/fitz/pixmap.h index 8be72914..800effd0 100644 --- a/include/mupdf/fitz/pixmap.h +++ b/include/mupdf/fitz/pixmap.h @@ -191,6 +191,15 @@ void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix); */ void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix); +/* + fz_tint_pixmap: Tint all the pixels in an RGB or Gray pixmap. + + Multiplies all the samples with the input color argument. + + r,g,b: The color to tint with, in 0 to 255 range. +*/ +void fz_tint_pixmap(fz_context *ctx, fz_pixmap *pix, int r, int g, int b); + /* fz_invert_pixmap: Invert all the pixels in a given rectangle of a pixmap. All components of all pixels in the rectangle are inverted diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c index 00f085a4..4f05a496 100644 --- a/platform/x11/pdfapp.c +++ b/platform/x11/pdfapp.c @@ -122,6 +122,9 @@ void pdfapp_init(fz_context *ctx, pdfapp_t *app) #else app->colorspace = fz_device_rgb(ctx); #endif + app->tint_r = 255; + app->tint_g = 250; + app->tint_b = 240; } void pdfapp_invert(pdfapp_t *app, const fz_rect *rect) @@ -820,6 +823,8 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai } if (app->invert) fz_invert_pixmap(app->ctx, app->image); + if (app->tint) + fz_tint_pixmap(app->ctx, app->image, app->tint_r, app->tint_g, app->tint_b); } if (transition) @@ -1116,6 +1121,11 @@ void pdfapp_onkey(pdfapp_t *app, int c) pdfapp_showpage(app, 0, 1, 1, 0, 0); break; + case 'C': + app->tint ^= 1; + pdfapp_showpage(app, 0, 1, 1, 0, 0); + break; + case 'c': app->grayscale ^= 1; pdfapp_showpage(app, 0, 1, 1, 0, 0); diff --git a/platform/x11/pdfapp.h b/platform/x11/pdfapp.h index b2ff78da..81211181 100644 --- a/platform/x11/pdfapp.h +++ b/platform/x11/pdfapp.h @@ -64,6 +64,7 @@ struct pdfapp_s int grayscale; fz_colorspace *colorspace; int invert; + int tint, tint_r, tint_g, tint_b; /* presentation mode */ int presentation_mode; diff --git a/platform/x11/x11_main.c b/platform/x11/x11_main.c index d3f3d368..908850eb 100644 --- a/platform/x11/x11_main.c +++ b/platform/x11/x11_main.c @@ -791,6 +791,7 @@ static void usage(void) fprintf(stderr, "\t-b -\tset anti-aliasing quality in bits (0=off, 8=best)\n"); fprintf(stderr, "\t-p -\tpassword\n"); fprintf(stderr, "\t-r -\tresolution\n"); + fprintf(stderr, "\t-C -\tRRGGBB (tint color in hexadecimal syntax)\n"); exit(1); } @@ -811,6 +812,7 @@ int main(int argc, char **argv) struct timeval now; struct timeval *timeout; struct timeval tmo_advance_delay; + int tint, tint_r, tint_g, tint_b; ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT); if (!ctx) @@ -819,10 +821,17 @@ int main(int argc, char **argv) exit(1); } - while ((c = fz_getopt(argc, argv, "p:r:b:")) != -1) + while ((c = fz_getopt(argc, argv, "p:r:b:C:")) != -1) { switch (c) { + case 'C': + c = strtol(fz_optarg, NULL, 16); + tint = 1; + tint_r = (c >> 16) & 255; + tint_g = (c >> 8) & 255; + tint_b = (c) & 255; + break; case 'p': password = fz_optarg; break; case 'r': resolution = atoi(fz_optarg); break; case 'b': fz_set_aa_level(ctx, atoi(fz_optarg)); break; @@ -839,6 +848,13 @@ int main(int argc, char **argv) pageno = atoi(argv[fz_optind++]); pdfapp_init(ctx, &gapp); + if (tint) + { + gapp.tint = tint; + gapp.tint_r = tint_r; + gapp.tint_g = tint_g; + gapp.tint_b = tint_b; + } winopen(); diff --git a/source/fitz/pixmap.c b/source/fitz/pixmap.c index a56fdbd9..9ce8ffba 100644 --- a/source/fitz/pixmap.c +++ b/source/fitz/pixmap.c @@ -414,6 +414,53 @@ fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity) return alpha; } +void +fz_tint_pixmap(fz_context *ctx, fz_pixmap *pix, int r, int g, int b) +{ + unsigned char *s = pix->samples; + int x, y; + + if (pix->colorspace == fz_device_bgr(ctx)) + { + int save = r; + r = b; + b = save; + } + else if (pix->colorspace == fz_device_gray(ctx)) + { + g = (r + g + b) / 3; + } + else if (pix->colorspace != fz_device_rgb(ctx)) + { + fz_throw(ctx, FZ_ERROR_GENERIC, "can only tint RGB, BGR and Gray pixmaps"); + } + + if (pix->n == 4) + { + for (x = 0; x < pix->w; x++) + { + for (y = 0; y < pix->h; y++) + { + s[0] = fz_mul255(s[0], r); + s[1] = fz_mul255(s[1], g); + s[2] = fz_mul255(s[2], b); + s += 4; + } + } + } + else if (pix->n == 2) + { + for (x = 0; x < pix->w; x++) + { + for (y = 0; y < pix->h; y++) + { + *s = fz_mul255(*s, g); + s += 2; + } + } + } +} + void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix) { -- cgit v1.2.3