## Migrating to ClutterPath

### Emmanuele Bassi

`<ebassi`linux.intel.com`>`

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.

Example 5. 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.

Example 6. 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.

Example 7. 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.

Example 8. 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");