Emmanuele
Bassi
ebassi@linux.intel.com
Migrating to ClutterPath
Between Clutter 0.8 and Clutter 1.0 the #ClutterBehaviourPath
behaviour lost all the path manipulation functions and the
ClutterBehaviourBspline class was entirely
deprecated.
The class that replaced the path description and manipulation
functionality is called #ClutterPath. A #ClutterPath allows
describing a path using a sequence of #ClutterPathNodes or
using a subset of the SVG path description syntax. A Path instance
also allows describing complex paths, with linear and Bezier segments
and with gaps.
Finally, #ClutterPath also provides integration with Cairo,
by being able to add paths described by the Cairo
cairo_path_t data structure and being able
to "replay" a #ClutterPath onto a cairo_t
Cairo context.
Creating a #ClutterPath
Before Clutter 1.0, all the path-related functions inside
#ClutterBehaviourPath and ClutterBehaviourBspline
were replicated, but were also subtly different given the different nature
of the types of path handled by the two #ClutterBehaviours.
ClutterBehaviourPath example
The following code shows how a #ClutterBehaviourPath was
created prior to the introduction of #ClutterPath. The path described
is a square box between 100, 100 and 200, 200.
ClutterBehaviour *behaviour;
ClutterKnot knots[] = {
{ 100, 100 },
{ 200, 100 },
{ 200, 200 },
{ 100, 200 },
{ 100, 100 }
};
behaviour = clutter_behaviour_path_new (alpha, knots, G_N_ELEMENTS (knots));
The construction for a B-Spline path behaviour was similar, though
the #ClutterKnots could only describe a curvilinear path.
Constructing ClutterPath
The following code shows how to construct a #ClutterPath and
assign it to a #ClutterBehaviourPath. The created path is the same as
the example above.
ClutterBehaviour *behaviour;
ClutterPath *path;
path = clutter_path_new ();
clutter_path_add_move_to (path, 100, 100);
clutter_path_add_line_to (path, 200, 100);
clutter_path_add_line_to (path, 200, 200);
clutter_path_add_line_to (path, 100, 200);
clutter_path_add_close (path);
behaviour = clutter_behaviour_path_new (alpha, path);
A #ClutterPath object can be shared across behaviours, just
like the #ClutterAlpha objects can.
Path can be described by using a subset of the SVG notation for
paths as well as using #ClutterPathNode structures.
Describing ClutterPath
The SVG path notation subset used by #ClutterPath is in
string format and can be both set as the whole path description
using clutter_path_set_description() or can be added to an
existing #ClutterPath using clutter_path_add_string(). The following
example shows the same path as the two examples above.
ClutterPath *path = clutter_path_new ();
clutter_path_set_description (path,
"M 100,100 " /* move to */
"L 200,100 " /* line to */
"L 200,200 "
"L 100,200 "
"z" /* close */);
A #ClutterPath can describe not only linear, closed paths; it
can also describe paths with Beziér curvers and can add gaps.
Describing a mixed ClutterPath
A mixed #ClutterPath, with a Beziér curve between the point
at 200, 200 and 100, 100 and both control points in 100, 200.
ClutterPath *path = clutter_path_new ();
clutter_path_set_description (path,
"M 100,100 "
"L 200,100 "
"L 200,200 "
"C 100,200 100,200 100,100");
Iterating over a #ClutterPath
It is possible to iterate over all the #ClutterPathNodes
inside a #ClutterPath by using clutter_path_get_nodes(), which will return
a #GSList of #ClutterPathNodes; or by using clutter_path_foreach()
with a function.
The function pointer passed to clutter_path_foreach() should have the
following definition:
static void
foreach_node (ClutterPathNode *path_node,
gpointer user_data)
{
}
Integration with Cairo
A #ClutterPath can use a previously defined
cairo_path_t to add new nodes, by using
the clutter_path_add_cairo_path() function.
It is also possible to paint a #ClutterPath on a Cairo context,
by moving the Cairo pen across the nodes of the path using the
clutter_path_to_cairo_path() function.