[gimp/symmetry: 3/8] app: add a "custom" guide concept.



commit ed0e48888eb3c4373ca95a7bcc78da04e456e451
Author: Jehan <jehan girinstud io>
Date:   Tue Mar 24 21:01:50 2015 +0100

    app: add a "custom" guide concept.
    
    With gimp_guide_custom_new(), you can create a custom guide with a different
    style on canvas (other pattern/color/width). A custom guide won't be saved
    and could be used for specific GEGL op guiding for instance.
    The first usage is guiding for mirror symmetry.

 app/core/Makefile.am                    |    2 -
 app/core/core-types.h                   |    1 -
 app/core/gimpguide.c                    |  147 ++++++++++++++++++++-
 app/core/gimpguide.h                    |    9 ++
 app/core/gimpguideundo.c                |    1 +
 app/core/gimpimage-arrange.c            |    1 +
 app/core/gimpimage-crop.c               |    1 +
 app/core/gimpimage-duplicate.c          |    1 +
 app/core/gimpimage-flip.c               |    1 +
 app/core/gimpimage-guides.c             |    1 +
 app/core/gimpimage-resize.c             |    1 +
 app/core/gimpimage-rotate.c             |    1 +
 app/core/gimpimage-scale.c              |    1 +
 app/core/gimpimage-snap.c               |    1 +
 app/core/gimpimage-symmetry.c           |   42 ++----
 app/core/gimpimage-symmetry.h           |    4 +-
 app/core/gimpimage-undo-push.c          |    1 +
 app/core/gimpimage.c                    |   16 +--
 app/core/gimpmirrorguide.c              |  131 -------------------
 app/core/gimpmirrorguide.h              |   57 --------
 app/core/gimpsymmetry-mirror.c          |  146 +++++++++++----------
 app/core/gimpsymmetry-mirror.h          |    4 +-
 app/core/gimpsymmetry-tiling.c          |    1 -
 app/core/gimpsymmetry.c                 |   86 ++++++++++---
 app/core/gimpsymmetry.h                 |   10 +-
 app/display/gimpcanvas-style.c          |   57 --------
 app/display/gimpcanvas-style.h          |    4 -
 app/display/gimpcanvasguide.c           |   81 +++++++++---
 app/display/gimpcanvasguide.h           |    4 +-
 app/display/gimpdisplayshell-handlers.c |    6 +-
 app/paint/gimppaintoptions.c            |    7 +-
 app/pdb/image-guides-cmds.c             |    1 +
 app/tools/gimpdrawtool.c                |   15 ++-
 app/tools/gimpdrawtool.h                |    4 +-
 app/tools/gimpmovetool.c                |    6 +-
 app/xcf/xcf-load.c                      |  164 ++++++------------------
 app/xcf/xcf-private.h                   |    1 -
 app/xcf/xcf-save.c                      |  217 +++++++------------------------
 tools/pdbgen/pdb/image_guides.pdb       |    3 +-
 39 files changed, 510 insertions(+), 727 deletions(-)
---
diff --git a/app/core/Makefile.am b/app/core/Makefile.am
index a1a01af..b5f21bc 100644
--- a/app/core/Makefile.am
+++ b/app/core/Makefile.am
@@ -197,8 +197,6 @@ libappcore_a_sources = \
        gimpgrouplayer.h                        \
        gimpgrouplayerundo.c                    \
        gimpgrouplayerundo.h                    \
-       gimpmirrorguide.c                       \
-       gimpmirrorguide.h                       \
        gimpguide.c                             \
        gimpguide.h                             \
        gimpguideundo.c                         \
diff --git a/app/core/core-types.h b/app/core/core-types.h
index 996c758..242191b 100644
--- a/app/core/core-types.h
+++ b/app/core/core-types.h
@@ -184,7 +184,6 @@ typedef struct _GimpMirror          GimpMirror;
 typedef struct _GimpBuffer          GimpBuffer;
 typedef struct _GimpEnvironTable    GimpEnvironTable;
 typedef struct _GimpGuide           GimpGuide;
-typedef struct _GimpMirrorGuide     GimpMirrorGuide;
 typedef struct _GimpHistogram       GimpHistogram;
 typedef struct _GimpIdTable         GimpIdTable;
 typedef struct _GimpImageMap        GimpImageMap;
diff --git a/app/core/gimpguide.c b/app/core/gimpguide.c
index eaa8b74..7c45352 100644
--- a/app/core/gimpguide.c
+++ b/app/core/gimpguide.c
@@ -20,6 +20,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gio/gio.h>
 
 #include "libgimpbase/gimpbase.h"
@@ -27,6 +28,7 @@
 
 #include "core-types.h"
 
+#include "gimp-cairo.h"
 #include "gimpguide.h"
 #include "gimpmarshal.h"
 
@@ -41,7 +43,10 @@ enum
   PROP_0,
   PROP_ID,
   PROP_ORIENTATION,
-  PROP_POSITION
+  PROP_POSITION,
+  PROP_NORMAL_STYLE,
+  PROP_ACTIVE_STYLE,
+  PROP_LINE_WIDTH
 };
 
 
@@ -50,9 +55,15 @@ struct _GimpGuidePrivate
   guint32              guide_ID;
   GimpOrientationType  orientation;
   gint                 position;
+
+  cairo_pattern_t     *active_style;
+  cairo_pattern_t     *normal_style;
+  gdouble              line_width;
+  gboolean             custom;
 };
 
 
+static void   gimp_guide_finalize     (GObject      *object);
 static void   gimp_guide_get_property (GObject      *object,
                                        guint         property_id,
                                        GValue       *value,
@@ -65,6 +76,8 @@ static void   gimp_guide_set_property (GObject      *object,
 
 G_DEFINE_TYPE (GimpGuide, gimp_guide, G_TYPE_OBJECT)
 
+#define parent_class gimp_guide_parent_class
+
 static guint gimp_guide_signals[LAST_SIGNAL] = { 0 };
 
 
@@ -83,6 +96,7 @@ gimp_guide_class_init (GimpGuideClass *klass)
                   G_TYPE_NONE, 0);
 
 
+  object_class->finalize     = gimp_guide_finalize;
   object_class->get_property = gimp_guide_get_property;
   object_class->set_property = gimp_guide_set_property;
 
@@ -106,6 +120,21 @@ gimp_guide_class_init (GimpGuideClass *klass)
                                 GIMP_GUIDE_POSITION_UNDEFINED,
                                 0);
 
+  g_object_class_install_property (object_class, PROP_NORMAL_STYLE,
+                                   g_param_spec_pointer ("normal-style", NULL, NULL,
+                                                         GIMP_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class, PROP_ACTIVE_STYLE,
+                                   g_param_spec_pointer ("active-style", NULL, NULL,
+                                                         GIMP_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class, PROP_LINE_WIDTH,
+                                   g_param_spec_double ("line-width", NULL, NULL,
+                                                        0, GIMP_MAX_IMAGE_SIZE,
+                                                        1.0,
+                                                        GIMP_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY));
+
   g_type_class_add_private (klass, sizeof (GimpGuidePrivate));
 }
 
@@ -117,6 +146,17 @@ gimp_guide_init (GimpGuide *guide)
 }
 
 static void
