diff options
author | Andrea Canciani <ranma42@gmail.com> | 2010-12-09 14:38:10 +0100 |
---|---|---|
committer | Andrea Canciani <ranma42@gmail.com> | 2010-12-09 17:33:12 +0100 |
commit | 4314a86aa7813bcd4131827181ecf44994142a72 (patch) | |
tree | ddb567bb8093d9e245bf43cc7219793a158dfb34 /src/cairo.c | |
parent | 028797a729ca74b4ce2d1062fc8c90c111bf2870 (diff) | |
download | cairo-4314a86aa7813bcd4131827181ecf44994142a72.tar.gz |
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.
Diffstat (limited to 'src/cairo.c')
-rw-r--r-- | src/cairo.c | 20 |
1 files changed, 16 insertions, 4 deletions
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), |