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.