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

This commit is contained in:
Michael Natterer
2012-04-28 16:14:52 +02:00
parent ce33d2ed33
commit c24ff24311
5 changed files with 143 additions and 15 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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_pop (GimpUndo *undo,
GimpUndoMode undo_mode,
GimpUndoAccumulator *accum);
static void gimp_mask_undo_free (GimpUndo *undo,
GimpUndoMode undo_mode);
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 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,

View File

@ -36,9 +36,12 @@ struct _GimpMaskUndo
{
GimpItemUndo parent_instance;
gboolean convert_precision;
GeglBuffer *buffer;
gint x;
gint y;
const Babl *format;
};
struct _GimpMaskUndoClass