From: Søren Sandmann Pedersen <s...@redhat.com>

pixman_composite_trapezoids() is supposed to composite across the
entire destination, but it actually only composites across the extent
of the trapezoids. For operators such as ADD or OVER this doesn't
matter since a zero source has no effect on the destination. But for
operators such as SRC or IN, it does matter.

So for such operators where a zero source has an effect, don't clip to
the trap extents.
---
 pixman/pixman-trap.c        |   43 +++++++++++++++++++++++++++++++++++--------
 test/composite-traps-test.c |    2 +-
 2 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index f633738..ab5c8c8 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -387,12 +387,43 @@ pixman_rasterize_trapezoid (pixman_image_t *          
image,
     }
 }
 
+static const pixman_bool_t zero_src_has_no_effect[PIXMAN_N_OPERATORS] =
+{
+    FALSE,     /* Clear                0                       0    */
+    FALSE,     /* Src                  1                       0    */
+    TRUE,      /* Dst                  0                       1    */
+    TRUE,      /* Over                 1                       1-Aa */
+    TRUE,      /* OverReverse          1-Ab                    1    */
+    FALSE,     /* In                   Ab                      0    */
+    FALSE,     /* InReverse            0                       Aa   */
+    FALSE,     /* Out                  1-Ab                    0    */
+    TRUE,      /* OutReverse           0                       1-Aa */
+    TRUE,      /* Atop                 Ab                      1-Aa */
+    FALSE,     /* AtopReverse          1-Ab                    Aa   */
+    TRUE,      /* Xor                  1-Ab                    1-Aa */
+    TRUE,      /* Add                  1                       1    */
+};
+
 static pixman_bool_t
-get_trap_extents (pixman_op_t op, const pixman_trapezoid_t *traps, int n_traps,
+get_trap_extents (pixman_op_t op, pixman_image_t *dest,
+                 const pixman_trapezoid_t *traps, int n_traps,
                  pixman_box32_t *box)
 {
     int i;
 
+    /* When the operator is such that a zero source has an
+     * effect on the underlying image, we have to
+     * composite across the entire destination
+     */
+    if (!zero_src_has_no_effect [op])
+    {
+       box->x1 = 0;
+       box->y1 = 0;
+       box->x2 = dest->bits.width;
+       box->y2 = dest->bits.height;
+       return TRUE;
+    }
+    
     box->x1 = INT32_MAX;
     box->y1 = INT32_MAX;
     box->x2 = INT32_MIN;
@@ -443,12 +474,8 @@ get_trap_extents (pixman_op_t op, const pixman_trapezoid_t 
*traps, int n_traps,
  * All the trapezoids are conceptually rendered to an infinitely big image.
  * The (0, 0) coordinates of this image are then aligned with the (x, y)
  * coordinates of the source image, and then both images are aligned with
- * the (x, y) coordinates of the destination. Then, in principle, compositing
- * of these three images takes place across the entire destination.
- *
- * FIXME: However, there is currently a bug, where we restrict this compositing
- * to the bounding box of the trapezoids. This is incorrect for operators such
- * as SRC and IN where blank source pixels do have an effect on the 
destination.
+ * the (x, y) coordinates of the destination. Then these three images are
+ * composited across the entire destination.
  */
 PIXMAN_EXPORT void
 pixman_composite_trapezoids (pixman_op_t               op,
@@ -491,7 +518,7 @@ pixman_composite_trapezoids (pixman_op_t            op,
        pixman_box32_t box;
        int i;
 
-       if (!get_trap_extents (op, traps, n_traps, &box))
+       if (!get_trap_extents (op, dst, traps, n_traps, &box))
            return;
        
        tmp = pixman_image_create_bits (
diff --git a/test/composite-traps-test.c b/test/composite-traps-test.c
index ff03b50..9fc94a4 100644
--- a/test/composite-traps-test.c
+++ b/test/composite-traps-test.c
@@ -251,6 +251,6 @@ test_composite (int      testnum,
 int
 main (int argc, const char *argv[])
 {
-    return fuzzer_test_main("composite traps", 40000, 0xE3112106,
+    return fuzzer_test_main("composite traps", 40000, 0x33BFAA55,
                            test_composite, argc, argv);
 }
-- 
1.7.4

_______________________________________________
Pixman mailing list
Pixman@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/pixman

Reply via email to