Skip to content

Commit bfe842c

Browse files
author
Jehan
committed
Issue #12359: encoding conversion undo does not undo the mask conversion.
In particular, we could end up with mask of wrong bytes per pixel, which was what was happening in the report. This commit adds a new GimpDrawableFilterMask class because we needed to implement a specific is_attached() method for effect masks. Note: the file is added to POTFILES but the only localized string already existed elsewhere. So this doesn't break string freeze.
1 parent a6fdc51 commit bfe842c

12 files changed

+338
-53
lines changed

app/core/core-types.h

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ typedef struct _GimpTagCache GimpTagCache;
163163
/* drawable objects */
164164

165165
typedef struct _GimpDrawable GimpDrawable;
166+
typedef struct _GimpDrawableFilterMask GimpDrawableFilterMask;
166167
typedef struct _GimpChannel GimpChannel;
167168
typedef struct _GimpLayerMask GimpLayerMask;
168169
typedef struct _GimpSelection GimpSelection;

app/core/gimpdrawable.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ gimp_drawable_scale (GimpItem *item,
580580
if (GIMP_IS_DRAWABLE_FILTER (list->data))
581581
{
582582
GimpDrawableFilter *filter = list->data;
583-
GimpChannel *mask = gimp_drawable_filter_get_mask (filter);
583+
GimpChannel *mask = GIMP_CHANNEL (gimp_drawable_filter_get_mask (filter));
584584
GeglRectangle *rect = GEGL_RECTANGLE (0, 0,
585585
new_width,
586586
new_height);
@@ -689,7 +689,7 @@ gimp_drawable_resize (GimpItem *item,
689689
if (GIMP_IS_DRAWABLE_FILTER (list->data))
690690
{
691691
GimpDrawableFilter *filter = list->data;
692-
GimpChannel *mask = gimp_drawable_filter_get_mask (filter);
692+
GimpChannel *mask = GIMP_CHANNEL (gimp_drawable_filter_get_mask (filter));
693693
GeglRectangle rect = {0, 0, new_width, new_height};
694694

695695
/* Don't resize partial layer effects */
@@ -1399,8 +1399,8 @@ gimp_drawable_convert_type (GimpDrawable *drawable,
13991399
{
14001400
if (GIMP_IS_DRAWABLE_FILTER (filter_list->data))
14011401
{
1402-
GimpDrawableFilter *filter = filter_list->data;
1403-
GimpChannel *mask;
1402+
GimpDrawableFilter *filter = filter_list->data;
1403+
GimpDrawableFilterMask *mask;
14041404

14051405
mask = gimp_drawable_filter_get_mask (filter);
14061406

app/core/gimpdrawablefilter.c

+46-33
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "gimpchannel.h"
4747
#include "gimpdrawable-filters.h"
4848
#include "gimpdrawablefilter.h"
49+
#include "gimpdrawablefiltermask.h"
4950
#include "gimperror.h"
5051
#include "gimpidtable.h"
5152
#include "gimpimage.h"
@@ -63,6 +64,7 @@ enum
6364
{
6465
PROP_0,
6566
PROP_ID,
67+
PROP_DRAWABLE,
6668
PROP_MASK,
6769
N_PROPS
6870
};
@@ -75,7 +77,7 @@ struct _GimpDrawableFilter
7577
gint ID;
7678

7779
GimpDrawable *drawable;
78-
GimpChannel *mask;
80+
GimpDrawableFilterMask *mask;
7981
GeglNode *operation;
8082

8183
gboolean has_input;
@@ -189,14 +191,22 @@ gimp_drawable_filter_class_init (GimpDrawableFilterClass *klass)
189191
object_class->dispose = gimp_drawable_filter_dispose;
190192
object_class->finalize = gimp_drawable_filter_finalize;
191193

192-
drawable_filter_props[PROP_ID] = g_param_spec_int ("id", NULL, NULL,
193-
0, G_MAXINT, 0,
194-
GIMP_PARAM_READABLE);
195-
196-
drawable_filter_props[PROP_MASK] = g_param_spec_object ("mask",
197-
NULL, NULL,
198-
GIMP_TYPE_CHANNEL,
199-
GIMP_PARAM_READWRITE);
194+
drawable_filter_props[PROP_ID] = g_param_spec_int ("id", NULL, NULL,
195+
0, G_MAXINT, 0,
196+
GIMP_PARAM_READABLE);
197+
198+
drawable_filter_props[PROP_DRAWABLE] = g_param_spec_object ("drawable", NULL, NULL,
199+
GIMP_TYPE_DRAWABLE,
200+
GIMP_PARAM_READWRITE |
201+
G_PARAM_CONSTRUCT_ONLY);
202+
/* The mask is in fact a GimpDrawableFilterMask but the property is a
203+
* GimpDrawable to allow setting any drawable. The set_property() code
204+
* will take care of creating a new object of the proper type.
205+
*/
206+
drawable_filter_props[PROP_MASK] = g_param_spec_object ("mask",
207+
NULL, NULL,
208+
GIMP_TYPE_DRAWABLE,
209+
GIMP_PARAM_READWRITE);
200210

201211
g_object_class_install_properties (object_class, N_PROPS, drawable_filter_props);
202212
}
@@ -223,15 +233,30 @@ gimp_drawable_filter_set_property (GObject *object,
223233
const GValue *value,
224234
GParamSpec *pspec)
225235
{
226-
GimpDrawableFilter *filter = GIMP_DRAWABLE_FILTER (object);
236+
GimpDrawableFilter *filter = GIMP_DRAWABLE_FILTER (object);
237+
GimpDrawableFilterMask *mask = NULL;
238+
GimpImage *image;
227239

228240
switch (property_id)
229241
{
242+
case PROP_DRAWABLE:
243+
g_set_object (&filter->drawable, g_value_get_object (value));
244+
break;
245+
230246
case PROP_MASK:
231-
g_set_object (&filter->mask, g_value_get_object (value));
247+
image = gimp_item_get_image (GIMP_ITEM (filter->drawable));
248+
249+
if (g_value_get_object (value) != NULL)
250+
mask = GIMP_DRAWABLE_FILTER_MASK (gimp_item_convert (GIMP_ITEM (g_value_get_object (value)),
251+
image, GIMP_TYPE_DRAWABLE_FILTER_MASK));
252+
g_set_object (&filter->mask, mask);
253+
g_clear_object (&mask);
232254

233255
if (filter->mask)
234-
gimp_drawable_filter_sync_mask (filter);
256+
{
257+
gimp_drawable_filter_mask_set_filter (filter->mask, filter);
258+
gimp_drawable_filter_sync_mask (filter);
259+
}
235260
break;
236261

237262
default:
@@ -321,10 +346,10 @@ gimp_drawable_filter_new (GimpDrawable *drawable,
321346
filter = g_object_new (GIMP_TYPE_DRAWABLE_FILTER,
322347
"name", undo_desc,
323348
"icon-name", icon_name,
349+
"drawable", drawable,
324350
"mask", NULL,
325351
NULL);
326352

327-
filter->drawable = g_object_ref (drawable);
328353
filter->operation = g_object_ref (operation);
329354

330355
image = gimp_item_get_image (GIMP_ITEM (drawable));
@@ -397,7 +422,6 @@ gimp_drawable_filter_duplicate (GimpDrawable *drawable,
397422
{
398423
GimpImage *image;
399424
GimpDrawableFilter *filter;
400-
GimpChannel *mask;
401425
GeglNode *prior_node;
402426
GeglNode *node = gegl_node_new ();
403427
gchar *operation;
@@ -466,15 +490,9 @@ gimp_drawable_filter_duplicate (GimpDrawable *drawable,
466490

467491
image = gimp_item_get_image (GIMP_ITEM (drawable));
468492
if (image != NULL)
469-
{
470-
mask = GIMP_CHANNEL (gimp_item_convert (GIMP_ITEM (prior_filter->mask),
471-
image, GIMP_TYPE_CHANNEL));
472-
473-
g_object_set (filter,
474-
"mask", mask,
475-
NULL);
476-
g_object_unref (mask);
477-
}
493+
g_object_set (filter,
494+
"mask", prior_filter->mask,
495+
NULL);
478496

479497
g_free (operation);
480498

@@ -517,7 +535,7 @@ gimp_drawable_filter_get_operation (GimpDrawableFilter *filter)
517535
return filter->operation;
518536
}
519537

520-
GimpChannel *
538+
GimpDrawableFilterMask *
521539
gimp_drawable_filter_get_mask (GimpDrawableFilter *filter)
522540
{
523541
g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), NULL);
@@ -1183,17 +1201,12 @@ gimp_drawable_filter_abort (GimpDrawableFilter *filter)
11831201
void
11841202
gimp_drawable_filter_layer_mask_freeze (GimpDrawableFilter *filter)
11851203
{
1186-
GimpImage *image = gimp_item_get_image (GIMP_ITEM (filter->drawable));
1187-
GimpChannel *mask;
1204+
GimpImage *image = gimp_item_get_image (GIMP_ITEM (filter->drawable));
11881205

11891206
if (! filter->mask)
1190-
{
1191-
mask = GIMP_CHANNEL (gimp_item_duplicate (GIMP_ITEM (gimp_image_get_mask (image)),
1192-
GIMP_TYPE_CHANNEL));
1193-
1194-
g_set_object (&filter->mask, mask);
1195-
g_object_unref (mask);
1196-
}
1207+
g_object_set (filter,
1208+
"mask", GIMP_DRAWABLE (gimp_image_get_mask (image)),
1209+
NULL);
11971210

11981211
g_signal_handlers_disconnect_by_func (image,
11991212
gimp_drawable_filter_mask_changed,

app/core/gimpdrawablefilter.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ GimpDrawableFilter *
6666
GimpDrawable *
6767
gimp_drawable_filter_get_drawable (GimpDrawableFilter *filter);
6868
GeglNode * gimp_drawable_filter_get_operation (GimpDrawableFilter *filter);
69-
GimpChannel *
69+
GimpDrawableFilterMask *
7070
gimp_drawable_filter_get_mask (GimpDrawableFilter *filter);
7171
gdouble gimp_drawable_filter_get_opacity (GimpDrawableFilter *filter);
7272
GimpLayerMode

0 commit comments

Comments
 (0)