From 4314a86aa7813bcd4131827181ecf44994142a72 Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Thu, 9 Dec 2010 14:38:10 +0100 Subject: arc: Avoid infinite loop Adding/subtracting 2 * M_PI to a huge floating point number doesn't change it (because of rounding) and for smaller numbers it still requires a lot of cycles before the angle is in the desired range. The same computation can be performed using fmod, which should provide more accurate results and only requires O(1) time. --- src/cairo.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src/cairo.c') diff --git a/src/cairo.c b/src/cairo.c index 562161099..3abcbb13b 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -1861,8 +1861,14 @@ cairo_arc (cairo_t *cr, return; } - while (angle2 < angle1) - angle2 += 2 * M_PI; + if (angle2 < angle1) { + /* increase angle2 by multiples of full circle until it + * satisfies angle2 >= angle1 */ + angle2 = fmod (angle2 - angle1, 2 * M_PI); + if (angle2 < 0) + angle2 += 2 * M_PI; + angle2 += angle1; + } cairo_line_to (cr, xc + radius * cos (angle1), @@ -1903,8 +1909,14 @@ cairo_arc_negative (cairo_t *cr, if (radius <= 0.0) return; - while (angle2 > angle1) - angle2 -= 2 * M_PI; + if (angle2 > angle1) { + /* decrease angle2 by multiples of full circle until it + * satisfies angle2 <= angle1 */ + angle2 = fmod (angle2 - angle1, 2 * M_PI); + if (angle2 > 0) + angle2 -= 2 * M_PI; + angle2 += angle1; + } cairo_line_to (cr, xc + radius * cos (angle1), -- cgit v1.2.1