Fix slightly skewed sampling grid for antialiased traps
authorSøren Sandmann Pedersen <sandmann@redhat.com>
Thu, 12 Nov 2009 22:03:53 +0000 (17:03 -0500)
committerSøren Sandmann Pedersen <sandmann@redhat.com>
Tue, 17 Nov 2009 06:58:01 +0000 (01:58 -0500)
The sampling grid is slightly skewed in the antialiased case. Consider
the case where we have n = 8 bits of alpha.

The small step is

     small_step = fixed_1 / 15 = 65536 / 15 = 4369

The first fraction is then

     frac_first = (small_step / 2) = (65536 - 15) / 2 = 2184

and the last fraction becomes

     frac_last
          = frac_first + (15 - 1) * small_step = 2184 + 14 * 4369 = 63350

which means the size of the last bit of the pixel is

     65536 - 63350 = 2186

which is 2 bigger than the first fraction. This is not the end of the
world, but it would be more correct to have 2185 and 2185, and we can
accomplish that simply by making the first fraction half the *big*
step instead of half the small step.

If we ever move to coordinates with 8 fractional bits, the
corresponding values become 8 and 10 out of 256, where 9 and 9 would
be better.

Similarly in the X direction.

pixman/pixman-private.h

index 5000f91..0745149 100644 (file)
@@ -350,13 +350,13 @@ _pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
 #define STEP_Y_SMALL(n) (pixman_fixed_1 / N_Y_FRAC (n))
 #define STEP_Y_BIG(n)   (pixman_fixed_1 - (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
 
-#define Y_FRAC_FIRST(n) (STEP_Y_SMALL (n) / 2)
+#define Y_FRAC_FIRST(n) (STEP_Y_BIG (n) / 2)
 #define Y_FRAC_LAST(n)  (Y_FRAC_FIRST (n) + (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
 
 #define STEP_X_SMALL(n) (pixman_fixed_1 / N_X_FRAC (n))
 #define STEP_X_BIG(n)   (pixman_fixed_1 - (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
 
-#define X_FRAC_FIRST(n) (STEP_X_SMALL (n) / 2)
+#define X_FRAC_FIRST(n) (STEP_X_BIG (n) / 2)
 #define X_FRAC_LAST(n)  (X_FRAC_FIRST (n) + (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
 
 #define RENDER_SAMPLES_X(x, n)                                         \