# No subject

=3D?UTF-8?q?S=3DC3=3DB8ren=3D20Sandmann=3D20Pedersen?=3D ssp at redhat.=
Sat Jun 19 16:12:47 PDT 2010

```com>
Date: Sat, 19 Jun 2010 18:57:45 -0400

Under the assumption that pixman gradients are supposed to match

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 simply to add 2*pi to the
parameter, and then use fmod() to make sure we didn't end up outside
the [0, 2*pi] range.

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.
---
1 files changed, 21 insertions(+), 14 deletions(-)

ent.c
index 1c8ddba..7d368dc 100644
@@ -32,6 +32,18 @@
#include <math.h>
#include "pixman-private.h"
=20
+static force_inline double
+coordinates_to_parameter (double x, double y, double angle)
+{
+    double t;
+
+    t =3D atan2 (y, x) + 2 * M_PI;	/* Add 2 * M_PI to make it positive */
+    t +=3D angle;				/* Add the rotation */
+    t =3D fmod (t, 2 * M_PI);		/* Make sure t is within [0, 2 * pi] */
+
+    return 1 - t / (2 * M_PI);		/* Scale t to [0, 1] and make the rotation=
CCW */
+}
+
static void
int             x,
@@ -52,7 +64,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
double rx =3D x + 0.5;
double ry =3D y + 0.5;
double rz =3D 1.;
-    double a =3D (conical->angle * M_PI) / (180. * 65536);
+    double a =3D pixman_fixed_to_double ((conical->angle * M_PI) / 180.0);
=20
);
=20
@@ -88,16 +100,12 @@ conical_gradient_get_scanline_32 (pixman_image_t *imag=
e,
=20
while (buffer < end)
{
-	    double angle;
-
{
-		pixman_fixed_48_16_t t;
+		double t =3D coordinates_to_parameter (rx, ry, a);
=20
-		angle =3D atan2 (ry, rx) + a;
-		t     =3D (pixman_fixed_48_16_t) (angle * (65536. / (2 * M_PI)));
-
-		*buffer =3D _pixman_gradient_walker_pixel (&walker, t);
+		    &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
}
=20
++buffer;
@@ -111,11 +119,10 @@ conical_gradient_get_scanline_32 (pixman_image_t *ima=
ge,
while (buffer < end)
{
double x, y;
-	    double angle;
=20
{
-		pixman_fixed_48_16_t t;
+		double t;
=20
if (rz !=3D 0)
{
@@ -129,11 +136,11 @@ conical_gradient_get_scanline_32 (pixman_image_t *ima=
ge,
=20
x -=3D conical->center.x / 65536.;
y -=3D conical->center.y / 65536.;
-=09=09
-		angle =3D atan2 (y, x) + a;
-		t     =3D (pixman_fixed_48_16_t) (angle * (65536. / (2 * M_PI)));
=20
-		*buffer =3D _pixman_gradient_walker_pixel (&walker, t);
+		t =3D coordinates_to_parameter (x, y, a);
+