pixman: Branch 'master' - 2 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Thu Jun 24 11:58:48 PDT 2010


 pixman/pixman-conical-gradient.c |   53 +++++++++++++++++++++++++--------------
 pixman/pixman-private.h          |    2 -
 2 files changed, 35 insertions(+), 20 deletions(-)

New commits:
commit ca846806cbc4e11cd134e464c7740c1cde19422b
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sun Jun 20 13:12:27 2010 -0400

    Store the conical angle in floating point radians, not fixed point degrees
    
    This is a slight simplification.

diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index d06dd0b..897948b 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -70,7 +70,6 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
     double rx = x + 0.5;
     double ry = y + 0.5;
     double rz = 1.;
-    double a = pixman_fixed_to_double ((conical->angle * M_PI) / 180.0);
 
     _pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
 
@@ -108,7 +107,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
 	{
 	    if (!mask || *mask++)
 	    {
-		double t = coordinates_to_parameter (rx, ry, a);
+		double t = coordinates_to_parameter (rx, ry, conical->angle);
 
 		*buffer = _pixman_gradient_walker_pixel (
 		    &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
@@ -143,7 +142,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
 		x -= conical->center.x / 65536.;
 		y -= conical->center.y / 65536.;
 
-		t = coordinates_to_parameter (x, y, a);
+		t = coordinates_to_parameter (x, y, conical->angle);
 
 		*buffer = _pixman_gradient_walker_pixel (
 		    &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
@@ -185,9 +184,12 @@ pixman_image_create_conical_gradient (pixman_point_fixed_t *        center,
 	return NULL;
     }
 
+    angle = MOD (angle, pixman_int_to_fixed (360));
+
     image->type = CONICAL;
+
     conical->center = *center;
-    conical->angle = MOD (angle, 360 << 16);
+    conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI;
 
     image->common.property_changed = conical_gradient_property_changed;
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 5b0eff3..8718fcb 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -161,7 +161,7 @@ struct conical_gradient
 {
     gradient_t           common;
     pixman_point_fixed_t center;
-    pixman_fixed_t       angle;
+    double		 angle;
 };
 
 struct bits_image
commit 3074d57b560d5ec9be2a0e1a6846012698f51208
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Jun 19 18:57:45 2010 -0400

    Fix conical gradients to match QConicalGradient from Qt
    
    Under the assumption that pixman gradients are supposed to match
    QConicalgradient, described here:
    
            http://doc.trolltech.com/4.4/qconicalgradient.html
    
    this patch fixes two separate bugs in pixman-conical-gradient.c.
    
    The first bug is that the output of atan2() is in the range of [-pi,
    pi], which means the parameter into the gradient can be negative. This
    is wrong since a QConicalGradient always interpolates around the
    center from 0 to 1. The fix for that is to (a) make sure the given
    angle is between 0 and 360, and (b) add or subtract 2 * M_PI if the
    computed angle ends up outside [0, 2 * pi].
    
    The other bug is that we were interpolating clockwise, whereas
    QConicalGradient calls for a counter-clockwise interpolation. This is
    easily fixed by subtracting the parameter from 1.
    
    Finally, this patch encapsulates the computation in a new force-inline
    function so that it can be reused in both the affine and non-affine
    case.

diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 1c8ddba..d06dd0b 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -32,6 +32,24 @@
 #include <math.h>
 #include "pixman-private.h"
 
+static force_inline double
+coordinates_to_parameter (double x, double y, double angle)
+{
+    double t;
+
+    t = atan2 (y, x) + angle;
+
+    while (t < 0)
+	t += 2 * M_PI;
+
+    while (t >= 2 * M_PI)
+	t -= 2 * M_PI;
+
+    return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and
+				      * make rotation CCW
+				      */
+}
+
 static void
 conical_gradient_get_scanline_32 (pixman_image_t *image,
                                   int             x,
@@ -52,7 +70,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
     double rx = x + 0.5;
     double ry = y + 0.5;
     double rz = 1.;
-    double a = (conical->angle * M_PI) / (180. * 65536);
+    double a = pixman_fixed_to_double ((conical->angle * M_PI) / 180.0);
 
     _pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
 
@@ -71,11 +89,11 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
 	cx = source->common.transform->matrix[0][0] / 65536.;
 	cy = source->common.transform->matrix[1][0] / 65536.;
 	cz = source->common.transform->matrix[2][0] / 65536.;
-	
+
 	rx = v.vector[0] / 65536.;
 	ry = v.vector[1] / 65536.;
 	rz = v.vector[2] / 65536.;
-	
+
 	affine =
 	    source->common.transform->matrix[2][0] == 0 &&
 	    v.vector[2] == pixman_fixed_1;
@@ -88,20 +106,16 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
 
 	while (buffer < end)
 	{
-	    double angle;
-
 	    if (!mask || *mask++)
 	    {
-		pixman_fixed_48_16_t t;
-
-		angle = atan2 (ry, rx) + a;
-		t     = (pixman_fixed_48_16_t) (angle * (65536. / (2 * M_PI)));
+		double t = coordinates_to_parameter (rx, ry, a);
 
-		*buffer = _pixman_gradient_walker_pixel (&walker, t);
+		*buffer = _pixman_gradient_walker_pixel (
+		    &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
 	    }
 
 	    ++buffer;
-	    
+
 	    rx += cx;
 	    ry += cy;
 	}
@@ -111,11 +125,10 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
 	while (buffer < end)
 	{
 	    double x, y;
-	    double angle;
 
 	    if (!mask || *mask++)
 	    {
-		pixman_fixed_48_16_t t;
+		double t;
 
 		if (rz != 0)
 		{
@@ -129,15 +142,15 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
 
 		x -= conical->center.x / 65536.;
 		y -= conical->center.y / 65536.;
-		
-		angle = atan2 (y, x) + a;
-		t     = (pixman_fixed_48_16_t) (angle * (65536. / (2 * M_PI)));
 
-		*buffer = _pixman_gradient_walker_pixel (&walker, t);
+		t = coordinates_to_parameter (x, y, a);
+
+		*buffer = _pixman_gradient_walker_pixel (
+		    &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
 	    }
 
 	    ++buffer;
-	    
+
 	    rx += cx;
 	    ry += cy;
 	    rz += cz;
@@ -174,7 +187,7 @@ pixman_image_create_conical_gradient (pixman_point_fixed_t *        center,
 
     image->type = CONICAL;
     conical->center = *center;
-    conical->angle = angle;
+    conical->angle = MOD (angle, 360 << 16);
 
     image->common.property_changed = conical_gradient_property_changed;
 


More information about the xorg-commit mailing list