+}
+
+
+/**
+ * converts a circle centered unit circle arc to a series of bezier curves
+ *
+ * Each bezier is stored as six values of three pairs of coordinates
+ *
+ * The beziers are stored without their start point as that is assumed
+ * to be the preceding elements end point.
+ *
+ * \param start The start angle of the arc (in radians)
+ * \param extent The size of the arc (in radians)
+ * \param bzpt The array to store the bezier values in
+ * \return The number of bezier segments output (max 4)
+ */
+static int
+circle_arc_to_bezier(double start, double extent, double *bzpt)
+{
+ int bzsegments;
+ double increment;
+ double controllen;
+ int pos = 0;
+ int segment;
+ double angle;
+ double dx, dy;
+
+ bzsegments = (int) ceil(fabs(extent) / M_PI_2);
+ increment = extent / bzsegments;
+ controllen = 4.0 / 3.0 * sin(increment / 2.0) / (1.0 + cos(increment / 2.0));
+
+ for (segment = 0; segment < bzsegments; segment++) {
+ /* first control point */
+ angle = start + (segment * increment);
+ dx = cos(angle);
+ dy = sin(angle);
+ bzpt[pos++] = dx - controllen * dy;
+ bzpt[pos++] = dy + controllen * dx;
+ /* second control point */
+ angle+=increment;
+ dx = cos(angle);
+ dy = sin(angle);
+ bzpt[pos++] = dx + controllen * dy;
+ bzpt[pos++] = dy - controllen * dx;
+ /* endpoint */
+ bzpt[pos++] = dx;
+ bzpt[pos++] = dy;
+
+ }
+ return bzsegments;
+}
+
+
+/**
+ * transform coordinate list
+ *
+ * perform a scale, rotate and translate on list of coordinates
+ *
+ * scale(rx,ry)
+ * rotate(an)
+ * translate (cx, cy)
+ *
+ * homogeneous transforms
+ *
+ * scaling
+ * | rx 0 0 |
+ * S = | 0 ry 0 |
+ * | 0 0 1 |
+ *
+ * rotate
+ * | cos(an) -sin(an) 0 |
+ * R = | sin(an) cos(an) 0 |
+ * | 0 0 1 |
+ *
+ * {{cos(a), -sin(a) 0}, {sin(a), cos(a),0}, {0,0,1}}
+ *
+ * translate
+ * | 1 0 cx |
+ * T = | 0 1 cy |
+ * | 0 0 1 |
+ *
+ * note order is significat here and the combined matrix is
+ * M = T.R.S
+ *
+ * | cos(an) -sin(an) cx |
+ * T.R = | sin(an) cos(an) cy |
+ * | 0 0 1 |
+ *
+ * | rx * cos(an) ry * -sin(an) cx |
+ * T.R.S = | rx * sin(an) ry * cos(an) cy |
+ * | 0 0 1 |
+ *
+ * {{Cos[a], -Sin[a], c}, {Sin[a], Cos[a], d}, {0, 0, 1}} . {{r, 0, 0}, {0, s, 0}, {0, 0, 1}}
+ *
+ * Each point
+ * | x1 |
+ * P = | y1 |
+ * | 1 |
+ *
+ * output
+ * | x2 |
+ * | y2 | = M . P
+ * | 1 |
+ *
+ * x2 = cx + (rx * x1 * cos(a)) + (ry * y1 * -1 * sin(a))
+ * y2 = cy + (ry * y1 * cos(a)) + (rx * x1 * sin(a))
+ *
+ *
+ * \param rx X scaling to apply
+ * \param ry Y scaling to apply
+ * \param radangle rotation to apply (in radians)
+ * \param cx X translation to apply
+ * \param cy Y translation to apply
+ * \param points The size of the bzpoints array
+ * \param bzpoints an array of x,y values to apply the transform to
+ */
+static void
+scale_rotate_translate_points(double rx, double ry,
+ double radangle,
+ double cx, double cy,
+ int pntsize,
+ double *points)
+{
+ int pnt;
+ double cosangle; /* cosine of rotation angle */
+ double sinangle; /* sine of rotation angle */
+ double rxcosangle, rxsinangle, rycosangle, rynsinangle;
+ double x2,y2;
+
+ /* compute the sin and cos of the angle */
+ cosangle = cos(radangle);
+ sinangle = sin(radangle);
+
+ rxcosangle = rx * cosangle;
+ rxsinangle = rx * sinangle;
+ rycosangle = ry * cosangle;
+ rynsinangle = ry * -1 * sinangle;
+
+ for (pnt = 0; pnt < pntsize; pnt+=2) {
+ x2 = cx + (points[pnt] * rxcosangle) + (points[pnt + 1] * rynsinangle);
+ y2 = cy + (points[pnt + 1] * rycosangle) + (points[pnt] * rxsinangle);
+ points[pnt] = x2;
+ points[pnt + 1] = y2;
+ }
+}
+
+
+/**
+ * convert an svg path arc to a bezier curve
+ *
+ * This function perfoms a transform on the nine arc parameters
+ * (coordinate pairs for start and end together with the radii of the
+ * elipse, the rotation angle and which of the four arcs to draw)
+ * which generates the parameters (coordinate pairs for start,
+ * end and their control points) for a set of up to four bezier curves.
+ *
+ * Obviously the start and end coordinates are not altered between
+ * representations so the aim is to calculate the coordinate pairs for
+ * the bezier control points.
+ *
+ * \param bzpoints the array to fill with bezier curves
+ * \return the number of bezier segments generated or -1 for a line
+ */
+static int
+svgarc_to_bezier(float start_x,
+ float start_y,
+ float end_x,
+ float end_y,
+ float rx,
+ float ry,
+ float angle,
+ bool largearc,
+ bool sweep,
+ double *bzpoints)
+{
+ double radangle; /* normalised elipsis rotation angle in radians */
+ double rx_sq; /* x radius squared */
+ double ry_sq; /* y radius squared */
+ double x1, y1; /* rotated midpoint vector */
+ double x1_sq, y1_sq; /* x1 vector squared */
+ double cx1,cy1; /* transformed circle center */
+ double cx,cy; /* circle center */
+ double start, extent;
+ int bzsegments;
+
+ if ((start_x == end_x) && (start_y == end_y)) {
+ /*
+ * if the start and end coordinates are the same the
+ * svg spec says this is equivalent to having no segment
+ * at all
+ */
+ return 0;
+ }
+
+ if ((rx == 0) || (ry == 0)) {
+ /*
+ * if either radii is zero the specified behaviour is a line
+ */
+ return -1;
+ }
+
+ /* obtain the absolute values of the radii */
+ rx = fabsf(rx);
+ ry = fabsf(ry);
+
+ /* convert normalised angle to radians */
+ radangle = degToRad(fmod(angle, 360.0));
+
+ /* step 1 */
+ /* x1,x2 is the midpoint vector rotated to remove the arc angle */
+ rotate_midpoint_vector(start_x, start_y, end_x, end_y, radangle, &x1, &y1);
+
+ /* step 2 */
+ /* get squared x1 values */
+ x1_sq = x1 * x1;
+ y1_sq = y1 * y1;
+
+ /* ensure radii are correctly scaled */
+ ensure_radii_scale(x1_sq, y1_sq, &rx, &ry, &rx_sq, &ry_sq);
+
+ /* compute the transformed centre point */
+ compute_transformed_centre_point(largearc == sweep?-1:1,
+ rx, ry,
+ rx_sq, ry_sq,
+ x1, y1,
+ x1_sq, y1_sq,
+ &cx1, &cy1);
+
+ /* step 3 */
+ /* get the untransformed centre point */
+ compute_centre_point(start_x, start_y,
+ end_x, end_y,
+ cx1, cy1,
+ radangle,
+ &cx, &cy);
+
+ /* step 4 */
+ /* compute anglestart and extent */
+ compute_angle_start_extent(rx,ry,
+ x1,y1,
+ cx1, cy1,
+ &start, &extent);
+
+ /* extent of 0 is a straight line */
+ if (extent == 0) {
+ return -1;