[gimp/goat-invasion] app: when converting an image's precision, don't forget the selection mask



commit 178d246744f868f37d44505101a8ae6e26b74879
Author: Michael Natterer <mitch gimp org>
Date:   Sat Apr 28 16:14:52 2012 +0200

    app: when converting an image's precision, don't forget the selection mask

 app/core/gimpimage-convert.c   |   19 +++++++
 app/core/gimpimage-undo-push.c |   25 ++++++++-
 app/core/gimpimage-undo-push.h |    5 ++-
 app/core/gimpmaskundo.c        |  106 +++++++++++++++++++++++++++++++++++----
 app/core/gimpmaskundo.h        |    3 +
 5 files changed, 143 insertions(+), 15 deletions(-)
---
diff --git a/app/core/gimpimage-convert.c b/app/core/gimpimage-convert.c
index 3617e3f..8e48f21 100644
--- a/app/core/gimpimage-convert.c
+++ b/app/core/gimpimage-convert.c
@@ -1158,6 +1158,25 @@ gimp_image_convert_precision (GimpImage     *image,
                                  (gdouble) nth_drawable / (gdouble) n_drawables);
     }
 
+  /*  convert the selection mask  */
+  {
+    GimpChannel *mask = gimp_image_get_mask (image);
+    GeglBuffer  *buffer;
+
+    gimp_image_undo_push_mask_precision (image, NULL, mask);
+
+    buffer = gimp_gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+                                                   gimp_image_get_width  (image),
+                                                   gimp_image_get_height (image)),
+                                   gimp_image_get_mask_format (image));
+
+    gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)), NULL,
+                      buffer, NULL);
+
+    gimp_drawable_set_buffer (GIMP_DRAWABLE (mask), FALSE, NULL, buffer);
+    g_object_unref (buffer);
+  }
+
   gimp_image_undo_group_end (image);
 
   gimp_image_precision_changed (image);
diff --git a/app/core/gimpimage-undo-push.c b/app/core/gimpimage-undo-push.c
index 7db3f4d..a7aa422 100644
--- a/app/core/gimpimage-undo-push.c
+++ b/app/core/gimpimage-undo-push.c
@@ -264,9 +264,9 @@ gimp_image_undo_push_drawable_mod (GimpImage    *image,
 }
 
 
-/***************/
-/*  Mask Undo  */
-/***************/
+/****************/
+/*  Mask Undos  */
+/****************/
 
 GimpUndo *
 gimp_image_undo_push_mask (GimpImage   *image,
@@ -286,6 +286,25 @@ gimp_image_undo_push_mask (GimpImage   *image,
                                NULL);
 }
 
+GimpUndo *
+gimp_image_undo_push_mask_precision (GimpImage   *image,
+                                     const gchar *undo_desc,
+                                     GimpChannel *mask)
+{
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
+  g_return_val_if_fail (GIMP_IS_CHANNEL (mask), NULL);
+  g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (mask)), NULL);
+
+  return gimp_image_undo_push (image, GIMP_TYPE_MASK_UNDO,
+                               GIMP_UNDO_MASK, undo_desc,
+                               GIMP_IS_SELECTION (mask) ?
+                               GIMP_DIRTY_SELECTION :
+                               GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
+                               "item",              mask,
+                               "convert-precision", TRUE,
+                               NULL);
+}
+
 
 /****************/
 /*  Item Undos  */
diff --git a/app/core/gimpimage-undo-push.h b/app/core/gimpimage-undo-push.h
index 41e93c8..d1c56ca 100644
--- a/app/core/gimpimage-undo-push.h
+++ b/app/core/gimpimage-undo-push.h
@@ -70,11 +70,14 @@ GimpUndo * gimp_image_undo_push_drawable_mod        (GimpImage     *image,
                                                      gboolean       copy_buffer);
 
 
-/*  mask undo  */
+/*  mask undos  */
 
 GimpUndo * gimp_image_undo_push_mask                (GimpImage     *image,
                                                      const gchar   *undo_desc,
                                                      GimpChannel   *mask);
+GimpUndo * gimp_image_undo_push_mask_precision      (GimpImage     *image,
+                                                     const gchar   *undo_desc,
+                                                     GimpChannel   *mask);
 
 
 /*  item undos  */
diff --git a/app/core/gimpmaskundo.c b/app/core/gimpmaskundo.c
index 24962e1..f673240 100644
--- a/app/core/gimpmaskundo.c
+++ b/app/core/gimpmaskundo.c
@@ -28,16 +28,31 @@
 #include "gimpmaskundo.h"
 
 
-static void     gimp_mask_undo_constructed (GObject             *object);
+enum
+{
+  PROP_0,
+  PROP_CONVERT_PRECISION
+};
+
 
-static gint64   gimp_mask_undo_get_memsize (GimpObject          *object,
-                                            gint64              *gui_size);
+static void     gimp_mask_undo_constructed  (GObject             *object);
+static void     gimp_mask_undo_set_property (GObject             *object,
+                                             guint                property_id,
+                                             const GValue        *value,
+                                             GParamSpec          *pspec);
+static void     gimp_mask_undo_get_property (GObject             *object,
+                                             guint                property_id,
+                                             GValue              *value,
+                                             GParamSpec          *pspec);
 
