[gimp] app: add internal and PDB API and UI to control a layer's composite mode
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add internal and PDB API and UI to control a layer's composite mode
- Date: Wed, 1 Feb 2017 23:41:29 +0000 (UTC)
commit 2a96d598c38d78e1a5d2f74ce919d1a46c0162ca
Author: Michael Natterer <mitch gimp org>
Date: Thu Feb 2 00:38:25 2017 +0100
app: add internal and PDB API and UI to control a layer's composite mode
Largely based on a patch by Ell, with the enum type renamed and
various small changes. Adds another axis of configurability to the
existing layer mode madness, and is WIP too.
app/actions/layers-actions.c | 65 +++++++++++++-
app/actions/layers-commands.c | 129 ++++++++++++++++++---------
app/actions/layers-commands.h | 3 +
app/config/gimpcoreconfig.h | 1 +
app/config/gimpdialogconfig.c | 15 +++
app/config/gimpdialogconfig.h | 1 +
app/config/gimprc-blurbs.h | 3 +
app/core/gimp-edit.c | 2 +
app/core/gimpchannel.c | 24 +++---
app/core/gimpdrawable-blend.c | 2 +-
app/core/gimpdrawable-bucket-fill.c | 1 +
app/core/gimpdrawable-combine.c | 28 +++---
app/core/gimpdrawable-combine.h | 41 +++++----
app/core/gimpdrawable-fill.c | 1 +
app/core/gimpdrawable-floating-selection.c | 3 +-
app/core/gimpdrawable-shadow.c | 1 +
app/core/gimpdrawable.c | 23 +++---
app/core/gimpdrawable.h | 2 +
app/core/gimpdrawablefilter.c | 62 +++++++------
app/core/gimpdrawablefilter.h | 3 +-
app/core/gimpdrawableundo.h | 15 ++--
app/core/gimpimage-merge.c | 20 +++--
app/core/gimplayer.c | 97 +++++++++++++++++++--
app/core/gimplayer.h | 28 ++++--
app/core/gimplayerpropundo.c | 15 +++-
app/core/gimplayerpropundo.h | 9 +-
app/dialogs/layer-options-dialog.c | 13 +++
app/dialogs/layer-options-dialog.h | 42 +++++----
app/gegl/gimp-gegl-nodes.c | 10 ++-
app/gegl/gimp-gegl-nodes.h | 5 +-
app/gegl/gimpapplicator.c | 24 +++--
app/gegl/gimpapplicator.h | 64 +++++++-------
app/operations/operations-enums.c | 12 ++-
app/operations/operations-enums.h | 11 ++-
app/paint/gimppaintcore.c | 3 +-
app/pdb/internal-procs.c | 2 +-
app/pdb/layer-cmds.c | 113 +++++++++++++++++++++++
app/tools/gimpblendtool.c | 6 +-
app/xcf/xcf-load.c | 11 +++
app/xcf/xcf-private.h | 1 +
app/xcf/xcf-save.c | 15 +++
libgimp/gimp.def | 3 +
libgimp/gimpenums.c.tail | 2 +
libgimp/gimpenums.h | 14 +++
libgimp/gimplayer_pdb.c | 66 ++++++++++++++
libgimp/gimplayer_pdb.h | 133 ++++++++++++++--------------
menus/layers-menu.xml | 7 ++
po/POTFILES.in | 1 +
tools/pdbgen/Makefile.am | 1 +
tools/pdbgen/enums.pl | 14 +++
tools/pdbgen/pdb/layer.pdb | 50 ++++++++++-
tools/pdbgen/stddefs.pdb | 4 +
52 files changed, 904 insertions(+), 317 deletions(-)
---
diff --git a/app/actions/layers-actions.c b/app/actions/layers-actions.c
index 116bd94..fb56b4e 100644
--- a/app/actions/layers-actions.c
+++ b/app/actions/layers-actions.c
@@ -50,6 +50,10 @@ static const GimpActionEntry layers_actions[] =
NC_("layers-action", "Layers Menu"), NULL, NULL, NULL,
GIMP_HELP_LAYER_DIALOG },
+ { "layers-composite-menu", NULL,
+ NC_("layers-action", "Composite"), NULL, NULL, NULL,
+ NULL },
+
{ "layers-color-tag-menu", GIMP_STOCK_CLOSE /* abused */,
NC_("layers-action", "Color Tag"), NULL, NULL, NULL,
GIMP_HELP_LAYER_COLOR_TAG },
@@ -315,6 +319,34 @@ static const GimpToggleActionEntry layers_toggle_actions[] =
GIMP_HELP_LAYER_LOCK_ALPHA },
};
+static const GimpRadioActionEntry layers_composite_actions[] =
+{
+ { "layers-composite-auto", NULL,
+ NC_("layers-action", "Auto"), NULL, NULL,
+ GIMP_LAYER_COMPOSITE_AUTO,
+ NULL },
+
+ { "layers-composite-src-over", NULL,
+ NC_("layers-action", "Source over"), NULL, NULL,
+ GIMP_LAYER_COMPOSITE_SRC_OVER,
+ NULL },
+
+ { "layers-composite-src-atop", NULL,
+ NC_("layers-action", "Source atop"), NULL, NULL,
+ GIMP_LAYER_COMPOSITE_SRC_ATOP,
+ NULL },
+
+ { "layers-composite-src-in", NULL,
+ NC_("layers-action", "Source in"), NULL, NULL,
+ GIMP_LAYER_COMPOSITE_SRC_IN,
+ NULL },
+
+ { "layers-composite-dst-atop", NULL,
+ NC_("layers-action", "Destination atop"), NULL, NULL,
+ GIMP_LAYER_COMPOSITE_DST_ATOP,
+ NULL }
+};
+
static const GimpEnumActionEntry layers_color_tag_actions[] =
{
{ "layers-color-tag-none", GIMP_STOCK_CLOSE /* abused */,
@@ -582,6 +614,12 @@ layers_actions_setup (GimpActionGroup *group)
layers_toggle_actions,
G_N_ELEMENTS (layers_toggle_actions));
+ gimp_action_group_add_radio_actions (group, "layers-action",
+ layers_composite_actions,
+ G_N_ELEMENTS (layers_composite_actions),
+ NULL, 0,
+ G_CALLBACK (layers_composite_cmd_callback));
+
gimp_action_group_add_enum_actions (group, "layers-action",
layers_color_tag_actions,
G_N_ELEMENTS (layers_color_tag_actions),
@@ -662,8 +700,25 @@ layers_actions_update (GimpActionGroup *group,
if (layer)
{
- GList *layer_list;
- GList *list;
+ const gchar *action = NULL;
+ GList *layer_list;
+ GList *list;
+
+ switch (gimp_layer_get_composite (layer))
+ {
+ case GIMP_LAYER_COMPOSITE_AUTO:
+ action = "layers-composite-auto"; break;
+ case GIMP_LAYER_COMPOSITE_SRC_OVER:
+ action = "layers-composite-src-over"; break;
+ case GIMP_LAYER_COMPOSITE_SRC_ATOP:
+ action = "layers-composite-src-atop"; break;
+ case GIMP_LAYER_COMPOSITE_SRC_IN:
+ action = "layers-composite-src-in"; break;
+ case GIMP_LAYER_COMPOSITE_DST_ATOP:
+ action = "layers-composite-dst-atop"; break;
+ }
+
+ gimp_action_group_set_action_active (group, action, TRUE);
mask = gimp_layer_get_mask (layer);
lock_alpha = gimp_layer_get_lock_alpha (layer);
@@ -770,6 +825,12 @@ layers_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("layers-lock-alpha", can_lock_alpha);
SET_ACTIVE ("layers-lock-alpha", lock_alpha);
+ SET_SENSITIVE ("layers-composite-auto", layer);
+ SET_SENSITIVE ("layers-composite-src-over", layer);
+ SET_SENSITIVE ("layers-composite-src-atop", layer);
+ SET_SENSITIVE ("layers-composite-src-in", layer);
+ SET_SENSITIVE ("layers-composite-dst-atop", layer);
+
SET_SENSITIVE ("layers-mask-add", layer && !fs && !ac && !mask && !children);
SET_SENSITIVE ("layers-mask-add-button", layer && !fs && !ac && !children);
SET_SENSITIVE ("layers-mask-add-last-values", layer && !fs && !ac && !mask && !children);
diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c
index d8d5323..da4cd23 100644
--- a/app/actions/layers-commands.c
+++ b/app/actions/layers-commands.c
@@ -42,6 +42,7 @@
#include "core/gimpimage-undo.h"
#include "core/gimpimage-undo-push.h"
#include "core/gimpitemundo.h"
+#include "core/gimplayerpropundo.h"
#include "core/gimplayer-floating-selection.h"
#include "core/gimplayer-new.h"
#include "core/gimppickable.h"
@@ -119,6 +120,7 @@ static void layers_new_callback (GtkWidget *dialog,
GimpContext *context,
const gchar *layer_name,
GimpLayerMode layer_mode,
+ GimpLayerCompositeMode layer_composite,
gdouble layer_opacity,
GimpFillType layer_fill_type,
gint layer_width,
@@ -139,6 +141,7 @@ static void layers_edit_attributes_callback (GtkWidget *dialog,
GimpContext *context,
const gchar *layer_name,
GimpLayerMode layer_mode,
+ GimpLayerCompositeMode layer_composite,
gdouble layer_opacity,
GimpFillType layer_fill_type,
gint layer_width,
@@ -259,6 +262,7 @@ layers_edit_attributes_cmd_callback (GtkAction *action,
GIMP_HELP_LAYER_EDIT,
gimp_object_get_name (layer),
gimp_layer_get_mode (layer),
+ gimp_layer_get_composite (layer),
gimp_layer_get_opacity (layer),
0 /* unused */,
gimp_item_get_visible (item),
@@ -325,6 +329,7 @@ layers_new_cmd_callback (GtkAction *action,
GIMP_HELP_LAYER_NEW,
config->layer_new_name,
config->layer_new_mode,
+ config->layer_new_composite_mode,
config->layer_new_opacity,
config->layer_new_fill_type,
TRUE,
@@ -1134,6 +1139,34 @@ layers_mode_cmd_callback (GtkAction *action,
}
void
+layers_composite_cmd_callback (GtkAction *action,
+ GtkAction *current,
+ gpointer data)
+{
+ GimpImage *image;
+ GimpLayer *layer;
+ GimpLayerCompositeMode composite;
+ return_if_no_layer (image, layer, data);
+
+ composite = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+
+ if (composite != gimp_layer_get_composite (layer))
+ {
+ GimpUndo *undo;
+ gboolean push_undo = TRUE;
+
+ undo = gimp_image_undo_can_compress (image, GIMP_TYPE_LAYER_PROP_UNDO,
+ GIMP_UNDO_LAYER_MODE);
+
+ if (undo && GIMP_ITEM_UNDO (undo)->item == GIMP_ITEM (layer))
+ push_undo = FALSE;
+
+ gimp_layer_set_composite (layer, composite, push_undo);
+ gimp_image_flush (image);
+ }
+}
+
+void
layers_visible_cmd_callback (GtkAction *action,
gpointer data)
{
@@ -1221,34 +1254,36 @@ layers_color_tag_cmd_callback (GtkAction *action,
/* private functions */
static void
-layers_new_callback (GtkWidget *dialog,
- GimpImage *image,
- GimpLayer *layer,
- GimpContext *context,
- const gchar *layer_name,
- GimpLayerMode layer_mode,
- gdouble layer_opacity,
- GimpFillType layer_fill_type,
- gint layer_width,
- gint layer_height,
- gint layer_offset_x,
- gint layer_offset_y,
- gboolean layer_visible,
- gboolean layer_linked,
- GimpColorTag layer_color_tag,
- gboolean layer_lock_pixels,
- gboolean layer_lock_position,
- gboolean layer_lock_alpha,
- gboolean rename_text_layer, /* unused */
- gpointer user_data)
+layers_new_callback (GtkWidget *dialog,
+ GimpImage *image,
+ GimpLayer *layer,
+ GimpContext *context,
+ const gchar *layer_name,
+ GimpLayerMode layer_mode,
+ GimpLayerCompositeMode layer_composite,
+ gdouble layer_opacity,
+ GimpFillType layer_fill_type,
+ gint layer_width,
+ gint layer_height,
+ gint layer_offset_x,
+ gint layer_offset_y,
+ gboolean layer_visible,
+ gboolean layer_linked,
+ GimpColorTag layer_color_tag,
+ gboolean layer_lock_pixels,
+ gboolean layer_lock_position,
+ gboolean layer_lock_alpha,
+ gboolean rename_text_layer, /* unused */
+ gpointer user_data)
{
GimpDialogConfig *config = GIMP_DIALOG_CONFIG (image->gimp->config);
g_object_set (config,
- "layer-new-name", layer_name,
- "layer-new-mode", layer_mode,
- "layer-new-opacity", layer_opacity,
- "layer-new-fill-type", layer_fill_type,
+ "layer-new-name", layer_name,
+ "layer-new-mode", layer_mode,
+ "layer-new-composite-mode", layer_composite,
+ "layer-new-opacity", layer_opacity,
+ "layer-new-fill-type", layer_fill_type,
NULL);
layer = gimp_layer_new (image, layer_width, layer_height,
@@ -1270,6 +1305,7 @@ layers_new_callback (GtkWidget *dialog,
gimp_item_set_lock_position (GIMP_ITEM (layer), layer_lock_position,
FALSE);
gimp_layer_set_lock_alpha (layer, layer_lock_alpha, FALSE);
+ gimp_layer_set_composite (layer, layer_composite, FALSE);
gimp_image_add_layer (image, layer,
GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
@@ -1284,31 +1320,33 @@ layers_new_callback (GtkWidget *dialog,
}
static void
-layers_edit_attributes_callback (GtkWidget *dialog,
- GimpImage *image,
- GimpLayer *layer,
- GimpContext *context,
- const gchar *layer_name,
- GimpLayerMode layer_mode,
- gdouble layer_opacity,
- GimpFillType unused1,
- gint unused2,
- gint unused3,
- gint layer_offset_x,
- gint layer_offset_y,
- gboolean layer_visible,
- gboolean layer_linked,
- GimpColorTag layer_color_tag,
- gboolean layer_lock_pixels,
- gboolean layer_lock_position,
- gboolean layer_lock_alpha,
- gboolean rename_text_layer,
- gpointer user_data)
+layers_edit_attributes_callback (GtkWidget *dialog,
+ GimpImage *image,
+ GimpLayer *layer,
+ GimpContext *context,
+ const gchar *layer_name,
+ GimpLayerMode layer_mode,
+ GimpLayerCompositeMode layer_composite,
+ gdouble layer_opacity,
+ GimpFillType unused1,
+ gint unused2,
+ gint unused3,
+ gint layer_offset_x,
+ gint layer_offset_y,
+ gboolean layer_visible,
+ gboolean layer_linked,
+ GimpColorTag layer_color_tag,
+ gboolean layer_lock_pixels,
+ gboolean layer_lock_position,
+ gboolean layer_lock_alpha,
+ gboolean rename_text_layer,
+ gpointer user_data)
{
GimpItem *item = GIMP_ITEM (layer);
if (strcmp (layer_name, gimp_object_get_name (layer)) ||
layer_mode != gimp_layer_get_mode (layer) ||
+ layer_composite != gimp_layer_get_composite (layer) ||
layer_opacity != gimp_layer_get_opacity (layer) ||
layer_offset_x != gimp_item_get_offset_x (item) ||
layer_offset_y != gimp_item_get_offset_y (item) ||
@@ -1339,6 +1377,9 @@ layers_edit_attributes_callback (GtkWidget *dialog,
if (layer_mode != gimp_layer_get_mode (layer))
gimp_layer_set_mode (layer, layer_mode, TRUE);
+ if (layer_composite != gimp_layer_get_composite (layer))
+ gimp_layer_set_composite (layer, layer_composite, TRUE);
+
if (layer_opacity != gimp_layer_get_opacity (layer))
gimp_layer_set_opacity (layer, layer_opacity, TRUE);
diff --git a/app/actions/layers-commands.h b/app/actions/layers-commands.h
index 32db839..27d3e72 100644
--- a/app/actions/layers-commands.h
+++ b/app/actions/layers-commands.h
@@ -106,6 +106,9 @@ void layers_opacity_cmd_callback (GtkAction *action,
void layers_mode_cmd_callback (GtkAction *action,
gint value,
gpointer data);
+void layers_composite_cmd_callback (GtkAction *action,
+ GtkAction *current,
+ gpointer data);
void layers_visible_cmd_callback (GtkAction *action,
gpointer data);
diff --git a/app/config/gimpcoreconfig.h b/app/config/gimpcoreconfig.h
index d63ada2..3ccbf12 100644
--- a/app/config/gimpcoreconfig.h
+++ b/app/config/gimpcoreconfig.h
@@ -21,6 +21,7 @@
#ifndef __GIMP_CORE_CONFIG_H__
#define __GIMP_CORE_CONFIG_H__
+#include "operations/operations-enums.h"
#include "core/core-enums.h"
#include "config/gimpgeglconfig.h"
diff --git a/app/config/gimpdialogconfig.c b/app/config/gimpdialogconfig.c
index e84fb44..554acf5 100644
--- a/app/config/gimpdialogconfig.c
+++ b/app/config/gimpdialogconfig.c
@@ -68,6 +68,7 @@ enum
PROP_LAYER_NEW_NAME,
PROP_LAYER_NEW_MODE,
+ PROP_LAYER_NEW_COMPOSITE_MODE,
PROP_LAYER_NEW_OPACITY,
PROP_LAYER_NEW_FILL_TYPE,
@@ -302,6 +303,14 @@ gimp_dialog_config_class_init (GimpDialogConfigClass *klass)
GIMP_LAYER_MODE_NORMAL,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_NEW_COMPOSITE_MODE,
+ "layer-new-composite-mode",
+ "Default new layer composite mode",
+ LAYER_NEW_COMPOSITE_MODE_BLURB,
+ GIMP_TYPE_LAYER_COMPOSITE_MODE,
+ GIMP_LAYER_COMPOSITE_AUTO,
+ GIMP_PARAM_STATIC_STRINGS);
+
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_LAYER_NEW_OPACITY,
"layer-new-opacity",
"Default new layer opacity",
@@ -640,6 +649,9 @@ gimp_dialog_config_set_property (GObject *object,
case PROP_LAYER_NEW_MODE:
config->layer_new_mode = g_value_get_enum (value);
break;
+ case PROP_LAYER_NEW_COMPOSITE_MODE:
+ config->layer_new_composite_mode = g_value_get_enum (value);
+ break;
case PROP_LAYER_NEW_OPACITY:
config->layer_new_opacity = g_value_get_double (value);
break;
@@ -820,6 +832,9 @@ gimp_dialog_config_get_property (GObject *object,
case PROP_LAYER_NEW_MODE:
g_value_set_enum (value, config->layer_new_mode);
break;
+ case PROP_LAYER_NEW_COMPOSITE_MODE:
+ g_value_set_enum (value, config->layer_new_composite_mode);
+ break;
case PROP_LAYER_NEW_OPACITY:
g_value_set_double (value, config->layer_new_opacity);
break;
diff --git a/app/config/gimpdialogconfig.h b/app/config/gimpdialogconfig.h
index 55cfcdc..78ea299 100644
--- a/app/config/gimpdialogconfig.h
+++ b/app/config/gimpdialogconfig.h
@@ -66,6 +66,7 @@ struct _GimpDialogConfig
gchar *layer_new_name;
GimpLayerMode layer_new_mode;
+ GimpLayerCompositeMode layer_new_composite_mode;
gdouble layer_new_opacity;
GimpFillType layer_new_fill_type;
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index 036b4a5..02c2cf8 100644
--- a/app/config/gimprc-blurbs.h
+++ b/app/config/gimprc-blurbs.h
@@ -482,6 +482,9 @@ _("Sets the default layer name for the 'New Layer' dialog.")
#define LAYER_NEW_MODE_BLURB \
_("Sets the default mode for the 'New Layer' dialog.")
+#define LAYER_NEW_COMPOSITE_MODE_BLURB \
+_("Sets the default composite mode for the 'New Layer' dialog.")
+
#define LAYER_NEW_OPACITY_BLURB \
_("Sets the default opacity for the 'New Layer' dialog.")
diff --git a/app/core/gimp-edit.c b/app/core/gimp-edit.c
index b622a8f..dc43e05 100644
--- a/app/core/gimp-edit.c
+++ b/app/core/gimp-edit.c
@@ -623,6 +623,7 @@ gimp_edit_fill (GimpImage *image,
TRUE, undo_desc,
gimp_context_get_opacity (GIMP_CONTEXT (options)),
gimp_context_get_paint_mode (GIMP_CONTEXT (options)),
+ GIMP_LAYER_COMPOSITE_AUTO,
NULL, x, y);
g_object_unref (buffer);
@@ -661,6 +662,7 @@ gimp_edit_fade (GimpImage *image,
gimp_object_get_name (undo),
gimp_context_get_opacity (context),
gimp_context_get_paint_mode (context),
+ GIMP_LAYER_COMPOSITE_AUTO,
NULL, undo->x, undo->y);
g_object_unref (buffer);
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index 2ec9db5..86cbef4 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -164,6 +164,7 @@ static void gimp_channel_apply_buffer (GimpDrawable *drawable,
const gchar *undo_desc,
gdouble opacity,
GimpLayerMode mode,
+ GimpLayerCompositeMode composite,
GeglBuffer *base_buffer,
gint base_x,
gint base_y);
@@ -1007,23 +1008,24 @@ gimp_channel_get_active_mask (GimpDrawable *drawable)
}
static void
-gimp_channel_apply_buffer (GimpDrawable *drawable,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_region,
- gboolean push_undo,
- const gchar *undo_desc,
- gdouble opacity,
- GimpLayerMode mode,
- GeglBuffer *base_buffer,
- gint base_x,
- gint base_y)
+gimp_channel_apply_buffer (GimpDrawable *drawable,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_region,
+ gboolean push_undo,
+ const gchar *undo_desc,
+ gdouble opacity,
+ GimpLayerMode mode,
+ GimpLayerCompositeMode composite,
+ GeglBuffer *base_buffer,
+ gint base_x,
+ gint base_y)
{
gimp_drawable_invalidate_boundary (drawable);
GIMP_DRAWABLE_CLASS (parent_class)->apply_buffer (drawable, buffer,
buffer_region,
push_undo, undo_desc,
- opacity, mode,
+ opacity, mode, composite,
base_buffer,
base_x, base_y);
diff --git a/app/core/gimpdrawable-blend.c b/app/core/gimpdrawable-blend.c
index 50e39a2..094affb 100644
--- a/app/core/gimpdrawable-blend.c
+++ b/app/core/gimpdrawable-blend.c
@@ -148,7 +148,7 @@ gimp_drawable_blend (GimpDrawable *drawable,
gimp_drawable_apply_buffer (drawable, buffer,
GEGL_RECTANGLE (x, y, width, height),
TRUE, C_("undo-type", "Blend"),
- opacity, paint_mode,
+ opacity, paint_mode, GIMP_LAYER_COMPOSITE_AUTO,
NULL, x, y);
gimp_drawable_update (drawable, x, y, width, height);
diff --git a/app/core/gimpdrawable-bucket-fill.c b/app/core/gimpdrawable-bucket-fill.c
index 568c9c6..c196beb 100644
--- a/app/core/gimpdrawable-bucket-fill.c
+++ b/app/core/gimpdrawable-bucket-fill.c
@@ -180,6 +180,7 @@ gimp_drawable_bucket_fill (GimpDrawable *drawable,
TRUE, C_("undo-type", "Bucket Fill"),
gimp_context_get_opacity (GIMP_CONTEXT (options)),
gimp_context_get_paint_mode (GIMP_CONTEXT (options)),
+ GIMP_LAYER_COMPOSITE_AUTO,
NULL, x, y);
g_object_unref (buffer);
diff --git a/app/core/gimpdrawable-combine.c b/app/core/gimpdrawable-combine.c
index 635a778..a285313 100644
--- a/app/core/gimpdrawable-combine.c
+++ b/app/core/gimpdrawable-combine.c
@@ -40,16 +40,17 @@
void
-gimp_drawable_real_apply_buffer (GimpDrawable *drawable,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_region,
- gboolean push_undo,
- const gchar *undo_desc,
- gdouble opacity,
- GimpLayerMode mode,
- GeglBuffer *base_buffer,
- gint base_x,
- gint base_y)
+gimp_drawable_real_apply_buffer (GimpDrawable *drawable,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_region,
+ gboolean push_undo,
+ const gchar *undo_desc,
+ gdouble opacity,
+ GimpLayerMode mode,
+ GimpLayerCompositeMode composite,
+ GeglBuffer *base_buffer,
+ gint base_x,
+ gint base_y)
{
GimpItem *item = GIMP_ITEM (drawable);
GimpImage *image = gimp_item_get_image (item);
@@ -102,8 +103,9 @@ gimp_drawable_real_apply_buffer (GimpDrawable *drawable,
if (undo)
{
- undo->paint_mode = mode;
- undo->opacity = opacity;
+ undo->paint_mode = mode;
+ undo->composite_mode = composite;
+ undo->opacity = opacity;
undo->applied_buffer =
gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
@@ -141,7 +143,7 @@ gimp_drawable_real_apply_buffer (GimpDrawable *drawable,
base_y - buffer_region->y);
gimp_applicator_set_opacity (applicator, opacity);
- gimp_applicator_set_mode (applicator, mode);
+ gimp_applicator_set_mode (applicator, mode, composite);
gimp_applicator_set_affect (applicator,
gimp_drawable_get_active_mask (drawable));
diff --git a/app/core/gimpdrawable-combine.h b/app/core/gimpdrawable-combine.h
index 9b73208..09a29ad 100644
--- a/app/core/gimpdrawable-combine.h
+++ b/app/core/gimpdrawable-combine.h
@@ -21,26 +21,27 @@
/* virtual functions of GimpDrawable, don't call directly */
-void gimp_drawable_real_apply_buffer (GimpDrawable *drawable,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_region,
- gboolean push_undo,
- const gchar *undo_desc,
- gdouble opacity,
- GimpLayerMode mode,
- GeglBuffer *base_buffer,
- gint base_x,
- gint base_y);
-void gimp_drawable_real_replace_buffer (GimpDrawable *drawable,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_region,
- gboolean push_undo,
- const gchar *undo_desc,
- gdouble opacity,
- GeglBuffer *mask,
- const GeglRectangle *mask_region,
- gint x,
- gint y);
+void gimp_drawable_real_apply_buffer (GimpDrawable *drawable,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_region,
+ gboolean push_undo,
+ const gchar *undo_desc,
+ gdouble opacity,
+ GimpLayerMode mode,
+ GimpLayerCompositeMode composite,
+ GeglBuffer *base_buffer,
+ gint base_x,
+ gint base_y);
+void gimp_drawable_real_replace_buffer (GimpDrawable *drawable,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_region,
+ gboolean push_undo,
+ const gchar *undo_desc,
+ gdouble opacity,
+ GeglBuffer *mask,
+ const GeglRectangle *mask_region,
+ gint x,
+ gint y);
#endif /* __GIMP_DRAWABLE_COMBINE_H__ */
diff --git a/app/core/gimpdrawable-fill.c b/app/core/gimpdrawable-fill.c
index 75566c2..59937ea 100644
--- a/app/core/gimpdrawable-fill.c
+++ b/app/core/gimpdrawable-fill.c
@@ -256,6 +256,7 @@ gimp_drawable_fill_scan_convert (GimpDrawable *drawable,
push_undo, C_("undo-type", "Render Stroke"),
gimp_context_get_opacity (context),
gimp_context_get_paint_mode (context),
+ GIMP_LAYER_COMPOSITE_AUTO,
NULL, x, y);
g_object_unref (buffer);
diff --git a/app/core/gimpdrawable-floating-selection.c b/app/core/gimpdrawable-floating-selection.c
index 0ceff8b..e3acecd 100644
--- a/app/core/gimpdrawable-floating-selection.c
+++ b/app/core/gimpdrawable-floating-selection.c
@@ -304,7 +304,8 @@ gimp_drawable_sync_fs_filter (GimpDrawable *drawable)
gimp_applicator_set_opacity (private->fs_applicator,
gimp_layer_get_opacity (fs));
gimp_applicator_set_mode (private->fs_applicator,
- gimp_layer_get_mode (fs));
+ gimp_layer_get_mode (fs),
+ gimp_layer_get_composite (fs));
gimp_applicator_set_affect (private->fs_applicator,
gimp_drawable_get_active_mask (drawable));
}
diff --git a/app/core/gimpdrawable-shadow.c b/app/core/gimpdrawable-shadow.c
index cb6f01f..52493fb 100644
--- a/app/core/gimpdrawable-shadow.c
+++ b/app/core/gimpdrawable-shadow.c
@@ -103,6 +103,7 @@ gimp_drawable_merge_shadow_buffer (GimpDrawable *drawable,
push_undo, undo_desc,
GIMP_OPACITY_OPAQUE,
GIMP_LAYER_MODE_REPLACE,
+ GIMP_LAYER_COMPOSITE_AUTO,
NULL, x, y);
g_object_unref (buffer);
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 79217fc..7c5d80c 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -1097,16 +1097,17 @@ gimp_drawable_convert_type (GimpDrawable *drawable,
}
void
-gimp_drawable_apply_buffer (GimpDrawable *drawable,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_region,
- gboolean push_undo,
- const gchar *undo_desc,
- gdouble opacity,
- GimpLayerMode mode,
- GeglBuffer *base_buffer,
- gint base_x,
- gint base_y)
+gimp_drawable_apply_buffer (GimpDrawable *drawable,
+ GeglBuffer *buffer,
+ const GeglRectangle *buffer_region,
+ gboolean push_undo,
+ const gchar *undo_desc,
+ gdouble opacity,
+ GimpLayerMode mode,
+ GimpLayerCompositeMode composite,
+ GeglBuffer *base_buffer,
+ gint base_x,
+ gint base_y)
{
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
@@ -1117,7 +1118,7 @@ gimp_drawable_apply_buffer (GimpDrawable *drawable,
GIMP_DRAWABLE_GET_CLASS (drawable)->apply_buffer (drawable, buffer,
buffer_region,
push_undo, undo_desc,
- opacity, mode,
+ opacity, mode, composite,
base_buffer,
base_x, base_y);
}
diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h
index 09a33d7..db23c81 100644
--- a/app/core/gimpdrawable.h
+++ b/app/core/gimpdrawable.h
@@ -76,6 +76,7 @@ struct _GimpDrawableClass
const gchar *undo_desc,
gdouble opacity,
GimpLayerMode mode,
+ GimpLayerCompositeMode composite,
GeglBuffer *base_buffer,
gint base_x,
gint base_y);
@@ -156,6 +157,7 @@ void gimp_drawable_apply_buffer (GimpDrawable *drawable,
const gchar *undo_desc,
gdouble opacity,
GimpLayerMode mode,
+ GimpLayerCompositeMode composite,
GeglBuffer *base_buffer,
gint base_x,
gint base_y);
diff --git a/app/core/gimpdrawablefilter.c b/app/core/gimpdrawablefilter.c
index 62a4a31..9639f63 100644
--- a/app/core/gimpdrawablefilter.c
+++ b/app/core/gimpdrawablefilter.c
@@ -57,29 +57,30 @@ enum
struct _GimpDrawableFilter
{
- GimpFilter parent_instance;
-
- GimpDrawable *drawable;
- GeglNode *operation;
-
- GimpFilterRegion region;
- gboolean preview_enabled;
- GimpAlignmentType preview_alignment;
- gdouble preview_position;
- gdouble opacity;
- GimpLayerMode paint_mode;
- gboolean color_managed;
- gboolean gamma_hack;
-
- GeglRectangle filter_area;
-
- GeglNode *translate;
- GeglNode *crop;
- GeglNode *cast_before;
- GeglNode *transform_before;
- GeglNode *transform_after;
- GeglNode *cast_after;
- GimpApplicator *applicator;
+ GimpFilter parent_instance;
+
+ GimpDrawable *drawable;
+ GeglNode *operation;
+
+ GimpFilterRegion region;
+ gboolean preview_enabled;
+ GimpAlignmentType preview_alignment;
+ gdouble preview_position;
+ gdouble opacity;
+ GimpLayerMode paint_mode;
+ GimpLayerCompositeMode composite_mode;
+ gboolean color_managed;
+ gboolean gamma_hack;
+
+ GeglRectangle filter_area;
+
+ GeglNode *translate;
+ GeglNode *crop;
+ GeglNode *cast_before;
+ GeglNode *transform_before;
+ GeglNode *transform_after;
+ GeglNode *cast_after;
+ GimpApplicator *applicator;
};
@@ -149,6 +150,7 @@ gimp_drawable_filter_init (GimpDrawableFilter *drawable_filter)
drawable_filter->preview_position = 1.0;
drawable_filter->opacity = GIMP_OPACITY_OPAQUE;
drawable_filter->paint_mode = GIMP_LAYER_MODE_REPLACE;
+ drawable_filter->composite_mode = GIMP_LAYER_COMPOSITE_AUTO;
}
static void
@@ -329,14 +331,17 @@ gimp_drawable_filter_set_opacity (GimpDrawableFilter *filter,
}
void
-gimp_drawable_filter_set_mode (GimpDrawableFilter *filter,
- GimpLayerMode paint_mode)
+gimp_drawable_filter_set_mode (GimpDrawableFilter *filter,
+ GimpLayerMode paint_mode,
+ GimpLayerCompositeMode composite_mode)
{
g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter));
- if (paint_mode != filter->paint_mode)
+ if (paint_mode != filter->paint_mode ||
+ composite_mode != filter->composite_mode)
{
- filter->paint_mode = paint_mode;
+ filter->paint_mode = paint_mode;
+ filter->composite_mode = composite_mode;
gimp_drawable_filter_sync_mode (filter);
@@ -583,7 +588,8 @@ static void
gimp_drawable_filter_sync_mode (GimpDrawableFilter *filter)
{
gimp_applicator_set_mode (filter->applicator,
- filter->paint_mode);
+ filter->paint_mode,
+ filter->composite_mode);
}
static void
diff --git a/app/core/gimpdrawablefilter.h b/app/core/gimpdrawablefilter.h
index 9e3a11d..3e364c0 100644
--- a/app/core/gimpdrawablefilter.h
+++ b/app/core/gimpdrawablefilter.h
@@ -64,7 +64,8 @@ void gimp_drawable_filter_set_preview (GimpDrawableFilter *filter,
void gimp_drawable_filter_set_opacity (GimpDrawableFilter *filter,
gdouble opacity);
void gimp_drawable_filter_set_mode (GimpDrawableFilter *filter,
- GimpLayerMode paint_mode);
+ GimpLayerMode paint_mode,
+ GimpLayerCompositeMode composite_mode);
void gimp_drawable_filter_set_color_managed
(GimpDrawableFilter *filter,
diff --git a/app/core/gimpdrawableundo.h b/app/core/gimpdrawableundo.h
index ff07b41..d355a5a 100644
--- a/app/core/gimpdrawableundo.h
+++ b/app/core/gimpdrawableundo.h
@@ -35,16 +35,17 @@ typedef struct _GimpDrawableUndoClass GimpDrawableUndoClass;
struct _GimpDrawableUndo
{
- GimpItemUndo parent_instance;
+ GimpItemUndo parent_instance;
- GeglBuffer *buffer;
- gint x;
- gint y;
+ GeglBuffer *buffer;
+ gint x;
+ gint y;
/* stuff for "Fade" */
- GeglBuffer *applied_buffer;
- GimpLayerMode paint_mode;
- gdouble opacity;
+ GeglBuffer *applied_buffer;
+ GimpLayerMode paint_mode;
+ GimpLayerCompositeMode composite_mode;
+ gdouble opacity;
};
struct _GimpDrawableUndoClass
diff --git a/app/core/gimpimage-merge.c b/app/core/gimpimage-merge.c
index 5a8b24e..02cc17b 100644
--- a/app/core/gimpimage-merge.c
+++ b/app/core/gimpimage-merge.c
@@ -598,10 +598,11 @@ gimp_image_merge_layers (GimpImage *image,
for (layers = reverse_list; layers; layers = g_slist_next (layers))
{
- GeglBuffer *merge_buffer;
- GeglBuffer *layer_buffer;
- GimpApplicator *applicator;
- GimpLayerMode mode;
+ GeglBuffer *merge_buffer;
+ GeglBuffer *layer_buffer;
+ GimpApplicator *applicator;
+ GimpLayerMode mode;
+ GimpLayerCompositeMode composite;
layer = layers->data;
@@ -611,9 +612,14 @@ gimp_image_merge_layers (GimpImage *image,
* work on the projection with the lower layer, but only locally on
* the layers alpha channel.
*/
- mode = gimp_layer_get_mode (layer);
+ mode = gimp_layer_get_mode (layer);
+ composite = gimp_layer_get_composite (layer);
+
if (layer == bottom_layer && mode != GIMP_LAYER_MODE_DISSOLVE)
- mode = GIMP_LAYER_MODE_NORMAL;
+ {
+ mode = GIMP_LAYER_MODE_NORMAL;
+ composite = GIMP_LAYER_COMPOSITE_AUTO;
+ }
merge_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (merge_layer));
layer_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
@@ -642,7 +648,7 @@ gimp_image_merge_layers (GimpImage *image,
- (y1 - off_y));
gimp_applicator_set_opacity (applicator, gimp_layer_get_opacity (layer));
- gimp_applicator_set_mode (applicator, mode);
+ gimp_applicator_set_mode (applicator, mode, composite);
gimp_applicator_blit (applicator,
GEGL_RECTANGLE (0, 0,
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index b716ba3..bc64f09 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -59,6 +59,7 @@ enum
{
OPACITY_CHANGED,
MODE_CHANGED,
+ COMPOSITE_CHANGED,
LOCK_ALPHA_CHANGED,
MASK_CHANGED,
APPLY_MASK_CHANGED,
@@ -72,6 +73,7 @@ enum
PROP_0,
PROP_OPACITY,
PROP_MODE,
+ PROP_COMPOSITE,
PROP_LOCK_ALPHA,
PROP_MASK,
PROP_FLOATING_SELECTION
@@ -247,6 +249,15 @@ gimp_layer_class_init (GimpLayerClass *klass)
gimp_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ layer_signals[COMPOSITE_CHANGED] =
+ g_signal_new ("composite-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpLayerClass, composite_changed),
+ NULL, NULL,
+ gimp_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
layer_signals[LOCK_ALPHA_CHANGED] =
g_signal_new ("lock-alpha-changed",
G_TYPE_FROM_CLASS (klass),
@@ -348,6 +359,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
klass->opacity_changed = NULL;
klass->mode_changed = NULL;
+ klass->composite_changed = NULL;
klass->lock_alpha_changed = NULL;
klass->mask_changed = NULL;
klass->apply_mask_changed = NULL;
@@ -367,6 +379,12 @@ gimp_layer_class_init (GimpLayerClass *klass)
GIMP_LAYER_MODE_NORMAL,
GIMP_PARAM_READABLE));
+ g_object_class_install_property (object_class, PROP_COMPOSITE,
+ g_param_spec_enum ("composite", NULL, NULL,
+ GIMP_TYPE_LAYER_COMPOSITE_MODE,
+ GIMP_LAYER_COMPOSITE_AUTO,
+ GIMP_PARAM_READABLE));
+
g_object_class_install_property (object_class, PROP_LOCK_ALPHA,
g_param_spec_boolean ("lock-alpha",
NULL, NULL,
@@ -391,6 +409,7 @@ gimp_layer_init (GimpLayer *layer)
{
layer->opacity = GIMP_OPACITY_OPAQUE;
layer->mode = GIMP_LAYER_MODE_NORMAL;
+ layer->composite = GIMP_LAYER_COMPOSITE_AUTO;
layer->lock_alpha = FALSE;
layer->mask = NULL;
@@ -449,6 +468,9 @@ gimp_layer_get_property (GObject *object,
case PROP_MODE:
g_value_set_enum (value, gimp_layer_get_mode (layer));
break;
+ case PROP_COMPOSITE:
+ g_value_set_enum (value, gimp_layer_get_composite (layer));
+ break;
case PROP_LOCK_ALPHA:
g_value_set_boolean (value, gimp_layer_get_lock_alpha (layer));
break;
@@ -508,29 +530,33 @@ gimp_layer_finalize (GObject *object)
static void
gimp_layer_update_mode_node (GimpLayer *layer)
{
- GeglNode *mode_node;
- GimpLayerMode visible_mode;
+ GeglNode *mode_node;
+ GimpLayerMode visible_mode;
+ GimpLayerCompositeMode visible_composite;
mode_node = gimp_drawable_get_mode_node (GIMP_DRAWABLE (layer));
if (layer->mask && layer->show_mask)
{
- visible_mode = GIMP_LAYER_MODE_NORMAL;
+ visible_mode = GIMP_LAYER_MODE_NORMAL;
+ visible_composite = GIMP_LAYER_COMPOSITE_AUTO;
}
else
{
if (layer->mode != GIMP_LAYER_MODE_DISSOLVE &&
gimp_filter_get_is_last_node (GIMP_FILTER (layer)))
{
- visible_mode = GIMP_LAYER_MODE_NORMAL;
+ visible_mode = GIMP_LAYER_MODE_NORMAL;
+ visible_composite = GIMP_LAYER_COMPOSITE_AUTO;
}
else
{
- visible_mode = layer->mode;
+ visible_mode = layer->mode;
+ visible_composite = layer->composite;
}
}
- gimp_gegl_mode_node_set_mode (mode_node, visible_mode);
+ gimp_gegl_mode_node_set_mode (mode_node, visible_mode, visible_composite);
gimp_gegl_mode_node_set_opacity (mode_node, layer->opacity);
}
@@ -747,8 +773,12 @@ gimp_layer_duplicate (GimpItem *item,
GimpLayer *layer = GIMP_LAYER (item);
GimpLayer *new_layer = GIMP_LAYER (new_item);
- gimp_layer_set_mode (new_layer, gimp_layer_get_mode (layer), FALSE);
- gimp_layer_set_opacity (new_layer, gimp_layer_get_opacity (layer), FALSE);
+ gimp_layer_set_mode (new_layer,
+ gimp_layer_get_mode (layer), FALSE);
+ gimp_layer_set_composite (new_layer,
+ gimp_layer_get_composite (layer), FALSE);
+ gimp_layer_set_opacity (new_layer,
+ gimp_layer_get_opacity (layer), FALSE);
if (gimp_layer_can_lock_alpha (new_layer))
gimp_layer_set_lock_alpha (new_layer,
@@ -2051,11 +2081,26 @@ gimp_layer_set_mode (GimpLayer *layer,
gimp_image_undo_push_layer_mode (image, NULL, layer);
}
+ g_object_freeze_notify (G_OBJECT (layer));
+
layer->mode = mode;
g_signal_emit (layer, layer_signals[MODE_CHANGED], 0);
g_object_notify (G_OBJECT (layer), "mode");
+ /* when changing modes, we always switch to AUTO composite in
+ * order to avoid confusion
+ */
+ if (layer->composite != GIMP_LAYER_COMPOSITE_AUTO)
+ {
+ layer->composite = GIMP_LAYER_COMPOSITE_AUTO;
+
+ g_signal_emit (layer, layer_signals[COMPOSITE_CHANGED], 0);
+ g_object_notify (G_OBJECT (layer), "composite");
+ }
+
+ g_object_thaw_notify (G_OBJECT (layer));
+
if (gimp_filter_peek_node (GIMP_FILTER (layer)))
gimp_layer_update_mode_node (layer);
@@ -2072,6 +2117,42 @@ gimp_layer_get_mode (GimpLayer *layer)
}
void
+gimp_layer_set_composite (GimpLayer *layer,
+ GimpLayerCompositeMode composite,
+ gboolean push_undo)
+{
+ g_return_if_fail (GIMP_IS_LAYER (layer));
+
+ if (layer->composite != composite)
+ {
+ if (push_undo && gimp_item_is_attached (GIMP_ITEM (layer)))
+ {
+ GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
+
+ gimp_image_undo_push_layer_mode (image, NULL, layer);
+ }
+
+ layer->composite = composite;
+
+ g_signal_emit (layer, layer_signals[COMPOSITE_CHANGED], 0);
+ g_object_notify (G_OBJECT (layer), "composite");
+
+ if (gimp_filter_peek_node (GIMP_FILTER (layer)))
+ gimp_layer_update_mode_node (layer);
+
+ gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
+ }
+}
+
+GimpLayerCompositeMode
+gimp_layer_get_composite (GimpLayer *layer)
+{
+ g_return_val_if_fail (GIMP_IS_LAYER (layer), FALSE);
+
+ return layer->composite;
+}
+
+void
gimp_layer_set_lock_alpha (GimpLayer *layer,
gboolean lock_alpha,
gboolean push_undo)
diff --git a/app/core/gimplayer.h b/app/core/gimplayer.h
index b19199f..078054f 100644
--- a/app/core/gimplayer.h
+++ b/app/core/gimplayer.h
@@ -34,19 +34,20 @@ typedef struct _GimpLayerClass GimpLayerClass;
struct _GimpLayer
{
- GimpDrawable parent_instance;
+ GimpDrawable parent_instance;
- gdouble opacity; /* layer opacity */
- GimpLayerMode mode; /* layer combination mode */
- gboolean lock_alpha; /* lock the alpha channel */
+ gdouble opacity; /* layer opacity */
+ GimpLayerMode mode; /* layer combination mode */
+ GimpLayerCompositeMode composite; /* layer composite mode */
+ gboolean lock_alpha; /* lock the alpha channel */
- GimpLayerMask *mask; /* possible layer mask */
- gboolean apply_mask; /* controls mask application */
- gboolean edit_mask; /* edit mask or layer? */
- gboolean show_mask; /* show mask or layer? */
+ GimpLayerMask *mask; /* possible layer mask */
+ gboolean apply_mask; /* controls mask application */
+ gboolean edit_mask; /* edit mask or layer? */
+ gboolean show_mask; /* show mask or layer? */
- GeglNode *layer_offset_node;
- GeglNode *mask_offset_node;
+ GeglNode *layer_offset_node;
+ GeglNode *mask_offset_node;
/* Floating selections */
struct
@@ -64,6 +65,7 @@ struct _GimpLayerClass
void (* opacity_changed) (GimpLayer *layer);
void (* mode_changed) (GimpLayer *layer);
+ void (* composite_changed) (GimpLayer *layer);
void (* lock_alpha_changed) (GimpLayer *layer);
void (* mask_changed) (GimpLayer *layer);
void (* apply_mask_changed) (GimpLayer *layer);
@@ -127,6 +129,12 @@ void gimp_layer_set_mode (GimpLayer *layer,
gboolean push_undo);
GimpLayerMode gimp_layer_get_mode (GimpLayer *layer);
+void gimp_layer_set_composite (GimpLayer *layer,
+ GimpLayerCompositeMode composite,
+ gboolean push_undo);
+GimpLayerCompositeMode
+ gimp_layer_get_composite (GimpLayer *layer);
+
void gimp_layer_set_lock_alpha (GimpLayer *layer,
gboolean lock_alpha,
gboolean push_undo);
diff --git a/app/core/gimplayerpropundo.c b/app/core/gimplayerpropundo.c
index e097c87..35597b5 100644
--- a/app/core/gimplayerpropundo.c
+++ b/app/core/gimplayerpropundo.c
@@ -72,7 +72,8 @@ gimp_layer_prop_undo_constructed (GObject *object)
switch (GIMP_UNDO (object)->undo_type)
{
case GIMP_UNDO_LAYER_MODE:
- layer_prop_undo->mode = gimp_layer_get_mode (layer);
+ layer_prop_undo->mode = gimp_layer_get_mode (layer);
+ layer_prop_undo->composite = gimp_layer_get_composite (layer);
break;
case GIMP_UNDO_LAYER_OPACITY:
@@ -102,11 +103,17 @@ gimp_layer_prop_undo_pop (GimpUndo *undo,
{
case GIMP_UNDO_LAYER_MODE:
{
- GimpLayerMode mode;
+ GimpLayerMode mode;
+ GimpLayerCompositeMode composite;
+
+ mode = gimp_layer_get_mode (layer);
+ composite = gimp_layer_get_composite (layer);
- mode = gimp_layer_get_mode (layer);
gimp_layer_set_mode (layer, layer_prop_undo->mode, FALSE);
- layer_prop_undo->mode = mode;
+ gimp_layer_set_composite (layer, layer_prop_undo->composite, FALSE);
+
+ layer_prop_undo->mode = mode;
+ layer_prop_undo->composite = composite;
}
break;
diff --git a/app/core/gimplayerpropundo.h b/app/core/gimplayerpropundo.h
index e660669..f3d61ba 100644
--- a/app/core/gimplayerpropundo.h
+++ b/app/core/gimplayerpropundo.h
@@ -35,11 +35,12 @@ typedef struct _GimpLayerPropUndoClass GimpLayerPropUndoClass;
struct _GimpLayerPropUndo
{
- GimpItemUndo parent_instance;
+ GimpItemUndo parent_instance;
- GimpLayerMode mode;
- gdouble opacity;
- gboolean lock_alpha;
+ GimpLayerMode mode;
+ GimpLayerCompositeMode composite;
+ gdouble opacity;
+ gboolean lock_alpha;
};
struct _GimpLayerPropUndoClass
diff --git a/app/dialogs/layer-options-dialog.c b/app/dialogs/layer-options-dialog.c
index 424c2cd..fd4f13f 100644
--- a/app/dialogs/layer-options-dialog.c
+++ b/app/dialogs/layer-options-dialog.c
@@ -51,6 +51,7 @@ struct _LayerOptionsDialog
{
GimpLayer *layer;
GimpLayerMode mode;
+ GimpLayerCompositeMode composite;
gdouble opacity;
GimpFillType fill_type;
gboolean lock_alpha;
@@ -96,6 +97,7 @@ layer_options_dialog_new (GimpImage *image,
const gchar *help_id,
const gchar *layer_name,
GimpLayerMode layer_mode,
+ GimpLayerCompositeMode layer_composite,
gdouble layer_opacity,
GimpFillType layer_fill_type,
gboolean layer_visible,
@@ -129,6 +131,7 @@ layer_options_dialog_new (GimpImage *image,
private->layer = layer;
private->mode = layer_mode;
+ private->composite = layer_composite;
private->opacity = layer_opacity * 100.0;
private->fill_type = layer_fill_type;
private->lock_alpha = layer_lock_alpha;
@@ -163,6 +166,15 @@ layer_options_dialog_new (GimpImage *image,
gimp_layer_mode_box_set_mode (GIMP_LAYER_MODE_BOX (private->mode_box),
private->mode);
+ combo = gimp_enum_combo_box_new (GIMP_TYPE_LAYER_COMPOSITE_MODE);
+ item_options_dialog_add_widget (dialog, _("Composite:"), combo);
+ gimp_enum_combo_box_set_icon_prefix (GIMP_ENUM_COMBO_BOX (combo),
+ "gimp-layer-composite");
+ gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
+ private->composite,
+ G_CALLBACK (gimp_int_combo_box_get_active),
+ &private->composite);
+
adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (private->opacity, 0.0, 100.0,
1.0, 10.0, 0.0));
scale = gimp_spin_scale_new (adjustment, NULL, 1);
@@ -446,6 +458,7 @@ layer_options_dialog_callback (GtkWidget *dialog,
context,
item_name,
private->mode,
+ private->composite,
private->opacity / 100.0,
private->fill_type,
width,
diff --git a/app/dialogs/layer-options-dialog.h b/app/dialogs/layer-options-dialog.h
index 1dbaab5..ad18b90 100644
--- a/app/dialogs/layer-options-dialog.h
+++ b/app/dialogs/layer-options-dialog.h
@@ -19,26 +19,27 @@
#define __LAYER_OPTIONS_DIALOG_H__
-typedef void (* GimpLayerOptionsCallback) (GtkWidget *dialog,
- GimpImage *image,
- GimpLayer *layer,
- GimpContext *context,
- const gchar *layer_name,
- GimpLayerMode layer_mode,
- gdouble layer_opacity,
- GimpFillType layer_fill_type,
- gint layer_width,
- gint layer_height,
- gint layer_offset_x,
- gint layer_offset_y,
- gboolean layer_visible,
- gboolean layer_linked,
- GimpColorTag layer_color_tag,
- gboolean layer_lock_content,
- gboolean layer_lock_position,
- gboolean layer_lock_alpha,
- gboolean rename_text_layer,
- gpointer user_data);
+typedef void (* GimpLayerOptionsCallback) (GtkWidget *dialog,
+ GimpImage *image,
+ GimpLayer *layer,
+ GimpContext *context,
+ const gchar *layer_name,
+ GimpLayerMode layer_mode,
+ GimpLayerCompositeMode layer_composite,
+ gdouble layer_opacity,
+ GimpFillType layer_fill_type,
+ gint layer_width,
+ gint layer_height,
+ gint layer_offset_x,
+ gint layer_offset_y,
+ gboolean layer_visible,
+ gboolean layer_linked,
+ GimpColorTag layer_color_tag,
+ gboolean layer_lock_content,
+ gboolean layer_lock_position,
+ gboolean layer_lock_alpha,
+ gboolean rename_text_layer,
+ gpointer user_data);
GtkWidget * layer_options_dialog_new (GimpImage *image,
@@ -52,6 +53,7 @@ GtkWidget * layer_options_dialog_new (GimpImage *image,
const gchar *help_id,
const gchar *layer_name,
GimpLayerMode layer_mode,
+ GimpLayerCompositeMode layer_composite,
gdouble layer_opacity,
GimpFillType layer_fill_type,
gboolean layer_visible,
diff --git a/app/gegl/gimp-gegl-nodes.c b/app/gegl/gimp-gegl-nodes.c
index 54b034b..548ed80 100644
--- a/app/gegl/gimp-gegl-nodes.c
+++ b/app/gegl/gimp-gegl-nodes.c
@@ -141,13 +141,17 @@ gimp_gegl_add_buffer_source (GeglNode *parent,
}
void
-gimp_gegl_mode_node_set_mode (GeglNode *node,
- GimpLayerMode mode)
+gimp_gegl_mode_node_set_mode (GeglNode *node,
+ GimpLayerMode mode,
+ GimpLayerCompositeMode composite)
{
gdouble opacity;
g_return_if_fail (GEGL_IS_NODE (node));
+ if (composite == GIMP_LAYER_COMPOSITE_AUTO)
+ composite = gimp_layer_mode_get_composite_mode (mode);
+
gegl_node_get (node,
"opacity", &opacity,
NULL);
@@ -158,11 +162,11 @@ gimp_gegl_mode_node_set_mode (GeglNode *node,
gegl_node_set (node,
"operation", gimp_layer_mode_get_operation (mode),
"layer-mode", mode,
+ "composite-mode", composite,
"opacity", opacity,
"linear", gimp_layer_mode_wants_linear_data (mode),
"blend-space", gimp_layer_mode_get_blend_space (mode),
"composite-space", gimp_layer_mode_get_composite_space (mode),
- "composite-mode", gimp_layer_mode_get_composite_mode (mode),
NULL);
}
diff --git a/app/gegl/gimp-gegl-nodes.h b/app/gegl/gimp-gegl-nodes.h
index e1233c9..6d63288 100644
--- a/app/gegl/gimp-gegl-nodes.h
+++ b/app/gegl/gimp-gegl-nodes.h
@@ -32,8 +32,9 @@ GeglNode * gimp_gegl_add_buffer_source (GeglNode *parent,
gint offset_x,
gint offset_y);
-void gimp_gegl_mode_node_set_mode (GeglNode *node,
- GimpLayerMode mode);
+void gimp_gegl_mode_node_set_mode (GeglNode *node,
+ GimpLayerMode mode,
+ GimpLayerCompositeMode composite);
void gimp_gegl_mode_node_set_opacity (GeglNode *node,
gdouble opacity);
diff --git a/app/gegl/gimpapplicator.c b/app/gegl/gimpapplicator.c
index 9d8dd16..b4ee0e4 100644
--- a/app/gegl/gimpapplicator.c
+++ b/app/gegl/gimpapplicator.c
@@ -57,9 +57,10 @@ gimp_applicator_class_init (GimpApplicatorClass *klass)
static void
gimp_applicator_init (GimpApplicator *applicator)
{
- applicator->opacity = 1.0;
- applicator->paint_mode = GIMP_LAYER_MODE_NORMAL;
- applicator->affect = GIMP_COMPONENT_MASK_ALL;
+ applicator->opacity = 1.0;
+ applicator->paint_mode = GIMP_LAYER_MODE_NORMAL;
+ applicator->composite_mode = GIMP_LAYER_COMPOSITE_AUTO;
+ applicator->affect = GIMP_COMPONENT_MASK_ALL;
}
static void
@@ -134,7 +135,8 @@ gimp_applicator_new (GeglNode *parent,
NULL);
gimp_gegl_mode_node_set_mode (applicator->mode_node,
- applicator->paint_mode);
+ applicator->paint_mode,
+ applicator->composite_mode);
gimp_gegl_mode_node_set_opacity (applicator->mode_node,
applicator->opacity);
@@ -445,16 +447,20 @@ gimp_applicator_set_opacity (GimpApplicator *applicator,
}
void
-gimp_applicator_set_mode (GimpApplicator *applicator,
- GimpLayerMode paint_mode)
+gimp_applicator_set_mode (GimpApplicator *applicator,
+ GimpLayerMode paint_mode,
+ GimpLayerCompositeMode composite_mode)
{
g_return_if_fail (GIMP_IS_APPLICATOR (applicator));
- if (applicator->paint_mode != paint_mode)
+ if (applicator->paint_mode != paint_mode ||
+ applicator->composite_mode != composite_mode)
{
- applicator->paint_mode = paint_mode;
+ applicator->paint_mode = paint_mode;
+ applicator->composite_mode = composite_mode;
- gimp_gegl_mode_node_set_mode (applicator->mode_node, paint_mode);
+ gimp_gegl_mode_node_set_mode (applicator->mode_node,
+ paint_mode, composite_mode);
}
}
diff --git a/app/gegl/gimpapplicator.h b/app/gegl/gimpapplicator.h
index 18b5497..6d4ee5b 100644
--- a/app/gegl/gimpapplicator.h
+++ b/app/gegl/gimpapplicator.h
@@ -34,48 +34,49 @@ typedef struct _GimpApplicatorClass GimpApplicatorClass;
struct _GimpApplicator
{
- GObject parent_instance;
+ GObject parent_instance;
- GeglNode *node;
- GeglNode *input_node;
- GeglNode *aux_node;
- GeglNode *output_node;
+ GeglNode *node;
+ GeglNode *input_node;
+ GeglNode *aux_node;
+ GeglNode *output_node;
- GeglBuffer *apply_buffer;
- GeglNode *apply_src_node;
+ GeglBuffer *apply_buffer;
+ GeglNode *apply_src_node;
- gint apply_offset_x;
- gint apply_offset_y;
- GeglNode *apply_offset_node;
+ gint apply_offset_x;
+ gint apply_offset_y;
+ GeglNode *apply_offset_node;
- GeglNode *dup_apply_buffer_node;
+ GeglNode *dup_apply_buffer_node;
- gboolean preview_enabled;
- GeglRectangle preview_rect;
- GeglNode *preview_cache_node;
- GeglNode *preview_crop_node;
+ gboolean preview_enabled;
+ GeglRectangle preview_rect;
+ GeglNode *preview_cache_node;
+ GeglNode *preview_crop_node;
- gdouble opacity;
- GimpLayerMode paint_mode;
- GeglNode *mode_node;
+ gdouble opacity;
+ GimpLayerMode paint_mode;
+ GimpLayerCompositeMode composite_mode;
+ GeglNode *mode_node;
- GimpComponentMask affect;
- GeglNode *affect_node;
+ GimpComponentMask affect;
+ GeglNode *affect_node;
- GeglNode *output_cache_node;
+ GeglNode *output_cache_node;
- GeglBuffer *src_buffer;
- GeglNode *src_node;
+ GeglBuffer *src_buffer;
+ GeglNode *src_node;
- GeglBuffer *dest_buffer;
- GeglNode *dest_node;
+ GeglBuffer *dest_buffer;
+ GeglNode *dest_node;
- GeglBuffer *mask_buffer;
- GeglNode *mask_node;
+ GeglBuffer *mask_buffer;
+ GeglNode *mask_node;
- gint mask_offset_x;
- gint mask_offset_y;
- GeglNode *mask_offset_node;
+ gint mask_offset_x;
+ gint mask_offset_y;
+ GeglNode *mask_offset_node;
};
struct _GimpApplicatorClass
@@ -110,7 +111,8 @@ void gimp_applicator_set_apply_offset (GimpApplicator *applicator,
void gimp_applicator_set_opacity (GimpApplicator *applicator,
gdouble opacity);
void gimp_applicator_set_mode (GimpApplicator *applicator,
- GimpLayerMode paint_mode);
+ GimpLayerMode paint_mode,
+ GimpLayerCompositeMode composite_mode);
void gimp_applicator_set_affect (GimpApplicator *applicator,
GimpComponentMask affect);
diff --git a/app/operations/operations-enums.c b/app/operations/operations-enums.c
index 7b4519d..de7adcf 100644
--- a/app/operations/operations-enums.c
+++ b/app/operations/operations-enums.c
@@ -44,8 +44,9 @@ gimp_layer_composite_mode_get_type (void)
{
static const GEnumValue values[] =
{
- { GIMP_LAYER_COMPOSITE_SRC_ATOP, "GIMP_LAYER_COMPOSITE_SRC_ATOP", "src-atop" },
+ { GIMP_LAYER_COMPOSITE_AUTO, "GIMP_LAYER_COMPOSITE_AUTO", "auto" },
{ GIMP_LAYER_COMPOSITE_SRC_OVER, "GIMP_LAYER_COMPOSITE_SRC_OVER", "src-over" },
+ { GIMP_LAYER_COMPOSITE_SRC_ATOP, "GIMP_LAYER_COMPOSITE_SRC_ATOP", "src-atop" },
{ GIMP_LAYER_COMPOSITE_SRC_IN, "GIMP_LAYER_COMPOSITE_SRC_IN", "src-in" },
{ GIMP_LAYER_COMPOSITE_DST_ATOP, "GIMP_LAYER_COMPOSITE_DST_ATOP", "dst-atop" },
{ 0, NULL, NULL }
@@ -53,10 +54,11 @@ gimp_layer_composite_mode_get_type (void)
static const GimpEnumDesc descs[] =
{
- { GIMP_LAYER_COMPOSITE_SRC_ATOP, "GIMP_LAYER_COMPOSITE_SRC_ATOP", NULL },
- { GIMP_LAYER_COMPOSITE_SRC_OVER, "GIMP_LAYER_COMPOSITE_SRC_OVER", NULL },
- { GIMP_LAYER_COMPOSITE_SRC_IN, "GIMP_LAYER_COMPOSITE_SRC_IN", NULL },
- { GIMP_LAYER_COMPOSITE_DST_ATOP, "GIMP_LAYER_COMPOSITE_DST_ATOP", NULL },
+ { GIMP_LAYER_COMPOSITE_AUTO, NC_("layer-composite-mode", "Auto"), NULL },
+ { GIMP_LAYER_COMPOSITE_SRC_OVER, NC_("layer-composite-mode", "Source over"), NULL },
+ { GIMP_LAYER_COMPOSITE_SRC_ATOP, NC_("layer-composite-mode", "Source atop"), NULL },
+ { GIMP_LAYER_COMPOSITE_SRC_IN, NC_("layer-composite-mode", "Source in"), NULL },
+ { GIMP_LAYER_COMPOSITE_DST_ATOP, NC_("layer-composite-mode", "Destination atop"), NULL },
{ 0, NULL, NULL }
};
diff --git a/app/operations/operations-enums.h b/app/operations/operations-enums.h
index 78227ca..be1eb4e 100644
--- a/app/operations/operations-enums.h
+++ b/app/operations/operations-enums.h
@@ -25,7 +25,7 @@
GType gimp_layer_color_space_get_type (void) G_GNUC_CONST;
-typedef enum
+typedef enum /*< pdb-skip >*/
{
GIMP_LAYER_COLOR_SPACE_RGB_LINEAR,
GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL,
@@ -39,10 +39,11 @@ GType gimp_layer_composite_mode_get_type (void) G_GNUC_CONST;
typedef enum
{
- GIMP_LAYER_COMPOSITE_SRC_ATOP,
- GIMP_LAYER_COMPOSITE_SRC_OVER,
- GIMP_LAYER_COMPOSITE_SRC_IN,
- GIMP_LAYER_COMPOSITE_DST_ATOP
+ GIMP_LAYER_COMPOSITE_AUTO, /*< desc="Auto" >*/
+ GIMP_LAYER_COMPOSITE_SRC_OVER, /*< desc="Source over" >*/
+ GIMP_LAYER_COMPOSITE_SRC_ATOP, /*< desc="Source atop" >*/
+ GIMP_LAYER_COMPOSITE_SRC_IN, /*< desc="Source in" >*/
+ GIMP_LAYER_COMPOSITE_DST_ATOP /*< desc="Destination atop" >*/
} GimpLayerCompositeMode;
diff --git a/app/paint/gimppaintcore.c b/app/paint/gimppaintcore.c
index 72b116d..72bc503 100644
--- a/app/paint/gimppaintcore.c
+++ b/app/paint/gimppaintcore.c
@@ -901,7 +901,8 @@ gimp_paint_core_paste (GimpPaintCore *core,
core->paint_buffer_y);
gimp_applicator_set_opacity (core->applicator, image_opacity);
- gimp_applicator_set_mode (core->applicator, paint_mode);
+ gimp_applicator_set_mode (core->applicator, paint_mode,
+ GIMP_LAYER_COMPOSITE_AUTO);
/* apply the paint area to the image */
gimp_applicator_blit (core->applicator,
diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c
index 5379699..ff75522 100644
--- a/app/pdb/internal-procs.c
+++ b/app/pdb/internal-procs.c
@@ -28,7 +28,7 @@
#include "internal-procs.h"
-/* 802 procedures registered total */
+/* 804 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)
diff --git a/app/pdb/layer-cmds.c b/app/pdb/layer-cmds.c
index 4126217..fde14a7 100644
--- a/app/pdb/layer-cmds.c
+++ b/app/pdb/layer-cmds.c
@@ -1150,6 +1150,59 @@ layer_set_mode_invoker (GimpProcedure *procedure,
error ? *error : NULL);
}
+static GimpValueArray *
+layer_get_composite_mode_invoker (GimpProcedure *procedure,
+ Gimp *gimp,
+ GimpContext *context,
+ GimpProgress *progress,
+ const GimpValueArray *args,
+ GError **error)
+{
+ gboolean success = TRUE;
+ GimpValueArray *return_vals;
+ GimpLayer *layer;
+ gint32 composite_mode = 0;
+
+ layer = gimp_value_get_layer (gimp_value_array_index (args, 0), gimp);
+
+ if (success)
+ {
+ composite_mode = gimp_layer_get_composite (layer);
+ }
+
+ return_vals = gimp_procedure_get_return_values (procedure, success,
+ error ? *error : NULL);
+
+ if (success)
+ g_value_set_enum (gimp_value_array_index (return_vals, 1), composite_mode);
+
+ return return_vals;
+}
+
+static GimpValueArray *
+layer_set_composite_mode_invoker (GimpProcedure *procedure,
+ Gimp *gimp,
+ GimpContext *context,
+ GimpProgress *progress,
+ const GimpValueArray *args,
+ GError **error)
+{
+ gboolean success = TRUE;
+ GimpLayer *layer;
+ gint32 composite_mode;
+
+ layer = gimp_value_get_layer (gimp_value_array_index (args, 0), gimp);
+ composite_mode = g_value_get_enum (gimp_value_array_index (args, 1));
+
+ if (success)
+ {
+ gimp_layer_set_composite (layer, composite_mode, TRUE);
+ }
+
+ return gimp_procedure_get_return_values (procedure, success,
+ error ? *error : NULL);
+}
+
void
register_layer_procs (GimpPDB *pdb)
{
@@ -2182,4 +2235,64 @@ register_layer_procs (GimpPDB *pdb)
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
+
+ /*
+ * gimp-layer-get-composite-mode
+ */
+ procedure = gimp_procedure_new (layer_get_composite_mode_invoker);
+ gimp_object_set_static_name (GIMP_OBJECT (procedure),
+ "gimp-layer-get-composite-mode");
+ gimp_procedure_set_static_strings (procedure,
+ "gimp-layer-get-composite-mode",
+ "Get the composite mode of the specified layer.",
+ "This procedure returns the specified layer's composite mode.",
+ "Ell",
+ "Ell",
+ "2017",
+ NULL);
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_layer_id ("layer",
+ "layer",
+ "The layer",
+ pdb->gimp, FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_return_value (procedure,
+ g_param_spec_enum ("composite-mode",
+ "composite mode",
+ "The layer composite mode",
+ GIMP_TYPE_LAYER_COMPOSITE_MODE,
+ GIMP_LAYER_COMPOSITE_AUTO,
+ GIMP_PARAM_READWRITE));
+ gimp_pdb_register_procedure (pdb, procedure);
+ g_object_unref (procedure);
+
+ /*
+ * gimp-layer-set-composite-mode
+ */
+ procedure = gimp_procedure_new (layer_set_composite_mode_invoker);
+ gimp_object_set_static_name (GIMP_OBJECT (procedure),
+ "gimp-layer-set-composite-mode");
+ gimp_procedure_set_static_strings (procedure,
+ "gimp-layer-set-composite-mode",
+ "Set the composite mode of the specified layer.",
+ "This procedure sets the specified layer's composite mode.",
+ "Ell",
+ "Ell",
+ "2017",
+ NULL);
+ gimp_procedure_add_argument (procedure,
+ gimp_param_spec_layer_id ("layer",
+ "layer",
+ "The layer",
+ pdb->gimp, FALSE,
+ GIMP_PARAM_READWRITE));
+ gimp_procedure_add_argument (procedure,
+ g_param_spec_enum ("composite-mode",
+ "composite mode",
+ "The new layer composite mode",
+ GIMP_TYPE_LAYER_COMPOSITE_MODE,
+ GIMP_LAYER_COMPOSITE_AUTO,
+ GIMP_PARAM_READWRITE));
+ gimp_pdb_register_procedure (pdb, procedure);
+ g_object_unref (procedure);
}
diff --git a/app/tools/gimpblendtool.c b/app/tools/gimpblendtool.c
index f219fb9..4bdeaa8 100644
--- a/app/tools/gimpblendtool.c
+++ b/app/tools/gimpblendtool.c
@@ -642,7 +642,8 @@ gimp_blend_tool_options_notify (GimpTool *tool,
! strcmp (pspec->name, "paint-mode"))
{
gimp_drawable_filter_set_mode (blend_tool->filter,
- gimp_context_get_paint_mode (context));
+ gimp_context_get_paint_mode (context),
+ GIMP_LAYER_COMPOSITE_AUTO);
}
}
@@ -1203,7 +1204,8 @@ gimp_blend_tool_create_filter (GimpBlendTool *blend_tool,
gimp_drawable_filter_set_opacity (blend_tool->filter,
gimp_context_get_opacity (context));
gimp_drawable_filter_set_mode (blend_tool->filter,
- gimp_context_get_paint_mode (context));
+ gimp_context_get_paint_mode (context),
+ GIMP_LAYER_COMPOSITE_AUTO);
g_signal_connect (blend_tool->filter, "flush",
G_CALLBACK (gimp_blend_tool_filter_flush),
diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c
index c0523c6..1f95b70 100644
--- a/app/xcf/xcf-load.c
+++ b/app/xcf/xcf-load.c
@@ -1100,6 +1100,17 @@ xcf_load_layer_props (XcfInfo *info,
}
break;
+ case PROP_COMPOSITE:
+ {
+ guint32 composite;
+
+ info->cp += xcf_read_int32 (info->input, &composite, 1);
+
+ gimp_layer_set_composite (*layer,
+ (GimpLayerCompositeMode) composite, FALSE);
+ }
+ break;
+
case PROP_TATTOO:
{
GimpTattoo tattoo;
diff --git a/app/xcf/xcf-private.h b/app/xcf/xcf-private.h
index cc21d48..99e4853 100644
--- a/app/xcf/xcf-private.h
+++ b/app/xcf/xcf-private.h
@@ -59,6 +59,7 @@ typedef enum
PROP_LOCK_POSITION = 32,
PROP_FLOAT_OPACITY = 33,
PROP_COLOR_TAG = 34,
+ PROP_COMPOSITE = 35,
} PropType;
typedef enum
diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c
index c43726d..de445c6 100644
--- a/app/xcf/xcf-save.c
+++ b/app/xcf/xcf-save.c
@@ -534,6 +534,8 @@ xcf_save_layer_props (XcfInfo *info,
offset_x, offset_y));
xcf_check_error (xcf_save_prop (info, image, PROP_MODE, error,
gimp_layer_get_mode (layer)));
+ xcf_check_error (xcf_save_prop (info, image, PROP_COMPOSITE, error,
+ gimp_layer_get_composite (layer)));
xcf_check_error (xcf_save_prop (info, image, PROP_TATTOO, error,
gimp_item_get_tattoo (GIMP_ITEM (layer))));
@@ -735,6 +737,19 @@ xcf_save_prop (XcfInfo *info,
}
break;
+ case PROP_COMPOSITE:
+ {
+ gint32 composite;
+
+ composite = va_arg (args, gint32);
+ size = 4;
+
+ xcf_write_prop_type_check_error (info, prop_type);
+ xcf_write_int32_check_error (info, &size, 1);
+ xcf_write_int32_check_error (info, (guint32 *) &composite, 1);
+ }
+ break;
+
case PROP_VISIBLE:
{
guint32 visible;
diff --git a/libgimp/gimp.def b/libgimp/gimp.def
index 2d7213b..f7eecdb 100644
--- a/libgimp/gimp.def
+++ b/libgimp/gimp.def
@@ -590,11 +590,13 @@ EXPORTS
gimp_item_transform_shear
gimp_layer_add_alpha
gimp_layer_add_mask
+ gimp_layer_composite_mode_get_type
gimp_layer_copy
gimp_layer_create_mask
gimp_layer_flatten
gimp_layer_from_mask
gimp_layer_get_apply_mask
+ gimp_layer_get_composite_mode
gimp_layer_get_edit_mask
gimp_layer_get_lock_alpha
gimp_layer_get_mask
@@ -616,6 +618,7 @@ EXPORTS
gimp_layer_scale
gimp_layer_scale_full
gimp_layer_set_apply_mask
+ gimp_layer_set_composite_mode
gimp_layer_set_edit_mask
gimp_layer_set_lock_alpha
gimp_layer_set_mode
diff --git a/libgimp/gimpenums.c.tail b/libgimp/gimpenums.c.tail
index ee44b28..d81f076 100644
--- a/libgimp/gimpenums.c.tail
+++ b/libgimp/gimpenums.c.tail
@@ -35,6 +35,7 @@ static const GimpGetTypeFunc get_type_funcs[] =
gimp_ink_blob_type_get_type,
gimp_interpolation_type_get_type,
gimp_join_style_get_type,
+ gimp_layer_composite_mode_get_type,
gimp_layer_mode_get_type,
gimp_mask_apply_mode_get_type,
gimp_merge_type_get_type,
@@ -99,6 +100,7 @@ static const gchar * const type_names[] =
"GimpInkBlobType",
"GimpInterpolationType",
"GimpJoinStyle",
+ "GimpLayerCompositeMode",
"GimpLayerMode",
"GimpMaskApplyMode",
"GimpMergeType",
diff --git a/libgimp/gimpenums.h b/libgimp/gimpenums.h
index 65fb76a..b21de2b 100644
--- a/libgimp/gimpenums.h
+++ b/libgimp/gimpenums.h
@@ -63,6 +63,20 @@ typedef enum
} GimpHistogramChannel;
+#define GIMP_TYPE_LAYER_COMPOSITE_MODE (gimp_layer_composite_mode_get_type ())
+
+GType gimp_layer_composite_mode_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_LAYER_COMPOSITE_AUTO,
+ GIMP_LAYER_COMPOSITE_SRC_OVER,
+ GIMP_LAYER_COMPOSITE_SRC_ATOP,
+ GIMP_LAYER_COMPOSITE_SRC_IN,
+ GIMP_LAYER_COMPOSITE_DST_ATOP
+} GimpLayerCompositeMode;
+
+
#define GIMP_TYPE_LAYER_MODE (gimp_layer_mode_get_type ())
GType gimp_layer_mode_get_type (void) G_GNUC_CONST;
diff --git a/libgimp/gimplayer_pdb.c b/libgimp/gimplayer_pdb.c
index dce0dcf..c06c219 100644
--- a/libgimp/gimplayer_pdb.c
+++ b/libgimp/gimplayer_pdb.c
@@ -1152,3 +1152,69 @@ gimp_layer_set_mode (gint32 layer_ID,
return success;
}
+
+/**
+ * gimp_layer_get_composite_mode:
+ * @layer_ID: The layer.
+ *
+ * Get the composite mode of the specified layer.
+ *
+ * This procedure returns the specified layer's composite mode.
+ *
+ * Returns: The layer composite mode.
+ *
+ * Since: 2.10
+ **/
+GimpLayerCompositeMode
+gimp_layer_get_composite_mode (gint32 layer_ID)
+{
+ GimpParam *return_vals;
+ gint nreturn_vals;
+ GimpLayerCompositeMode composite_mode = 0;
+
+ return_vals = gimp_run_procedure ("gimp-layer-get-composite-mode",
+ &nreturn_vals,
+ GIMP_PDB_LAYER, layer_ID,
+ GIMP_PDB_END);
+
+ if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
+ composite_mode = return_vals[1].data.d_int32;
+
+ gimp_destroy_params (return_vals, nreturn_vals);
+
+ return composite_mode;
+}
+
+/**
+ * gimp_layer_set_composite_mode:
+ * @layer_ID: The layer.
+ * @composite_mode: The new layer composite mode.
+ *
+ * Set the composite mode of the specified layer.
+ *
+ * This procedure sets the specified layer's composite mode.
+ *
+ * Returns: TRUE on success.
+ *
+ * Since: 2.10
+ **/
+gboolean
+gimp_layer_set_composite_mode (gint32 layer_ID,
+ GimpLayerCompositeMode composite_mode)
+{
+ GimpParam *return_vals;
+ gint nreturn_vals;
+ gboolean success = TRUE;
+
+ return_vals = gimp_run_procedure ("gimp-layer-set-composite-mode",
+ &nreturn_vals,
+ GIMP_PDB_LAYER, layer_ID,
+ GIMP_PDB_INT32, composite_mode,
+ GIMP_PDB_END);
+
+ success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
+
+ gimp_destroy_params (return_vals, nreturn_vals);
+
+ return success;
+}
diff --git a/libgimp/gimplayer_pdb.h b/libgimp/gimplayer_pdb.h
index d5a8fef..d88b21d 100644
--- a/libgimp/gimplayer_pdb.h
+++ b/libgimp/gimplayer_pdb.h
@@ -32,72 +32,75 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
-G_GNUC_INTERNAL gint32 _gimp_layer_new (gint32 image_ID,
- gint width,
- gint height,
- GimpImageType type,
- const gchar *name,
- gdouble opacity,
- GimpLayerMode mode);
-gint32 gimp_layer_new_from_visible (gint32 image_ID,
- gint32 dest_image_ID,
- const gchar *name);
-gint32 gimp_layer_new_from_drawable (gint32 drawable_ID,
- gint32 dest_image_ID);
-gint32 gimp_layer_group_new (gint32 image_ID);
-G_GNUC_INTERNAL gint32 _gimp_layer_copy (gint32 layer_ID,
- gboolean add_alpha);
-gboolean gimp_layer_add_alpha (gint32 layer_ID);
-gboolean gimp_layer_flatten (gint32 layer_ID);
-gboolean gimp_layer_scale (gint32 layer_ID,
- gint new_width,
- gint new_height,
- gboolean local_origin);
+G_GNUC_INTERNAL gint32 _gimp_layer_new (gint32 image_ID,
+ gint width,
+ gint height,
+ GimpImageType type,
+ const gchar *name,
+ gdouble opacity,
+ GimpLayerMode mode);
+gint32 gimp_layer_new_from_visible (gint32 image_ID,
+ gint32 dest_image_ID,
+ const gchar *name);
+gint32 gimp_layer_new_from_drawable (gint32 drawable_ID,
+ gint32 dest_image_ID);
+gint32 gimp_layer_group_new (gint32 image_ID);
+G_GNUC_INTERNAL gint32 _gimp_layer_copy (gint32 layer_ID,
+ gboolean add_alpha);
+gboolean gimp_layer_add_alpha (gint32 layer_ID);
+gboolean gimp_layer_flatten (gint32 layer_ID);
+gboolean gimp_layer_scale (gint32 layer_ID,
+ gint new_width,
+ gint new_height,
+ gboolean local_origin);
GIMP_DEPRECATED_FOR(gimp_layer_scale)
-gboolean gimp_layer_scale_full (gint32 layer_ID,
- gint new_width,
- gint new_height,
- gboolean local_origin,
- GimpInterpolationType interpolation);
-gboolean gimp_layer_resize (gint32 layer_ID,
- gint new_width,
- gint new_height,
- gint offx,
- gint offy);
-gboolean gimp_layer_resize_to_image_size (gint32 layer_ID);
-gboolean gimp_layer_translate (gint32 layer_ID,
- gint offx,
- gint offy);
-gboolean gimp_layer_set_offsets (gint32 layer_ID,
- gint offx,
- gint offy);
-gint32 gimp_layer_create_mask (gint32 layer_ID,
- GimpAddMaskType mask_type);
-gint32 gimp_layer_get_mask (gint32 layer_ID);
-gint32 gimp_layer_from_mask (gint32 mask_ID);
-gboolean gimp_layer_add_mask (gint32 layer_ID,
- gint32 mask_ID);
-gboolean gimp_layer_remove_mask (gint32 layer_ID,
- GimpMaskApplyMode mode);
-gboolean gimp_layer_is_floating_sel (gint32 layer_ID);
-gboolean gimp_layer_get_lock_alpha (gint32 layer_ID);
-gboolean gimp_layer_set_lock_alpha (gint32 layer_ID,
- gboolean lock_alpha);
-gboolean gimp_layer_get_apply_mask (gint32 layer_ID);
-gboolean gimp_layer_set_apply_mask (gint32 layer_ID,
- gboolean apply_mask);
-gboolean gimp_layer_get_show_mask (gint32 layer_ID);
-gboolean gimp_layer_set_show_mask (gint32 layer_ID,
- gboolean show_mask);
-gboolean gimp_layer_get_edit_mask (gint32 layer_ID);
-gboolean gimp_layer_set_edit_mask (gint32 layer_ID,
- gboolean edit_mask);
-gdouble gimp_layer_get_opacity (gint32 layer_ID);
-gboolean gimp_layer_set_opacity (gint32 layer_ID,
- gdouble opacity);
-GimpLayerMode gimp_layer_get_mode (gint32 layer_ID);
-gboolean gimp_layer_set_mode (gint32 layer_ID,
- GimpLayerMode mode);
+gboolean gimp_layer_scale_full (gint32 layer_ID,
+ gint new_width,
+ gint new_height,
+ gboolean local_origin,
+ GimpInterpolationType interpolation);
+gboolean gimp_layer_resize (gint32 layer_ID,
+ gint new_width,
+ gint new_height,
+ gint offx,
+ gint offy);
+gboolean gimp_layer_resize_to_image_size (gint32 layer_ID);
+gboolean gimp_layer_translate (gint32 layer_ID,
+ gint offx,
+ gint offy);
+gboolean gimp_layer_set_offsets (gint32 layer_ID,
+ gint offx,
+ gint offy);
+gint32 gimp_layer_create_mask (gint32 layer_ID,
+ GimpAddMaskType mask_type);
+gint32 gimp_layer_get_mask (gint32 layer_ID);
+gint32 gimp_layer_from_mask (gint32 mask_ID);
+gboolean gimp_layer_add_mask (gint32 layer_ID,
+ gint32 mask_ID);
+gboolean gimp_layer_remove_mask (gint32 layer_ID,
+ GimpMaskApplyMode mode);
+gboolean gimp_layer_is_floating_sel (gint32 layer_ID);
+gboolean gimp_layer_get_lock_alpha (gint32 layer_ID);
+gboolean gimp_layer_set_lock_alpha (gint32 layer_ID,
+ gboolean lock_alpha);
+gboolean gimp_layer_get_apply_mask (gint32 layer_ID);
+gboolean gimp_layer_set_apply_mask (gint32 layer_ID,
+ gboolean apply_mask);
+gboolean gimp_layer_get_show_mask (gint32 layer_ID);
+gboolean gimp_layer_set_show_mask (gint32 layer_ID,
+ gboolean show_mask);
+gboolean gimp_layer_get_edit_mask (gint32 layer_ID);
+gboolean gimp_layer_set_edit_mask (gint32 layer_ID,
+ gboolean edit_mask);
+gdouble gimp_layer_get_opacity (gint32 layer_ID);
+gboolean gimp_layer_set_opacity (gint32 layer_ID,
+ gdouble opacity);
+GimpLayerMode gimp_layer_get_mode (gint32 layer_ID);
+gboolean gimp_layer_set_mode (gint32 layer_ID,
+ GimpLayerMode mode);
+GimpLayerCompositeMode gimp_layer_get_composite_mode (gint32 layer_ID);
+gboolean gimp_layer_set_composite_mode (gint32 layer_ID,
+ GimpLayerCompositeMode composite_mode);
G_END_DECLS
diff --git a/menus/layers-menu.xml b/menus/layers-menu.xml
index 27d8674..03d28e4 100644
--- a/menus/layers-menu.xml
+++ b/menus/layers-menu.xml
@@ -5,6 +5,13 @@
<popup action="layers-popup">
<menuitem action="layers-text-tool" />
<menuitem action="layers-edit-attributes" />
+ <menu action="layers-composite-menu" name="Composite">
+ <menuitem action="layers-composite-auto" />
+ <menuitem action="layers-composite-src-over" />
+ <menuitem action="layers-composite-src-atop" />
+ <menuitem action="layers-composite-src-in" />
+ <menuitem action="layers-composite-dst-atop" />
+ </menu>
<menu action="layers-color-tag-menu" name="Color Tags">
<menuitem action="layers-color-tag-none" />
<menuitem action="layers-color-tag-blue" />
diff --git a/po/POTFILES.in b/po/POTFILES.in
index be9cad4..75b57f9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -261,6 +261,7 @@ app/file/file-utils.c
app/gegl/gimp-babl.c
app/gegl/gimp-gegl-enums.c
+app/operations/operations-enums.c
app/operations/gimpbrightnesscontrastconfig.c
app/operations/gimpcolorbalanceconfig.c
app/operations/gimpcolorizeconfig.c
diff --git a/tools/pdbgen/Makefile.am b/tools/pdbgen/Makefile.am
index b396303..8940408 100644
--- a/tools/pdbgen/Makefile.am
+++ b/tools/pdbgen/Makefile.am
@@ -76,6 +76,7 @@ EXTRA_DIST = \
enum_headers = \
../../libgimpbase/gimpbaseenums.h \
../../libgimpconfig/gimpconfigenums.h \
+ ../../app/operations/operations-enums.h \
../../app/core/core-enums.h \
../../app/paint/paint-enums.h
diff --git a/tools/pdbgen/enums.pl b/tools/pdbgen/enums.pl
index 35a480b..46a3d20 100644
--- a/tools/pdbgen/enums.pl
+++ b/tools/pdbgen/enums.pl
@@ -669,6 +669,20 @@ package Gimp::CodeGen::enums;
GIMP_COLOR_RENDERING_INTENT_SATURATION => '2',
GIMP_COLOR_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC => '3' }
},
+ GimpLayerCompositeMode =>
+ { contig => 1,
+ header => 'operations/operations-enums.h',
+ symbols => [ qw(GIMP_LAYER_COMPOSITE_AUTO
+ GIMP_LAYER_COMPOSITE_SRC_OVER
+ GIMP_LAYER_COMPOSITE_SRC_ATOP
+ GIMP_LAYER_COMPOSITE_SRC_IN
+ GIMP_LAYER_COMPOSITE_DST_ATOP) ],
+ mapping => { GIMP_LAYER_COMPOSITE_AUTO => '0',
+ GIMP_LAYER_COMPOSITE_SRC_OVER => '1',
+ GIMP_LAYER_COMPOSITE_SRC_ATOP => '2',
+ GIMP_LAYER_COMPOSITE_SRC_IN => '3',
+ GIMP_LAYER_COMPOSITE_DST_ATOP => '4' }
+ },
GimpConvertDitherType =>
{ contig => 1,
header => 'core/core-enums.h',
diff --git a/tools/pdbgen/pdb/layer.pdb b/tools/pdbgen/pdb/layer.pdb
index a4d19c0..e259605 100644
--- a/tools/pdbgen/pdb/layer.pdb
+++ b/tools/pdbgen/pdb/layer.pdb
@@ -1198,6 +1198,53 @@ CODE
);
}
+sub layer_get_composite_mode {
+ $blurb = 'Get the composite mode of the specified layer.';
+ $help = "This procedure returns the specified layer's composite mode.";
+
+ &ell_pdb_misc('2017', '2.10');
+
+ @inargs = (
+ { name => 'layer', type => 'layer',
+ desc => 'The layer' }
+ );
+
+ @outargs = (
+ { name => 'composite_mode', type => 'enum GimpLayerCompositeMode',
+ desc => 'The layer composite mode' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ composite_mode = gimp_layer_get_composite (layer);
+}
+CODE
+ );
+}
+
+sub layer_set_composite_mode {
+ $blurb = 'Set the composite mode of the specified layer.';
+ $help = "This procedure sets the specified layer's composite mode.";
+
+ &ell_pdb_misc('2017', '2.10');
+
+ @inargs = (
+ { name => 'layer', type => 'layer',
+ desc => 'The layer' },
+ { name => 'composite_mode', type => 'enum GimpLayerCompositeMode',
+ desc => 'The new layer composite mode' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ gimp_layer_set_composite (layer, composite_mode, TRUE);
+}
+CODE
+ );
+}
+
@headers = qw(<cairo.h>
"libgimpbase/gimpbase.h"
"libgimpcolor/gimpcolor.h"
@@ -1234,7 +1281,8 @@ CODE
layer_get_show_mask layer_set_show_mask
layer_get_edit_mask layer_set_edit_mask
layer_get_opacity layer_set_opacity
- layer_get_mode layer_set_mode);
+ layer_get_mode layer_set_mode
+ layer_get_composite_mode layer_set_composite_mode);
%exports = (app => [@procs], lib => [@procs]);
diff --git a/tools/pdbgen/stddefs.pdb b/tools/pdbgen/stddefs.pdb
index c73bb67..e4e3cb7 100644
--- a/tools/pdbgen/stddefs.pdb
+++ b/tools/pdbgen/stddefs.pdb
@@ -77,6 +77,10 @@ sub ejs_pdb_misc {
contrib_pdb_misc('Ed Swartz', '', @_);
}
+sub ell_pdb_misc {
+ contrib_pdb_misc('Ell', '', @_);
+}
+
sub federico_pdb_misc {
contrib_pdb_misc('Federico Mena Quintero', '', @_);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]