diff --git a/app/core/gimpdrawablefilter.c b/app/core/gimpdrawablefilter.c index e6f3a0f4a7..c02b81ba8e 100644 --- a/app/core/gimpdrawablefilter.c +++ b/app/core/gimpdrawablefilter.c @@ -734,12 +734,15 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter, GimpLayerColorSpace blend_space, GimpLayerColorSpace composite_space, GimpLayerCompositeMode composite_mode, + const gchar **auxinputnames, + const GimpDrawable **auxinputs, GError **error) { GParamSpec **pspecs; gchar *opname; guint n_pspecs; gint n_values; + gint n_auxinputs; gboolean changed = FALSE; g_return_val_if_fail (GIMP_IS_DRAWABLE_FILTER (filter), FALSE); @@ -755,6 +758,18 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter, return FALSE; } + n_auxinputs = 0; + while (auxinputs[n_auxinputs] != NULL) + n_auxinputs++; + + if (n_auxinputs != g_strv_length ((gchar **) auxinputnames)) + { + g_set_error (error, GIMP_ERROR, GIMP_FAILED, + "%s: the number of aux input names and aux inputs differ.", + G_STRFUNC); + return FALSE; + } + g_object_freeze_notify (G_OBJECT (filter)); gegl_node_get (filter->operation, "operation", &opname, NULL); @@ -881,6 +896,36 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter, changed = TRUE; } + if (*error == NULL) + { + for (gint i = 0; auxinputnames[i]; i++) + { + GeglNode *src_node; + GeglBuffer *buffer; + + if (! gegl_node_has_pad (filter->operation, auxinputnames[i])) + { + g_set_error (error, GIMP_ERROR, GIMP_FAILED, + /* TODO: localize after string freeze. */ + "GEGL operation '%s' has been called with an " + "invalid aux input name '%s'.", + opname, auxinputnames[i]); + break; + } + + + buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (auxinputs[i])); + g_object_ref (buffer); + src_node = gegl_node_new_child (gegl_node_get_parent (filter->operation), + "operation", "gegl:buffer-source", + "buffer", buffer, + NULL); + g_object_unref (buffer); + + gegl_node_connect (src_node, "output", filter->operation, auxinputnames[i]); + } + } + g_object_thaw_notify (G_OBJECT (filter)); g_free (pspecs); diff --git a/app/core/gimpdrawablefilter.h b/app/core/gimpdrawablefilter.h index 64e2583755..921561a604 100644 --- a/app/core/gimpdrawablefilter.h +++ b/app/core/gimpdrawablefilter.h @@ -107,6 +107,8 @@ gboolean gimp_drawable_filter_update (GimpDrawableFilter *filter, GimpLayerColorSpace blend_space, GimpLayerColorSpace composite_space, GimpLayerCompositeMode composite_mode, + const gchar **auxinputnames, + const GimpDrawable **auxinputs, GError **error); void gimp_drawable_filter_set_opacity (GimpDrawableFilter *filter, gdouble opacity); diff --git a/app/pdb/drawable-filter-cmds.c b/app/pdb/drawable-filter-cmds.c index ce064c8f37..1ca6618331 100644 --- a/app/pdb/drawable-filter-cmds.c +++ b/app/pdb/drawable-filter-cmds.c @@ -349,6 +349,8 @@ drawable_filter_update_invoker (GimpProcedure *procedure, gint blend_space; gint composite_mode; gint composite_space; + const gchar **auxinputnames; + const GimpDrawable **auxinputs; filter = g_value_get_object (gimp_value_array_index (args, 0)); propnames = g_value_get_boxed (gimp_value_array_index (args, 1)); @@ -358,6 +360,8 @@ drawable_filter_update_invoker (GimpProcedure *procedure, blend_space = g_value_get_enum (gimp_value_array_index (args, 5)); composite_mode = g_value_get_enum (gimp_value_array_index (args, 6)); composite_space = g_value_get_enum (gimp_value_array_index (args, 7)); + auxinputnames = g_value_get_boxed (gimp_value_array_index (args, 8)); + auxinputs = g_value_get_boxed (gimp_value_array_index (args, 9)); if (success) { @@ -365,6 +369,7 @@ drawable_filter_update_invoker (GimpProcedure *procedure, opacity, blend_mode, blend_space, composite_mode, composite_space, + auxinputnames, auxinputs, error); } @@ -922,6 +927,18 @@ register_drawable_filter_procs (GimpPDB *pdb) GIMP_TYPE_LAYER_COLOR_SPACE, GIMP_LAYER_COLOR_SPACE_AUTO, GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + g_param_spec_boxed ("auxinputnames", + "auxinputnames", + "Array of aux input pads", + G_TYPE_STRV, + GIMP_PARAM_READWRITE)); + gimp_procedure_add_argument (procedure, + gimp_param_spec_core_object_array ("auxinputs", + "auxinputs", + "Array of drawables, one per auxinputnames", + GIMP_TYPE_DRAWABLE, + GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE)); gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); diff --git a/libgimp/gimp.def b/libgimp/gimp.def index 387572d44c..9dbbc5bcf4 100644 --- a/libgimp/gimp.def +++ b/libgimp/gimp.def @@ -227,6 +227,7 @@ EXPORTS gimp_drawable_filter_id_is_valid gimp_drawable_filter_is_valid gimp_drawable_filter_new + gimp_drawable_filter_set_aux_input gimp_drawable_filter_set_blend_mode gimp_drawable_filter_set_opacity gimp_drawable_filter_set_visible diff --git a/libgimp/gimpdrawablefilter.c b/libgimp/gimpdrawablefilter.c index 7c090714e9..37216a6226 100644 --- a/libgimp/gimpdrawablefilter.c +++ b/libgimp/gimpdrawablefilter.c @@ -46,6 +46,8 @@ struct _GimpDrawableFilter GimpLayerCompositeMode composite_mode; GimpLayerColorSpace composite_space; + GHashTable *pad_inputs; + GimpDrawableFilterConfig *config; }; @@ -98,6 +100,8 @@ gimp_drawable_filter_init (GimpDrawableFilter *drawable_filter) drawable_filter->blend_space = GIMP_LAYER_COLOR_SPACE_AUTO; drawable_filter->composite_mode = GIMP_LAYER_COMPOSITE_AUTO; drawable_filter->composite_space = GIMP_LAYER_COLOR_SPACE_AUTO; + + drawable_filter->pad_inputs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); } static void @@ -106,6 +110,7 @@ gimp_drawable_filter_finalize (GObject *object) GimpDrawableFilter *filter = GIMP_DRAWABLE_FILTER (object); g_clear_object (&filter->config); + g_hash_table_unref (filter->pad_inputs); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -254,6 +259,31 @@ gimp_drawable_filter_set_blend_mode (GimpDrawableFilter *filter, filter->blend_mode = mode; } +/** + * gimp_drawable_filter_set_aux_input: + * @filter: The drawable's filter. + * @input_pad_name: name of the filter's input pad. + * @input: the drawable to use as auxiliary input. + * + * When a filter has one or several auxiliary inputs, you can use this + * function to set them. + * + * The change is not synced immediately with the core application. + * Use [method@Gimp.Drawable.update] to trigger an actual update. + * + * Since: 3.0 + **/ +void +gimp_drawable_filter_set_aux_input (GimpDrawableFilter *filter, + const gchar *input_pad_name, + GimpDrawable *input) +{ + g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter)); + g_return_if_fail (GIMP_IS_DRAWABLE (input)); + + g_hash_table_insert (filter->pad_inputs, (gpointer) g_strdup (input_pad_name), input); +} + /** * gimp_drawable_filter_get_config: * @filter: A drawable filter. @@ -349,9 +379,12 @@ gimp_drawable_filter_get_config (GimpDrawableFilter *filter) void gimp_drawable_filter_update (GimpDrawableFilter *filter) { - GStrvBuilder *builder = g_strv_builder_new (); - GimpValueArray *values = NULL; - GStrv propnames; + GStrvBuilder *builder = g_strv_builder_new (); + GimpValueArray *values = NULL; + GStrv propnames; + GStrv auxnames; + const GimpDrawable **auxinputs; + guint n_aux; if (filter->config) { @@ -387,12 +420,20 @@ gimp_drawable_filter_update (GimpDrawableFilter *filter) } propnames = g_strv_builder_end (builder); + auxnames = (GStrv) g_hash_table_get_keys_as_array (filter->pad_inputs, &n_aux); + auxinputs = g_new0 (const GimpDrawable *, n_aux + 1); + for (guint i = 0; auxnames[i]; i++) + auxinputs[i] = g_hash_table_lookup (filter->pad_inputs, auxnames[i]); + _gimp_drawable_filter_update (filter, (const gchar **) propnames, values, filter->opacity, filter->blend_mode, filter->blend_space, - filter->composite_mode, filter->composite_space); + filter->composite_mode, filter->composite_space, + (const gchar **) auxnames, auxinputs); g_strfreev (propnames); g_strv_builder_unref (builder); gimp_value_array_unref (values); + g_free (auxnames); + g_free (auxinputs); } diff --git a/libgimp/gimpdrawablefilter.h b/libgimp/gimpdrawablefilter.h index edf52061a9..8535f3c1ca 100644 --- a/libgimp/gimpdrawablefilter.h +++ b/libgimp/gimpdrawablefilter.h @@ -45,6 +45,9 @@ void gimp_drawable_filter_set_opacity (GimpDrawabl gdouble opacity); void gimp_drawable_filter_set_blend_mode (GimpDrawableFilter *filter, GimpLayerMode mode); +void gimp_drawable_filter_set_aux_input (GimpDrawableFilter *filter, + const gchar *input_pad_name, + GimpDrawable *input); GimpDrawableFilterConfig * gimp_drawable_filter_get_config (GimpDrawableFilter *filter); diff --git a/libgimp/gimpdrawablefilter_pdb.c b/libgimp/gimpdrawablefilter_pdb.c index c86dd81f6e..4050dcf0d3 100644 --- a/libgimp/gimpdrawablefilter_pdb.c +++ b/libgimp/gimpdrawablefilter_pdb.c @@ -357,6 +357,8 @@ gimp_drawable_filter_get_blend_mode (GimpDrawableFilter *filter) * @blend_space: The effect blending space. * @composite_mode: The layer composite mode. * @composite_space: The effect composite space. + * @auxinputnames: (array zero-terminated=1): Array of aux input pads. + * @auxinputs: (element-type GimpDrawable) (array zero-terminated=1): Array of drawables, one per auxinputnames. * * Update the settings of the specified filter. * @@ -379,7 +381,9 @@ _gimp_drawable_filter_update (GimpDrawableFilter *filter, GimpLayerMode blend_mode, GimpLayerColorSpace blend_space, GimpLayerCompositeMode composite_mode, - GimpLayerColorSpace composite_space) + GimpLayerColorSpace composite_space, + const gchar **auxinputnames, + const GimpDrawable **auxinputs) { GimpValueArray *args; GimpValueArray *return_vals; @@ -394,6 +398,8 @@ _gimp_drawable_filter_update (GimpDrawableFilter *filter, GIMP_TYPE_LAYER_COLOR_SPACE, blend_space, GIMP_TYPE_LAYER_COMPOSITE_MODE, composite_mode, GIMP_TYPE_LAYER_COLOR_SPACE, composite_space, + G_TYPE_STRV, auxinputnames, + GIMP_TYPE_CORE_OBJECT_ARRAY, auxinputs, G_TYPE_NONE); return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), diff --git a/libgimp/gimpdrawablefilter_pdb.h b/libgimp/gimpdrawablefilter_pdb.h index 1e79c80d1e..07a79f2b7f 100644 --- a/libgimp/gimpdrawablefilter_pdb.h +++ b/libgimp/gimpdrawablefilter_pdb.h @@ -50,7 +50,9 @@ G_GNUC_INTERNAL gboolean _gimp_drawable_filter_update (GimpDraw GimpLayerMode blend_mode, GimpLayerColorSpace blend_space, GimpLayerCompositeMode composite_mode, - GimpLayerColorSpace composite_space); + GimpLayerColorSpace composite_space, + const gchar **auxinputnames, + const GimpDrawable **auxinputs); G_GNUC_INTERNAL gint _gimp_drawable_filter_get_number_arguments (const gchar *operation_name); G_GNUC_INTERNAL GParamSpec* _gimp_drawable_filter_get_pspec (const gchar *operation_name, gint arg_num); diff --git a/pdb/groups/drawable_filter.pdb b/pdb/groups/drawable_filter.pdb index 0e1152110d..28e00d2d30 100644 --- a/pdb/groups/drawable_filter.pdb +++ b/pdb/groups/drawable_filter.pdb @@ -336,6 +336,10 @@ HELP { name => 'composite_space', type => 'enum GimpLayerColorSpace', default => 'GIMP_LAYER_COLOR_SPACE_AUTO', desc => 'The effect composite space' }, + { name => 'auxinputnames', type => 'strv', + desc => 'Array of aux input pads' }, + { name => 'auxinputs', type => 'drawablearray', no_validate => 1, + desc => 'Array of drawables, one per auxinputnames' }, ); %invoke = ( @@ -345,6 +349,7 @@ HELP opacity, blend_mode, blend_space, composite_mode, composite_space, + auxinputnames, auxinputs, error); } CODE