diff options
Diffstat (limited to 'raster/porterduff.c')
-rw-r--r-- | raster/porterduff.c | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/raster/porterduff.c b/raster/porterduff.c new file mode 100644 index 00000000..9cd99dbb --- /dev/null +++ b/raster/porterduff.c @@ -0,0 +1,357 @@ +#include <fitz.h> + +typedef unsigned char byte; + +/* + * Blend pixmap regions + */ + +/* dst = src over dst */ +static void +duff_non(byte *sp0, int sw, int sn, byte *dp0, int dw, int w0, int h) +{ + int k; + while (h--) + { + byte *sp = sp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte sa = sp[0]; + byte ssa = 255 - sa; + for (k = 0; k < sn; k++) + { + dp[k] = sp[k] + fz_mul255(dp[k], ssa); + } + sp += sn; + dp += sn; + } + sp0 += sw; + dp0 += dw; + } +} + +/* dst = src in msk */ +static void +duff_nimcn(byte *sp0, int sw, int sn, byte *mp0, int mw, int mn, byte *dp0, int dw, int w0, int h) +{ + int k; + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ma = mp[0]; + for (k = 0; k < sn; k++) + dp[k] = fz_mul255(sp[k], ma); + sp += sn; + mp += mn; + dp += sn; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +/* dst = src in msk over dst */ +static void +duff_nimon(byte *sp0, int sw, int sn, byte *mp0, int mw, int mn, byte *dp0, int dw, int w0, int h) +{ + int k; + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + /* TODO: validate this */ + byte ma = mp[0]; + byte sa = fz_mul255(sp[0], ma); + byte ssa = 255 - sa; + for (k = 0; k < sn; k++) + { + dp[k] = fz_mul255(sp[k], ma) + fz_mul255(dp[k], ssa); + } + sp += sn; + mp += mn; + dp += sn; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +static void duff_1o1(byte *sp0, int sw, byte *dp0, int dw, int w0, int h) +{ + /* duff_non(sp0, sw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + dp[0] = sp[0] + fz_mul255(dp[0], 255 - sp[0]); + sp ++; + dp ++; + } + sp0 += sw; + dp0 += dw; + } +} + +static void duff_4o4(byte *sp0, int sw, byte *dp0, int dw, int w0, int h) +{ + /* duff_non(sp0, sw, 4, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ssa = 255 - sp[0]; + dp[0] = sp[0] + fz_mul255(dp[0], ssa); + dp[1] = sp[1] + fz_mul255(dp[1], ssa); + dp[2] = sp[2] + fz_mul255(dp[2], ssa); + dp[3] = sp[3] + fz_mul255(dp[3], ssa); + sp += 4; + dp += 4; + } + sp0 += sw; + dp0 += dw; + } +} + +static void duff_1i1c1(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h) +{ + /* duff_nimcn(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + dp[0] = fz_mul255(sp[0], mp[0]); + sp ++; + mp ++; + dp ++; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +static void duff_4i1c4(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h) +{ + /* duff_nimcn(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ma = mp[0]; + dp[0] = fz_mul255(sp[0], ma); + dp[1] = fz_mul255(sp[1], ma); + dp[2] = fz_mul255(sp[2], ma); + dp[3] = fz_mul255(sp[3], ma); + sp += 4; + mp += 1; + dp += 4; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +static void duff_1i1o1(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h) +{ + /* duff_nimon(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ma = mp[0]; + byte sa = fz_mul255(sp[0], ma); + byte ssa = 255 - sa; + dp[0] = fz_mul255(sp[0], ma) + fz_mul255(dp[0], ssa); + sp ++; + mp ++; + dp ++; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +static void duff_4i1o4(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw, int w0, int h) +{ + /* duff_nimon(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */ + while (h--) + { + byte *sp = sp0; + byte *mp = mp0; + byte *dp = dp0; + int w = w0; + while (w--) + { + byte ma = mp[0]; + byte sa = fz_mul255(sp[0], ma); + byte ssa = 255 - sa; + dp[0] = fz_mul255(sp[0], ma) + fz_mul255(dp[0], ssa); + dp[1] = fz_mul255(sp[1], ma) + fz_mul255(dp[1], ssa); + dp[2] = fz_mul255(sp[2], ma) + fz_mul255(dp[2], ssa); + dp[3] = fz_mul255(sp[3], ma) + fz_mul255(dp[3], ssa); + sp += 4; + mp += 1; + dp += 4; + } + sp0 += sw; + mp0 += mw; + dp0 += dw; + } +} + +/* + * Path and text masks + */ + +static void path_1c1(byte *src, int cov, int len, byte *dst) +{ + while (len--) + { + cov += *src; *src = 0; src++; + *dst++ = cov; + } +} + +static void path_1o1(byte *src, int cov, int len, byte *dst) +{ + while (len--) + { + cov += *src; *src = 0; src++; + dst[0] = cov + fz_mul255(dst[0], 255 - cov); + dst++; + } +} + +static void path_w3i1o4(byte *rgb, byte *src, int cov, int len, byte *dst) +{ + byte rgb0 = rgb[0]; + byte rgb1 = rgb[1]; + byte rgb2 = rgb[2]; + byte ssa; + while (len--) + { + cov += *src; *src = 0; src++; + ssa = 255 - cov; + dst[0] = cov + fz_mul255(dst[0], ssa); + dst[1] = rgb0 + fz_mul255((short)dst[1] - rgb0, ssa); + dst[2] = rgb1 + fz_mul255((short)dst[2] - rgb1, ssa); + dst[3] = rgb2 + fz_mul255((short)dst[3] - rgb2, ssa); + dst += 4; + } +} + +static void text_1c1(byte *src0, int srcw, byte *dst0, int dstw, int w0, int h) +{ + while (h--) + { + byte *src = src0; + byte *dst = dst0; + int w = w0; + while (w--) + { + *dst++ = *src++; + } + src0 += srcw; + dst0 += dstw; + } +} + +static void text_1o1(byte *src0, int srcw, byte *dst0, int dstw, int w0, int h) +{ + while (h--) + { + byte *src = src0; + byte *dst = dst0; + int w = w0; + while (w--) + { + dst[0] = src[0] + fz_mul255(dst[0], 255 - src[0]); + src++; + dst++; + } + src0 += srcw; + dst0 += dstw; + } +} + +static void text_w3i1o4(byte *rgb, byte *src0, int srcw, byte *dst0, int dstw, int w0, int h) +{ + unsigned char rgb0 = rgb[0]; + unsigned char rgb1 = rgb[1]; + unsigned char rgb2 = rgb[2]; + while (h--) + { + byte *src = src0; + byte *dst = dst0; + int w = w0; + while (w--) + { + byte sa = src[0]; + byte ssa = 255 - sa; + dst[0] = sa + fz_mul255(dst[0], ssa); + dst[1] = rgb0 + fz_mul255((short)dst[1] - rgb0, ssa); + dst[2] = rgb1 + fz_mul255((short)dst[2] - rgb1, ssa); + dst[3] = rgb2 + fz_mul255((short)dst[3] - rgb2, ssa); + src ++; + dst += 4; + } + src0 += srcw; + dst0 += dstw; + } +} + +/* + * ... and the function pointers + */ + +void (*fz_duff_non)(byte*,int,int,byte*,int,int,int) = duff_non; +void (*fz_duff_nimcn)(byte*,int,int,byte*,int,int,byte*,int,int,int) = duff_nimcn; +void (*fz_duff_nimon)(byte*,int,int,byte*,int,int,byte*,int,int,int) = duff_nimon; +void (*fz_duff_1o1)(byte*,int,byte*,int,int,int) = duff_1o1; +void (*fz_duff_4o4)(byte*,int,byte*,int,int,int) = duff_4o4; +void (*fz_duff_1i1c1)(byte*,int,byte*,int,byte*,int,int,int) = duff_1i1c1; +void (*fz_duff_4i1c4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1c4; +void (*fz_duff_1i1o1)(byte*,int,byte*,int,byte*,int,int,int) = duff_1i1o1; +void (*fz_duff_4i1o4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1o4; + +void (*fz_path_1c1)(byte*,int,int,byte*) = path_1c1; +void (*fz_path_1o1)(byte*,int,int,byte*) = path_1o1; +void (*fz_path_w3i1o4)(byte*,byte*,int,int,byte*) = path_w3i1o4; + +void (*fz_text_1c1)(byte*,int,byte*,int,int,int) = text_1c1; +void (*fz_text_1o1)(byte*,int,byte*,int,int,int) = text_1o1; +void (*fz_text_w3i1o4)(byte*,byte*,int,byte*,int,int,int) = text_w3i1o4; + |