From a6392ed84aaef863000c399b06204c63c57db1f8 Mon Sep 17 00:00:00 2001 From: Jehan Date: Mon, 16 Dec 2024 23:11:06 +0100 Subject: [PATCH] app, libgimp, pdb, plug-ins: add a few Script-fu wrapper of libgimp filter API. In particular (gimp-drawable-filter-configure), (gimp-drawable-merge-filter) and (gimp-drawable-append-filter) are proper Script-fu methods. I had to rename the PDB procedures for the 2 latter because they were clashing with these wrapper. I had not realized that private PDB procedures are still visible by Script-fu. This is not so glop. :-/ Right now, it doesn't look so useful compared to the -new- one-liner variant procedures. But it will make sense when I will add aux input C procedure wrappers. --- app/pdb/drawable-cmds.c | 42 +- libgimp/gimpdrawable.c | 4 +- libgimp/gimpdrawable_pdb.c | 20 +- libgimp/gimpdrawable_pdb.h | 148 +++---- pdb/groups/drawable.pdb | 14 +- .../script-fu/libscriptfu/scheme-wrapper.c | 383 +++++++++++++----- 6 files changed, 392 insertions(+), 219 deletions(-) diff --git a/app/pdb/drawable-cmds.c b/app/pdb/drawable-cmds.c index a86ea8f487..322f6444ea 100644 --- a/app/pdb/drawable-cmds.c +++ b/app/pdb/drawable-cmds.c @@ -605,12 +605,12 @@ drawable_mask_intersect_invoker (GimpProcedure *procedure, } static GimpValueArray * -drawable_append_filter_invoker (GimpProcedure *procedure, - Gimp *gimp, - GimpContext *context, - GimpProgress *progress, - const GimpValueArray *args, - GError **error) +drawable_append_filter_private_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) { gboolean success = TRUE; GimpDrawable *drawable; @@ -666,12 +666,12 @@ drawable_append_filter_invoker (GimpProcedure *procedure, } static GimpValueArray * -drawable_merge_filter_invoker (GimpProcedure *procedure, - Gimp *gimp, - GimpContext *context, - GimpProgress *progress, - const GimpValueArray *args, - GError **error) +drawable_merge_filter_private_invoker (GimpProcedure *procedure, + Gimp *gimp, + GimpContext *context, + GimpProgress *progress, + const GimpValueArray *args, + GError **error) { gboolean success = TRUE; GimpDrawable *drawable; @@ -1711,16 +1711,17 @@ register_drawable_procs (GimpPDB *pdb) g_object_unref (procedure); /* - * gimp-drawable-append-filter + * gimp-drawable-append-filter-private */ - procedure = gimp_procedure_new (drawable_append_filter_invoker); + procedure = gimp_procedure_new (drawable_append_filter_private_invoker); gimp_object_set_static_name (GIMP_OBJECT (procedure), - "gimp-drawable-append-filter"); + "gimp-drawable-append-filter-private"); gimp_procedure_set_static_help (procedure, "Append the specified effect to the top of the list of drawable effects.", "This procedure adds the specified drawable effect at the top of the effect list of @drawable.\n" "The @drawable argument must be the same as the one used when you created the effect with [ctor@Gimp.DrawableFilter.new].\n" - "Some effects may be slower than others to render. In order to minimize processing time, it is preferred to customize the operation's arguments as received with [method@Gimp.DrawableFilter.get_config] then sync them to the application with [method@Gimp.DrawableFilter.update] before adding the effect.", + "Some effects may be slower than others to render. In order to minimize processing time, it is preferred to customize the operation's arguments as received with [method@Gimp.DrawableFilter.get_config] then sync them to the application with [method@Gimp.DrawableFilter.update] before adding the effect.\n" + "This function is private and should not be used. Use [method@Gimp.Drawable.append_filter] instead.", NULL); gimp_procedure_set_static_attribution (procedure, "Jehan", @@ -1742,16 +1743,17 @@ register_drawable_procs (GimpPDB *pdb) g_object_unref (procedure); /* - * gimp-drawable-merge-filter + * gimp-drawable-merge-filter-private */ - procedure = gimp_procedure_new (drawable_merge_filter_invoker); + procedure = gimp_procedure_new (drawable_merge_filter_private_invoker); gimp_object_set_static_name (GIMP_OBJECT (procedure), - "gimp-drawable-merge-filter"); + "gimp-drawable-merge-filter-private"); gimp_procedure_set_static_help (procedure, "Apply the specified effect directly to the drawable.", "This procedure applies the specified drawable effect on @drawable and merge it (therefore before non-destructive effects are computed).\n" "The @drawable argument must be the same as the one used when you created the effect with [ctor@Gimp.DrawableFilter.new].\n" - "Once this is run, @filter is not valid anymore and you should not try to do anything with it. In particular, you must customize the operation's arguments as received with [method@Gimp.DrawableFilter.get_config] then sync them to the application with [method@Gimp.DrawableFilter.update] before merging the effect.", + "Once this is run, @filter is not valid anymore and you should not try to do anything with it. In particular, you must customize the operation's arguments as received with [method@Gimp.DrawableFilter.get_config] then sync them to the application with [method@Gimp.DrawableFilter.update] before merging the effect.\n" + "This function is private and should not be used. Use [method@Gimp.Drawable.merge_filter] instead.", NULL); gimp_procedure_set_static_attribution (procedure, "Jehan", diff --git a/libgimp/gimpdrawable.c b/libgimp/gimpdrawable.c index 284cc08c49..01e97f5c35 100644 --- a/libgimp/gimpdrawable.c +++ b/libgimp/gimpdrawable.c @@ -461,7 +461,7 @@ gimp_drawable_append_filter (GimpDrawable *drawable, g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter)); gimp_drawable_filter_update (filter); - _gimp_drawable_append_filter (drawable, filter); + _gimp_drawable_append_filter_private (drawable, filter); } /** @@ -491,7 +491,7 @@ gimp_drawable_merge_filter (GimpDrawable *drawable, g_return_if_fail (GIMP_IS_DRAWABLE_FILTER (filter)); gimp_drawable_filter_update (filter); - _gimp_drawable_merge_filter (drawable, filter); + _gimp_drawable_merge_filter_private (drawable, filter); } /** diff --git a/libgimp/gimpdrawable_pdb.c b/libgimp/gimpdrawable_pdb.c index 17c19441e3..81268ab626 100644 --- a/libgimp/gimpdrawable_pdb.c +++ b/libgimp/gimpdrawable_pdb.c @@ -677,7 +677,7 @@ gimp_drawable_mask_intersect (GimpDrawable *drawable, } /** - * _gimp_drawable_append_filter: + * _gimp_drawable_append_filter_private: * @drawable: The drawable. * @filter: The drawable filter to append. * @@ -694,14 +694,16 @@ gimp_drawable_mask_intersect (GimpDrawable *drawable, * [method@Gimp.DrawableFilter.get_config] then sync them to the * application with [method@Gimp.DrawableFilter.update] before adding * the effect. + * This function is private and should not be used. Use + * [method@Gimp.Drawable.append_filter] instead. * * Returns: TRUE on success. * * Since: 3.0 **/ gboolean -_gimp_drawable_append_filter (GimpDrawable *drawable, - GimpDrawableFilter *filter) +_gimp_drawable_append_filter_private (GimpDrawable *drawable, + GimpDrawableFilter *filter) { GimpValueArray *args; GimpValueArray *return_vals; @@ -713,7 +715,7 @@ _gimp_drawable_append_filter (GimpDrawable *drawable, G_TYPE_NONE); return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), - "gimp-drawable-append-filter", + "gimp-drawable-append-filter-private", args); gimp_value_array_unref (args); @@ -725,7 +727,7 @@ _gimp_drawable_append_filter (GimpDrawable *drawable, } /** - * _gimp_drawable_merge_filter: + * _gimp_drawable_merge_filter_private: * @drawable: The drawable. * @filter: The drawable filter to merge. * @@ -742,14 +744,16 @@ _gimp_drawable_append_filter (GimpDrawable *drawable, * [method@Gimp.DrawableFilter.get_config] then sync them to the * application with [method@Gimp.DrawableFilter.update] before merging * the effect. + * This function is private and should not be used. Use + * [method@Gimp.Drawable.merge_filter] instead. * * Returns: TRUE on success. * * Since: 3.0 **/ gboolean -_gimp_drawable_merge_filter (GimpDrawable *drawable, - GimpDrawableFilter *filter) +_gimp_drawable_merge_filter_private (GimpDrawable *drawable, + GimpDrawableFilter *filter) { GimpValueArray *args; GimpValueArray *return_vals; @@ -761,7 +765,7 @@ _gimp_drawable_merge_filter (GimpDrawable *drawable, G_TYPE_NONE); return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), - "gimp-drawable-merge-filter", + "gimp-drawable-merge-filter-private", args); gimp_value_array_unref (args); diff --git a/libgimp/gimpdrawable_pdb.h b/libgimp/gimpdrawable_pdb.h index 396fbe82b5..37cabd6ff1 100644 --- a/libgimp/gimpdrawable_pdb.h +++ b/libgimp/gimpdrawable_pdb.h @@ -32,80 +32,80 @@ G_BEGIN_DECLS /* For information look into the C source or the html documentation */ -G_GNUC_INTERNAL gchar* _gimp_drawable_get_format (GimpDrawable *drawable); -G_GNUC_INTERNAL gchar* _gimp_drawable_get_thumbnail_format (GimpDrawable *drawable); -GeglColor* gimp_drawable_get_pixel (GimpDrawable *drawable, - gint x_coord, - gint y_coord); -gboolean gimp_drawable_set_pixel (GimpDrawable *drawable, - gint x_coord, - gint y_coord, - GeglColor *color); -GimpImageType gimp_drawable_type (GimpDrawable *drawable); -GimpImageType gimp_drawable_type_with_alpha (GimpDrawable *drawable); -gboolean gimp_drawable_has_alpha (GimpDrawable *drawable); -gboolean gimp_drawable_is_rgb (GimpDrawable *drawable); -gboolean gimp_drawable_is_gray (GimpDrawable *drawable); -gboolean gimp_drawable_is_indexed (GimpDrawable *drawable); -gint gimp_drawable_get_bpp (GimpDrawable *drawable); -gint gimp_drawable_get_width (GimpDrawable *drawable); -gint gimp_drawable_get_height (GimpDrawable *drawable); -gboolean gimp_drawable_get_offsets (GimpDrawable *drawable, - gint *offset_x, - gint *offset_y); -gboolean gimp_drawable_mask_bounds (GimpDrawable *drawable, - gint *x1, - gint *y1, - gint *x2, - gint *y2); -gboolean gimp_drawable_mask_intersect (GimpDrawable *drawable, - gint *x, - gint *y, - gint *width, - gint *height); -G_GNUC_INTERNAL gboolean _gimp_drawable_append_filter (GimpDrawable *drawable, - GimpDrawableFilter *filter); -G_GNUC_INTERNAL gboolean _gimp_drawable_merge_filter (GimpDrawable *drawable, - GimpDrawableFilter *filter); -GimpDrawableFilter** gimp_drawable_get_filters (GimpDrawable *drawable); -gboolean gimp_drawable_merge_filters (GimpDrawable *drawable); -gboolean gimp_drawable_merge_shadow (GimpDrawable *drawable, - gboolean undo); -gboolean gimp_drawable_free_shadow (GimpDrawable *drawable); -gboolean gimp_drawable_update (GimpDrawable *drawable, - gint x, - gint y, - gint width, - gint height); -gboolean gimp_drawable_fill (GimpDrawable *drawable, - GimpFillType fill_type); -gboolean gimp_drawable_offset (GimpDrawable *drawable, - gboolean wrap_around, - GimpOffsetType fill_type, - GeglColor *color, - gint offset_x, - gint offset_y); -G_GNUC_INTERNAL gboolean _gimp_drawable_thumbnail (GimpDrawable *drawable, - gint width, - gint height, - gint *actual_width, - gint *actual_height, - gint *bpp, - GBytes **thumbnail_data); -G_GNUC_INTERNAL gboolean _gimp_drawable_sub_thumbnail (GimpDrawable *drawable, - gint src_x, - gint src_y, - gint src_width, - gint src_height, - gint dest_width, - gint dest_height, - gint *width, - gint *height, - gint *bpp, - GBytes **thumbnail_data); -gboolean gimp_drawable_foreground_extract (GimpDrawable *drawable, - GimpForegroundExtractMode mode, - GimpDrawable *mask); +G_GNUC_INTERNAL gchar* _gimp_drawable_get_format (GimpDrawable *drawable); +G_GNUC_INTERNAL gchar* _gimp_drawable_get_thumbnail_format (GimpDrawable *drawable); +GeglColor* gimp_drawable_get_pixel (GimpDrawable *drawable, + gint x_coord, + gint y_coord); +gboolean gimp_drawable_set_pixel (GimpDrawable *drawable, + gint x_coord, + gint y_coord, + GeglColor *color); +GimpImageType gimp_drawable_type (GimpDrawable *drawable); +GimpImageType gimp_drawable_type_with_alpha (GimpDrawable *drawable); +gboolean gimp_drawable_has_alpha (GimpDrawable *drawable); +gboolean gimp_drawable_is_rgb (GimpDrawable *drawable); +gboolean gimp_drawable_is_gray (GimpDrawable *drawable); +gboolean gimp_drawable_is_indexed (GimpDrawable *drawable); +gint gimp_drawable_get_bpp (GimpDrawable *drawable); +gint gimp_drawable_get_width (GimpDrawable *drawable); +gint gimp_drawable_get_height (GimpDrawable *drawable); +gboolean gimp_drawable_get_offsets (GimpDrawable *drawable, + gint *offset_x, + gint *offset_y); +gboolean gimp_drawable_mask_bounds (GimpDrawable *drawable, + gint *x1, + gint *y1, + gint *x2, + gint *y2); +gboolean gimp_drawable_mask_intersect (GimpDrawable *drawable, + gint *x, + gint *y, + gint *width, + gint *height); +G_GNUC_INTERNAL gboolean _gimp_drawable_append_filter_private (GimpDrawable *drawable, + GimpDrawableFilter *filter); +G_GNUC_INTERNAL gboolean _gimp_drawable_merge_filter_private (GimpDrawable *drawable, + GimpDrawableFilter *filter); +GimpDrawableFilter** gimp_drawable_get_filters (GimpDrawable *drawable); +gboolean gimp_drawable_merge_filters (GimpDrawable *drawable); +gboolean gimp_drawable_merge_shadow (GimpDrawable *drawable, + gboolean undo); +gboolean gimp_drawable_free_shadow (GimpDrawable *drawable); +gboolean gimp_drawable_update (GimpDrawable *drawable, + gint x, + gint y, + gint width, + gint height); +gboolean gimp_drawable_fill (GimpDrawable *drawable, + GimpFillType fill_type); +gboolean gimp_drawable_offset (GimpDrawable *drawable, + gboolean wrap_around, + GimpOffsetType fill_type, + GeglColor *color, + gint offset_x, + gint offset_y); +G_GNUC_INTERNAL gboolean _gimp_drawable_thumbnail (GimpDrawable *drawable, + gint width, + gint height, + gint *actual_width, + gint *actual_height, + gint *bpp, + GBytes **thumbnail_data); +G_GNUC_INTERNAL gboolean _gimp_drawable_sub_thumbnail (GimpDrawable *drawable, + gint src_x, + gint src_y, + gint src_width, + gint src_height, + gint dest_width, + gint dest_height, + gint *width, + gint *height, + gint *bpp, + GBytes **thumbnail_data); +gboolean gimp_drawable_foreground_extract (GimpDrawable *drawable, + GimpForegroundExtractMode mode, + GimpDrawable *mask); G_END_DECLS diff --git a/pdb/groups/drawable.pdb b/pdb/groups/drawable.pdb index d0fbacdb30..e3dcf49bd6 100644 --- a/pdb/groups/drawable.pdb +++ b/pdb/groups/drawable.pdb @@ -111,7 +111,7 @@ CODE ); } -sub drawable_append_filter { +sub drawable_append_filter_private { $blurb = 'Append the specified effect to the top of the list of drawable effects.'; $help = <<'HELP'; @@ -125,6 +125,9 @@ processing time, it is preferred to customize the operation's arguments as received with [method@Gimp.DrawableFilter.get_config] then sync them to the application with [method@Gimp.DrawableFilter.update] before adding the effect. + +This function is private and should not be used. Use +[method@Gimp.Drawable.append_filter] instead. HELP &jehan_pdb_misc('2024', '3.0'); @@ -182,7 +185,7 @@ HELP CODE } -sub drawable_merge_filter { +sub drawable_merge_filter_private { $blurb = 'Apply the specified effect directly to the drawable.'; $help = <<'HELP'; @@ -197,6 +200,9 @@ do anything with it. In particular, you must customize the operation's arguments as received with [method@Gimp.DrawableFilter.get_config] then sync them to the application with [method@Gimp.DrawableFilter.update] before merging the effect. + +This function is private and should not be used. Use +[method@Gimp.Drawable.merge_filter] instead. HELP &jehan_pdb_misc('2024', '3.0'); @@ -1225,8 +1231,8 @@ CODE drawable_get_offsets drawable_mask_bounds drawable_mask_intersect - drawable_append_filter - drawable_merge_filter + drawable_append_filter_private + drawable_merge_filter_private drawable_get_filters drawable_merge_filters drawable_merge_shadow diff --git a/plug-ins/script-fu/libscriptfu/scheme-wrapper.c b/plug-ins/script-fu/libscriptfu/scheme-wrapper.c index f0b9adafd4..f7ba0a715c 100644 --- a/plug-ins/script-fu/libscriptfu/scheme-wrapper.c +++ b/plug-ins/script-fu/libscriptfu/scheme-wrapper.c @@ -53,65 +53,71 @@ #undef cons -static void ts_init_constants (scheme *sc, - GIRepository *repo); -static void ts_init_enums (scheme *sc, - GIRepository *repo, - const char *namespace); -static void ts_define_procedure (scheme *sc, - const gchar *symbol_name, - TsWrapperFunc func); -static void ts_init_procedures (scheme *sc, - gboolean register_scipts); -static void ts_load_init_and_compatibility_scripts (GList *paths); +static void ts_init_constants (scheme *sc, + GIRepository *repo); +static void ts_init_enums (scheme *sc, + GIRepository *repo, + const char *namespace); +static void ts_define_procedure (scheme *sc, + const gchar *symbol_name, + TsWrapperFunc func); +static void ts_init_procedures (scheme *sc, + gboolean register_scipts); +static void ts_load_init_and_compatibility_scripts (GList *paths); -static pointer script_fu_marshal_arg_to_value (scheme *sc, - pointer a, - const gchar *proc_name, - gint arg_index, - GParamSpec *arg_spec, - GValue *value); +static pointer script_fu_marshal_arg_to_value (scheme *sc, + pointer a, + const gchar *proc_name, + gint arg_index, + GParamSpec *arg_spec, + GValue *value); -static pointer script_fu_marshal_procedure_call (scheme *sc, - pointer a, - gboolean permissive, - gboolean deprecated); -static pointer script_fu_marshal_procedure_call_strict (scheme *sc, - pointer a); -static pointer script_fu_marshal_procedure_call_permissive (scheme *sc, - pointer a); -static pointer script_fu_marshal_procedure_call_deprecated (scheme *sc, - pointer a); +static pointer script_fu_marshal_procedure_call (scheme *sc, + pointer a, + gboolean permissive, + gboolean deprecated); +static pointer script_fu_marshal_procedure_call_strict (scheme *sc, + pointer a); +static pointer script_fu_marshal_procedure_call_permissive (scheme *sc, + pointer a); +static pointer script_fu_marshal_procedure_call_deprecated (scheme *sc, + pointer a); -static pointer script_fu_marshal_drawable_create_filter (scheme *sc, - pointer a, - const gchar *proc_name, - GimpDrawable **drawable, - GimpDrawableFilter **filter); -static pointer script_fu_marshal_drawable_merge_filter_call (scheme *sc, - pointer a); -static pointer script_fu_marshal_drawable_append_filter_call (scheme *sc, - pointer a); +static pointer script_fu_marshal_drawable_create_filter (scheme *sc, + pointer a, + const gchar *proc_name, + GimpDrawable **drawable, + GimpDrawableFilter **filter); +static pointer script_fu_marshal_drawable_filter_configure_call (scheme *sc, + pointer a); +static pointer script_fu_marshal_drawable_merge_filter_call (scheme *sc, + pointer a); +static pointer script_fu_marshal_drawable_append_filter_call (scheme *sc, + pointer a); +static pointer script_fu_marshal_drawable_merge_new_filter_call (scheme *sc, + pointer a); +static pointer script_fu_marshal_drawable_append_new_filter_call (scheme *sc, + pointer a); -static pointer script_fu_register_call (scheme *sc, - pointer a); -static pointer script_fu_register_call_filter (scheme *sc, - pointer a); -static pointer script_fu_register_call_procedure (scheme *sc, - pointer a); -static pointer script_fu_menu_register_call (scheme *sc, - pointer a); -static pointer script_fu_use_v3_call (scheme *sc, - pointer a); -static pointer script_fu_use_v2_call (scheme *sc, - pointer a); -static pointer script_fu_quit_call (scheme *sc, - pointer a); -static pointer script_fu_nil_call (scheme *sc, - pointer a); +static pointer script_fu_register_call (scheme *sc, + pointer a); +static pointer script_fu_register_call_filter (scheme *sc, + pointer a); +static pointer script_fu_register_call_procedure (scheme *sc, + pointer a); +static pointer script_fu_menu_register_call (scheme *sc, + pointer a); +static pointer script_fu_use_v3_call (scheme *sc, + pointer a); +static pointer script_fu_use_v2_call (scheme *sc, + pointer a); +static pointer script_fu_quit_call (scheme *sc, + pointer a); +static pointer script_fu_nil_call (scheme *sc, + pointer a); -static gboolean ts_load_file (const gchar *dirname, - const gchar *basename); +static gboolean ts_load_file (const gchar *dirname, + const gchar *basename); typedef struct { @@ -562,8 +568,11 @@ ts_define_procedure (sc, "load-extension", scm_load_ext); ts_define_procedure (sc, "-gimp-proc-db-call", script_fu_marshal_procedure_call_permissive); ts_define_procedure (sc, "--gimp-proc-db-call", script_fu_marshal_procedure_call_deprecated); - ts_define_procedure (sc, "gimp-drawable-merge-new-filter", script_fu_marshal_drawable_merge_filter_call); - ts_define_procedure (sc, "gimp-drawable-append-new-filter", script_fu_marshal_drawable_append_filter_call); + ts_define_procedure (sc, "gimp-drawable-filter-configure", script_fu_marshal_drawable_filter_configure_call); + ts_define_procedure (sc, "gimp-drawable-merge-filter", script_fu_marshal_drawable_merge_filter_call); + ts_define_procedure (sc, "gimp-drawable-append-filter", script_fu_marshal_drawable_append_filter_call); + ts_define_procedure (sc, "gimp-drawable-merge-new-filter", script_fu_marshal_drawable_merge_new_filter_call); + ts_define_procedure (sc, "gimp-drawable-append-new-filter", script_fu_marshal_drawable_append_new_filter_call); /* Define each PDB procedure as a scheme func. * Each call passes through one of the wrapper funcs. @@ -1583,6 +1592,74 @@ script_fu_marshal_procedure_call_deprecated (scheme *sc, return script_fu_marshal_procedure_call (sc, a, TRUE, TRUE); } +static pointer +script_fu_marshal_drawable_filter_configure (scheme *sc, + pointer a, + const gchar *proc_name, + GimpDrawableFilter *filter) +{ + pointer return_val = sc->NIL; + GimpLayerMode mode = GIMP_LAYER_MODE_REPLACE; + gdouble opacity = 1.0; + GimpDrawableFilterConfig *config; + gint arg_index; + gchar error_str[1024]; + + if (sc->vptr->list_length (sc, a) > 0) + { + mode = sc->vptr->ivalue (sc->vptr->pair_car (a)); + a = sc->vptr->pair_cdr (a); + } + + if (sc->vptr->list_length (sc, a) > 0) + { + opacity = sc->vptr->rvalue (sc->vptr->pair_car (a)); + a = sc->vptr->pair_cdr (a); + } + gimp_drawable_filter_set_opacity (filter, opacity); + gimp_drawable_filter_set_blend_mode (filter, mode); + + config = gimp_drawable_filter_get_config (filter); + arg_index = 3; + while (sc->vptr->list_length (sc, a) > 1) + { + gchar *argname; + GParamSpec *arg_spec; + GValue value = G_VALUE_INIT; + + argname = g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a))); + arg_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config), argname); + if (arg_spec == NULL) + { + g_snprintf (error_str, sizeof (error_str), + "Invalid argument name: %s", argname); + g_free (argname); + gimp_drawable_filter_delete (filter); + return script_error (sc, error_str, 0); + } + g_value_init (&value, arg_spec->value_type); + a = sc->vptr->pair_cdr (a); + + return_val = script_fu_marshal_arg_to_value (sc, a, proc_name, arg_index, arg_spec, &value); + + if (return_val != sc->NIL) + { + g_value_unset (&value); + g_free (argname); + gimp_drawable_filter_delete (filter); + return return_val; + } + + g_object_set_property (G_OBJECT (config), argname, &value); + g_value_unset (&value); + + a = sc->vptr->pair_cdr (a); + arg_index += 2; + } + + return sc->NIL; +} + static pointer script_fu_marshal_drawable_create_filter (scheme *sc, pointer a, @@ -1590,14 +1667,9 @@ script_fu_marshal_drawable_create_filter (scheme *sc, GimpDrawable **drawable, GimpDrawableFilter **filter) { - pointer return_val = sc->NIL; - gchar *operation_name; - gchar *filter_name = NULL; - GimpLayerMode mode = GIMP_LAYER_MODE_REPLACE; - gdouble opacity = 1.0; - GimpDrawableFilterConfig *config; - gint arg_index; - gchar error_str[1024]; + gchar *operation_name; + gchar *filter_name = NULL; + gchar error_str[1024]; if (sc->vptr->list_length (sc, a) < 2) { @@ -1605,7 +1677,7 @@ script_fu_marshal_drawable_create_filter (scheme *sc, "Drawable Filter marshaller was called with missing arguments. " "The drawable ID, the GEGL operation, filter name, blend mode, opacity " "and the arguments' names and values it requires (possibly none) must be specified: " - "(%s drawable op title mode arg1 val1 arg2 val2...)", + "(%s drawable op title mode opacity arg1 val1 arg2 val2...)", proc_name); return implementation_error (sc, error_str, 0); } @@ -1615,7 +1687,7 @@ script_fu_marshal_drawable_create_filter (scheme *sc, "Drawable Filter marshaller was called with an even number of arguments. " "The drawable ID, the GEGL operation, filter name, blend mode, opacity " "and the arguments' names and values it requires (possibly none) must be specified: " - "(%s drawable op title mode arg1 val1 arg2 val2...)", + "(%s drawable op title mode opacity arg1 val1 arg2 val2...)", proc_name); return implementation_error (sc, error_str, 0); } @@ -1652,18 +1724,6 @@ script_fu_marshal_drawable_create_filter (scheme *sc, a = sc->vptr->pair_cdr (a); } - if (sc->vptr->list_length (sc, a) > 0) - { - mode = sc->vptr->ivalue (sc->vptr->pair_car (a)); - a = sc->vptr->pair_cdr (a); - } - - if (sc->vptr->list_length (sc, a) > 0) - { - opacity = sc->vptr->rvalue (sc->vptr->pair_car (a)); - a = sc->vptr->pair_cdr (a); - } - *filter = gimp_drawable_filter_new (*drawable, operation_name, filter_name); g_free (filter_name); @@ -1676,53 +1736,154 @@ script_fu_marshal_drawable_create_filter (scheme *sc, } g_free (operation_name); - gimp_drawable_filter_set_opacity (*filter, opacity); - gimp_drawable_filter_set_blend_mode (*filter, mode); + return script_fu_marshal_drawable_filter_configure (sc, a, proc_name, *filter); +} - config = gimp_drawable_filter_get_config (*filter); - arg_index = 5; - while (sc->vptr->list_length (sc, a) > 1) +static pointer +script_fu_marshal_drawable_filter_configure_call (scheme *sc, + pointer a) +{ + GimpDrawableFilter *filter = NULL; + const gchar *proc_name = "gimp-drawable-filter-configure"; + gchar error_str[1024]; + + if (sc->vptr->list_length (sc, a) < 3) { - gchar *argname; - GParamSpec *arg_spec; - GValue value = G_VALUE_INIT; + g_snprintf (error_str, sizeof (error_str), + "Drawable Filter marshaller was called with missing arguments. " + "The filter ID, blend mode, opacity and the arguments' names " + "and values it requires (possibly none) must be specified: " + "(%s mode opacity arg1 val1 arg2 val2...)", + proc_name); + return implementation_error (sc, error_str, 0); + } + else if (sc->vptr->list_length (sc, a) > 3 && sc->vptr->list_length (sc, a) % 2 != 1) + { + g_snprintf (error_str, sizeof (error_str), + "Drawable Filter marshaller was called with an even number of arguments. " + "The drawable ID, the GEGL operation, filter name, blend mode, opacity " + "and the arguments' names and values it requires (possibly none) must be specified: " + "(%s mode opacity arg1 val1 arg2 val2...)", + proc_name); + return implementation_error (sc, error_str, 0); + } + else if (! sc->vptr->is_number (sc->vptr->pair_car (a))) + { + return script_type_error (sc, "numeric", 0, proc_name); + } + else + { + gint id; - argname = g_strdup (sc->vptr->string_value (sc->vptr->pair_car (a))); - arg_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config), argname); - if (arg_spec == NULL) + id = sc->vptr->ivalue (sc->vptr->pair_car (a)); + filter = gimp_drawable_filter_get_by_id (id); + + if (filter == NULL || ! GIMP_IS_DRAWABLE_FILTER (filter)) { g_snprintf (error_str, sizeof (error_str), - "Invalid argument name: %s", argname); - g_free (argname); - gimp_drawable_filter_delete (*filter); + "Invalid Drawable Filter ID: %d", id); return script_error (sc, error_str, 0); } - g_value_init (&value, arg_spec->value_type); - a = sc->vptr->pair_cdr (a); - - return_val = script_fu_marshal_arg_to_value (sc, a, proc_name, arg_index, arg_spec, &value); - - if (return_val != sc->NIL) - { - g_value_unset (&value); - g_free (argname); - gimp_drawable_filter_delete (*filter); - return return_val; - } - - g_object_set_property (G_OBJECT (config), argname, &value); - g_value_unset (&value); a = sc->vptr->pair_cdr (a); - arg_index += 2; } - return sc->NIL; + return script_fu_marshal_drawable_filter_configure (sc, a, proc_name, filter); } static pointer script_fu_marshal_drawable_merge_filter_call (scheme *sc, pointer a) +{ + const gchar *proc_name = "gimp-drawable-merge-filter"; + GimpItem *item; + GimpDrawableFilter *filter; + gint id; + gchar error_str[1024]; + + if (sc->vptr->list_length (sc, a) != 2) + { + g_snprintf (error_str, sizeof (error_str), + "Drawable Filter marshaller was called with missing arguments. " + "The drawable and filter IDs are required: " + "(%s mode opacity arg1 val1 arg2 val2...)", + proc_name); + + return implementation_error (sc, error_str, 0); + } + + id = sc->vptr->ivalue (sc->vptr->pair_car (a)); + item = gimp_item_get_by_id (id); + if (item == NULL || ! GIMP_IS_DRAWABLE (item)) + { + g_snprintf (error_str, sizeof (error_str), + "Invalid Drawable ID: %d", id); + return script_error (sc, error_str, 0); + } + a = sc->vptr->pair_cdr (a); + + id = sc->vptr->ivalue (sc->vptr->pair_car (a)); + filter = gimp_drawable_filter_get_by_id (id); + if (filter == NULL || ! GIMP_IS_DRAWABLE_FILTER (filter)) + { + g_snprintf (error_str, sizeof (error_str), + "Invalid Drawable Filter ID: %d", id); + return script_error (sc, error_str, 0); + } + + gimp_drawable_merge_filter (GIMP_DRAWABLE (item), filter); + + return sc->NIL; +} + +static pointer +script_fu_marshal_drawable_append_filter_call (scheme *sc, + pointer a) +{ + const gchar *proc_name = "gimp-drawable-append-filter"; + GimpItem *item; + GimpDrawableFilter *filter; + gint id; + gchar error_str[1024]; + + if (sc->vptr->list_length (sc, a) != 2) + { + g_snprintf (error_str, sizeof (error_str), + "Drawable Filter marshaller was called with missing arguments. " + "The drawable and filter IDs are required: " + "(%s mode opacity arg1 val1 arg2 val2...)", + proc_name); + + return implementation_error (sc, error_str, 0); + } + + id = sc->vptr->ivalue (sc->vptr->pair_car (a)); + item = gimp_item_get_by_id (id); + if (item == NULL || ! GIMP_IS_DRAWABLE (item)) + { + g_snprintf (error_str, sizeof (error_str), + "Invalid Drawable ID: %d", id); + return script_error (sc, error_str, 0); + } + a = sc->vptr->pair_cdr (a); + + id = sc->vptr->ivalue (sc->vptr->pair_car (a)); + filter = gimp_drawable_filter_get_by_id (id); + if (filter == NULL || ! GIMP_IS_DRAWABLE_FILTER (filter)) + { + g_snprintf (error_str, sizeof (error_str), + "Invalid Drawable Filter ID: %d", id); + return script_error (sc, error_str, 0); + } + + gimp_drawable_append_filter (GIMP_DRAWABLE (item), filter); + + return sc->NIL; +} + +static pointer +script_fu_marshal_drawable_merge_new_filter_call (scheme *sc, + pointer a) { GimpDrawable *drawable = NULL; GimpDrawableFilter *filter = NULL; @@ -1740,8 +1901,8 @@ script_fu_marshal_drawable_merge_filter_call (scheme *sc, } static pointer -script_fu_marshal_drawable_append_filter_call (scheme *sc, - pointer a) +script_fu_marshal_drawable_append_new_filter_call (scheme *sc, + pointer a) { GimpDrawable *drawable = NULL; GimpDrawableFilter *filter = NULL;