<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC
  "-//OASIS//DTD DocBook XML V4.3//EN"
  "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="migrating-ClutterPath">

  <chapterinfo>
    <author>
      <firstname>Emmanuele</firstname>
      <surname>Bassi</surname>
      <affiliation>
        <address>
          <email>ebassi@linux.intel.com</email>
        </address>
      </affiliation>
    </author>
  </chapterinfo>

  <title>Migrating to ClutterPath</title>

  <para>Between Clutter 0.8 and Clutter 1.0 the #ClutterBehaviourPath
  behaviour lost all the path manipulation functions and the
  <structname>ClutterBehaviourBspline</structname> class was entirely
  deprecated.</para>

  <para>The class that replaced the path description and manipulation
  functionality is called #ClutterPath. A #ClutterPath allows
  describing a path using a sequence of #ClutterPathNode<!-- -->s 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.</para>

  <para>Finally, #ClutterPath also provides integration with Cairo,
  by being able to add paths described by the Cairo
  <structname>cairo_path_t</structname> data structure and being able
  to "replay" a #ClutterPath onto a <structname>cairo_t</structname>
  Cairo context.</para>

  <section id="creating-paths">
    <title>Creating a #ClutterPath</title>

    <para>Before Clutter 1.0, all the path-related functions inside
    #ClutterBehaviourPath and <structname>ClutterBehaviourBspline</structname>
    were replicated, but were also subtly different given the different nature
    of the types of path handled by the two #ClutterBehaviour<!-- -->s.</para>

    <example id="example-clutter-behaviour-path">
      <title>ClutterBehaviourPath example</title>
      <para>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.</para>
      <programlisting>
  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));
      </programlisting>
    </example>

    <para>The construction for a B-Spline path behaviour was similar, though
    the #ClutterKnot<!-- -->s could only describe a curvilinear path.</para>

    <example id="example-construct-clutter-path">
      <title>Constructing ClutterPath</title>
      <para>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.</para>
      <programlisting>
  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);
      </programlisting>
    </example>

    <para><note>A #ClutterPath object can be shared across behaviours, just
    like the #ClutterAlpha objects can.</note></para>

    <para>Path can be described by using a subset of the SVG notation for
    paths as well as using #ClutterPathNode structures.</para>

    <example id="example-describe-clutter-path">
      <title>Describing ClutterPath</title>
      <para>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.</para>
      <programlisting>
  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   */);
      </programlisting>
    </example>

    <para>A #ClutterPath can describe not only linear, closed paths; it
    can also describe paths with Beziér curvers and can add gaps.</para>

    <example id="example-describe-mixed-clutter-path">
      <title>Describing a mixed ClutterPath</title>
      <para>A mixed #ClutterPath, with a Beziér curve between the point
      at 200, 200 and 100, 100 and both control points in 100, 200.</para>
      <programlisting>
  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");
      </programlisting>
    </example>

  </section>

  <section id="iterating-paths">
    <title>Iterating over a #ClutterPath</title>

    <para>It is possible to iterate over all the #ClutterPathNode<!-- -->s
    inside a #ClutterPath by using clutter_path_get_nodes(), which will return
    a #GSList of #ClutterPathNode<!-- -->s; or by using clutter_path_foreach()
    with a function.</para>

    <para>The function pointer passed to clutter_path_foreach() should have the
    following definition:</para>

    <informalexample><programlisting>
  static void
  foreach_node (ClutterPathNode *path_node,
                gpointer         user_data)
  {
  }
    </programlisting></informalexample>
  </section>

  <section id="using-cairo">
    <title>Integration with Cairo</title>

    <para>A #ClutterPath can use a previously defined
    <structname>cairo_path_t</structname> to add new nodes, by using
    the clutter_path_add_cairo_path() function.</para>

    <para>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.</para>
  </section>

</chapter>