aboutsummaryrefslogtreecommitdiff
path: root/pixman/pixman/combine.inc
diff options
context:
space:
mode:
Diffstat (limited to 'pixman/pixman/combine.inc')
-rw-r--r--pixman/pixman/combine.inc1269
1 files changed, 1269 insertions, 0 deletions
diff --git a/pixman/pixman/combine.inc b/pixman/pixman/combine.inc
new file mode 100644
index 000000000..9f88dee15
--- /dev/null
+++ b/pixman/pixman/combine.inc
@@ -0,0 +1,1269 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "pixman-private.h"
+
+#include "pixman-combine.h"
+
+/*
+ * There are two ways of handling alpha -- either as a single unified value or
+ * a separate value for each component, hence each macro must have two
+ * versions. The unified alpha version has a 'U' at the end of the name,
+ * the component version has a 'C'. Similarly, functions which deal with
+ * this difference will have two versions using the same convention.
+ */
+
+
+/*
+ * Combine src and mask
+ */
+FASTCALL static void
+pixman_fbCombineMaskU (comp4_t *src, const comp4_t *mask, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t a = *(mask + i) >> A_SHIFT;
+ comp4_t s = *(src + i);
+ FbByteMul(s, a);
+ *(src + i) = s;
+ }
+}
+
+/*
+ * All of the composing functions
+ */
+
+FASTCALL static void
+fbCombineClear (comp4_t *dest, const comp4_t *src, int width)
+{
+ memset(dest, 0, width*sizeof(comp4_t));
+}
+
+FASTCALL static void
+fbCombineSrcU (comp4_t *dest, const comp4_t *src, int width)
+{
+ memcpy(dest, src, width*sizeof(comp4_t));
+}
+
+/* if the Src is opaque, call fbCombineSrcU */
+FASTCALL static void
+fbCombineOverU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t d = *(dest + i);
+ comp4_t ia = Alpha(~s);
+
+ FbByteMulAdd(d, ia, s);
+ *(dest + i) = d;
+ }
+}
+
+/* if the Dst is opaque, this is a noop */
+FASTCALL static void
+fbCombineOverReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t d = *(dest + i);
+ comp4_t ia = Alpha(~*(dest + i));
+ FbByteMulAdd(s, ia, d);
+ *(dest + i) = s;
+ }
+}
+
+/* if the Dst is opaque, call fbCombineSrcU */
+FASTCALL static void
+fbCombineInU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t a = Alpha(*(dest + i));
+ FbByteMul(s, a);
+ *(dest + i) = s;
+ }
+}
+
+/* if the Src is opaque, this is a noop */
+FASTCALL static void
+fbCombineInReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t d = *(dest + i);
+ comp4_t a = Alpha(*(src + i));
+ FbByteMul(d, a);
+ *(dest + i) = d;
+ }
+}
+
+/* if the Dst is opaque, call fbCombineClear */
+FASTCALL static void
+fbCombineOutU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t a = Alpha(~*(dest + i));
+ FbByteMul(s, a);
+ *(dest + i) = s;
+ }
+}
+
+/* if the Src is opaque, call fbCombineClear */
+FASTCALL static void
+fbCombineOutReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t d = *(dest + i);
+ comp4_t a = Alpha(~*(src + i));
+ FbByteMul(d, a);
+ *(dest + i) = d;
+ }
+}
+
+/* if the Src is opaque, call fbCombineInU */
+/* if the Dst is opaque, call fbCombineOverU */
+/* if both the Src and Dst are opaque, call fbCombineSrcU */
+FASTCALL static void
+fbCombineAtopU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t d = *(dest + i);
+ comp4_t dest_a = Alpha(d);
+ comp4_t src_ia = Alpha(~s);
+
+ FbByteAddMul(s, dest_a, d, src_ia);
+ *(dest + i) = s;
+ }
+}
+
+/* if the Src is opaque, call fbCombineOverReverseU */
+/* if the Dst is opaque, call fbCombineInReverseU */
+/* if both the Src and Dst are opaque, call fbCombineDstU */
+FASTCALL static void
+fbCombineAtopReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t d = *(dest + i);
+ comp4_t src_a = Alpha(s);
+ comp4_t dest_ia = Alpha(~d);
+
+ FbByteAddMul(s, dest_ia, d, src_a);
+ *(dest + i) = s;
+ }
+}
+
+/* if the Src is opaque, call fbCombineOverU */
+/* if the Dst is opaque, call fbCombineOverReverseU */
+/* if both the Src and Dst are opaque, call fbCombineClear */
+FASTCALL static void
+fbCombineXorU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t d = *(dest + i);
+ comp4_t src_ia = Alpha(~s);
+ comp4_t dest_ia = Alpha(~d);
+
+ FbByteAddMul(s, dest_ia, d, src_ia);
+ *(dest + i) = s;
+ }
+}
+
+FASTCALL static void
+fbCombineAddU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t d = *(dest + i);
+ FbByteAdd(d, s);
+ *(dest + i) = d;
+ }
+}
+
+/* if the Src is opaque, call fbCombineAddU */
+/* if the Dst is opaque, call fbCombineAddU */
+/* if both the Src and Dst are opaque, call fbCombineAddU */
+FASTCALL static void
+fbCombineSaturateU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t d = *(dest + i);
+ comp2_t sa, da;
+
+ sa = s >> A_SHIFT;
+ da = ~d >> A_SHIFT;
+ if (sa > da)
+ {
+ sa = IntDiv(da, sa);
+ FbByteMul(s, sa);
+ };
+ FbByteAdd(d, s);
+ *(dest + i) = d;
+ }
+}
+
+
+/*
+ * All of the disjoint composing functions
+
+ The four entries in the first column indicate what source contributions
+ come from each of the four areas of the picture -- areas covered by neither
+ A nor B, areas covered only by A, areas covered only by B and finally
+ areas covered by both A and B.
+
+ Disjoint Conjoint
+ Fa Fb Fa Fb
+ (0,0,0,0) 0 0 0 0
+ (0,A,0,A) 1 0 1 0
+ (0,0,B,B) 0 1 0 1
+ (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0)
+ (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1
+ (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0
+ (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1)
+ (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0
+ (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0)
+ (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
+ (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
+ (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
+
+*/
+
+#define CombineAOut 1
+#define CombineAIn 2
+#define CombineBOut 4
+#define CombineBIn 8
+
+#define CombineClear 0
+#define CombineA (CombineAOut|CombineAIn)
+#define CombineB (CombineBOut|CombineBIn)
+#define CombineAOver (CombineAOut|CombineBOut|CombineAIn)
+#define CombineBOver (CombineAOut|CombineBOut|CombineBIn)
+#define CombineAAtop (CombineBOut|CombineAIn)
+#define CombineBAtop (CombineAOut|CombineBIn)
+#define CombineXor (CombineAOut|CombineBOut)
+
+/* portion covered by a but not b */
+FASTCALL static comp1_t
+fbCombineDisjointOutPart (comp1_t a, comp1_t b)
+{
+ /* min (1, (1-b) / a) */
+
+ b = ~b; /* 1 - b */
+ if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
+ return MASK; /* 1 */
+ return IntDiv(b,a); /* (1-b) / a */
+}
+
+/* portion covered by both a and b */
+FASTCALL static comp1_t
+fbCombineDisjointInPart (comp1_t a, comp1_t b)
+{
+ /* max (1-(1-b)/a,0) */
+ /* = - min ((1-b)/a - 1, 0) */
+ /* = 1 - min (1, (1-b)/a) */
+
+ b = ~b; /* 1 - b */
+ if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */
+ return 0; /* 1 - 1 */
+ return ~IntDiv(b,a); /* 1 - (1-b) / a */
+}
+
+/* portion covered by a but not b */
+FASTCALL static comp1_t
+fbCombineConjointOutPart (comp1_t a, comp1_t b)
+{
+ /* max (1-b/a,0) */
+ /* = 1-min(b/a,1) */
+
+ /* min (1, (1-b) / a) */
+
+ if (b >= a) /* b >= a -> b/a >= 1 */
+ return 0x00; /* 0 */
+ return ~IntDiv(b,a); /* 1 - b/a */
+}
+
+/* portion covered by both a and b */
+FASTCALL static comp1_t
+fbCombineConjointInPart (comp1_t a, comp1_t b)
+{
+ /* min (1,b/a) */
+
+ if (b >= a) /* b >= a -> b/a >= 1 */
+ return MASK; /* 1 */
+ return IntDiv(b,a); /* b/a */
+}
+
+FASTCALL static void
+fbCombineDisjointGeneralU (comp4_t *dest, const comp4_t *src, int width, comp1_t combine)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t d = *(dest + i);
+ comp4_t m,n,o,p;
+ comp2_t Fa, Fb, t, u, v;
+ comp1_t sa = s >> A_SHIFT;
+ comp1_t da = d >> A_SHIFT;
+
+ switch (combine & CombineA) {
+ default:
+ Fa = 0;
+ break;
+ case CombineAOut:
+ Fa = fbCombineDisjointOutPart (sa, da);
+ break;
+ case CombineAIn:
+ Fa = fbCombineDisjointInPart (sa, da);
+ break;
+ case CombineA:
+ Fa = MASK;
+ break;
+ }
+
+ switch (combine & CombineB) {
+ default:
+ Fb = 0;
+ break;
+ case CombineBOut:
+ Fb = fbCombineDisjointOutPart (da, sa);
+ break;
+ case CombineBIn:
+ Fb = fbCombineDisjointInPart (da, sa);
+ break;
+ case CombineB:
+ Fb = MASK;
+ break;
+ }
+ m = FbGen (s,d,0,Fa,Fb,t, u, v);
+ n = FbGen (s,d,G_SHIFT,Fa,Fb,t, u, v);
+ o = FbGen (s,d,B_SHIFT,Fa,Fb,t, u, v);
+ p = FbGen (s,d,A_SHIFT,Fa,Fb,t, u, v);
+ s = m|n|o|p;
+ *(dest + i) = s;
+ }
+}
+
+FASTCALL static void
+fbCombineDisjointOverU (comp4_t *dest, const comp4_t *src, int width)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp2_t a = s >> A_SHIFT;
+
+ if (a != 0x00)
+ {
+ if (a != MASK)
+ {
+ comp4_t d = *(dest + i);
+ a = fbCombineDisjointOutPart (d >> A_SHIFT, a);
+ FbByteMulAdd(d, a, s);
+ s = d;
+ }
+ *(dest + i) = s;
+ }
+ }
+}
+
+FASTCALL static void
+fbCombineDisjointInU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineAIn);
+}
+
+FASTCALL static void
+fbCombineDisjointInReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineBIn);
+}
+
+FASTCALL static void
+fbCombineDisjointOutU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineAOut);
+}
+
+FASTCALL static void
+fbCombineDisjointOutReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineBOut);
+}
+
+FASTCALL static void
+fbCombineDisjointAtopU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineAAtop);
+}
+
+FASTCALL static void
+fbCombineDisjointAtopReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineBAtop);
+}
+
+FASTCALL static void
+fbCombineDisjointXorU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineDisjointGeneralU (dest, src, width, CombineXor);
+}
+
+FASTCALL static void
+fbCombineConjointGeneralU (comp4_t *dest, const comp4_t *src, int width, comp1_t combine)
+{
+ int i;
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t d = *(dest + i);
+ comp4_t m,n,o,p;
+ comp2_t Fa, Fb, t, u, v;
+ comp1_t sa = s >> A_SHIFT;
+ comp1_t da = d >> A_SHIFT;
+
+ switch (combine & CombineA) {
+ default:
+ Fa = 0;
+ break;
+ case CombineAOut:
+ Fa = fbCombineConjointOutPart (sa, da);
+ break;
+ case CombineAIn:
+ Fa = fbCombineConjointInPart (sa, da);
+ break;
+ case CombineA:
+ Fa = MASK;
+ break;
+ }
+
+ switch (combine & CombineB) {
+ default:
+ Fb = 0;
+ break;
+ case CombineBOut:
+ Fb = fbCombineConjointOutPart (da, sa);
+ break;
+ case CombineBIn:
+ Fb = fbCombineConjointInPart (da, sa);
+ break;
+ case CombineB:
+ Fb = MASK;
+ break;
+ }
+ m = FbGen (s,d,0,Fa,Fb,t, u, v);
+ n = FbGen (s,d,G_SHIFT,Fa,Fb,t, u, v);
+ o = FbGen (s,d,B_SHIFT,Fa,Fb,t, u, v);
+ p = FbGen (s,d,A_SHIFT,Fa,Fb,t, u, v);
+ s = m|n|o|p;
+ *(dest + i) = s;
+ }
+}
+
+FASTCALL static void
+fbCombineConjointOverU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineAOver);
+}
+
+
+FASTCALL static void
+fbCombineConjointOverReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineBOver);
+}
+
+
+FASTCALL static void
+fbCombineConjointInU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineAIn);
+}
+
+
+FASTCALL static void
+fbCombineConjointInReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineBIn);
+}
+
+FASTCALL static void
+fbCombineConjointOutU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineAOut);
+}
+
+FASTCALL static void
+fbCombineConjointOutReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineBOut);
+}
+
+FASTCALL static void
+fbCombineConjointAtopU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineAAtop);
+}
+
+FASTCALL static void
+fbCombineConjointAtopReverseU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineBAtop);
+}
+
+FASTCALL static void
+fbCombineConjointXorU (comp4_t *dest, const comp4_t *src, int width)
+{
+ fbCombineConjointGeneralU (dest, src, width, CombineXor);
+}
+
+/********************************************************************************/
+/*************************** Per Channel functions ******************************/
+/********************************************************************************/
+
+FASTCALL static void
+fbCombineMaskC (comp4_t *src, comp4_t *mask)
+{
+ comp4_t a = *mask;
+
+ comp4_t x;
+ comp2_t xa;
+
+ if (!a)
+ {
+ *(src) = 0;
+ return;
+ }
+
+ x = *(src);
+ if (a == ~0)
+ {
+ x = x >> A_SHIFT;
+ x |= x << G_SHIFT;
+ x |= x << B_SHIFT;
+ *(mask) = x;
+ return;
+ }
+
+ xa = x >> A_SHIFT;
+ FbByteMulC(x, a);
+ *(src) = x;
+ FbByteMul(a, xa);
+ *(mask) = a;
+}
+
+FASTCALL static void
+fbCombineMaskValueC (comp4_t *src, const comp4_t *mask)
+{
+ comp4_t a = *mask;
+ comp4_t x;
+
+ if (!a)
+ {
+ *(src) = 0;
+ return;
+ }
+
+ if (a == ~0)
+ return;
+
+ x = *(src);
+ FbByteMulC(x, a);
+ *(src) =x;
+}
+
+FASTCALL static void
+fbCombineMaskAlphaC (const comp4_t *src, comp4_t *mask)
+{
+ comp4_t a = *(mask);
+ comp4_t x;
+
+ if (!a)
+ return;
+
+ x = *(src) >> A_SHIFT;
+ if (x == MASK)
+ return;
+ if (a == ~0)
+ {
+ x = x >> A_SHIFT;
+ x |= x << G_SHIFT;
+ x |= x << B_SHIFT;
+ *(mask) = x;
+ return;
+ }
+
+ FbByteMul(a, x);
+ *(mask) = a;
+}
+
+
+
+FASTCALL static void
+fbCombineClearC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ memset(dest, 0, width*sizeof(comp4_t));
+}
+
+FASTCALL static void
+fbCombineSrcC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t m = *(mask + i);
+
+ fbCombineMaskValueC (&s, &m);
+
+ *(dest) = s;
+ }
+}
+
+FASTCALL static void
+fbCombineOverC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t m = *(mask + i);
+ comp4_t a;
+
+ fbCombineMaskC (&s, &m);
+
+ a = ~m;
+ if (a != ~0)
+ {
+ if (a)
+ {
+ comp4_t d = *(dest + i);
+ FbByteMulAddC(d, a, s);
+ s = d;
+ }
+ *(dest + i) = s;
+ }
+ }
+}
+
+FASTCALL static void
+fbCombineOverReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t d = *(dest + i);
+ comp4_t a = ~d >> A_SHIFT;
+
+ if (a)
+ {
+ comp4_t s = *(src + i);
+ comp4_t m = *(mask + i);
+
+ fbCombineMaskValueC (&s, &m);
+
+ if (a != MASK)
+ {
+ FbByteMulAdd(s, a, d);
+ }
+ *(dest + i) = s;
+ }
+ }
+}
+
+FASTCALL static void
+fbCombineInC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t d = *(dest + i);
+ comp2_t a = d >> A_SHIFT;
+ comp4_t s = 0;
+ if (a)
+ {
+ comp4_t m = *(mask + i);
+
+ s = *(src + i);
+ fbCombineMaskValueC (&s, &m);
+ if (a != MASK)
+ {
+ FbByteMul(s, a);
+ }
+ }
+ *(dest + i) = s;
+ }
+}
+
+FASTCALL static void
+fbCombineInReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t m = *(mask + i);
+ comp4_t a;
+
+ fbCombineMaskAlphaC (&s, &m);
+
+ a = m;
+ if (a != ~0)
+ {
+ comp4_t d = 0;
+ if (a)
+ {
+ d = *(dest + i);
+ FbByteMulC(d, a);
+ }
+ *(dest + i) = d;
+ }
+ }
+}
+
+FASTCALL static void
+fbCombineOutC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t d = *(dest + i);
+ comp2_t a = ~d >> A_SHIFT;
+ comp4_t s = 0;
+ if (a)
+ {
+ comp4_t m = *(mask + i);
+
+ s = *(src + i);
+ fbCombineMaskValueC (&s, &m);
+
+ if (a != MASK)
+ {
+ FbByteMul(s, a);
+ }
+ }
+ *(dest + i) = s;
+ }
+}
+
+FASTCALL static void
+fbCombineOutReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t m = *(mask + i);
+ comp4_t a;
+
+ fbCombineMaskAlphaC (&s, &m);
+
+ a = ~m;
+ if (a != ~0)
+ {
+ comp4_t d = 0;
+ if (a)
+ {
+ d = *(dest + i);
+ FbByteMulC(d, a);
+ }
+ *(dest + i) = d;
+ }
+ }
+}
+
+FASTCALL static void
+fbCombineAtopC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t d = *(dest + i);
+ comp4_t s = *(src + i);
+ comp4_t m = *(mask + i);
+ comp4_t ad;
+ comp2_t as = d >> A_SHIFT;
+
+ fbCombineMaskC (&s, &m);
+
+ ad = ~m;
+
+ FbByteAddMulC(d, ad, s, as);
+ *(dest + i) = d;
+ }
+}
+
+FASTCALL static void
+fbCombineAtopReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+
+ comp4_t d = *(dest + i);
+ comp4_t s = *(src + i);
+ comp4_t m = *(mask + i);
+ comp4_t ad;
+ comp2_t as = ~d >> A_SHIFT;
+
+ fbCombineMaskC (&s, &m);
+
+ ad = m;
+
+ FbByteAddMulC(d, ad, s, as);
+ *(dest + i) = d;
+ }
+}
+
+FASTCALL static void
+fbCombineXorC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t d = *(dest + i);
+ comp4_t s = *(src + i);
+ comp4_t m = *(mask + i);
+ comp4_t ad;
+ comp2_t as = ~d >> A_SHIFT;
+
+ fbCombineMaskC (&s, &m);
+
+ ad = ~m;
+
+ FbByteAddMulC(d, ad, s, as);
+ *(dest + i) = d;
+ }
+}
+
+FASTCALL static void
+fbCombineAddC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t s = *(src + i);
+ comp4_t m = *(mask + i);
+ comp4_t d = *(dest + i);
+
+ fbCombineMaskValueC (&s, &m);
+
+ FbByteAdd(d, s);
+ *(dest + i) = d;
+ }
+}
+
+FASTCALL static void
+fbCombineSaturateC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t s, d;
+ comp2_t sa, sr, sg, sb, da;
+ comp2_t t, u, v;
+ comp4_t m,n,o,p;
+
+ d = *(dest + i);
+ s = *(src + i);
+ m = *(mask + i);
+
+ fbCombineMaskC (&s, &m);
+
+ sa = (m >> A_SHIFT);
+ sr = (m >> B_SHIFT) & MASK;
+ sg = (m >> G_SHIFT) & MASK;
+ sb = m & MASK;
+ da = ~d >> A_SHIFT;
+
+ if (sb <= da)
+ m = Add(s,d,0,t);
+ else
+ m = FbGen (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v);
+
+ if (sg <= da)
+ n = Add(s,d,G_SHIFT,t);
+ else
+ n = FbGen (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v);
+
+ if (sr <= da)
+ o = Add(s,d,B_SHIFT,t);
+ else
+ o = FbGen (s, d, B_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v);
+
+ if (sa <= da)
+ p = Add(s,d,A_SHIFT,t);
+ else
+ p = FbGen (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v);
+
+ *(dest + i) = m|n|o|p;
+ }
+}
+
+FASTCALL static void
+fbCombineDisjointGeneralC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width, comp1_t combine)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t s, d;
+ comp4_t m,n,o,p;
+ comp4_t Fa, Fb;
+ comp2_t t, u, v;
+ comp4_t sa;
+ comp1_t da;
+
+ s = *(src + i);
+ m = *(mask + i);
+ d = *(dest + i);
+ da = d >> A_SHIFT;
+
+ fbCombineMaskC (&s, &m);
+
+ sa = m;
+
+ switch (combine & CombineA) {
+ default:
+ Fa = 0;
+ break;
+ case CombineAOut:
+ m = (comp4_t)fbCombineDisjointOutPart ((comp1_t) (sa >> 0), da);
+ n = (comp4_t)fbCombineDisjointOutPart ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT;
+ o = (comp4_t)fbCombineDisjointOutPart ((comp1_t) (sa >> B_SHIFT), da) << B_SHIFT;
+ p = (comp4_t)fbCombineDisjointOutPart ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT;
+ Fa = m|n|o|p;
+ break;
+ case CombineAIn:
+ m = (comp4_t)fbCombineDisjointInPart ((comp1_t) (sa >> 0), da);
+ n = (comp4_t)fbCombineDisjointInPart ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT;
+ o = (comp4_t)fbCombineDisjointInPart ((comp1_t) (sa >> B_SHIFT), da) << B_SHIFT;
+ p = (comp4_t)fbCombineDisjointInPart ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT;
+ Fa = m|n|o|p;
+ break;
+ case CombineA:
+ Fa = ~0;
+ break;
+ }
+
+ switch (combine & CombineB) {
+ default:
+ Fb = 0;
+ break;
+ case CombineBOut:
+ m = (comp4_t)fbCombineDisjointOutPart (da, (comp1_t) (sa >> 0));
+ n = (comp4_t)fbCombineDisjointOutPart (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT;
+ o = (comp4_t)fbCombineDisjointOutPart (da, (comp1_t) (sa >> B_SHIFT)) << B_SHIFT;
+ p = (comp4_t)fbCombineDisjointOutPart (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT;
+ Fb = m|n|o|p;
+ break;
+ case CombineBIn:
+ m = (comp4_t)fbCombineDisjointInPart (da, (comp1_t) (sa >> 0));
+ n = (comp4_t)fbCombineDisjointInPart (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT;
+ o = (comp4_t)fbCombineDisjointInPart (da, (comp1_t) (sa >> B_SHIFT)) << B_SHIFT;
+ p = (comp4_t)fbCombineDisjointInPart (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT;
+ Fb = m|n|o|p;
+ break;
+ case CombineB:
+ Fb = ~0;
+ break;
+ }
+ m = FbGen (s,d,0,GetComp(Fa,0),GetComp(Fb,0),t, u, v);
+ n = FbGen (s,d,G_SHIFT,GetComp(Fa,G_SHIFT),GetComp(Fb,G_SHIFT),t, u, v);
+ o = FbGen (s,d,B_SHIFT,GetComp(Fa,B_SHIFT),GetComp(Fb,B_SHIFT),t, u, v);
+ p = FbGen (s,d,A_SHIFT,GetComp(Fa,A_SHIFT),GetComp(Fb,A_SHIFT),t, u, v);
+ s = m|n|o|p;
+ *(dest + i) = s;
+ }
+}
+
+FASTCALL static void
+fbCombineDisjointOverC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOver);
+}
+
+FASTCALL static void
+fbCombineDisjointInC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineAIn);
+}
+
+FASTCALL static void
+fbCombineDisjointInReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineBIn);
+}
+
+FASTCALL static void
+fbCombineDisjointOutC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOut);
+}
+
+FASTCALL static void
+fbCombineDisjointOutReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineBOut);
+}
+
+FASTCALL static void
+fbCombineDisjointAtopC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineAAtop);
+}
+
+FASTCALL static void
+fbCombineDisjointAtopReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineBAtop);
+}
+
+FASTCALL static void
+fbCombineDisjointXorC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineDisjointGeneralC (dest, src, mask, width, CombineXor);
+}
+
+FASTCALL static void
+fbCombineConjointGeneralC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width, comp1_t combine)
+{
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ comp4_t s, d;
+ comp4_t m,n,o,p;
+ comp4_t Fa, Fb;
+ comp2_t t, u, v;
+ comp4_t sa;
+ comp1_t da;
+
+ s = *(src + i);
+ m = *(mask + i);
+ d = *(dest + i);
+ da = d >> A_SHIFT;
+
+ fbCombineMaskC (&s, &m);
+
+ sa = m;
+
+ switch (combine & CombineA) {
+ default:
+ Fa = 0;
+ break;
+ case CombineAOut:
+ m = (comp4_t)fbCombineConjointOutPart ((comp1_t) (sa >> 0), da);
+ n = (comp4_t)fbCombineConjointOutPart ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT;
+ o = (comp4_t)fbCombineConjointOutPart ((comp1_t) (sa >> B_SHIFT), da) << B_SHIFT;
+ p = (comp4_t)fbCombineConjointOutPart ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT;
+ Fa = m|n|o|p;
+ break;
+ case CombineAIn:
+ m = (comp4_t)fbCombineConjointInPart ((comp1_t) (sa >> 0), da);
+ n = (comp4_t)fbCombineConjointInPart ((comp1_t) (sa >> G_SHIFT), da) << G_SHIFT;
+ o = (comp4_t)fbCombineConjointInPart ((comp1_t) (sa >> B_SHIFT), da) << B_SHIFT;
+ p = (comp4_t)fbCombineConjointInPart ((comp1_t) (sa >> A_SHIFT), da) << A_SHIFT;
+ Fa = m|n|o|p;
+ break;
+ case CombineA:
+ Fa = ~0;
+ break;
+ }
+
+ switch (combine & CombineB) {
+ default:
+ Fb = 0;
+ break;
+ case CombineBOut:
+ m = (comp4_t)fbCombineConjointOutPart (da, (comp1_t) (sa >> 0));
+ n = (comp4_t)fbCombineConjointOutPart (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT;
+ o = (comp4_t)fbCombineConjointOutPart (da, (comp1_t) (sa >> B_SHIFT)) << B_SHIFT;
+ p = (comp4_t)fbCombineConjointOutPart (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT;
+ Fb = m|n|o|p;
+ break;
+ case CombineBIn:
+ m = (comp4_t)fbCombineConjointInPart (da, (comp1_t) (sa >> 0));
+ n = (comp4_t)fbCombineConjointInPart (da, (comp1_t) (sa >> G_SHIFT)) << G_SHIFT;
+ o = (comp4_t)fbCombineConjointInPart (da, (comp1_t) (sa >> B_SHIFT)) << B_SHIFT;
+ p = (comp4_t)fbCombineConjointInPart (da, (comp1_t) (sa >> A_SHIFT)) << A_SHIFT;
+ Fb = m|n|o|p;
+ break;
+ case CombineB:
+ Fb = ~0;
+ break;
+ }
+ m = FbGen (s,d,0,GetComp(Fa,0),GetComp(Fb,0),t, u, v);
+ n = FbGen (s,d,G_SHIFT,GetComp(Fa,G_SHIFT),GetComp(Fb,G_SHIFT),t, u, v);
+ o = FbGen (s,d,B_SHIFT,GetComp(Fa,B_SHIFT),GetComp(Fb,B_SHIFT),t, u, v);
+ p = FbGen (s,d,A_SHIFT,GetComp(Fa,A_SHIFT),GetComp(Fb,A_SHIFT),t, u, v);
+ s = m|n|o|p;
+ *(dest + i) = s;
+ }
+}
+
+FASTCALL static void
+fbCombineConjointOverC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineAOver);
+}
+
+FASTCALL static void
+fbCombineConjointOverReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineBOver);
+}
+
+FASTCALL static void
+fbCombineConjointInC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineAIn);
+}
+
+FASTCALL static void
+fbCombineConjointInReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineBIn);
+}
+
+FASTCALL static void
+fbCombineConjointOutC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineAOut);
+}
+
+FASTCALL static void
+fbCombineConjointOutReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineBOut);
+}
+
+FASTCALL static void
+fbCombineConjointAtopC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineAAtop);
+}
+
+FASTCALL static void
+fbCombineConjointAtopReverseC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineBAtop);
+}
+
+FASTCALL static void
+fbCombineConjointXorC (comp4_t *dest, comp4_t *src, comp4_t *mask, int width)
+{
+ fbCombineConjointGeneralC (dest, src, mask, width, CombineXor);
+}
+
+static CombineFuncU pixman_fbCombineFuncU[] = {
+ fbCombineClear,
+ fbCombineSrcU,
+ NULL, /* CombineDst */
+ fbCombineOverU,
+ fbCombineOverReverseU,
+ fbCombineInU,
+ fbCombineInReverseU,
+ fbCombineOutU,
+ fbCombineOutReverseU,
+ fbCombineAtopU,
+ fbCombineAtopReverseU,
+ fbCombineXorU,
+ fbCombineAddU,
+ fbCombineSaturateU,
+ NULL,
+ NULL,
+ fbCombineClear,
+ fbCombineSrcU,
+ NULL, /* CombineDst */
+ fbCombineDisjointOverU,
+ fbCombineSaturateU, /* DisjointOverReverse */
+ fbCombineDisjointInU,
+ fbCombineDisjointInReverseU,
+ fbCombineDisjointOutU,
+ fbCombineDisjointOutReverseU,
+ fbCombineDisjointAtopU,
+ fbCombineDisjointAtopReverseU,
+ fbCombineDisjointXorU,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ fbCombineClear,
+ fbCombineSrcU,
+ NULL, /* CombineDst */
+ fbCombineConjointOverU,
+ fbCombineConjointOverReverseU,
+ fbCombineConjointInU,
+ fbCombineConjointInReverseU,
+ fbCombineConjointOutU,
+ fbCombineConjointOutReverseU,
+ fbCombineConjointAtopU,
+ fbCombineConjointAtopReverseU,
+ fbCombineConjointXorU,
+};
+
+static CombineFuncC pixman_fbCombineFuncC[] = {
+ fbCombineClearC,
+ fbCombineSrcC,
+ NULL, /* Dest */
+ fbCombineOverC,
+ fbCombineOverReverseC,
+ fbCombineInC,
+ fbCombineInReverseC,
+ fbCombineOutC,
+ fbCombineOutReverseC,
+ fbCombineAtopC,
+ fbCombineAtopReverseC,
+ fbCombineXorC,
+ fbCombineAddC,
+ fbCombineSaturateC,
+ NULL,
+ NULL,
+ fbCombineClearC, /* 0x10 */
+ fbCombineSrcC,
+ NULL, /* Dest */
+ fbCombineDisjointOverC,
+ fbCombineSaturateC, /* DisjointOverReverse */
+ fbCombineDisjointInC,
+ fbCombineDisjointInReverseC,
+ fbCombineDisjointOutC,
+ fbCombineDisjointOutReverseC,
+ fbCombineDisjointAtopC,
+ fbCombineDisjointAtopReverseC,
+ fbCombineDisjointXorC, /* 0x1b */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ fbCombineClearC,
+ fbCombineSrcC,
+ NULL, /* Dest */
+ fbCombineConjointOverC,
+ fbCombineConjointOverReverseC,
+ fbCombineConjointInC,
+ fbCombineConjointInReverseC,
+ fbCombineConjointOutC,
+ fbCombineConjointOutReverseC,
+ fbCombineConjointAtopC,
+ fbCombineConjointAtopReverseC,
+ fbCombineConjointXorC,
+};
+
+FbComposeFunctions pixman_composeFunctions = {
+ pixman_fbCombineFuncU,
+ pixman_fbCombineFuncC,
+ pixman_fbCombineMaskU
+};