+gimp_guide_finalize (GObject *object)
+{
+  GimpGuide *guide = GIMP_GUIDE (object);
+
+  cairo_pattern_destroy (guide->priv->normal_style);
+  cairo_pattern_destroy (guide->priv->active_style);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
 gimp_guide_get_property (GObject      *object,
                          guint         property_id,
                          GValue       *value,
@@ -135,6 +175,15 @@ gimp_guide_get_property (GObject      *object,
     case PROP_POSITION:
       g_value_set_int (value, guide->priv->position);
       break;
+    case PROP_NORMAL_STYLE:
+      g_value_set_pointer (value, guide->priv->normal_style);
+      break;
+    case PROP_ACTIVE_STYLE:
+      g_value_set_pointer (value, guide->priv->active_style);
+      break;
+    case PROP_LINE_WIDTH:
+      g_value_set_double (value, guide->priv->line_width);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -160,6 +209,23 @@ gimp_guide_set_property (GObject      *object,
     case PROP_POSITION:
       guide->priv->position = g_value_get_int (value);
       break;
+    case PROP_NORMAL_STYLE:
+      if (guide->priv->normal_style)
+        cairo_pattern_destroy (guide->priv->normal_style);
+
+      guide->priv->normal_style = g_value_get_pointer (value);
+      break;
+    case PROP_ACTIVE_STYLE:
+      if (guide->priv->active_style)
+        cairo_pattern_destroy (guide->priv->active_style);
+
+      guide->priv->active_style = g_value_get_pointer (value);
+      break;
+    case PROP_LINE_WIDTH:
+      guide->priv->line_width = g_value_get_double (value);
+      if (guide->priv->line_width != 1.0)
+        guide->priv->custom = TRUE;
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -170,12 +236,63 @@ GimpGuide *
 gimp_guide_new (GimpOrientationType  orientation,
                 guint32              guide_ID)
 {
+  const GimpRGB    normal_fg = { 0.0, 0.0, 0.0, 1.0 };
+  const GimpRGB    normal_bg = { 0.0, 0.5, 1.0, 1.0 };
+  const GimpRGB    active_fg = { 0.0, 0.0, 0.0, 1.0 };
+  const GimpRGB    active_bg = { 1.0, 0.0, 0.0, 1.0 };
+  cairo_pattern_t *normal_style;
+  cairo_pattern_t *active_style;
+
+  normal_style = gimp_cairo_stipple_pattern_create (&normal_fg,
+                                                    &normal_bg,
+                                                    0);
+  active_style = gimp_cairo_stipple_pattern_create (&active_fg,
+                                                    &active_bg,
+                                                    0);
   return g_object_new (GIMP_TYPE_GUIDE,
-                       "id",          guide_ID,
-                       "orientation", orientation,
+                       "id",           guide_ID,
+                       "orientation",  orientation,
+                       "normal-style", normal_style,
+                       "active-style", active_style,
+                       "line-width",   1.0,
                        NULL);
 }
 
+/**
+ * gimp_guide_custom_new:
+ * @orientation:  the #GimpOrientationType
+ * @guide_ID:     the unique guide ID
+ * @normal_style: a cairo pattern to use to draw the normal state
+ * @active_style: a cairo pattern to use to draw the active state
+ * @line_width:   the width of the guide line
+ *
+ * This function returns a new guide and will flag it as "custom".
+ * Custom guides are used for purpose "other" than the basic guides
+ * a user can create, for instance as symmetry guides, or drive GEGL ops,
+ * etc. They are not saved. If an op, a symmetry or a plugin wishes to
+ * save its state, it has to do it internally.
+ **/
+GimpGuide *
+gimp_guide_custom_new (GimpOrientationType  orientation,
+                       guint32              guide_ID,
+                       cairo_pattern_t     *normal_style,
+                       cairo_pattern_t     *active_style,
+                       gdouble              line_width)
+{
+  GimpGuide *guide;
+
+  guide = g_object_new (GIMP_TYPE_GUIDE,
+                        "id",          guide_ID,
+                        "orientation", orientation,
+                        "normal-style", normal_style,
+                        "active-style", active_style,
+                        "line-width", line_width,
+                        NULL);
+  guide->priv->custom = TRUE;
+
+  return guide;
+}
+
 guint32
 gimp_guide_get_ID (GimpGuide *guide)
 {
@@ -229,3 +346,27 @@ gimp_guide_removed (GimpGuide *guide)
 
   g_signal_emit (guide, gimp_guide_signals[REMOVED], 0);
 }
+
+cairo_pattern_t *
+gimp_guide_get_normal_style (GimpGuide *guide)
+{
+  return guide->priv->normal_style;
+}
+
+cairo_pattern_t *
+gimp_guide_get_active_style (GimpGuide *guide)
+{
+  return guide->priv->active_style;
+}
+
+gdouble
+gimp_guide_get_line_width (GimpGuide *guide)
+{
+  return guide->priv->line_width;
+}
+
+gboolean
+gimp_guide_is_custom (GimpGuide *guide)
+{
+  return guide->priv->custom;
+}
diff --git a/app/core/gimpguide.h b/app/core/gimpguide.h
index 20cc34e..c15fc86 100644
--- a/app/core/gimpguide.h
+++ b/app/core/gimpguide.h
@@ -59,6 +59,11 @@ GType               gimp_guide_get_type        (void) G_GNUC_CONST;
 
 GimpGuide *         gimp_guide_new             (GimpOrientationType  orientation,
                                                 guint32              guide_ID);
+GimpGuide *         gimp_guide_custom_new      (GimpOrientationType  orientation,
+                                                guint32              guide_ID,
+                                                cairo_pattern_t     *normal_style,
+                                                cairo_pattern_t     *active_style,
+                                                gdouble              line_width);
 
 guint32             gimp_guide_get_ID          (GimpGuide           *guide);
 
@@ -71,5 +76,9 @@ void                gimp_guide_set_position    (GimpGuide           *guide,
                                                 gint                 position);
 void                gimp_guide_removed         (GimpGuide           *guide);
 
+cairo_pattern_t   * gimp_guide_get_normal_style (GimpGuide           *guide);
+cairo_pattern_t   * gimp_guide_get_active_style (GimpGuide           *guide);
+gdouble             gimp_guide_get_line_width   (GimpGuide           *guide);
+gboolean            gimp_guide_is_custom        (GimpGuide           *guide);
 
 #endif /* __GIMP_GUIDE_H__ */
diff --git a/app/core/gimpguideundo.c b/app/core/gimpguideundo.c
index 37b83d3..7db4efd 100644
--- a/app/core/gimpguideundo.c
+++ b/app/core/gimpguideundo.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-arrange.c b/app/core/gimpimage-arrange.c
index cbbab3c..698fe01 100644
--- a/app/core/gimpimage-arrange.c
+++ b/app/core/gimpimage-arrange.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-crop.c b/app/core/gimpimage-crop.c
index 48537d0..e37237f 100644
--- a/app/core/gimpimage-crop.c
+++ b/app/core/gimpimage-crop.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-duplicate.c b/app/core/gimpimage-duplicate.c
index 95d8993..a4332e4 100644
--- a/app/core/gimpimage-duplicate.c
+++ b/app/core/gimpimage-duplicate.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-flip.c b/app/core/gimpimage-flip.c
index 0eefa8d..cc28d55 100644
--- a/app/core/gimpimage-flip.c
+++ b/app/core/gimpimage-flip.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-guides.c b/app/core/gimpimage-guides.c
index 4eafcb3..d80bea3 100644
--- a/app/core/gimpimage-guides.c
+++ b/app/core/gimpimage-guides.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-resize.c b/app/core/gimpimage-resize.c
index a96f334..d2f2949 100644
--- a/app/core/gimpimage-resize.c
+++ b/app/core/gimpimage-resize.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-rotate.c b/app/core/gimpimage-rotate.c
index 686ee10..1f32506 100644
--- a/app/core/gimpimage-rotate.c
+++ b/app/core/gimpimage-rotate.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-scale.c b/app/core/gimpimage-scale.c
index eb78c15..477d900 100644
--- a/app/core/gimpimage-scale.c
+++ b/app/core/gimpimage-scale.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-snap.c b/app/core/gimpimage-snap.c
index c651895..ceacd5a 100644
--- a/app/core/gimpimage-snap.c
+++ b/app/core/gimpimage-snap.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage-symmetry.c b/app/core/gimpimage-symmetry.c
index c34bda6..6d292f2 100644
--- a/app/core/gimpimage-symmetry.c
+++ b/app/core/gimpimage-symmetry.c
@@ -32,12 +32,17 @@
 #include "gimpsymmetry-mirror.h"
 #include "gimpsymmetry-tiling.h"
 
-static GimpSymmetry * gimp_image_symmetry_new (GimpImage *image,
-                                               GType      type);
+GList *
+gimp_image_symmetry_list (void)
+{
+  GList *list = NULL;
 
-/*** Private Functions ***/
+  list = g_list_prepend (list, GINT_TO_POINTER (GIMP_TYPE_MIRROR));
+  list = g_list_prepend (list, GINT_TO_POINTER (GIMP_TYPE_TILING));
+  return list;
+}
 
-static GimpSymmetry *
+GimpSymmetry *
 gimp_image_symmetry_new (GimpImage *image,
                          GType      type)
 {
@@ -54,18 +59,6 @@ gimp_image_symmetry_new (GimpImage *image,
   return sym;
 }
 
-/*** Public Functions ***/
-
-GList *
-gimp_image_symmetry_list (void)
-{
-  GList *list = NULL;
-
-  list = g_list_prepend (list, GINT_TO_POINTER (GIMP_TYPE_MIRROR));
-  list = g_list_prepend (list, GINT_TO_POINTER (GIMP_TYPE_TILING));
-  return list;
-}
-
 /**
  * gimp_image_symmetry_add:
  * @image: the #GimpImage
@@ -74,26 +67,20 @@ gimp_image_symmetry_list (void)
  * Add a symmetry of type @type to @image and make it the
  * selected transformation.
  **/
-GimpSymmetry *
-gimp_image_symmetry_add (GimpImage *image,
-                         GType      type)
+void
+gimp_image_symmetry_add (GimpImage    *image,
+                         GimpSymmetry *sym)
 {
   GimpImagePrivate *private;
-  GimpSymmetry     *sym;
 
-  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
-  g_return_val_if_fail (g_type_is_a (type, GIMP_TYPE_SYMMETRY), NULL);
-
-
-  sym = gimp_image_symmetry_new (image, type);
+  g_return_if_fail (GIMP_IS_IMAGE (image));
+  g_return_if_fail (GIMP_IS_SYMMETRY (sym));
 
   private = GIMP_IMAGE_GET_PRIVATE (image);
 
   private->symmetries = g_list_prepend (private->symmetries,
                                         sym);
   private->selected_symmetry = sym;
-
-  return sym;
 }
 
 /**
@@ -180,6 +167,7 @@ gimp_image_symmetry_select (GimpImage *image,
             }
         }
     }
+
   return FALSE;
 }
 
diff --git a/app/core/gimpimage-symmetry.h b/app/core/gimpimage-symmetry.h
index b9dacc9..109bd53 100644
--- a/app/core/gimpimage-symmetry.h
+++ b/app/core/gimpimage-symmetry.h
@@ -23,8 +23,10 @@
 
 GList        * gimp_image_symmetry_list      (void);
 
-GimpSymmetry * gimp_image_symmetry_add       (GimpImage    *image,
+GimpSymmetry * gimp_image_symmetry_new       (GimpImage    *image,
                                               GType         type);
+void           gimp_image_symmetry_add       (GimpImage    *image,
+                                              GimpSymmetry *sym);
 void           gimp_image_symmetry_remove    (GimpImage    *image,
                                               GimpSymmetry *sym);
 GList        * gimp_image_symmetry_get       (GimpImage    *image);
diff --git a/app/core/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c
index 066f35a..3f04cef 100644
--- a/app/core/gimpimage-undo-push.c
+++ b/app/core/gimpimage-undo-push.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <cairo.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gegl.h>
 
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 1cfb594..1e2b6c7 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -2292,12 +2292,9 @@ gimp_image_get_xcf_version (GimpImage    *image,
                             gint         *gimp_version,
                             const gchar **version_string)
 {
-  GList            *layers;
-  GimpImagePrivate *private;
-  GList            *list;
-  gint              version = 0;  /* default to oldest */
-
-  private = GIMP_IMAGE_GET_PRIVATE (image);
+  GList *layers;
+  GList *list;
+  gint   version = 0;  /* default to oldest */
 
   /* need version 1 for colormaps */
   if (gimp_image_get_colormap (image))
@@ -2347,12 +2344,6 @@ gimp_image_get_xcf_version (GimpImage    *image,
   if (zlib_compression)
     version = MAX (8, version);
 
-  /* need version 9 for symmetry */
-  if (private->symmetries)
-    {
-      version = MAX (9, version);
-    }
-
   switch (version)
     {
     case 0:
@@ -2372,7 +2363,6 @@ gimp_image_get_xcf_version (GimpImage    *image,
     case 6:
     case 7:
     case 8:
-    case 9:
       if (gimp_version)   *gimp_version   = 210;
       if (version_string) *version_string = "GIMP 2.10";
       break;
diff --git a/app/core/gimpsymmetry-mirror.c b/app/core/gimpsymmetry-mirror.c
index 96585ad..be06c97 100644
--- a/app/core/gimpsymmetry-mirror.c
+++ b/app/core/gimpsymmetry-mirror.c
@@ -22,6 +22,7 @@
 
 #include <string.h>
 
+#include <cairo.h>
 #include <gegl.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
@@ -30,8 +31,9 @@
 #include "core-types.h"
 
 #include "gimp.h"
+#include "gimp-cairo.h"
 #include "gimpbrush.h"
-#include "gimpmirrorguide.h"
+#include "gimpguide.h"
 #include "gimpimage.h"
 #include "gimpimage-guides.h"
 #include "gimpimage-symmetry.h"
@@ -75,6 +77,8 @@ static GeglNode * gimp_mirror_get_operation       (GimpSymmetry *mirror,
                                                    gint          paint_width,
                                                    gint          paint_height);
 static void       gimp_mirror_reset               (GimpMirror   *mirror);
+static GimpGuide * gimp_mirror_create_guide       (GimpImage    *image,
+                                                   GimpOrientationType orientation);
 static void       gimp_mirror_guide_removed_cb    (GObject      *object,
                                                    GimpMirror   *mirror);
 static void       gimp_mirror_guide_position_cb   (GObject      *object,
@@ -82,8 +86,6 @@ static void       gimp_mirror_guide_position_cb   (GObject      *object,
                                                    GimpMirror   *mirror);
 static GParamSpec ** gimp_mirror_get_settings     (GimpSymmetry *sym,
                                                    gint         *n_settings);
-static GParamSpec ** gimp_mirror_get_xcf_settings (GimpSymmetry *sym,
-                                                   gint         *n_settings);
 static void  gimp_mirror_set_horizontal_symmetry  (GimpMirror   *mirror,
                                                    gboolean      active);
 static void    gimp_mirror_set_vertical_symmetry  (GimpMirror   *mirror,
@@ -109,7 +111,6 @@ gimp_mirror_class_init (GimpMirrorClass *klass)
   symmetry_class->update_strokes    = gimp_mirror_update_strokes;
   symmetry_class->get_operation     = gimp_mirror_get_operation;
   symmetry_class->get_settings      = gimp_mirror_get_settings;
-  symmetry_class->get_xcf_settings  = gimp_mirror_get_xcf_settings;
 
   /* Properties for user settings */
   GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_HORIZONTAL_SYMMETRY,
@@ -207,13 +208,13 @@ gimp_mirror_set_property (GObject      *object,
     case PROP_HORIZONTAL_POSITION:
       mirror->horizontal_position = g_value_get_double (value);
       if (mirror->horizontal_guide)
-        gimp_guide_set_position (GIMP_GUIDE (mirror->horizontal_guide),
+        gimp_guide_set_position (mirror->horizontal_guide,
                                  mirror->horizontal_position);
       break;
     case PROP_VERTICAL_POSITION:
       mirror->vertical_position = g_value_get_double (value);
       if (mirror->vertical_guide)
-        gimp_guide_set_position (GIMP_GUIDE (mirror->vertical_guide),
+        gimp_guide_set_position (mirror->vertical_guide,
                                  mirror->vertical_position);
       break;
     default:
@@ -392,6 +393,32 @@ gimp_mirror_reset (GimpMirror *mirror)
     }
 }
 
+static GimpGuide *
+gimp_mirror_create_guide (GimpImage           *image,
+                          GimpOrientationType  orientation)
+{
+  static const GimpRGB  normal_fg = { 1.0, 1.0, 1.0, 1.0 };
+  static const GimpRGB  normal_bg = { 0.0, 1.0, 0.0, 1.0 };
+  static const GimpRGB  active_fg = { 0.0, 1.0, 0.0, 1.0 };
+  static const GimpRGB  active_bg = { 1.0, 0.0, 0.0, 1.0 };
+  Gimp                 *gimp  = GIMP (image->gimp);
+  GimpGuide            *guide;
+  cairo_pattern_t      *normal_style;
+  cairo_pattern_t      *active_style;
+
+  normal_style = gimp_cairo_stipple_pattern_create (&normal_fg,
+                                                    &normal_bg,
+                                                    0);
+  active_style = gimp_cairo_stipple_pattern_create (&active_fg,
+                                                    &active_bg,
+                                                    0);
+
+  guide = gimp_guide_custom_new (orientation,
+                                 gimp->next_guide_ID++,
+                                 normal_style, active_style, 1.0);
+  return guide;
+}
+
 static void
 gimp_mirror_guide_removed_cb (GObject    *object,
                               GimpMirror *mirror)
@@ -402,7 +429,7 @@ gimp_mirror_guide_removed_cb (GObject    *object,
   g_signal_handlers_disconnect_by_func (object,
                                         gimp_mirror_guide_position_cb,
                                         mirror);
-  if (GIMP_MIRROR_GUIDE (object) == mirror->horizontal_guide)
+  if (GIMP_GUIDE (object) == mirror->horizontal_guide)
     {
       g_object_unref (mirror->horizontal_guide);
 
@@ -412,7 +439,7 @@ gimp_mirror_guide_removed_cb (GObject    *object,
       mirror->point_symmetry      = FALSE;
       mirror->horizontal_position = 0.0;
     }
-  else if (GIMP_MIRROR_GUIDE (object) == mirror->vertical_guide)
+  else if (GIMP_GUIDE (object) == mirror->vertical_guide)
     {
       g_object_unref (mirror->vertical_guide);
       mirror->vertical_guide    = NULL;
@@ -446,11 +473,11 @@ gimp_mirror_guide_position_cb (GObject    *object,
 
   guide = GIMP_GUIDE (object);
 
-  if (GIMP_MIRROR_GUIDE (guide) == mirror->horizontal_guide)
+  if (guide == mirror->horizontal_guide)
     {
       mirror->horizontal_position = (gdouble) gimp_guide_get_position (guide);
     }
-  else if (GIMP_MIRROR_GUIDE (guide) == mirror->vertical_guide)
+  else if (guide == mirror->vertical_guide)
     {
       mirror->vertical_position = (gdouble) gimp_guide_get_position (guide);
     }
@@ -478,31 +505,6 @@ gimp_mirror_get_settings (GimpSymmetry *sym,
   return pspecs;
 }
 
-static GParamSpec **
-gimp_mirror_get_xcf_settings (GimpSymmetry *sym,
-                              gint         *n_settings)
-{
-  GParamSpec **pspecs;
-
-  *n_settings = 6;
-  pspecs = g_new (GParamSpec*, 6);
-
-  pspecs[0] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "horizontal-symmetry");
-  pspecs[1] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "vertical-symmetry");
-  pspecs[2] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "point-symmetry");
-  pspecs[3] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "horizontal-position");
-  pspecs[4] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "vertical-position");
-  pspecs[5] = g_object_class_find_property (G_OBJECT_GET_CLASS (sym),
-                                            "disable-transformation");
-
-  return pspecs;
-}
-
 static void
 gimp_mirror_set_horizontal_symmetry (GimpMirror *mirror,
                                      gboolean    active)
@@ -523,22 +525,22 @@ gimp_mirror_set_horizontal_symmetry (GimpMirror *mirror,
   if (active && ! mirror->horizontal_guide)
     {
       /* Create a new mirror guide. */
-      Gimp            *gimp  = GIMP (image->gimp);
-      GimpMirrorGuide *guide;
+      GimpGuide *guide;
 
-      /* Mirror guide position at first activation is at canvas middle. */
-      if (mirror->horizontal_position < 1.0)
-      mirror->horizontal_position = (gdouble) gimp_image_get_height (image) / 2.0;
-      guide = gimp_mirror_guide_new (gimp,
-                                     GIMP_ORIENTATION_HORIZONTAL,
-                                     gimp->next_guide_ID++);
+      guide = gimp_mirror_create_guide (image,
+                                        GIMP_ORIENTATION_HORIZONTAL);
       mirror->horizontal_guide = guide;
 
       g_signal_connect (G_OBJECT (mirror->horizontal_guide), "removed",
                         G_CALLBACK (gimp_mirror_guide_removed_cb),
                         mirror);
-      gimp_image_add_guide (image, GIMP_GUIDE (mirror->horizontal_guide),
+
+      /* Mirror guide position at first activation is at canvas middle. */
+      if (mirror->horizontal_position < 1.0)
+        mirror->horizontal_position = (gdouble) gimp_image_get_height (image) / 2.0;
+      gimp_image_add_guide (image, mirror->horizontal_guide,
                             (gint) mirror->horizontal_position);
+
       g_signal_connect (G_OBJECT (mirror->horizontal_guide), "notify::position",
                         G_CALLBACK (gimp_mirror_guide_position_cb),
                         mirror);
@@ -582,22 +584,23 @@ gimp_mirror_set_vertical_symmetry (GimpMirror *mirror,
       if (! mirror->vertical_guide)
         {
           /* Create a new mirror guide. */
-          Gimp            *gimp  = GIMP (image->gimp);
-          GimpMirrorGuide *guide;
+          GimpGuide *guide;
+
+          guide = gimp_mirror_create_guide (image,
+                                            GIMP_ORIENTATION_VERTICAL);
 
-          /* Mirror guide position at first activation is at canvas middle. */
-          if (mirror->vertical_position < 1.0)
-            mirror->vertical_position = (gdouble) gimp_image_get_width (image) / 2.0;
-          guide = gimp_mirror_guide_new (gimp,
-                                         GIMP_ORIENTATION_VERTICAL,
-                                         gimp->next_guide_ID++);
           mirror->vertical_guide = guide;
 
           g_signal_connect (G_OBJECT (mirror->vertical_guide), "removed",
                             G_CALLBACK (gimp_mirror_guide_removed_cb),
                             mirror);
-          gimp_image_add_guide (image, GIMP_GUIDE (mirror->vertical_guide),
+
+          /* Mirror guide position at first activation is at canvas middle. */
+          if (mirror->vertical_position < 1.0)
+            mirror->vertical_position = (gdouble) gimp_image_get_width (image) / 2.0;
+          gimp_image_add_guide (image, mirror->vertical_guide,
                                 (gint) mirror->vertical_position);
+
           g_signal_connect (G_OBJECT (mirror->vertical_guide), "notify::position",
                             G_CALLBACK (gimp_mirror_guide_position_cb),
                             mirror);
@@ -645,23 +648,22 @@ gimp_mirror_set_point_symmetry (GimpMirror *mirror,
           if (! mirror->horizontal_guide)
             {
               /* Create a new mirror guide. */
-              Gimp            *gimp  = GIMP (image->gimp);
-              GimpMirrorGuide *guide;
+              GimpGuide *guide;
 
-              /* Mirror guide position at first activation is at canvas middle. */
-              if (mirror->horizontal_position < 1.0)
-                mirror->horizontal_position = (gdouble) gimp_image_get_height (image) / 2.0;
-              guide = gimp_mirror_guide_new (gimp,
-                                             GIMP_ORIENTATION_HORIZONTAL,
-                                             gimp->next_guide_ID++);
+              guide = gimp_mirror_create_guide (image,
+                                                GIMP_ORIENTATION_HORIZONTAL);
               mirror->horizontal_guide = guide;
 
-
               g_signal_connect (G_OBJECT (mirror->horizontal_guide), "removed",
                                 G_CALLBACK (gimp_mirror_guide_removed_cb),
                                 mirror);
-              gimp_image_add_guide (image, GIMP_GUIDE (mirror->horizontal_guide),
+
+              /* Mirror guide position at first activation is at canvas middle. */
+              if (mirror->horizontal_position < 1.0)
+                mirror->horizontal_position = (gdouble) gimp_image_get_height (image) / 2.0;
+              gimp_image_add_guide (image, mirror->horizontal_guide,
                                     (gint) mirror->horizontal_position);
+
               g_signal_connect (G_OBJECT (mirror->horizontal_guide), "notify::position",
                                 G_CALLBACK (gimp_mirror_guide_position_cb),
                                 mirror);
@@ -674,22 +676,22 @@ gimp_mirror_set_point_symmetry (GimpMirror *mirror,
           if (! mirror->vertical_guide)
             {
               /* Create a new mirror guide. */
-              Gimp            *gimp  = GIMP (image->gimp);
-              GimpMirrorGuide *guide;
+              GimpGuide *guide;
 
-              /* Mirror guide position at first activation is at canvas middle. */
-              if (mirror->vertical_position < 1.0)
-                mirror->vertical_position = (gdouble) gimp_image_get_width (image) / 2.0;
-              guide = gimp_mirror_guide_new (gimp,
-                                             GIMP_ORIENTATION_VERTICAL,
-                                             gimp->next_guide_ID++);
+              guide = gimp_mirror_create_guide (image,
+                                                GIMP_ORIENTATION_VERTICAL);
               mirror->vertical_guide = guide;
 
               g_signal_connect (G_OBJECT (mirror->vertical_guide), "removed",
                                 G_CALLBACK (gimp_mirror_guide_removed_cb),
                                 mirror);
-              gimp_image_add_guide (image, GIMP_GUIDE (mirror->vertical_guide),
+
+              /* Mirror guide position at first activation is at canvas middle. */
+              if (mirror->vertical_position < 1.0)
+                mirror->vertical_position = (gdouble) gimp_image_get_width (image) / 2.0;
+              gimp_image_add_guide (image, mirror->vertical_guide,
                                     (gint) mirror->vertical_position);
+
               g_signal_connect (G_OBJECT (mirror->vertical_guide), "notify::position",
                                 G_CALLBACK (gimp_mirror_guide_position_cb),
                                 mirror);
diff --git a/app/core/gimpsymmetry-mirror.h b/app/core/gimpsymmetry-mirror.h
index abe6e51..b943eef 100644
--- a/app/core/gimpsymmetry-mirror.h
+++ b/app/core/gimpsymmetry-mirror.h
@@ -45,8 +45,8 @@ struct _GimpMirror
 
   gdouble          horizontal_position;
   gdouble          vertical_position;
-  GimpMirrorGuide *horizontal_guide;
-  GimpMirrorGuide *vertical_guide;
+  GimpGuide       *horizontal_guide;
+  GimpGuide       *vertical_guide;
 
   /* Cached data */
   gint             last_paint_width;
diff --git a/app/core/gimpsymmetry-tiling.c b/app/core/gimpsymmetry-tiling.c
index af22de5..1af053b 100644
--- a/app/core/gimpsymmetry-tiling.c
+++ b/app/core/gimpsymmetry-tiling.c
@@ -100,7 +100,6 @@ gimp_tiling_class_init (GimpTilingClass *klass)
   symmetry_class->update_strokes   = gimp_tiling_update_strokes;
   symmetry_class->get_operation    = gimp_tiling_get_operation;
   symmetry_class->get_settings     = gimp_tiling_get_settings;
-  symmetry_class->get_xcf_settings = gimp_tiling_get_settings;
 
   GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_X_INTERVAL,
                                    "x-interval", _("Intervals on x-axis (pixels)"),
diff --git a/app/core/gimpsymmetry.c b/app/core/gimpsymmetry.c
index 5c0eb4c..91fac39 100644
--- a/app/core/gimpsymmetry.c
+++ b/app/core/gimpsymmetry.c
@@ -25,10 +25,14 @@
 #include <gegl.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
 #include "core-types.h"
 
 #include "gimpdrawable.h"
 #include "gimpimage.h"
+#include "gimpimage-symmetry.h"
 #include "gimpitem.h"
 #include "gimpsymmetry.h"
 
@@ -72,7 +76,9 @@ static GParamSpec **
           gimp_symmetry_real_get_settings (GimpSymmetry *sym,
                                            gint         *n_properties);
 
-G_DEFINE_TYPE (GimpSymmetry, gimp_symmetry, GIMP_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_CODE (GimpSymmetry, gimp_symmetry, GIMP_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL))
+
 
 #define parent_class gimp_symmetry_parent_class
 
@@ -116,7 +122,6 @@ gimp_symmetry_class_init (GimpSymmetryClass *klass)
   klass->update_strokes      = gimp_symmetry_real_update_strokes;
   klass->get_operation       = gimp_symmetry_real_get_op;
   klass->get_settings        = gimp_symmetry_real_get_settings;
-  klass->get_xcf_settings    = gimp_symmetry_real_get_settings;
 
   g_object_class_install_property (object_class, PROP_IMAGE,
                                    g_param_spec_object ("image",
@@ -347,24 +352,69 @@ gimp_symmetry_get_settings (GimpSymmetry *sym,
                                                       n_properties);
 }
 
-/**
- * gimp_symmetry_get_xcf_settings:
- * @sym:         the #GimpSymmetry
- * @n_properties: the number of properties in the returned array
+/*
+ * gimp_symmetry_parasite_name:
+ * @type: the #GimpSymmetry's #GType
  *
- * Returns an array of the symmetry properties which are to be serialized
- * when saving to XCF.
- * These properties may be different to `gimp_symmetry_get_settings()`
- * (for instance some properties are not meant to be user-changeable but
- * still saved)
- * The returned array must be freed by the caller.
- **/
-GParamSpec **
-gimp_symmetry_get_xcf_settings (GimpSymmetry *sym,
-                                gint         *n_properties)
+ * Returns: a newly allocated string.
+ */
+gchar *
+gimp_symmetry_parasite_name (GType type)
+{
+  GimpSymmetryClass *klass;
+
+  klass = g_type_class_ref (type);
+
+  return g_strconcat ("gimp-image-symmetry:", klass->label, NULL);
+}
+
+GimpParasite *
+gimp_symmetry_to_parasite (const GimpSymmetry *sym)
 {
+  GimpParasite *parasite;
+  gchar        *str;
+
   g_return_val_if_fail (GIMP_IS_SYMMETRY (sym), NULL);
 
-  return GIMP_SYMMETRY_GET_CLASS (sym)->get_xcf_settings (sym,
-                                                          n_properties);
+  str = gimp_config_serialize_to_string (GIMP_CONFIG (sym), NULL);
+  g_return_val_if_fail (str != NULL, NULL);
+
+  parasite = gimp_parasite_new (gimp_symmetry_parasite_name (sym->type),
+                                GIMP_PARASITE_PERSISTENT,
+                                strlen (str) + 1, str);
+  g_free (str);
+
+  return parasite;
+}
+
+GimpSymmetry *
+gimp_symmetry_from_parasite (const GimpParasite *parasite,
+                             GimpImage          *image,
+                             GType               type)
+{
+  GimpSymmetry    *symmetry;
+  const gchar     *str;
+  GError          *error = NULL;
+
+  g_return_val_if_fail (parasite != NULL, NULL);
+  g_return_val_if_fail (strcmp (gimp_parasite_name (parasite),
+                                gimp_symmetry_parasite_name (type)) == 0,
+                        NULL);
+
+  str = gimp_parasite_data (parasite);
+  g_return_val_if_fail (str != NULL, NULL);
+
+  symmetry = gimp_image_symmetry_new (image, type);
+
+  if (! gimp_config_deserialize_string (GIMP_CONFIG (symmetry),
+                                        str,
+                                        gimp_parasite_data_size (parasite),
+                                        NULL,
+                                        &error))
+    {
+      g_warning ("Failed to deserialize symmetry parasite: %s", error->message);
+      g_error_free (error);
+    }
+
+  return symmetry;
 }
diff --git a/app/core/gimpsymmetry.h b/app/core/gimpsymmetry.h
index 44f1d8c..ed966ef 100644
--- a/app/core/gimpsymmetry.h
+++ b/app/core/gimpsymmetry.h
@@ -64,9 +64,6 @@ struct _GimpSymmetryClass
   GParamSpec **
              (* get_settings)               (GimpSymmetry *sym,
                                              gint         *n_properties);
-  GParamSpec **
-             (* get_xcf_settings)           (GimpSymmetry *sym,
-                                             gint         *n_properties);
 };
 
 
@@ -86,7 +83,10 @@ GeglNode   * gimp_symmetry_get_operation    (GimpSymmetry *sym,
                                              gint          paint_height);
 GParamSpec ** gimp_symmetry_get_settings     (GimpSymmetry *sym,
                                               gint         *n_properties);
-GParamSpec ** gimp_symmetry_get_xcf_settings (GimpSymmetry *sym,
-                                              gint         *n_properties);
 
+gchar        * gimp_symmetry_parasite_name  (GType type);
+GimpParasite * gimp_symmetry_to_parasite    (const GimpSymmetry *symmetry);
+GimpSymmetry * gimp_symmetry_from_parasite  (const GimpParasite *parasite,
+                                             GimpImage          *image,
+                                             GType               type);
 #endif  /*  __GIMP_SYMMETRY_H__  */
diff --git a/app/display/gimpcanvas-style.c b/app/display/gimpcanvas-style.c
index 8af29b3..39ade03 100644
--- a/app/display/gimpcanvas-style.c
+++ b/app/display/gimpcanvas-style.c
@@ -35,16 +35,6 @@
 #include "gimpcanvas-style.h"
 
 
-static const GimpRGB guide_normal_fg     = { 0.0, 0.0, 0.0, 1.0 };
-static const GimpRGB guide_normal_bg     = { 0.0, 0.5, 1.0, 1.0 };
-static const GimpRGB guide_active_fg     = { 0.0, 0.0, 0.0, 1.0 };
-static const GimpRGB guide_active_bg     = { 1.0, 0.0, 0.0, 1.0 };
-
-static const GimpRGB mirror_guide_normal_fg = { 1.0, 1.0, 1.0, 1.0 };
-static const GimpRGB mirror_guide_normal_bg = { 0.0, 1.0, 0.0, 1.0 };
-static const GimpRGB mirror_guide_active_fg = { 0.0, 1.0, 0.0, 1.0 };
-static const GimpRGB mirror_guide_active_bg = { 1.0, 0.0, 0.0, 1.0 };
-
 static const GimpRGB sample_point_normal = { 0.0, 0.5, 1.0, 1.0 };
 static const GimpRGB sample_point_active = { 1.0, 0.0, 0.0, 1.0 };
 
@@ -82,53 +72,6 @@ static const GimpRGB tool_fg_highlight   = { 1.0, 0.8, 0.2, 0.8 };
 /*  public functions  */
 
 void
-gimp_canvas_set_guide_style (GtkWidget      *canvas,
-                             cairo_t        *cr,
-                             GimpGuideStyle  style,
-                             gboolean        active)
-{
-  cairo_pattern_t *pattern;
-  const GimpRGB *fg;
-  const GimpRGB *bg;
-
-  g_return_if_fail (GTK_IS_WIDGET (canvas));
-  g_return_if_fail (cr != NULL);
-
-  cairo_set_line_width (cr, 1.0);
-
-  if (active)
-    {
-      if (style == GIMP_GUIDE_STYLE_MIRROR)
-        {
-          fg = &mirror_guide_active_fg;
-          bg = &mirror_guide_active_bg;
-        }
-      else /* style == GIMP_GUIDE_STYLE_NORMAL */
-        {
-          fg = &guide_active_fg;
-          bg = &guide_active_bg;
-        }
-    }
-  else
-    {
-      if (style == GIMP_GUIDE_STYLE_MIRROR)
-        {
-          fg = &mirror_guide_normal_fg;
-          bg = &mirror_guide_normal_bg;
-        }
-      else /* style == GIMP_GUIDE_STYLE_NORMAL */
-        {
-          fg = &guide_normal_fg;
-          bg = &guide_normal_bg;
-        }
-    }
-  pattern = gimp_cairo_stipple_pattern_create (fg, bg, 0);
-
-  cairo_set_source (cr, pattern);
-  cairo_pattern_destroy (pattern);
-}
-
-void
 gimp_canvas_set_sample_point_style (GtkWidget *canvas,
                                     cairo_t   *cr,
                                     gboolean   active)
diff --git a/app/display/gimpcanvas-style.h b/app/display/gimpcanvas-style.h
index 301f940..726afa6 100644
--- a/app/display/gimpcanvas-style.h
+++ b/app/display/gimpcanvas-style.h
@@ -22,10 +22,6 @@
 #define __GIMP_CANVAS_STYLE_H__
 
 
-void   gimp_canvas_set_guide_style         (GtkWidget     *canvas,
-                                            cairo_t       *cr,
-                                            GimpGuideStyle style,
-                                            gboolean       active);
 void   gimp_canvas_set_sample_point_style  (GtkWidget     *canvas,
                                             cairo_t       *cr,
                                             gboolean       active);
diff --git a/app/display/gimpcanvasguide.c b/app/display/gimpcanvasguide.c
index ccc64c8..62d4cf5 100644
--- a/app/display/gimpcanvasguide.c
+++ b/app/display/gimpcanvasguide.c
@@ -38,7 +38,9 @@ enum
   PROP_0,
   PROP_ORIENTATION,
   PROP_POSITION,
-  PROP_GUIDE_STYLE
+  PROP_NORMAL_STYLE,
+  PROP_ACTIVE_STYLE,
+  PROP_LINE_WIDTH
 };
 
 
@@ -46,9 +48,12 @@ typedef struct _GimpCanvasGuidePrivate GimpCanvasGuidePrivate;
 
 struct _GimpCanvasGuidePrivate
 {
-  GimpOrientationType orientation;
-  gint                position;
-  GimpGuideStyle      guide_style;
+  GimpOrientationType  orientation;
+  gint                 position;
+
+  cairo_pattern_t     *active_style;
+  cairo_pattern_t     *normal_style;
+  gdouble              line_width;
 };
 
 #define GET_PRIVATE(guide) \
@@ -104,11 +109,20 @@ gimp_canvas_guide_class_init (GimpCanvasGuideClass *klass)
                                                      GIMP_MAX_IMAGE_SIZE, 0,
                                                      GIMP_PARAM_READWRITE));
 
-  g_object_class_install_property (object_class, PROP_GUIDE_STYLE,
-                                   g_param_spec_enum ("guide-style", NULL, NULL,
-                                                      GIMP_TYPE_GUIDE_STYLE,
-                                                      GIMP_GUIDE_STYLE_NONE,
-                                                      GIMP_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_NORMAL_STYLE,
+                                   g_param_spec_pointer ("normal-style", NULL, NULL,
+                                                         GIMP_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class, PROP_ACTIVE_STYLE,
+                                   g_param_spec_pointer ("active-style", NULL, NULL,
+                                                         GIMP_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class, PROP_LINE_WIDTH,
+                                   g_param_spec_double ("line-width", NULL, NULL,
+                                                        0, GIMP_MAX_IMAGE_SIZE,
+                                                        1.0,
+                                                        GIMP_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY));
 
   g_type_class_add_private (klass, sizeof (GimpCanvasGuidePrivate));
 }
@@ -134,8 +148,14 @@ gimp_canvas_guide_set_property (GObject      *object,
     case PROP_POSITION:
       private->position = g_value_get_int (value);
       break;
-    case PROP_GUIDE_STYLE:
-      private->guide_style = g_value_get_enum (value);
+    case PROP_NORMAL_STYLE:
+      private->normal_style = g_value_get_pointer (value);
+      break;
+    case PROP_ACTIVE_STYLE:
+      private->active_style = g_value_get_pointer (value);
+      break;
+    case PROP_LINE_WIDTH:
+      private->line_width = g_value_get_double (value);
       break;
 
     default:
@@ -160,8 +180,14 @@ gimp_canvas_guide_get_property (GObject    *object,
     case PROP_POSITION:
       g_value_set_int (value, private->position);
       break;
-    case PROP_GUIDE_STYLE:
-      g_value_set_enum (value, private->guide_style);
+    case PROP_NORMAL_STYLE:
+      g_value_set_pointer (value, private->normal_style);
+      break;
+    case PROP_ACTIVE_STYLE:
+      g_value_set_pointer (value, private->active_style);
+      break;
+    case PROP_LINE_WIDTH:
+      g_value_set_double (value, private->line_width);
       break;
 
     default:
@@ -247,11 +273,18 @@ gimp_canvas_guide_stroke (GimpCanvasItem *item,
 {
   GimpCanvasGuidePrivate *private = GET_PRIVATE (item);
 
-  if (private->guide_style != GIMP_GUIDE_STYLE_NONE)
+  if (private->active_style &&
+      gimp_canvas_item_get_highlight (item))
+    {
+      cairo_set_line_width (cr, private->line_width);
+      cairo_set_source (cr, private->active_style);
+      cairo_stroke (cr);
+    }
+  else if (private->normal_style &&
+           ! gimp_canvas_item_get_highlight (item))
     {
-      gimp_canvas_set_guide_style (gimp_canvas_item_get_canvas (item), cr,
-                                   private->guide_style,
-                                   gimp_canvas_item_get_highlight (item));
+      cairo_set_line_width (cr, private->line_width);
+      cairo_set_source (cr, private->normal_style);
       cairo_stroke (cr);
     }
   else
@@ -264,15 +297,19 @@ GimpCanvasItem *
 gimp_canvas_guide_new (GimpDisplayShell    *shell,
                        GimpOrientationType  orientation,
                        gint                 position,
-                       GimpGuideStyle       guide_style)
+                       cairo_pattern_t     *normal_style,
+                       cairo_pattern_t     *active_style,
+                       gdouble              line_width)
 {
   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
 
   return g_object_new (GIMP_TYPE_CANVAS_GUIDE,
-                       "shell",       shell,
-                       "orientation", orientation,
-                       "position",    position,
-                       "guide-style", guide_style,
+                       "shell",        shell,
+                       "orientation",  orientation,
+                       "position",     position,
+                       "normal-style", normal_style,
+                       "active-style", active_style,
+                       "line-width",   line_width,
                        NULL);
 }
 
diff --git a/app/display/gimpcanvasguide.h b/app/display/gimpcanvasguide.h
index d825dd7..380238b 100644
--- a/app/display/gimpcanvasguide.h
+++ b/app/display/gimpcanvasguide.h
@@ -52,7 +52,9 @@ GType            gimp_canvas_guide_get_type (void) G_GNUC_CONST;
 GimpCanvasItem * gimp_canvas_guide_new      (GimpDisplayShell    *shell,
                                              GimpOrientationType  orientation,
                                              gint                 position,
-                                             GimpGuideStyle       guide_style);
+                                             cairo_pattern_t     *normal_style,
+                                             cairo_pattern_t     *active_style,
+                                             gdouble              line_width);
 
 void             gimp_canvas_guide_set      (GimpCanvasItem      *guide,
                                              GimpOrientationType  orientation,
diff --git a/app/display/gimpdisplayshell-handlers.c b/app/display/gimpdisplayshell-handlers.c
index 2d5046d..04a28cb 100644
--- a/app/display/gimpdisplayshell-handlers.c
+++ b/app/display/gimpdisplayshell-handlers.c
@@ -32,7 +32,6 @@
 
 #include "core/gimp.h"
 #include "core/gimpguide.h"
-#include "core/gimpmirrorguide.h"
 #include "core/gimpimage.h"
 #include "core/gimpimage-grid.h"
 #include "core/gimpimage-guides.h"
@@ -627,8 +626,9 @@ gimp_display_shell_guide_add_handler (GimpImage        *image,
   item = gimp_canvas_guide_new (shell,
                                 gimp_guide_get_orientation (guide),
                                 gimp_guide_get_position (guide),
-                                GIMP_IS_MIRROR_GUIDE (guide) ?
-                                GIMP_GUIDE_STYLE_MIRROR : GIMP_GUIDE_STYLE_NORMAL);
+                                gimp_guide_get_normal_style (guide),
+                                gimp_guide_get_active_style (guide),
+                                gimp_guide_get_line_width (guide));
 
   gimp_canvas_proxy_group_add_item (group, guide, item);
   g_object_unref (item);
diff --git a/app/paint/gimppaintoptions.c b/app/paint/gimppaintoptions.c
index 255de56..846ad2d 100644
--- a/app/paint/gimppaintoptions.c
+++ b/app/paint/gimppaintoptions.c
@@ -593,8 +593,11 @@ gimp_paint_options_set_property (GObject      *object,
           if (! gimp_image_symmetry_select (context->image,
                                             options->symmetry))
             {
-              gimp_image_symmetry_add (context->image,
-                                       options->symmetry);
+              GimpSymmetry *sym;
+
+              sym = gimp_image_symmetry_new (context->image,
+                                             options->symmetry);
+              gimp_image_symmetry_add (context->image, sym);
             }
         }
       else
diff --git a/app/pdb/image-guides-cmds.c b/app/pdb/image-guides-cmds.c
index 10e78c9..e81335c 100644
--- a/app/pdb/image-guides-cmds.c
+++ b/app/pdb/image-guides-cmds.c
@@ -27,6 +27,7 @@
 
 #include "pdb-types.h"
 
+#include "cairo.h"
 #include "core/gimpguide.h"
 #include "core/gimpimage-guides.h"
 #include "core/gimpimage-undo-push.h"
diff --git a/app/tools/gimpdrawtool.c b/app/tools/gimpdrawtool.c
index 1f707f0..6ab57c8 100644
--- a/app/tools/gimpdrawtool.c
+++ b/app/tools/gimpdrawtool.c
@@ -19,6 +19,7 @@
 
 #include <string.h>
 
+#include <cairo.h>
 #include <gegl.h>
 #include <gtk/gtk.h>
 
@@ -27,6 +28,7 @@
 #include "tools-types.h"
 
 #include "core/gimpdrawable.h"
+#include "core/gimpguide.h"
 #include "core/gimpimage.h"
 
 #include "vectors/gimpanchor.h"
@@ -583,14 +585,17 @@ GimpCanvasItem *
 gimp_draw_tool_add_guide (GimpDrawTool        *draw_tool,
                           GimpOrientationType  orientation,
                           gint                 position,
-                          gboolean             guide_style)
+                          cairo_pattern_t     *normal_style,
+                          cairo_pattern_t     *active_style,
+                          gdouble              line_width)
 {
   GimpCanvasItem *item;
 
   g_return_val_if_fail (GIMP_IS_DRAW_TOOL (draw_tool), NULL);
 
   item = gimp_canvas_guide_new (gimp_display_get_shell (draw_tool->display),
-                                orientation, position, guide_style);
+                                orientation, position,
+                                normal_style, active_style, line_width);
 
   gimp_draw_tool_add_item (draw_tool, item);
   g_object_unref (item);
@@ -617,9 +622,11 @@ gimp_draw_tool_add_crosshair (GimpDrawTool *draw_tool,
 
   gimp_draw_tool_push_group (draw_tool, group);
   gimp_draw_tool_add_guide (draw_tool,
-                            GIMP_ORIENTATION_VERTICAL, position_x, FALSE);
+                            GIMP_ORIENTATION_VERTICAL, position_x,
+                           NULL, NULL, 1.0);
   gimp_draw_tool_add_guide (draw_tool,
-                            GIMP_ORIENTATION_HORIZONTAL, position_y, FALSE);
+                            GIMP_ORIENTATION_HORIZONTAL, position_y,
+                           NULL, NULL, 1.0);
   gimp_draw_tool_pop_group (draw_tool);
 
   return GIMP_CANVAS_ITEM (group);
diff --git a/app/tools/gimpdrawtool.h b/app/tools/gimpdrawtool.h
index 6f358c4..2ae34b2 100644
--- a/app/tools/gimpdrawtool.h
+++ b/app/tools/gimpdrawtool.h
@@ -115,7 +115,9 @@ GimpCanvasItem * gimp_draw_tool_add_line             (GimpDrawTool     *draw_too
 GimpCanvasItem * gimp_draw_tool_add_guide            (GimpDrawTool     *draw_tool,
                                                       GimpOrientationType  orientation,
                                                       gint              position,
-                                                      gboolean          guide_style);
+                                                      cairo_pattern_t  *normal_style,
+                                                      cairo_pattern_t  *active_style,
+                                                      gdouble           line_width);
 GimpCanvasItem * gimp_draw_tool_add_crosshair        (GimpDrawTool     *draw_tool,
                                                       gint              position_x,
                                                       gint              position_y);
diff --git a/app/tools/gimpmovetool.c b/app/tools/gimpmovetool.c
index 6e89f6c..c267c9d 100644
--- a/app/tools/gimpmovetool.c
+++ b/app/tools/gimpmovetool.c
@@ -839,7 +839,9 @@ gimp_move_tool_draw (GimpDrawTool *draw_tool)
       item = gimp_draw_tool_add_guide (draw_tool,
                                        gimp_guide_get_orientation (move->guide),
                                        gimp_guide_get_position (move->guide),
-                                       TRUE);
+                                       gimp_guide_get_normal_style (move->guide),
+                                       gimp_guide_get_active_style (move->guide),
+                                       gimp_guide_get_line_width (move->guide));
       gimp_canvas_item_set_highlight (item, TRUE);
     }
 
@@ -849,7 +851,7 @@ gimp_move_tool_draw (GimpDrawTool *draw_tool)
       gimp_draw_tool_add_guide (draw_tool,
                                 move->guide_orientation,
                                 move->guide_position,
-                                FALSE);
+                                NULL, NULL, 1.0);
     }
 }
 
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index fd2d06b..39b8b6f 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -159,6 +159,7 @@ xcf_load_image (Gimp     *gimp,
   gint                image_type;
   GimpPrecision       precision = GIMP_PRECISION_U8_GAMMA;
   gint                num_successful_elements = 0;
+  GList              *iter;
 
   /* read in the image width, height and type */
   info->cp += xcf_read_int32 (info->input, (guint32 *) &width, 1);
@@ -271,6 +272,44 @@ xcf_load_image (Gimp     *gimp,
                                  gimp_parasite_name (parasite));
     }
 
+  /* check for symmetry parasites */
+  for (iter = gimp_image_symmetry_list (); iter; iter = g_list_next (iter))
+    {
+      GType  type = (GType) iter->data;
+      gchar *parasite_name = gimp_symmetry_parasite_name (type);
+
+      parasite = gimp_image_parasite_find (image,
+                                           parasite_name);
+      g_free (parasite_name);
+      if (parasite)
+        {
+          GimpSymmetry *sym = gimp_symmetry_from_parasite (parasite,
+                                                           image,
+                                                           type);
+
+          if (sym)
+            {
+              GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+
+              gimp_parasite_list_remove (private->parasites,
+                                         gimp_parasite_name (parasite));
+
+              gimp_image_symmetry_add (image, sym);
+            }
+        }
+    }
+  parasite = gimp_image_parasite_find (image, "gimp-image-symmetry-selected");
+  if (parasite)
+    {
+      const gchar *str;
+
+      str = gimp_parasite_data (parasite);
+      if (! gimp_image_symmetry_select (image, g_type_from_name (str)))
+        g_warning ("%s: no symmetry of type %s",
+                   G_STRFUNC, str);
+    }
+
+
   /* migrate the old "exif-data" parasite */
   parasite = gimp_image_parasite_find (GIMP_IMAGE (image),
                                        "exif-data");
@@ -739,131 +778,6 @@ xcf_load_image_props (XcfInfo   *info,
           }
           break;
 
-        case PROP_SYMMETRY:
-            {
-              GimpSymmetry  *sym;
-              GimpSymmetry  *active_sym = NULL;
-              gint32         active;
-              gint32         n_syms;
-              gchar         *name;
-              GType          type;
-              GParamSpec   **settings;
-              GParamSpec    *spec;
-              gint           n_settings;
-              gint           i, j;
-
-              info->cp += xcf_read_int32 (info->input,
-                                          (guint32 *) &active, 1);
-              info->cp += xcf_read_int32 (info->input,
-                                          (guint32 *) &n_syms, 1);
-              for (i = 1; i <= n_syms; i++)
-                {
-                  info->cp += xcf_read_string (info->input, &name, 1);
-                  type = g_type_from_name (name);
-                  if (! type || ! g_type_is_a (type, GIMP_TYPE_SYMMETRY))
-                    {
-                      gimp_message (info->gimp, G_OBJECT (info->progress),
-                                    GIMP_MESSAGE_ERROR,
-                                    "Unknown Symmetry: %s",
-                                    name);
-                      g_free (name);
-                      return FALSE;
-                    }
-                  sym = gimp_image_symmetry_add (image, type);
-
-                  settings = gimp_symmetry_get_xcf_settings (sym,
-                                                             &n_settings);
-                  for (j = 0; j < n_settings; j++)
-                    {
-                      if (settings[j] == NULL)
-                        continue;
-
-                      spec = settings[j];
-                      switch (spec->value_type)
-                        {
-                        case G_TYPE_BOOLEAN:
-                            {
-                              guint8 value;
-
-                              info->cp += xcf_read_int8 (info->input,
-                                                         &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            (gboolean) value,
-                                            NULL);
-                            }
-                          break;
-                        case G_TYPE_FLOAT:
-                        case G_TYPE_DOUBLE:
-                            {
-                              gfloat value;
-
-                              info->cp += xcf_read_float (info->input,
-                                                          &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            (spec->value_type == G_TYPE_FLOAT) ?
-                                            value : (gdouble) value,
-                                            NULL);
-                            }
-                          break;
-                        case G_TYPE_UINT:
-                            {
-                              guint32 value;
-
-                              info->cp += xcf_read_int32 (info->input,
-                                                          &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            (guint) value,
-                                            NULL);
-                            }
-                          break;
-                        case G_TYPE_INT:
-                            {
-                              guint32 value;
-
-                              info->cp += xcf_read_int32 (info->input,
-                                                          &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            (gint) value,
-                                            NULL);
-                            }
-                          break;
-                        case G_TYPE_STRING:
-                            {
-                              gchar* value;
-
-                              info->cp += xcf_read_string (info->input,
-                                                           &value, 1);
-                              g_object_set (sym,
-                                            g_param_spec_get_name (spec),
-                                            value,
-                                            NULL);
-                              g_free (value);
-                            }
-                          break;
-                        default:
-                          /* We don't handle this settings. */
-                          gimp_message (info->gimp, G_OBJECT (info->progress),
-                                        GIMP_MESSAGE_ERROR,
-                                        "Unknown settings '%s' for '%s'",
-                                        name, g_param_spec_get_name (spec));
-                          g_free (name);
-                          return FALSE;
-                        }
-                    }
-                  g_free (settings);
-
-                  if (active == i)
-                    active_sym = sym;
-                }
-              gimp_image_symmetry_select (image, active_sym->type);
-              g_free (name);
-            }
-          break;
-
         case PROP_SAMPLE_POINTS:
           {
             gint32 x, y;
diff --git a/app/xcf/xcf-private.h b/app/xcf/xcf-private.h
index 0c3681b..8c7bb27 100644
--- a/app/xcf/xcf-private.h
+++ b/app/xcf/xcf-private.h
@@ -58,7 +58,6 @@ typedef enum
   PROP_GROUP_ITEM_FLAGS   = 31,
   PROP_LOCK_POSITION      = 32,
   PROP_FLOAT_OPACITY      = 33,
-  PROP_SYMMETRY           = 34
 } PropType;
 
 typedef enum
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index 17ebe3b..3482c2e 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -48,7 +48,6 @@
 #include "core/gimpimage-symmetry.h"
 #include "core/gimplayer.h"
 #include "core/gimplayermask.h"
-#include "core/gimpmirrorguide.h"
 #include "core/gimpparasitelist.h"
 #include "core/gimpprogress.h"
 #include "core/gimpsamplepoint.h"
@@ -340,11 +339,13 @@ xcf_save_image_props (XcfInfo    *info,
                       GimpImage  *image,
                       GError    **error)
 {
-  GimpImagePrivate *private         = GIMP_IMAGE_GET_PRIVATE (image);
-  GimpParasite     *grid_parasite   = NULL;
-  GimpParasite     *meta_parasite   = NULL;
-  GimpParasite     *compat_parasite = NULL;
-  GimpUnit          unit            = gimp_image_get_unit (image);
+  GimpImagePrivate *private            = GIMP_IMAGE_GET_PRIVATE (image);
+  GimpParasite     *grid_parasite      = NULL;
+  GimpParasite     *meta_parasite      = NULL;
+  GimpParasite     *compat_parasite    = NULL;
+  GList            *symmetry_parasites = NULL;
+  GList            *iter;
+  GimpUnit          unit               = gimp_image_get_unit (image);
   gdouble           xres;
   gdouble           yres;
 
@@ -364,10 +365,6 @@ xcf_save_image_props (XcfInfo    *info,
     xcf_check_error (xcf_save_prop (info, image, PROP_GUIDES, error,
                                     gimp_image_get_guides (image)));
 
-  if (g_list_length (gimp_image_symmetry_get (image)))
-    xcf_check_error (xcf_save_prop (info, image, PROP_SYMMETRY, error,
-                                    gimp_image_symmetry_get (image)));
-
   if (gimp_image_get_sample_points (image))
     xcf_check_error (xcf_save_prop (info, image, PROP_SAMPLE_POINTS, error,
                                     gimp_image_get_sample_points (image)));
@@ -435,6 +432,31 @@ xcf_save_image_props (XcfInfo    *info,
       gimp_parasite_list_add (private->parasites, compat_parasite);
     }
 
+  if (g_list_length (gimp_image_symmetry_get (image)))
+    {
+      GimpParasite *parasite  = NULL;
+
+      for (iter = gimp_image_symmetry_get (image); iter; iter = g_list_next (iter))
+        {
+          parasite = gimp_symmetry_to_parasite (GIMP_SYMMETRY (iter->data));
+          gimp_parasite_list_add (private->parasites, parasite);
+          symmetry_parasites = g_list_prepend (symmetry_parasites, parasite);
+        }
+      if (gimp_image_symmetry_selected (image))
+        {
+          const gchar *name;
+
+          name = g_type_name (gimp_image_symmetry_selected (image)->type);
+
+          parasite = gimp_parasite_new ("gimp-image-symmetry-selected",
+                                        GIMP_PARASITE_PERSISTENT,
+                                        strlen (name) + 1,
+                                        name);
+          gimp_parasite_list_add (private->parasites, parasite);
+          symmetry_parasites = g_list_prepend (symmetry_parasites, parasite);
+        }
+    }
+
   if (gimp_parasite_list_length (private->parasites) > 0)
     {
       xcf_check_error (xcf_save_prop (info, image, PROP_PARASITES, error,
@@ -461,6 +483,17 @@ xcf_save_image_props (XcfInfo    *info,
                                  gimp_parasite_name (compat_parasite));
       gimp_parasite_free (compat_parasite);
     }
+
+  for (iter = symmetry_parasites; iter; iter = g_list_next (iter))
+    {
+      GimpParasite *parasite = iter->data;
+
+      gimp_parasite_list_remove (private->parasites,
+                                 gimp_parasite_name (parasite));
+    }
+  g_list_free_full (symmetry_parasites,
+                    (GDestroyNotify) gimp_parasite_free);
+
   xcf_check_error (xcf_save_prop (info, image, PROP_END, error));
 
   return TRUE;
@@ -906,8 +939,8 @@ xcf_save_prop (XcfInfo    *info,
 
         for (iter = guides; iter; iter = g_list_next (iter))
           {
-            /* Do not write down mirror guides here. */
-            if (GIMP_IS_MIRROR_GUIDE (iter->data))
+            /* Do not save custom guides. */
+            if (gimp_guide_is_custom (GIMP_GUIDE (iter->data)))
               n_guides--;
           }
         size = n_guides * (4 + 1);
@@ -921,7 +954,7 @@ xcf_save_prop (XcfInfo    *info,
             gint32     position = gimp_guide_get_position (guide);
             gint8      orientation;
 
-            if (GIMP_IS_MIRROR_GUIDE (guide))
+            if (gimp_guide_is_custom (guide))
               continue;
 
             switch (gimp_guide_get_orientation (guide))
@@ -946,164 +979,6 @@ xcf_save_prop (XcfInfo    *info,
       }
       break;
 
-    case PROP_SYMMETRY:
-      {
-        GList         *syms;
-        GList         *iter;
-        GimpSymmetry  *sym;
-        GParamSpec   **settings;
-        GParamSpec    *spec;
-        gint           n_settings;
-        guint32        base;
-        glong          pos;
-        gint           i = 0;
-
-        xcf_write_prop_type_check_error (info, prop_type);
-        /* because we don't know how much room the Symmetry list
-         * will take we save the file position and write the length
-         * later.
-         */
-        pos = info->cp;
-        size = 0;
-        xcf_write_int32_check_error (info, &size, 1);
-        base = info->cp;
-
-        syms = va_arg (args, GList *);
-
-        /* Index of active symmetry starting at 1
-         * (because 0 means none active) */
-        if (gimp_image_symmetry_selected (image))
-          {
-            for (i = 1, iter = syms; iter; iter = g_list_next (iter), i++)
-              {
-                sym = GIMP_SYMMETRY (iter->data);
-                if (sym == gimp_image_symmetry_selected (image))
-                  break;
-              }
-          }
-        xcf_write_int32_check_error (info, (guint32 *)  &i, 1);
-        /* Number of symmetry that follows. */
-        i = g_list_length (syms);
-        xcf_write_int32_check_error (info, (guint32 *)  &i, 1);
-
-        for (iter = syms; iter; iter = g_list_next (iter))
-          {
-            const gchar *name;
-
-            sym = GIMP_SYMMETRY (iter->data);
-
-            name = g_type_name (sym->type);
-            xcf_write_string_check_error (info, (gchar **) &name, 1);
-
-            settings = gimp_symmetry_get_xcf_settings (sym,
-                                                       &n_settings);
-
-            for (i = 0; i < n_settings; i++)
-              {
-                if (settings[i] == NULL)
-                  continue;
-
-                spec = settings[i];
-
-                switch (spec->value_type)
-                  {
-                  case G_TYPE_BOOLEAN:
-                      {
-                        gboolean value;
-                        guint8   uint_value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        uint_value = (guint8) value;
-                        xcf_write_int8_check_error (info, &uint_value, 1);
-                      }
-                    break;
-                  case G_TYPE_FLOAT:
-                      {
-                        gfloat value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        xcf_write_float_check_error (info, &value, 1);
-                      }
-                    break;
-                  case G_TYPE_DOUBLE:
-                      {
-                        gdouble value;
-                        gfloat  float_value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        float_value = (gfloat) value;
-                        xcf_write_float_check_error (info, &float_value, 1);
-                      }
-                    break;
-                  case G_TYPE_UINT:
-                      {
-                        guint   value;
-                        guint32 uint_value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        uint_value = (guint32) value;
-                        xcf_write_int32_check_error (info, &uint_value, 1);
-                      }
-                    break;
-                  case G_TYPE_INT:
-                      {
-                        gint    value;
-                        guint32 uint_value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        uint_value = (guint32) value;
-                        xcf_write_int32_check_error (info, &uint_value, 1);
-                      }
-                    break;
-                  case G_TYPE_STRING:
-                      {
-                        gchar* value;
-
-                        g_object_get (sym,
-                                      g_param_spec_get_name (spec),
-                                      &value,
-                                      NULL);
-                        xcf_write_string_check_error (info, &value, 1);
-                        g_free (value);
-                      }
-                    break;
-                  default:
-                    /* We don't handle this settings. */
-                    gimp_message (info->gimp, G_OBJECT (info->progress),
-                                  GIMP_MESSAGE_ERROR,
-                                  "Unknown settings '%s' for '%s'",
-                                  name, g_param_spec_get_name (spec));
-                    return FALSE;
-                  }
-              }
-            g_free (settings);
-          }
-
-        size = info->cp - base;
-
-        /* go back to the saved position and write the length */
-        xcf_check_error (xcf_seek_pos (info, pos, error));
-        xcf_write_int32_check_error (info, &size, 1);
-
-        xcf_check_error (xcf_seek_pos (info, base + size, error));
-      }
-      break;
-
     case PROP_SAMPLE_POINTS:
       {
         GList *sample_points;
diff --git a/tools/pdbgen/pdb/image_guides.pdb b/tools/pdbgen/pdb/image_guides.pdb
index dcfd9ca..88e0c49 100644
--- a/tools/pdbgen/pdb/image_guides.pdb
+++ b/tools/pdbgen/pdb/image_guides.pdb
@@ -246,7 +246,8 @@ CODE
 }
 
 
- headers = qw("core/gimpguide.h"
+ headers = qw("cairo.h"
+              "core/gimpguide.h"
               "core/gimpimage-guides.h"
               "core/gimpimage-undo-push.h"
               "gimppdb-utils.h"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]