summaryrefslogtreecommitdiff
path: root/gsk/gsktransform.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2020-02-11 10:00:34 +0100
committerAlexander Larsson <alexl@redhat.com>2020-02-11 13:51:06 +0100
commit1f0438e7fe7a6580116d95a922948ee63c7547b4 (patch)
tree9b38f3291283225f02ca3b64cf764bc2daad4ba4 /gsk/gsktransform.c
parentaf98c46d04d86e192349d20711d36dbb1de9bc9d (diff)
downloadgtk+-1f0438e7fe7a6580116d95a922948ee63c7547b4.tar.gz
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.
Diffstat (limited to 'gsk/gsktransform.c')
-rw-r--r--gsk/gsktransform.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/gsk/gsktransform.c b/gsk/gsktransform.c
index b474ec4114..c8e0d321b7 100644
--- a/gsk/gsktransform.c
+++ b/gsk/gsktransform.c
@@ -821,20 +821,28 @@ static const GskTransformClass GSK_ROTATE_TRANSFORM_CLASS =
static inline float
normalize_angle (float angle)
{
- float f;
if (angle >= 0 && angle < 360)
return angle;
- f = angle - (360 * ((int)(angle / 360.0)));
+ while (angle >= 360)
+ angle -= 360;
+ while (angle < 0)
+ angle += 360;
- if (f < 0)
- f = 360 + f;
+ /* Due to precision issues we may end up with a result that is just
+ * 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.
+ */
+
+ if (angle >= 360)
+ angle = 0;
- g_assert (f < 360.0);
- g_assert (f >= 0.0);
+ g_assert (angle < 360.0);
+ g_assert (angle >= 0.0);
- return f;
+ return angle;
}
/**