[cairo] [PATCH] fix 1/2 pixel offset in pixman code. fixes #2488

Bertram Felgenhauer bertram.felgenhauer at googlemail.com
Thu Apr 27 09:33:15 PDT 2006


* src/fbcompose.c (fbFetchSourcePict, fbFetchTransformed): use the
center of the pixel as the sampling point for rendering.

* src/fbcompose.c (fbFetchTransformed): give source image values
maximim effect in the center of the corresponding pixel.

---

 pixman/src/fbcompose.c |   21 +++++++++++++++------
 1 files changed, 15 insertions(+), 6 deletions(-)

This patch is nearly identical to the one at bug #2488; there's an
additional -1 in some calculations to get the boundary case that
the filter-nearest-offset test checks for right. This fixes that
test case; it also fixes the targeted pixman-rotate-image case.
There is some breakage because linear gradients are sampled
slightly differently with this patch, but it's all visually
ok and in the lowest bit.

36ccc8588fdacddaf5b9ce3e4b0c853aaa640dad
diff --git a/pixman/src/fbcompose.c b/pixman/src/fbcompose.c
index e316c6d..25037e3 100644
--- a/pixman/src/fbcompose.c
+++ b/pixman/src/fbcompose.c
@@ -2827,8 +2827,9 @@ static void fbFetchSourcePict(PicturePtr
         xFixed_32_32 l;
         xFixed_48_16 dx, dy, a, b, off;
 
-        v.vector[0] = IntToxFixed(x);
-        v.vector[1] = IntToxFixed(y);
+        /* reference point is the center of the pixel */
+        v.vector[0] = IntToxFixed(x) + xFixed1/2 - 1;
+        v.vector[1] = IntToxFixed(y) + xFixed1/2 - 1;
         v.vector[2] = xFixed1;
         if (pict->transform) {
             if (!PictureTransformPoint3d (pict->transform, &v))
@@ -2941,8 +2942,9 @@ static void fbFetchSourcePict(PicturePtr
 
         if (pict->transform) {
             PictVector v;
-            v.vector[0] = IntToxFixed(x);
-            v.vector[1] = IntToxFixed(y);
+            /* reference point is the center of the pixel */
+            v.vector[0] = IntToxFixed(x) + xFixed1/2 - 1;
+            v.vector[1] = IntToxFixed(y) + xFixed1/2 - 1;
             v.vector[2] = xFixed1;
             if (!PictureTransformPoint3d (pict->transform, &v))
                 return;
@@ -3081,8 +3083,9 @@ #endif
     x += xoff;
     y += yoff;
 
-    v.vector[0] = IntToxFixed(x);
-    v.vector[1] = IntToxFixed(y);
+    /* reference point is the center of the pixel */
+    v.vector[0] = IntToxFixed(x) + xFixed1/2 - 1;
+    v.vector[1] = IntToxFixed(y) + xFixed1/2 - 1;
     v.vector[2] = xFixed1;
 
     /* when using convolution filters one might get here without a transform */
@@ -3197,6 +3200,12 @@ #endif
             }
         }
     } else if (pict->filter == PIXMAN_FILTER_BILINEAR || pict->filter == PIXMAN_FILTER_GOOD || pict->filter == PIXMAN_FILTER_BEST) {
+        /* adjust vector for maximum contribution at 0.5, 0.5 of each texel. */
+        v.vector[0] -= v.vector[2]/2;
+        v.vector[1] -= v.vector[2]/2;
+        unit.vector[0] -= unit.vector[2]/2;
+        unit.vector[1] -= unit.vector[2]/2;
+
         if (pict->repeat == RepeatNormal) {
             if (PIXREGION_NUM_RECTS(pict->pCompositeClip) == 1) {
                 box = pict->pCompositeClip->extents;
-- 
1.3.0



More information about the cairo mailing list