CpmlArc — Manipulation of circular arcs
cairo_bool_t 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);
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.
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.
cairo_bool_t 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.
|
|
the CpmlPrimitive arc data |
|
|
where to store the center coordinates (can be NULL) |
|
|
where to store the radius (can be NULL) |
|
|
where to store the starting angle (can be NULL) |
|
|
where to store the ending angle (can be NULL) |
|
Returns : |
1 if the function worked succesfully, 0 on errors |
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.
|
|
the CpmlPrimitive arc data |
|
|
the destination cairo context |
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.
|
|
the CpmlPrimitive arc data |
|
|
the destination CpmlSegment |
|
|
number of Bézier to use |