diff options
author | Glenn Kennard <glenn.kennard@gmail.com> | 2008-04-20 12:34:07 +0200 |
---|---|---|
committer | Glenn Kennard <glenn.kennard@gmail.com> | 2008-04-20 12:34:07 +0200 |
commit | 319e57ddaf303bdc11de0ff0960576cb15519112 (patch) | |
tree | 17c1e40ee607138bee8c480b6c4a9cf1ecd56fcd /raster | |
parent | 5167bc26e0b89a8ce912fbaea5467a2871dcb230 (diff) | |
download | mupdf-319e57ddaf303bdc11de0ff0960576cb15519112.tar.xz |
Forgot to add blendmodes.c
Not functional yet.
Diffstat (limited to 'raster')
-rw-r--r-- | raster/blendmodes.c | 213 | ||||
-rw-r--r-- | raster/render.c | 2 |
2 files changed, 214 insertions, 1 deletions
diff --git a/raster/blendmodes.c b/raster/blendmodes.c new file mode 100644 index 00000000..f3ba8ac5 --- /dev/null +++ b/raster/blendmodes.c @@ -0,0 +1,213 @@ +#include "fitz-base.h" +#include "fitz-world.h" +#include "fitz-draw.h" + +typedef unsigned char byte; + +/* +PDF 1.4 blend modes, except Normal and Multiply which are Over and In respectively. +Only the actual blend routines are here, not the node rendering logic which lives in render.c. +These are slow. +*/ + + +/* These functions apply to a single component, 0-255 range typically */ + +static int +fz_screen_byte(int bd, int s) +{ + return bd + s - fz_mul255(bd, s); +} + + +static int +fz_hardlight_byte(int bd, int s) +{ + int s2 = s << 1; + if (s <= 127) + return fz_mul255(bd, s2); + else + return fz_screen_byte(bd, s2); +} + + +static int +fz_overlay_byte(int bd, int s) +{ + return fz_hardlight_byte(s, bd); // note swapped order +} + + +static int +fz_darken_byte(int bd, int s) +{ + return MIN(bd, s); +} + + +static int +fz_lighten_byte(int bd, int s) +{ + return MAX(bd, s); +} + + +static int +fz_colordodge_byte(int bd, int s) +{ + if (s < 255) + return MIN(255, 255 * bd / (255 - s)); + else + return 255; +} + + +static int +fz_colorburn_byte(int bd, int s) +{ + if (s > 0) + return 255 - MIN(255, 255 * (255 - bd) / s); + else + return 0; +} + + +static int +fz_softlight_byte(int bd, int s) +{ + /* review this */ + if (s < 128) { + return bd - fz_mul255(fz_mul255((255 - (s<<1)), bd), 255 - bd); + } + else { + int dbd; + if (bd < 64) + dbd = fz_mul255(fz_mul255((bd << 4) - 12, bd) + 4, bd); + else + dbd = (int)sqrtf(255.0f * bd); + return bd + fz_mul255(((s<<1) - 255), (dbd - bd)); + } +} + + +static int +fz_difference_byte(int bd, int s) +{ + return ABS(bd - s); +} + + +static int +fz_exclusion_byte(int bd, int s) +{ + return bd + s - (fz_mul255(bd, s)<<1); +} + + +/* Non-separable blend modes */ + + +static int +lum(int r, int g, int b) +{ + /* 0.3, 0.59, 0.11 in 16.16 fixed point */ + return (19662 * r + 38666 * g + 7208 * b) >> 16; +} + + +static void +clipcolor(int r, int g, int b, int *dr, int *dg, int *db) +{ + int l = lum(r, g, b); + int n = MIN(MIN(r, g), b); + int x = MAX(MAX(r, g), b); + if (n < 0) { + *dr = l + 255 * (r - l) / (l - n); + *dg = l + 255 * (g - l) / (l - n); + *db = l + 255 * (b - l) / (l - n); + } + else { + *dr = l + 255 * (255 - l) / (x - l); + *dg = l + 255 * (255 - l) / (x - l); + *db = l + 255 * (255 - l) / (x - l); + } +} + + +static void +setlum(int r, int g, int b, int l, int *dr, int *dg, int *db) +{ + int d = 255 - lum(r, g, b); + clipcolor(r + d, g + d, b + d, dr, dg, db); +} + + +static int +sat(int r, int g, int b) +{ + return MAX(MAX(r, g), b) - MIN(MIN(r, g), b); +} + + +static void +setsat(int r, int g, int b, int s, int *dr, int *dg, int *db) +{ + int *m[3] = { &r, &g, &b }; /* min, med, max */ + int *t; +#define SWAP(a, b) (t = a, a = b, b = t) + if (*m[0] > *m[1]) + SWAP(m[0], m[1]); + if (*m[0] > *m[2]) + SWAP(m[0], m[2]); + if (*m[1] > *m[2]) + SWAP(m[1], m[2]); + + if (*m[2] > *m[0]) { + *m[1] = (*m[1] - *m[0]) * s / (*m[2] - *m[0]); + *m[2] = s; + } + else { + *m[1] = 0; + *m[2] = 0; + } + *dr = r; + *dg = g; + *db = b; +} + + +static void +fz_hue_rgb(int *bdr, int *bdg, int *bdb, int sr, int sg, int sb) +{ + int tr, tg, tb; + setsat(sr, sg, sb, sat(*bdr, *bdg, *bdb), &tr, &tg, &tb); + setlum(tr, tg, tb, lum(*bdr, *bdg, *bdb), bdr, bdg, bdb); +} + + +static void +fz_saturation_rgb(int *bdr, int *bdg, int *bdb, int sr, int sg, int sb) +{ + int tr, tg, tb; + setsat(*bdr, *bdg, *bdb, sat(sr, sg, sb), &tr, &tg, &tb); + setlum(tr, tg, tb, lum(*bdr, *bdg, *bdb), bdr, bdg, bdb); +} + + +static void +fz_color_rgb(int *bdr, int *bdg, int *bdb, int sr, int sg, int sb) +{ + setlum(sr, sg, sb, lum(*bdr, *bdg, *bdb), bdr, bdg, bdb); +} + + +static void +fz_luminosity_rgb(int *bdr, int *bdg, int *bdb, int sr, int sg, int sb) +{ + setlum(*bdr, *bdg, *bdb, lum(sr, sg, sb), bdr, bdg, bdb); +} + + +//fz_separable_blend(, fz_blendkind mode) +//{ +//} diff --git a/raster/render.c b/raster/render.c index a7c2e2f5..fc649469 100644 --- a/raster/render.c +++ b/raster/render.c @@ -198,7 +198,7 @@ renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm) if (path->paint == FZ_STROKE) { float lw = path->linewidth; - // Check for hairline + /* Check for hairline */ if (lw * expansion < 0.2) { lw = 1.0f / expansion; } |