Add INVERT and SUBTRACT blend modes used in Flash
authorBenjamin Otte <otte@gnome.org>
Tue, 7 Oct 2008 13:13:45 +0000 (15:13 +0200)
committerSøren Sandmann Pedersen <sandmann@redhat.com>
Tue, 23 Jun 2009 18:42:33 +0000 (14:42 -0400)
pixman/pixman-combine.c.template
pixman/pixman.h

index 3cd5740..b06ce5b 100644 (file)
@@ -628,6 +628,64 @@ fbCombineExclusionU (pixman_implementation_t *imp, pixman_op_t op,
 
 #undef FbBlendLoop
 
+static FASTCALL void
+fbCombineSubtractU (pixman_implementation_t *imp, pixman_op_t op,
+                   comp4_t *dest, const comp4_t *src, const comp4_t *mask, int width)
+{
+    int i;
+
+#define Subtract(res, Color)                                           \
+    do {                                                               \
+      comp1_t dc, sc;                                                  \
+      dc = Color (d);                                                  \
+      sc = Color (s);                                                  \
+      if (sc >= dc)                                                    \
+       res = 0;                                                        \
+      else                                                             \
+       res = dc - sc;                                                  \
+    } while (0);
+
+    for (i = 0; i < width; ++i) {
+       comp4_t d, s;
+       comp4_t r, g, b;
+
+       d = *(dest + i);
+       s = combineMask (src, mask, i);
+
+       Subtract (r, Red);
+       Subtract (g, Green);
+       Subtract (b, Blue);
+
+       *(dest + i) = (Alpha (d) << A_SHIFT)
+           | (r << R_SHIFT)
+           | (g << G_SHIFT)
+           | b;
+    }
+
+#undef Subtract
+}
+
+static FASTCALL void
+fbCombineInvertU (pixman_implementation_t *imp, pixman_op_t op,
+                 comp4_t *dest, const comp4_t *src, const comp4_t *mask, int width)
+{
+    int i;
+
+    for (i = 0; i < width; ++i) {
+      comp4_t inv, d, s;
+      comp1_t a, ia;
+
+      d = *(dest + i);
+      s = combineMask (src, mask, i);
+      a = Alpha (s);
+      inv = ~d | A_MASK;
+      ia = ~a;
+
+      FbByteAddMul (inv, a, d, ia);
+      *(dest + i) = inv;
+    }
+}
+
 /*
  * All of the disjoint composing functions
 
@@ -1684,6 +1742,8 @@ _pixman_setup_combiner_functions_width (pixman_implementation_t *imp)
     imp->combine_width[PIXMAN_OP_SOFT_LIGHT] = fbCombineSoftLightU;
     imp->combine_width[PIXMAN_OP_DIFFERENCE] = fbCombineDifferenceU;
     imp->combine_width[PIXMAN_OP_EXCLUSION] = fbCombineExclusionU;
+    imp->combine_width[PIXMAN_OP_SUBTRACT] = fbCombineSubtractU;
+    imp->combine_width[PIXMAN_OP_INVERT] = fbCombineInvertU;
 
     /* Component alpha combiners */
     imp->combine_width_ca[PIXMAN_OP_CLEAR] = fbCombineClearC;
@@ -1729,4 +1789,3 @@ _pixman_setup_combiner_functions_width (pixman_implementation_t *imp)
     imp->combine_width_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = fbCombineConjointAtopReverseC;
     imp->combine_width_ca[PIXMAN_OP_CONJOINT_XOR] = fbCombineConjointXorC;
 }
-
index a56f55a..68e8640 100644 (file)
@@ -379,6 +379,8 @@ typedef enum
     PIXMAN_OP_SOFT_LIGHT                = 0x38,
     PIXMAN_OP_DIFFERENCE                = 0x39,
     PIXMAN_OP_EXCLUSION                 = 0x3a,
+    PIXMAN_OP_SUBTRACT                 = 0x3b,
+    PIXMAN_OP_INVERT                   = 0x3c,
 
     PIXMAN_OP_NONE,
     PIXMAN_OP_LAST = PIXMAN_OP_NONE