Author: duncan Date: 2005-10-03 06:47:08 -0400 (Mon, 03 Oct 2005) New Revision: 51112
Modified: trunk/libgdiplus/src/ChangeLog trunk/libgdiplus/src/graphics-path.c trunk/libgdiplus/src/graphics.c Log: 2005-10-03 Duncan Mak <[EMAIL PROTECTED]> * graphics.c (make_arcs): * graphics-path.c (append_arcs): Helper functions for dividing the arcs into smaller segments. Properly handles negative starting angles and sweep angles. * graphics-path.c (GdipAddPathArc, GdipAddPathPie): * graphics.c (GdipDrawArc, make_pie): Simplified to make use of the new helper functions. Modified: trunk/libgdiplus/src/ChangeLog =================================================================== --- trunk/libgdiplus/src/ChangeLog 2005-10-03 10:46:44 UTC (rev 51111) +++ trunk/libgdiplus/src/ChangeLog 2005-10-03 10:47:08 UTC (rev 51112) @@ -1,3 +1,14 @@ +2005-10-03 Duncan Mak <[EMAIL PROTECTED]> + + * graphics.c (make_arcs): + * graphics-path.c (append_arcs): Helper functions for dividing + the arcs into smaller segments. Properly handles negative starting + angles and sweep angles. + + * graphics-path.c (GdipAddPathArc, GdipAddPathPie): + * graphics.c (GdipDrawArc, make_pie): Simplified to make use of the + new helper functions. + 2005-09-20 Jordi Mas i Hernandez <[EMAIL PROTECTED]> * image.c, gdip.h, image.c: Creates the surface and then creates the Modified: trunk/libgdiplus/src/graphics-path.c =================================================================== --- trunk/libgdiplus/src/graphics-path.c 2005-10-03 10:46:44 UTC (rev 51111) +++ trunk/libgdiplus/src/graphics-path.c 2005-10-03 10:47:08 UTC (rev 51112) @@ -560,6 +560,7 @@ /* angles in radians */ float alpha = startAngle * PI / 180; float beta = endAngle * PI / 180; + float sweep = abs (beta - alpha); float delta = beta - alpha; float bcp = 4.0 / 3 * (1 - cos (delta / 2)) / sin (delta / 2); @@ -572,7 +573,7 @@ /* starting point */ double sx = cx + rx * cos_alpha; double sy = cy + ry * sin_alpha; - + /* move to the starting point if we're not continuing a curve */ if (start) append (path, sx, sy, PathPointTypeLine); @@ -586,27 +587,50 @@ cy + ry * sin_beta); } +static void +append_arcs (GpPath *path, float x, float y, float width, float height, float startAngle, float sweepAngle) +{ + int i; + float drawn = 0; + float endAngle = startAngle + sweepAngle; + int sign = (endAngle > 0) ? 1 : -1; + int increment = sign * 90; + + if (abs (sweepAngle) >= 360) { + GdipAddPathEllipse (path, x, y, width, height); + return; + } + + /* i is the number of sub-arcs drawn, each sub-arc can be at most 90 degrees.*/ + /* there can be no more then 4 subarcs, ie. 90 + 90 + 90 + (something less than 90) */ + for (i = 0; i < 4; i++) { + float current = startAngle + drawn; + + /* we've drawn enough */ + if (abs (current) >= abs (endAngle)) + break; + + /* if we are not done yet */ + float additional = abs (current + increment) < abs (endAngle) ? + increment : /* add the default increment */ + endAngle - current; /* otherwise, add the remainder */ + + append_arc (path, + (i == 0) ? TRUE : FALSE, /* only move to the starting pt in the 1st iteration */ + x, y, width, height, /* bounding rectangle */ + current, current + additional); + drawn += additional; + } +} + GpStatus GdipAddPathArc (GpPath *path, float x, float y, float width, float height, float startAngle, float sweepAngle) { - float endAngle = startAngle + sweepAngle; - int i, sign = (endAngle > 0) ? 1 : -1; - g_return_val_if_fail (path != NULL, InvalidParameter); - if (abs (sweepAngle) >= 360) - return GdipAddPathEllipse (path, x, y, width, height); - /* draw the arcs */ - for (i = 0; i < abs (endAngle); i += 90) { - append_arc (path, - (i == 0) ? TRUE : FALSE, /* only move to the starting pt in the 1st iteration */ - x, y, width, height, /* bounding rectangle */ - i * sign, /* start angle */ - (i + 90 < abs (endAngle)) ? (i + 90) * sign : endAngle); /* sweep angle, - at most up to 90 degrees */ - } + append_arcs (path, x, y, width, height, startAngle, sweepAngle); return Ok; } @@ -796,19 +820,8 @@ append (path, cx + rx * cos_alpha, cy + ry * sin_alpha, PathPointTypeLine); - /* draw arc */ - if (abs (sweepAngle) >= 360) - return GdipAddPathEllipse (path, x, y, width, height); - /* draw the arcs */ - for (i = 0; i < abs (endAngle); i += 90) { - append_arc (path, - (i == 0) ? TRUE : FALSE, /* only move to the starting pt in the 1st iteration */ - x, y, width, height, /* bounding rectangle */ - i * sign, /* start angle */ - (i + 90 < abs (endAngle)) ? (i + 90) * sign : endAngle); /* sweep angle, - at most up to 90 degrees */ - } + append_arcs (path, x, y, width, height, startAngle, sweepAngle); /* draw pie edge */ append (path, cx, cy, PathPointTypeLine); Modified: trunk/libgdiplus/src/graphics.c =================================================================== --- trunk/libgdiplus/src/graphics.c 2005-10-03 10:46:44 UTC (rev 51111) +++ trunk/libgdiplus/src/graphics.c 2005-10-03 10:47:08 UTC (rev 51112) @@ -164,7 +164,7 @@ */ static void make_arc (GpGraphics *graphics, bool start, float x, float y, float width, - float height, float startAngle, float endAngle) + float height, float startAngle, float endAngle) { float rx = width / 2; float ry = height / 2; @@ -176,6 +176,7 @@ /* angles in radians */ float alpha = startAngle * PI / 180; float beta = endAngle * PI / 180; + float sweep = abs (beta - alpha); float delta = beta - alpha; float bcp = 4.0 / 3 * (1 - cos (delta / 2)) / sin (delta /2); @@ -188,7 +189,7 @@ /* starting point */ double sx = cx + rx * cos_alpha; double sy = cy + ry * sin_alpha; - + /* don't move to starting point if we're continuing an existing curve */ if (start) cairo_move_to (graphics->ct, sx, sy); @@ -203,6 +204,42 @@ } static void +make_arcs (GpGraphics *graphics, float x, float y, float width, float height, float startAngle, float sweepAngle) +{ + int i; + float drawn = 0; + float endAngle = startAngle + sweepAngle; + int sign = (endAngle > 0) ? 1 : -1; + int increment = sign * 90; + + if (abs (sweepAngle) >= 360) { + make_ellipse (graphics, x, y, width, height); + return; + } + + /* i is the number of sub-arcs drawn, each sub-arc can be at most 90 degrees.*/ + /* there can be no more then 4 subarcs, ie. 90 + 90 + 90 + (something less than 90) */ + for (i = 0; i < 4; i++) { + float current = startAngle + drawn; + + /* we've drawn enough */ + if (abs (current) >= abs (endAngle)) + break; + + /* if we are not done yet */ + float additional = abs (current + increment) < abs (endAngle) ? + increment : /* add the default increment */ + endAngle - current; /* otherwise, add the remainder */ + + make_arc (graphics, + (i == 0) ? TRUE : FALSE, /* only move to the starting pt in the 1st iteration */ + x, y, width, height, /* bounding rectangle */ + current, current + additional); + drawn += additional; + } +} + +static void make_pie (GpGraphics *graphics, float x, float y, float width, float height, float startAngle, float sweepAngle) { @@ -213,10 +250,6 @@ float cx = x + rx; float cy = y + ry; - float endAngle = startAngle + sweepAngle; - - int i, sign = (sweepAngle > 0) ? 1 : -1; - /* angles in radians */ float alpha = startAngle * PI / 180; @@ -231,22 +264,8 @@ cx + rx * cos_alpha, cy + ry * sin_alpha); - /* just make an ellipse if we're going a full 2 PI (360 degrees) */ - if (abs (sweepAngle) >= 360) { - make_ellipse (graphics, x, y, width, height); - return; - } - /* draw the arcs */ - for (i = 0; i < abs (sweepAngle); i += 90) { - make_arc (graphics, - (i == 0) ? TRUE : FALSE, /* only move to the starting pt in the 1st iteration */ - x, y, width, height, /* bounding rectangle */ - startAngle + i * sign, /* start angle */ - (i + 90 < abs (sweepAngle)) ? - startAngle + (i + 90) * sign : endAngle); /* sweep angle at most up to 90 degrees */ - - } + make_arcs (graphics, x, y, width, height, startAngle, sweepAngle); /* draws line back to center */ cairo_line_to (graphics->ct, cx, cy); @@ -607,22 +626,8 @@ * have it set already. */ - /* just make an ellipse if we're going a full 360 degrees */ - if (abs (sweepAngle) >= 360) - make_ellipse (graphics, x, y, width, height); - else { - int i, sign = (endAngle > 0) ? 1 : -1; + make_arcs (graphics, x, y, width, height, startAngle, sweepAngle); - /* draw the arcs */ - for (i = 0; i < abs (endAngle); i += 90) { - make_arc (graphics, - (i == 0) ? TRUE : FALSE, /* only move to the starting pt in the 1st iteration */ - x, y, width, height, /* bounding rectangle */ - i * sign, /* start angle */ - (i + 90 < abs (endAngle)) ? (i + 90) * sign : endAngle); /* sweep angle, at most up to 90 degrees */ - } - } - /* We do pen setup just before stroking. */ gdip_pen_setup (graphics, pen); cairo_stroke (graphics->ct); _______________________________________________ Mono-patches maillist - Mono-patches@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-patches