gsk: Fix angle normalization

I was getting assertions that normalize_angle() failed the
result < 260 check. Doing some research on this it turns out
to be a precision issue. If the incomming angle is very slightly
below zero, then adding 360 to it may end up with exactly 360.

I simplified the code a bit to avoid division and rounding, because in
practice most angles will be "just outside" the 0-360 degree anyway.
And i also added a workaround for the "result is 360" case by just
setting it to 0.
This commit is contained in:
Alexander Larsson 2020-02-11 10:00:34 +01:00
parent af98c46d04
commit 1f0438e7fe

View File

@ -821,20 +821,28 @@ static const GskTransformClass GSK_ROTATE_TRANSFORM_CLASS =
static inline float static inline float
normalize_angle (float angle) normalize_angle (float angle)
{ {
float f;
if (angle >= 0 && angle < 360) if (angle >= 0 && angle < 360)
return angle; return angle;
f = angle - (360 * ((int)(angle / 360.0))); while (angle >= 360)
angle -= 360;
while (angle < 0)
angle += 360;
if (f < 0) /* Due to precision issues we may end up with a result that is just
f = 360 + f; * past the allowed range when rounded. For example, something like
* -epsilon + 360 when rounded to a float may end up with 360.
* So, we handle these cases by returning the exact value 0.
*/
g_assert (f < 360.0); if (angle >= 360)
g_assert (f >= 0.0); angle = 0;
return f; g_assert (angle < 360.0);
g_assert (angle >= 0.0);
return angle;
} }
/** /**