app: fix compositing of layers with masks, outside the mask bounds

In GimpOperationLayerMode, when the op has a mask connected, and
we're processing an area outside the mask bounds, set the op's
opacity to 0, so that the backdrop shows through.  The actual
process() function gets a NULL mask pointer in this case, and so
would composite the layer as if it had no mask, exposing areas that
should be masked out.

Add a GimpOperationLayerMode::parent_process() function, which
subclasses can override instead of GeglOperation::process(), and
make sure to update the GimpOperationLayerMode::opacity field
before calling this function (and, subsequently, before calling
GimpOperationLayerMode::process()).

Clean up the rest of the fields, and adjust the rest of the code.
This commit is contained in:
Ell 2020-02-21 21:58:15 +02:00
parent 3a1aec3051
commit 646c804c04
13 changed files with 150 additions and 95 deletions

View File

@ -82,7 +82,7 @@ gimp_operation_anti_erase_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity; gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL; const gboolean has_mask = mask != NULL;
switch (layer_mode->real_composite_mode) switch (layer_mode->composite_mode)
{ {
case GIMP_LAYER_COMPOSITE_UNION: case GIMP_LAYER_COMPOSITE_UNION:
case GIMP_LAYER_COMPOSITE_AUTO: case GIMP_LAYER_COMPOSITE_AUTO:

View File

@ -80,7 +80,7 @@ gimp_operation_behind_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity; gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL; const gboolean has_mask = mask != NULL;
switch (layer_mode->real_composite_mode) switch (layer_mode->composite_mode)
{ {
case GIMP_LAYER_COMPOSITE_UNION: case GIMP_LAYER_COMPOSITE_UNION:
case GIMP_LAYER_COMPOSITE_AUTO: case GIMP_LAYER_COMPOSITE_AUTO:

View File

@ -120,8 +120,8 @@ gimp_operation_dissolve_process (GeglOperation *op,
out[1] = in[1]; out[1] = in[1];
out[2] = in[2]; out[2] = in[2];
if (layer_mode->real_composite_mode == GIMP_LAYER_COMPOSITE_UNION || if (layer_mode->composite_mode == GIMP_LAYER_COMPOSITE_UNION ||
layer_mode->real_composite_mode == GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP) layer_mode->composite_mode == GIMP_LAYER_COMPOSITE_CLIP_TO_BACKDROP)
{ {
out[3] = in[3]; out[3] = in[3];
} }
@ -136,8 +136,8 @@ gimp_operation_dissolve_process (GeglOperation *op,
out[1] = layer[1]; out[1] = layer[1];
out[2] = layer[2]; out[2] = layer[2];
if (layer_mode->real_composite_mode == GIMP_LAYER_COMPOSITE_UNION || if (layer_mode->composite_mode == GIMP_LAYER_COMPOSITE_UNION ||
layer_mode->real_composite_mode == GIMP_LAYER_COMPOSITE_CLIP_TO_LAYER) layer_mode->composite_mode == GIMP_LAYER_COMPOSITE_CLIP_TO_LAYER)
{ {
out[3] = 1.0f; out[3] = 1.0f;
} }

View File

@ -79,7 +79,7 @@ gimp_operation_erase_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity; gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL; const gboolean has_mask = mask != NULL;
switch (layer_mode->real_composite_mode) switch (layer_mode->composite_mode)
{ {
case GIMP_LAYER_COMPOSITE_UNION: case GIMP_LAYER_COMPOSITE_UNION:
while (samples--) while (samples--)

View File

@ -68,49 +68,54 @@ typedef void (* CompositeFunc) (const gfloat *in,
gint samples); gint samples);
static void gimp_operation_layer_mode_set_property (GObject *object, static void gimp_operation_layer_mode_set_property (GObject *object,
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gimp_operation_layer_mode_get_property (GObject *object, static void gimp_operation_layer_mode_get_property (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gimp_operation_layer_mode_prepare (GeglOperation *operation); static void gimp_operation_layer_mode_prepare (GeglOperation *operation);
static GeglRectangle gimp_operation_layer_mode_get_bounding_box (GeglOperation *operation); static GeglRectangle gimp_operation_layer_mode_get_bounding_box (GeglOperation *operation);
static gboolean gimp_operation_layer_mode_parent_process (GeglOperation *operation, static gboolean gimp_operation_layer_mode_parent_process (GeglOperation *operation,
GeglOperationContext *context, GeglOperationContext *context,
const gchar *output_prop, const gchar *output_prop,
const GeglRectangle *result, const GeglRectangle *result,
gint level); gint level);
static gboolean gimp_operation_layer_mode_process (GeglOperation *operation, static gboolean gimp_operation_layer_mode_process (GeglOperation *operation,
void *in, void *in,
void *layer, void *layer,
void *mask, void *mask,
void *out, void *out,
glong samples, glong samples,
const GeglRectangle *roi, const GeglRectangle *roi,
gint level); gint level);
static gboolean gimp_operation_layer_mode_real_process (GeglOperation *operation, static gboolean gimp_operation_layer_mode_real_parent_process (GeglOperation *operation,
void *in, GeglOperationContext *context,
void *layer, const gchar *output_prop,
void *mask, const GeglRectangle *result,
void *out, gint level);
glong samples, static gboolean gimp_operation_layer_mode_real_process (GeglOperation *operation,
const GeglRectangle *roi, void *in,
gint level); void *layer,
void *mask,
void *out,
glong samples,
const GeglRectangle *roi,
gint level);
static gboolean process_last_node (GeglOperation *operation, static gboolean process_last_node (GeglOperation *operation,
void *in, void *in,
void *layer, void *layer,
void *mask, void *mask,
void *out, void *out,
glong samples, glong samples,
const GeglRectangle *roi, const GeglRectangle *roi,
gint level); gint level);
G_DEFINE_TYPE (GimpOperationLayerMode, gimp_operation_layer_mode, G_DEFINE_TYPE (GimpOperationLayerMode, gimp_operation_layer_mode,
@ -148,6 +153,7 @@ gimp_operation_layer_mode_class_init (GimpOperationLayerModeClass *klass)
point_composer3_class->process = gimp_operation_layer_mode_process; point_composer3_class->process = gimp_operation_layer_mode_process;
klass->parent_process = gimp_operation_layer_mode_real_parent_process;
klass->process = gimp_operation_layer_mode_real_process; klass->process = gimp_operation_layer_mode_real_process;
klass->get_affected_region = NULL; klass->get_affected_region = NULL;
@ -218,7 +224,7 @@ gimp_operation_layer_mode_set_property (GObject *object,
break; break;
case PROP_OPACITY: case PROP_OPACITY:
self->opacity = g_value_get_double (value); self->prop_opacity = g_value_get_double (value);
break; break;
case PROP_BLEND_SPACE: case PROP_BLEND_SPACE:
@ -230,7 +236,7 @@ gimp_operation_layer_mode_set_property (GObject *object,
break; break;
case PROP_COMPOSITE_MODE: case PROP_COMPOSITE_MODE:
self->composite_mode = g_value_get_enum (value); self->prop_composite_mode = g_value_get_enum (value);
break; break;
default: default:
@ -254,7 +260,7 @@ gimp_operation_layer_mode_get_property (GObject *object,
break; break;
case PROP_OPACITY: case PROP_OPACITY:
g_value_set_double (value, self->opacity); g_value_set_double (value, self->prop_opacity);
break; break;
case PROP_BLEND_SPACE: case PROP_BLEND_SPACE:
@ -266,7 +272,7 @@ gimp_operation_layer_mode_get_property (GObject *object,
break; break;
case PROP_COMPOSITE_MODE: case PROP_COMPOSITE_MODE:
g_value_set_enum (value, self->composite_mode); g_value_set_enum (value, self->prop_composite_mode);
break; break;
default: default:
@ -280,23 +286,25 @@ gimp_operation_layer_mode_prepare (GeglOperation *operation)
{ {
GimpOperationLayerMode *self = GIMP_OPERATION_LAYER_MODE (operation); GimpOperationLayerMode *self = GIMP_OPERATION_LAYER_MODE (operation);
const GeglRectangle *input_extent; const GeglRectangle *input_extent;
const GeglRectangle *mask_extent;
const Babl *preferred_format; const Babl *preferred_format;
const Babl *format; const Babl *format;
self->real_composite_mode = self->composite_mode; self->composite_mode = self->prop_composite_mode;
if (self->real_composite_mode == GIMP_LAYER_COMPOSITE_AUTO) if (self->composite_mode == GIMP_LAYER_COMPOSITE_AUTO)
{ {
self->real_composite_mode = self->composite_mode =
gimp_layer_mode_get_composite_mode (self->layer_mode); gimp_layer_mode_get_composite_mode (self->layer_mode);
g_warn_if_fail (self->real_composite_mode != GIMP_LAYER_COMPOSITE_AUTO); g_warn_if_fail (self->composite_mode != GIMP_LAYER_COMPOSITE_AUTO);
} }
self->function = gimp_layer_mode_get_function (self->layer_mode); self->function = gimp_layer_mode_get_function (self->layer_mode);
self->blend_function = gimp_layer_mode_get_blend_function (self->layer_mode); self->blend_function = gimp_layer_mode_get_blend_function (self->layer_mode);
input_extent = gegl_operation_source_get_bounding_box (operation, "input"); input_extent = gegl_operation_source_get_bounding_box (operation, "input");
mask_extent = gegl_operation_source_get_bounding_box (operation, "aux2");
/* if the input pad has data, work as usual. */ /* if the input pad has data, work as usual. */
if (input_extent && ! gegl_rectangle_is_empty (input_extent)) if (input_extent && ! gegl_rectangle_is_empty (input_extent))
@ -325,12 +333,14 @@ gimp_operation_layer_mode_prepare (GeglOperation *operation)
*/ */
else else
{ {
self->real_composite_mode = GIMP_LAYER_COMPOSITE_UNION; self->composite_mode = GIMP_LAYER_COMPOSITE_UNION;
} }
preferred_format = gegl_operation_get_source_format (operation, "aux"); preferred_format = gegl_operation_get_source_format (operation, "aux");
} }
self->has_mask = mask_extent && ! gegl_rectangle_is_empty (mask_extent);
format = gimp_layer_mode_get_format (self->layer_mode, format = gimp_layer_mode_get_format (self->layer_mode,
self->blend_space, self->blend_space,
self->composite_space, self->composite_space,
@ -417,7 +427,7 @@ gimp_operation_layer_mode_get_bounding_box (GeglOperation *op)
self->composite_mode); self->composite_mode);
} }
if (self->opacity == 0.0) if (self->prop_opacity == 0.0)
included_region &= ~GIMP_LAYER_COMPOSITE_REGION_SOURCE; included_region &= ~GIMP_LAYER_COMPOSITE_REGION_SOURCE;
gegl_rectangle_intersect (&result, &src_rect, &dst_rect); gegl_rectangle_intersect (&result, &src_rect, &dst_rect);
@ -437,6 +447,58 @@ gimp_operation_layer_mode_parent_process (GeglOperation *operation,
const gchar *output_prop, const gchar *output_prop,
const GeglRectangle *result, const GeglRectangle *result,
gint level) gint level)
{
GimpOperationLayerMode *point = GIMP_OPERATION_LAYER_MODE (operation);
point->opacity = point->prop_opacity;
/* if we have a mask, but it's not included in the output, pretend the
* opacity is 0, so that we don't composite 'aux' over 'input' as if there
* was no mask.
*/
if (point->has_mask)
{
GObject *mask;
gboolean has_mask;
/* get the raw value. this does not increase the reference count. */
mask = gegl_operation_context_get_object (context, "aux2");
/* disregard 'mask' if it's not included in the roi. */
has_mask =
mask &&
gegl_rectangle_intersect (NULL,
gegl_buffer_get_extent (GEGL_BUFFER (mask)),
result);
if (! has_mask)
point->opacity = 0.0;
}
return GIMP_OPERATION_LAYER_MODE_GET_CLASS (point)->parent_process (
operation, context, output_prop, result, level);
}
static gboolean
gimp_operation_layer_mode_process (GeglOperation *operation,
void *in,
void *layer,
void *mask,
void *out,
glong samples,
const GeglRectangle *roi,
gint level)
{
return ((GimpOperationLayerMode *) operation)->function (
operation, in, layer, mask, out, samples, roi, level);
}
static gboolean
gimp_operation_layer_mode_real_parent_process (GeglOperation *operation,
GeglOperationContext *context,
const gchar *output_prop,
const GeglRectangle *result,
gint level)
{ {
GimpOperationLayerMode *point = GIMP_OPERATION_LAYER_MODE (operation); GimpOperationLayerMode *point = GIMP_OPERATION_LAYER_MODE (operation);
GObject *input; GObject *input;
@ -569,20 +631,6 @@ gimp_operation_layer_mode_parent_process (GeglOperation *operation,
level); level);
} }
static gboolean
gimp_operation_layer_mode_process (GeglOperation *operation,
void *in,
void *layer,
void *mask,
void *out,
glong samples,
const GeglRectangle *roi,
gint level)
{
return ((GimpOperationLayerMode *) operation)->function (
operation, in, layer, mask, out, samples, roi, level);
}
static gboolean static gboolean
gimp_operation_layer_mode_real_process (GeglOperation *operation, gimp_operation_layer_mode_real_process (GeglOperation *operation,
void *in_p, void *in_p,
@ -601,7 +649,7 @@ gimp_operation_layer_mode_real_process (GeglOperation *operation,
gfloat opacity = layer_mode->opacity; gfloat opacity = layer_mode->opacity;
GimpLayerColorSpace blend_space = layer_mode->blend_space; GimpLayerColorSpace blend_space = layer_mode->blend_space;
GimpLayerColorSpace composite_space = layer_mode->composite_space; GimpLayerColorSpace composite_space = layer_mode->composite_space;
GimpLayerCompositeMode composite_mode = layer_mode->real_composite_mode; GimpLayerCompositeMode composite_mode = layer_mode->composite_mode;
GimpLayerModeBlendFunc blend_function = layer_mode->blend_function; GimpLayerModeBlendFunc blend_function = layer_mode->blend_function;
gboolean composite_needs_in_color; gboolean composite_needs_in_color;
gfloat *blend_in; gfloat *blend_in;

View File

@ -47,10 +47,13 @@ struct _GimpOperationLayerMode
const Babl *cached_fish_format; const Babl *cached_fish_format;
const Babl *space_fish[3 /* from */][3 /* to */]; const Babl *space_fish[3 /* from */][3 /* to */];
GimpLayerCompositeMode real_composite_mode; gdouble prop_opacity;
GimpLayerCompositeMode prop_composite_mode;
GimpLayerModeFunc function; GimpLayerModeFunc function;
GimpLayerModeBlendFunc blend_function; GimpLayerModeBlendFunc blend_function;
gboolean is_last_node; gboolean is_last_node;
gboolean has_mask;
}; };
struct _GimpOperationLayerModeClass struct _GimpOperationLayerModeClass
@ -58,6 +61,11 @@ struct _GimpOperationLayerModeClass
GeglOperationPointComposer3Class parent_class; GeglOperationPointComposer3Class parent_class;
/* virtual functions */ /* virtual functions */
gboolean (* parent_process) (GeglOperation *operation,
GeglOperationContext *context,
const gchar *output_prop,
const GeglRectangle *result,
gint level);
gboolean (* process) (GeglOperation *operation, gboolean (* process) (GeglOperation *operation,
void *in, void *in,
void *aux, void *aux,

View File

@ -79,7 +79,7 @@ gimp_operation_merge_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity; gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL; const gboolean has_mask = mask != NULL;
switch (layer_mode->real_composite_mode) switch (layer_mode->composite_mode)
{ {
case GIMP_LAYER_COMPOSITE_UNION: case GIMP_LAYER_COMPOSITE_UNION:
case GIMP_LAYER_COMPOSITE_AUTO: case GIMP_LAYER_COMPOSITE_AUTO:

View File

@ -62,7 +62,7 @@ gimp_operation_normal_process_sse2 (GeglOperation *op,
const __v4sf one = _mm_set1_ps (1.0f); const __v4sf one = _mm_set1_ps (1.0f);
const __v4sf v_opacity = _mm_set1_ps (opacity); const __v4sf v_opacity = _mm_set1_ps (opacity);
switch (layer_mode->real_composite_mode) switch (layer_mode->composite_mode)
{ {
case GIMP_LAYER_COMPOSITE_UNION: case GIMP_LAYER_COMPOSITE_UNION:
case GIMP_LAYER_COMPOSITE_AUTO: case GIMP_LAYER_COMPOSITE_AUTO:

View File

@ -62,7 +62,7 @@ gimp_operation_normal_process_sse4 (GeglOperation *op,
const __v4sf one = _mm_set1_ps (1.0f); const __v4sf one = _mm_set1_ps (1.0f);
const __v4sf v_opacity = _mm_set1_ps (opacity); const __v4sf v_opacity = _mm_set1_ps (opacity);
switch (layer_mode->real_composite_mode) switch (layer_mode->composite_mode)
{ {
case GIMP_LAYER_COMPOSITE_UNION: case GIMP_LAYER_COMPOSITE_UNION:
case GIMP_LAYER_COMPOSITE_AUTO: case GIMP_LAYER_COMPOSITE_AUTO:

View File

@ -100,7 +100,7 @@ gimp_operation_normal_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity; gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL; const gboolean has_mask = mask != NULL;
switch (layer_mode->real_composite_mode) switch (layer_mode->composite_mode)
{ {
case GIMP_LAYER_COMPOSITE_UNION: case GIMP_LAYER_COMPOSITE_UNION:
case GIMP_LAYER_COMPOSITE_AUTO: case GIMP_LAYER_COMPOSITE_AUTO:

View File

@ -31,12 +31,12 @@
static GeglRectangle gimp_operation_replace_get_bounding_box (GeglOperation *op); static GeglRectangle gimp_operation_replace_get_bounding_box (GeglOperation *op);
static gboolean gimp_operation_replace_parent_process (GeglOperation *op, static gboolean gimp_operation_replace_parent_process (GeglOperation *op,
GeglOperationContext *context, GeglOperationContext *context,
const gchar *output_prop, const gchar *output_prop,
const GeglRectangle *result, const GeglRectangle *result,
gint level); gint level);
static gboolean gimp_operation_replace_process (GeglOperation *op, static gboolean gimp_operation_replace_process (GeglOperation *op,
void *in, void *in,
void *layer, void *layer,
@ -66,8 +66,8 @@ gimp_operation_replace_class_init (GimpOperationReplaceClass *klass)
NULL); NULL);
operation_class->get_bounding_box = gimp_operation_replace_get_bounding_box; operation_class->get_bounding_box = gimp_operation_replace_get_bounding_box;
operation_class->process = gimp_operation_replace_parent_process;
layer_mode_class->parent_process = gimp_operation_replace_parent_process;
layer_mode_class->process = gimp_operation_replace_process; layer_mode_class->process = gimp_operation_replace_process;
layer_mode_class->get_affected_region = gimp_operation_replace_get_affected_region; layer_mode_class->get_affected_region = gimp_operation_replace_get_affected_region;
} }
@ -114,9 +114,9 @@ gimp_operation_replace_get_bounding_box (GeglOperation *op)
self->composite_mode); self->composite_mode);
} }
if (self->opacity == 0.0) if (self->prop_opacity == 0.0)
included_region &= ~GIMP_LAYER_COMPOSITE_REGION_SOURCE; included_region &= ~GIMP_LAYER_COMPOSITE_REGION_SOURCE;
else if (self->opacity == 1.0 && ! aux2_rect) else if (self->prop_opacity == 1.0 && ! aux2_rect)
included_region &= ~GIMP_LAYER_COMPOSITE_REGION_DESTINATION; included_region &= ~GIMP_LAYER_COMPOSITE_REGION_DESTINATION;
gegl_rectangle_intersect (&result, &src_rect, &dst_rect); gegl_rectangle_intersect (&result, &src_rect, &dst_rect);
@ -141,13 +141,13 @@ gimp_operation_replace_parent_process (GeglOperation *op,
GimpLayerCompositeRegion included_region; GimpLayerCompositeRegion included_region;
included_region = gimp_layer_mode_get_included_region included_region = gimp_layer_mode_get_included_region
(layer_mode->layer_mode, layer_mode->real_composite_mode); (layer_mode->layer_mode, layer_mode->composite_mode);
/* if the layer's opacity is 100%, it has no mask, and its composite mode /* if the layer's opacity is 100%, it has no mask, and its composite mode
* contains "aux" (the latter should always be the case in practice, * contains "aux" (the latter should always be the case in practice,
* currently,) we can just pass "aux" directly as output. * currently,) we can just pass "aux" directly as output.
*/ */
if (layer_mode->opacity == 1.0 && if (layer_mode->opacity == 1.0 &&
! gegl_operation_context_get_object (context, "aux2") && ! gegl_operation_context_get_object (context, "aux2") &&
(included_region & GIMP_LAYER_COMPOSITE_REGION_SOURCE)) (included_region & GIMP_LAYER_COMPOSITE_REGION_SOURCE))
{ {
@ -215,8 +215,8 @@ gimp_operation_replace_parent_process (GeglOperation *op,
} }
} }
return GEGL_OPERATION_CLASS (parent_class)->process (op, context, output_prop, return GIMP_OPERATION_LAYER_MODE_CLASS (parent_class)->parent_process (
result, level); op, context, output_prop, result, level);
} }
static gboolean static gboolean
@ -237,7 +237,7 @@ gimp_operation_replace_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity; gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL; const gboolean has_mask = mask != NULL;
switch (layer_mode->real_composite_mode) switch (layer_mode->composite_mode)
{ {
case GIMP_LAYER_COMPOSITE_UNION: case GIMP_LAYER_COMPOSITE_UNION:
case GIMP_LAYER_COMPOSITE_AUTO: case GIMP_LAYER_COMPOSITE_AUTO:
@ -336,7 +336,7 @@ gimp_operation_replace_get_affected_region (GimpOperationLayerMode *layer_mode)
{ {
GimpLayerCompositeRegion affected_region = GIMP_LAYER_COMPOSITE_REGION_INTERSECTION; GimpLayerCompositeRegion affected_region = GIMP_LAYER_COMPOSITE_REGION_INTERSECTION;
if (layer_mode->opacity != 0.0) if (layer_mode->prop_opacity != 0.0)
affected_region |= GIMP_LAYER_COMPOSITE_REGION_DESTINATION; affected_region |= GIMP_LAYER_COMPOSITE_REGION_DESTINATION;
/* if opacity != 1.0, or we have a mask, then we also affect SOURCE, but this /* if opacity != 1.0, or we have a mask, then we also affect SOURCE, but this

View File

@ -79,7 +79,7 @@ gimp_operation_split_process (GeglOperation *op,
gfloat opacity = layer_mode->opacity; gfloat opacity = layer_mode->opacity;
const gboolean has_mask = mask != NULL; const gboolean has_mask = mask != NULL;
switch (layer_mode->real_composite_mode) switch (layer_mode->composite_mode)
{ {
case GIMP_LAYER_COMPOSITE_UNION: case GIMP_LAYER_COMPOSITE_UNION:
while (samples--) while (samples--)

View File

@ -1883,14 +1883,13 @@ struct DoLayerBlend : Base
DoLayerBlend (const GimpPaintCoreLoopsParams *params) : DoLayerBlend (const GimpPaintCoreLoopsParams *params) :
Base (params) Base (params)
{ {
layer_mode.layer_mode = params->paint_mode; layer_mode.layer_mode = params->paint_mode;
layer_mode.opacity = params->image_opacity; layer_mode.opacity = params->image_opacity;
layer_mode.function = gimp_layer_mode_get_function (params->paint_mode); layer_mode.function = gimp_layer_mode_get_function (params->paint_mode);
layer_mode.blend_function = gimp_layer_mode_get_blend_function (params->paint_mode); layer_mode.blend_function = gimp_layer_mode_get_blend_function (params->paint_mode);
layer_mode.blend_space = gimp_layer_mode_get_blend_space (params->paint_mode); layer_mode.blend_space = gimp_layer_mode_get_blend_space (params->paint_mode);
layer_mode.composite_space = gimp_layer_mode_get_composite_space (params->paint_mode); layer_mode.composite_space = gimp_layer_mode_get_composite_space (params->paint_mode);
layer_mode.composite_mode = gimp_layer_mode_get_paint_composite_mode (params->paint_mode); layer_mode.composite_mode = gimp_layer_mode_get_paint_composite_mode (params->paint_mode);
layer_mode.real_composite_mode = layer_mode.composite_mode;
iterator_format = gimp_layer_mode_get_format (params->paint_mode, iterator_format = gimp_layer_mode_get_format (params->paint_mode,
layer_mode.blend_space, layer_mode.blend_space,