#include "fitz.h" typedef unsigned char byte; /* * Blend pixmap regions */ /* dst = src over dst */ static void duff_non(byte * restrict sp, int sw, int sn, byte * restrict dp, int dw, int w0, int h) { int k; sw -= w0*sn; dw -= w0*sn; while (h--) { int w = w0; while (w--) { /* RJW: Alpha handling suspicious here; sp[0] counts twice */ int sa = FZ_EXPAND(sp[0]); for (k = 0; k < sn; k++) { dp[k] = FZ_BLEND(sp[k], dp[k], sa); } sp += sn; dp += sn; } sp += sw; dp += dw; } } /* dst = src in msk over dst */ static void duff_nimon(byte * restrict sp, int sw, int sn, byte * restrict mp, int mw, int mn, byte * restrict dp, int dw, int w0, int h) { int k; sw -= w0*sn; mw -= w0*mn; dw -= w0*sn; while (h--) { int w = w0; while (w--) { /* TODO: validate this */ int ma = FZ_COMBINE(FZ_EXPAND(mp[0]), FZ_EXPAND(sp[0])); for (k = 0; k < sn; k++) { dp[k] = FZ_BLEND(sp[k], dp[k], ma); } sp += sn; mp += mn; dp += sn; } sp += sw; mp += mw; dp += dw; } } static void duff_1o1(byte * restrict sp, int sw, byte * restrict dp, int dw, int w0, int h) { /* duff_non(sp0, sw, 1, dp0, dw, w0, h); */ sw -= w0; dw -= w0; while (h--) { int w = w0; while (w--) { dp[0] = FZ_BLEND(255, dp[0], FZ_EXPAND(sp[0])); sp ++; dp ++; } sp += sw; dp += dw; } } static void duff_4o4(byte *sp, int sw, byte *dp, int dw, int w0, int h) { /* duff_non(sp0, sw, 4, dp0, dw, w0, h); */ sw -= w0<<2; dw -= w0<<2; while (h--) { int w = w0; while (w--) { int alpha = FZ_EXPAND(sp[0]); dp[0] = FZ_BLEND(sp[0], dp[0], alpha); dp[1] = FZ_BLEND(sp[1], dp[1], alpha); dp[2] = FZ_BLEND(sp[2], dp[2], alpha); dp[3] = FZ_BLEND(sp[3], dp[3], alpha); sp += 4; dp += 4; } sp += sw; dp += dw; } } static void duff_1i1o1(byte * restrict sp, int sw, byte * restrict mp, int mw, byte * restrict dp, int dw, int w0, int h) { /* duff_nimon(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */ sw -= w0; mw -= w0; dw -= w0; while (h--) { int w = w0; while (w--) { int ma = FZ_COMBINE(FZ_EXPAND(mp[0]), FZ_EXPAND(sp[0])); dp[0] = FZ_BLEND(255, dp[0], ma); sp ++; mp ++; dp ++; } sp += sw; mp += mw; dp += dw; } } static void duff_4i1o4(byte * restrict sp, int sw, byte * restrict mp, int mw, byte * restrict dp, int dw, int w0, int h) { /* duff_nimon(sp, sw, 4, mp, mw, 1, dp, dw, w0, h); */ sw -= w0<<2; dw -= w0<<2; mw -= w0; while (h--) { int w = w0; while (w--) { int ma = FZ_COMBINE(FZ_EXPAND(mp[0]), FZ_EXPAND(sp[0])); dp[0] = FZ_BLEND(255, dp[0], ma); dp[1] = FZ_BLEND(sp[1], dp[1], ma); dp[2] = FZ_BLEND(sp[2], dp[2], ma); dp[3] = FZ_BLEND(sp[3], dp[3], ma); sp += 4; mp += 1; dp += 4; } sp += sw; mp += mw; dp += dw; } } /* * Path masks */ static void path_1o1(byte * restrict src, byte cov, int len, byte * restrict dst) { while (len--) { int c; cov += *src; *src = 0; src++; c = FZ_EXPAND(cov); dst[0] = FZ_BLEND(255, dst[0], c); dst++; } } static void path_w4i1o4(byte * restrict argb, byte * restrict src, byte cov, int len, byte * restrict dst) { int alpha = FZ_EXPAND(argb[0]); byte r = argb[1]; byte g = argb[2]; byte b = argb[3]; while (len--) { int ca; cov += *src; *src = 0; src++; ca = FZ_COMBINE(FZ_EXPAND(cov), alpha); dst[0] = FZ_BLEND(255, dst[0], ca); dst[1] = FZ_BLEND(r, dst[1], ca); dst[2] = FZ_BLEND(g, dst[2], ca); dst[3] = FZ_BLEND(b, dst[3], ca); dst += 4; } } /* * Text masks */ static void text_1o1(byte * restrict src, int srcw, byte * restrict dst, int dstw, int w0, int h) { srcw -= w0; dstw -= w0; while (h--) { int w = w0; while (w--) { int c = FZ_EXPAND(src[0]); dst[0] = FZ_BLEND(255, dst[0], c); src++; dst++; } src += srcw; dst += dstw; } } static void text_w4i1o4(byte * restrict argb, byte * restrict src, int srcw, byte * restrict dst, int dstw, int w0, int h) { int alpha = FZ_EXPAND(argb[0]); byte r = argb[1]; byte g = argb[2]; byte b = argb[3]; srcw -= w0; dstw -= w0<<2; while (h--) { int w = w0; while (w--) { int c = FZ_COMBINE(FZ_EXPAND(src[0]), alpha); dst[0] = FZ_BLEND(255, dst[0], c); dst[1] = FZ_BLEND(r, dst[1], c); dst[2] = FZ_BLEND(g, dst[2], c); dst[3] = FZ_BLEND(b, dst[3], c); src ++; dst += 4; } src += srcw; dst += dstw; } } /* * ... and the function pointers */ void (*fz_duff_non)(byte*,int,int,byte*,int,int,int) = duff_non; 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_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_1o1)(byte*,byte,int,byte*) = path_1o1; void (*fz_path_w4i1o4)(byte*,byte*,byte,int,byte*) = path_w4i1o4; void (*fz_text_1o1)(byte*,int,byte*,int,int,int) = text_1o1; void (*fz_text_w4i1o4)(byte*,byte*,int,byte*,int,int,int) = text_w4i1o4;