Synopsis

#include <cpml-1/cpml.h>

int                 cpml_arc_info                       (const CpmlPrimitive *arc,
                                                         CpmlPair *center,
                                                         double *r,
                                                         double *start,
                                                         double *end);
void                cpml_arc_to_cairo                   (const CpmlPrimitive *arc,
                                                         cairo_t *cr);
void                cpml_arc_to_curves                  (const CpmlPrimitive *arc,
                                                         CpmlSegment *segment,
                                                         size_t n_curves);

Description

The following functions manipulate CPML_ARC CpmlPrimitive. No validation is made on the input so use the following methods only when you are sure the primitive argument is effectively an arc-to.

The arc primitive is defined by 3 points: the first one is the usual implicit point got from the previous primitive, the second point is an arbitrary intermediate point laying on the arc and the third point is the end of the arc. These points identify univocally an arc: furthermore, the intermediate point also gives the side of the arc.

As a special case, when the first point is coincident with the end point the primitive is considered a circle with diameter defined by the segment between the first and the intermediate point.

Important

An arc is not a native cairo primitive and should be treated specially.

Using these CPML APIs you are free to use CPML_ARC whenever you want but, if you are directly accessing the struct fields, you are responsible of converting arcs to curves before passing them to cairo. In other words, do not directly feed CpmlPath struct to cairo (throught cairo_append_path() for example) or at least do not expect it will work.

The conversion is provided by two APIs: cpml_arc_to_cairo() and cpml_arc_to_curves(). The former directly renders to a cairo context and is internally used by all the ..._to_cairo() functions when an arc is met. The latter provided a more powerful (and more complex) approach as it allows to specify the number of curves to use and do not need a cairo context.

TODO

  • the get_closest_pos() method must be implemented;
  • the put_intersections() method must be implemented;

Details

cpml_arc_info ()

int                 cpml_arc_info                       (const CpmlPrimitive *arc,
                                                         CpmlPair *center,
                                                         double *r,
                                                         double *start,
                                                         double *end);

Given an arc, this function calculates and returns its basic data. Any pointer can be NULL, in which case the requested info is not returned. This function can fail (when the three points lay on a straight line, for example) in which case 0 is returned and no data can be considered valid.

The radius r can be 0 when the three points are coincidents: a circle with radius 0 is considered a valid path.

When the start and end angle are returned, together with their values these angles implicitely gives another important information: the arc direction.

If start < end the arc must be rendered with increasing angle value (clockwise direction using the ordinary cairo coordinate system) while if start > end the arc must be rendered in reverse order (that is counterclockwise in the cairo world). This is the reason the angle values are returned in the range { -M_PI < value < 3*M_PI } inclusive instead of the usual { -M_PI < value < M_PI } range.

arc :

the CpmlPrimitive arc data. [in]

center :

where to store the center coordinates. [out][allow-none]

r :

where to store the radius. [out][allow-none]

start :

where to store the starting angle. [out][allow-none]

end :

where to store the ending angle. [out][allow-none]

Returns :

1 if the function worked succesfully, 0 on errors. [type boolean]

Since 1.0


cpml_arc_to_cairo ()

void                cpml_arc_to_cairo                   (const CpmlPrimitive *arc,
                                                         cairo_t *cr);

Renders arc to the cr cairo context. As cairo does not support arcs natively, it is approximated using one or more Bézier curves.

The number of curves used is dependent from the angle of the arc. Anyway, this function uses internally the hardcoded M_PI_2 value as threshold value. This means the maximum arc approximated by a single curve will be a quarter of a circle and, consequently, a whole circle will be approximated by 4 Bézier curves.

arc :

the CpmlPrimitive arc data. [in]

cr :

the destination cairo context. [inout]

Since 1.0


cpml_arc_to_curves ()

void                cpml_arc_to_curves                  (const CpmlPrimitive *arc,
                                                         CpmlSegment *segment,
                                                         size_t n_curves);

Converts arc to a serie of n_curves Bézier curves and puts them inside segment. Obviously, segment must have enough space to contain at least n_curves curves.

This function works in a similar way as cpml_arc_to_cairo() but has two important differences: it does not need a cairo context and the number of curves to be generated is explicitely defined. The latter difference allows a more specific error control from the application: in the file src/cairo-arc.c, found in the cairo tarball (at least in cairo-1.9.1), there is a table showing the magnitude of error of this curve approximation algorithm.

arc :

the CpmlPrimitive arc data. [in]

segment :

the destination CpmlSegment. [out]

n_curves :

number of Bézier to use. [in]

Since 1.0