-static void     gimp_mask_undo_pop         (GimpUndo            *undo,
-                                            GimpUndoMode         undo_mode,
-                                            GimpUndoAccumulator *accum);
-static void     gimp_mask_undo_free        (GimpUndo            *undo,
-                                            GimpUndoMode         undo_mode);
+static gint64   gimp_mask_undo_get_memsize  (GimpObject          *object,
+                                             gint64              *gui_size);
+
+static void     gimp_mask_undo_pop          (GimpUndo            *undo,
+                                             GimpUndoMode         undo_mode,
+                                             GimpUndoAccumulator *accum);
+static void     gimp_mask_undo_free         (GimpUndo            *undo,
+                                             GimpUndoMode         undo_mode);
 
 
 G_DEFINE_TYPE (GimpMaskUndo, gimp_mask_undo, GIMP_TYPE_ITEM_UNDO)
@@ -53,11 +68,20 @@ gimp_mask_undo_class_init (GimpMaskUndoClass *klass)
   GimpUndoClass   *undo_class        = GIMP_UNDO_CLASS (klass);
 
   object_class->constructed      = gimp_mask_undo_constructed;
+  object_class->set_property     = gimp_mask_undo_set_property;
+  object_class->get_property     = gimp_mask_undo_get_property;
 
   gimp_object_class->get_memsize = gimp_mask_undo_get_memsize;
 
   undo_class->pop                = gimp_mask_undo_pop;
   undo_class->free               = gimp_mask_undo_free;
+
+  g_object_class_install_property (object_class, PROP_CONVERT_PRECISION,
+                                   g_param_spec_boolean ("convert-precision",
+                                                         NULL, NULL,
+                                                         FALSE,
+                                                         GIMP_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
@@ -70,6 +94,7 @@ gimp_mask_undo_constructed (GObject *object)
 {
   GimpMaskUndo *mask_undo = GIMP_MASK_UNDO (object);
   GimpChannel  *channel;
+  GimpDrawable *drawable;
   gint          x1, y1, x2, y2;
 
   if (G_OBJECT_CLASS (parent_class)->constructed)
@@ -77,12 +102,11 @@ gimp_mask_undo_constructed (GObject *object)
 
   g_assert (GIMP_IS_CHANNEL (GIMP_ITEM_UNDO (object)->item));
 
-  channel = GIMP_CHANNEL (GIMP_ITEM_UNDO (object)->item);
+  channel  = GIMP_CHANNEL (GIMP_ITEM_UNDO (object)->item);
+  drawable = GIMP_DRAWABLE (channel);
 
   if (gimp_channel_bounds (channel, &x1, &y1, &x2, &y2))
     {
-      GimpDrawable *drawable = GIMP_DRAWABLE (channel);
-
       mask_undo->buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                            x2 - x1, y2 - y1),
                                            gimp_drawable_get_format (drawable));
@@ -95,6 +119,48 @@ gimp_mask_undo_constructed (GObject *object)
       mask_undo->x = x1;
       mask_undo->y = y1;
     }
+
+  mask_undo->format = gimp_drawable_get_format (drawable);
+}
+
+static void
+gimp_mask_undo_set_property (GObject      *object,
+                             guint         property_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+  GimpMaskUndo *mask_undo = GIMP_MASK_UNDO (object);
+
+  switch (property_id)
+    {
+    case PROP_CONVERT_PRECISION:
+      mask_undo->convert_precision = g_value_get_boolean (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_mask_undo_get_property (GObject    *object,
+                             guint       property_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+  GimpMaskUndo *mask_undo = GIMP_MASK_UNDO (object);
+
+  switch (property_id)
+    {
+    case PROP_CONVERT_PRECISION:
+      g_value_set_boolean (value, mask_undo->convert_precision);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
 }
 
 static gint64
@@ -119,6 +185,7 @@ gimp_mask_undo_pop (GimpUndo            *undo,
   GimpChannel  *channel   = GIMP_CHANNEL (GIMP_ITEM_UNDO (undo)->item);
   GimpDrawable *drawable  = GIMP_DRAWABLE (channel);
   GeglBuffer   *new_buffer;
+  const Babl   *format;
   gint          x1, y1, x2, y2;
   gint          width  = 0;
   gint          height = 0;
@@ -143,6 +210,22 @@ gimp_mask_undo_pop (GimpUndo            *undo,
       new_buffer = NULL;
     }
 
+  format = gimp_drawable_get_format (drawable);
+
+  if (mask_undo->convert_precision)
+    {
+      GeglBuffer *buffer;
+      gint        width  = gimp_item_get_width  (GIMP_ITEM (channel));
+      gint        height = gimp_item_get_height (GIMP_ITEM (channel));
+
+      buffer = gimp_gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
+                                     mask_undo->format);
+      gegl_buffer_clear (buffer, NULL);
+
+      gimp_drawable_set_buffer (drawable, FALSE, NULL, buffer);
+      g_object_unref (buffer);
+    }
+
   if (mask_undo->buffer)
     {
       width  = gegl_buffer_get_width  (mask_undo->buffer);
@@ -183,6 +266,7 @@ gimp_mask_undo_pop (GimpUndo            *undo,
   mask_undo->buffer = new_buffer;
   mask_undo->x      = x1;
   mask_undo->y      = y1;
+  mask_undo->format = format;
 
   gimp_drawable_update (GIMP_DRAWABLE (channel),
                         0, 0,
diff --git a/app/core/gimpmaskundo.h b/app/core/gimpmaskundo.h
index 0161cff..ae39550 100644
--- a/app/core/gimpmaskundo.h
+++ b/app/core/gimpmaskundo.h
@@ -36,9 +36,12 @@ struct _GimpMaskUndo
 {
   GimpItemUndo  parent_instance;
 
+  gboolean      convert_precision;
+
   GeglBuffer   *buffer;
   gint          x;
   gint          y;
+  const Babl   *format;
 };
 
 struct _GimpMaskUndoClass



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