From 38c2cd3b1530f6dd1ea6e55dc6f5326701fc67b1 Mon Sep 17 00:00:00 2001 From: Jehan Date: Mon, 21 Oct 2024 21:59:26 +0200 Subject: [PATCH] =?UTF-8?q?app,=20libgimp,=20pdb,=20plug-ins:=20new=20Gimp?= =?UTF-8?q?CoreObjectArray=20type=20and=20drawablearray=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … PDB type. This is a first step for #7369. Clearly our GimpObjectArray was meant to be used with C arrays, hence the wrapper function gimp_value_set_object_array() which was taking a C array and actually creating and setting a GimpObjectArray. This is why our new type is actually a C array aliased as a boxed type and containing its own size (thanks to NULL-termination). Eventually GimpCoreObjectArray is meant to replace GimpObjectArray. The only issue is that such a type does not allow NULL as a valid element in such an array, but fact is that I don't think we currently have any use case where this matters. If ever such a case arise in the future, we may introduce back GimpObjectArray. In this first commit, I replaced all itemarray PDB types with a new drawablearray using this new boxed type when relevant. --- app/pdb/edit-cmds.c | 139 ++++++----------- app/pdb/image-cmds.c | 67 +++------ app/pdb/selection-cmds.c | 32 ++-- libgimp/gimp.c | 53 +++---- libgimp/gimpedit_pdb.c | 89 ++++------- libgimp/gimpedit_pdb.h | 37 ++--- libgimp/gimpgpparams-body.c | 159 ++++++++++++++++++++ libgimp/gimpimage.c | 11 +- libgimp/gimpimage_pdb.c | 42 ++---- libgimp/gimpimage_pdb.h | 6 +- libgimp/gimpselection.c | 9 +- libgimp/gimpselection.h | 1 - libgimp/gimpselection_pdb.c | 14 +- libgimp/gimpselection_pdb.h | 61 ++++---- libgimp/tests/test-selection-float.c | 8 +- libgimpbase/gimpbase.def | 3 + libgimpbase/gimpparamspecs.c | 217 +++++++++++++++++++++++++++ libgimpbase/gimpparamspecs.h | 52 +++++++ pdb/app.pl | 9 ++ pdb/groups/edit.pdb | 65 +++----- pdb/groups/image.pdb | 25 ++- pdb/groups/selection.pdb | 14 +- pdb/pdb.pl | 12 ++ plug-ins/common/curve-bend.c | 11 +- plug-ins/common/file-pdf-export.c | 14 +- plug-ins/common/file-ps.c | 5 +- plug-ins/file-dds/ddswrite.c | 9 +- plug-ins/file-fits/fits.c | 12 +- 28 files changed, 739 insertions(+), 437 deletions(-) diff --git a/app/pdb/edit-cmds.c b/app/pdb/edit-cmds.c index 0b12fef09c..20dedcd7ab 100644 --- a/app/pdb/edit-cmds.c +++ b/app/pdb/edit-cmds.c @@ -60,12 +60,10 @@ edit_cut_invoker (GimpProcedure *procedure, { gboolean success = TRUE; GimpValueArray *return_vals; - gint num_drawables; - const GimpItem **drawables; + const GimpDrawable **drawables; gboolean non_empty = FALSE; - num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); - drawables = (const GimpItem **) gimp_value_get_object_array (gimp_value_array_index (args, 1)); + drawables = g_value_get_boxed (gimp_value_array_index (args, 0)); if (success) { @@ -73,7 +71,7 @@ edit_cut_invoker (GimpProcedure *procedure, GList *drawable_list = NULL; gint i; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, GIMP_PDB_ITEM_CONTENT, error) || @@ -139,12 +137,10 @@ edit_copy_invoker (GimpProcedure *procedure, { gboolean success = TRUE; GimpValueArray *return_vals; - gint num_drawables; - const GimpItem **drawables; + const GimpDrawable **drawables; gboolean non_empty = FALSE; - num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); - drawables = (const GimpItem **) gimp_value_get_object_array (gimp_value_array_index (args, 1)); + drawables = g_value_get_boxed (gimp_value_array_index (args, 0)); if (success) { @@ -152,7 +148,7 @@ edit_copy_invoker (GimpProcedure *procedure, GList *drawables_list = NULL; gint i; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, 0, error)) { @@ -171,7 +167,7 @@ edit_copy_invoker (GimpProcedure *procedure, drawables_list = g_list_prepend (drawables_list, (gpointer) drawables[i]); } - if (success && num_drawables > 0) + if (success && g_list_length (drawables_list) > 0) { GError *my_error = NULL; @@ -251,8 +247,7 @@ edit_paste_invoker (GimpProcedure *procedure, GimpValueArray *return_vals; GimpDrawable *drawable; gboolean paste_into; - gint num_layers = 0; - GimpLayer **layers = NULL; + GimpDrawable **new_drawables = NULL; drawable = g_value_get_object (gimp_value_array_index (args, 0)); paste_into = g_value_get_boolean (gimp_value_array_index (args, 1)); @@ -268,6 +263,7 @@ edit_paste_invoker (GimpProcedure *procedure, { GList *drawables = NULL; GList *list; + gint num_drawables; gint i; if (drawable != NULL) @@ -285,11 +281,11 @@ edit_paste_invoker (GimpProcedure *procedure, if (! list) success = FALSE; - num_layers = g_list_length (list); - layers = g_new (GimpLayer *, num_layers); + num_drawables = g_list_length (list); + new_drawables = g_new0 (GimpDrawable *, num_drawables + 1); - for (i = 0; i < num_layers; i++, list = g_list_next (list)) - layers[i] = g_object_ref (list->data); + for (i = 0; i < num_drawables; i++, list = g_list_next (list)) + new_drawables[i] = g_object_ref (list->data); g_list_free (list); } @@ -301,10 +297,7 @@ edit_paste_invoker (GimpProcedure *procedure, error ? *error : NULL); if (success) - { - g_value_set_int (gimp_value_array_index (return_vals, 1), num_layers); - gimp_value_take_object_array (gimp_value_array_index (return_vals, 2), GIMP_TYPE_LAYER, (GObject **) layers, num_layers); - } + g_value_take_boxed (gimp_value_array_index (return_vals, 1), new_drawables); return return_vals; } @@ -350,14 +343,12 @@ edit_named_cut_invoker (GimpProcedure *procedure, { gboolean success = TRUE; GimpValueArray *return_vals; - gint num_drawables; - const GimpItem **drawables; + const GimpDrawable **drawables; const gchar *buffer_name; gchar *real_name = NULL; - num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); - drawables = (const GimpItem **) gimp_value_get_object_array (gimp_value_array_index (args, 1)); - buffer_name = g_value_get_string (gimp_value_array_index (args, 2)); + drawables = g_value_get_boxed (gimp_value_array_index (args, 0)); + buffer_name = g_value_get_string (gimp_value_array_index (args, 1)); if (success) { @@ -365,7 +356,7 @@ edit_named_cut_invoker (GimpProcedure *procedure, GList *drawable_list = NULL; gint i; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, GIMP_PDB_ITEM_CONTENT, error) || @@ -436,14 +427,12 @@ edit_named_copy_invoker (GimpProcedure *procedure, { gboolean success = TRUE; GimpValueArray *return_vals; - gint num_drawables; - const GimpItem **drawables; + const GimpDrawable **drawables; const gchar *buffer_name; gchar *real_name = NULL; - num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); - drawables = (const GimpItem **) gimp_value_get_object_array (gimp_value_array_index (args, 1)); - buffer_name = g_value_get_string (gimp_value_array_index (args, 2)); + drawables = g_value_get_boxed (gimp_value_array_index (args, 0)); + buffer_name = g_value_get_string (gimp_value_array_index (args, 1)); if (success) { @@ -451,7 +440,7 @@ edit_named_copy_invoker (GimpProcedure *procedure, GList *drawable_list = NULL; gint i; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, 0, error)) @@ -680,17 +669,11 @@ register_edit_procs (GimpPDB *pdb) "Spencer Kimball & Peter Mattis", "1995-1996"); gimp_procedure_add_argument (procedure, - g_param_spec_int ("num-drawables", - "num drawables", - "The number of drawables", - 1, G_MAXINT32, 1, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_argument (procedure, - gimp_param_spec_object_array ("drawables", - "drawables", - "The drawables to cut from", - GIMP_TYPE_ITEM, - GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE)); + gimp_param_spec_core_object_array ("drawables", + "drawables", + "The drawables to cut from", + GIMP_TYPE_DRAWABLE, + GIMP_PARAM_READWRITE)); gimp_procedure_add_return_value (procedure, g_param_spec_boolean ("non-empty", "non empty", @@ -717,17 +700,11 @@ register_edit_procs (GimpPDB *pdb) "Spencer Kimball & Peter Mattis", "1995-1996"); gimp_procedure_add_argument (procedure, - g_param_spec_int ("num-drawables", - "num drawables", - "The number of drawables to save", - 1, G_MAXINT32, 1, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_argument (procedure, - gimp_param_spec_object_array ("drawables", - "drawables", - "Drawables to copy from", - GIMP_TYPE_ITEM, - GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE)); + gimp_param_spec_core_object_array ("drawables", + "drawables", + "Drawables to copy from", + GIMP_TYPE_DRAWABLE, + GIMP_PARAM_READWRITE)); gimp_procedure_add_return_value (procedure, g_param_spec_boolean ("non-empty", "non empty", @@ -774,8 +751,8 @@ register_edit_procs (GimpPDB *pdb) "gimp-edit-paste"); gimp_procedure_set_static_help (procedure, "Paste buffer to the specified drawable.", - "This procedure pastes a copy of the internal GIMP edit buffer to the specified drawable. The GIMP edit buffer will be empty unless a call was previously made to either 'gimp-edit-cut' or 'gimp-edit-copy'. The \"paste_into\" option specifies whether to clear the current image selection, or to paste the buffer \"behind\" the selection. This allows the selection to act as a mask for the pasted buffer. Anywhere that the selection mask is non-zero, the pasted buffer will show through. The pasted data may be a floating selection when relevant, layers otherwise. If the image has a floating selection at the time of pasting, the old floating selection will be anchored to its drawable before the new floating selection is added.\n" - "This procedure returns the new layers (floating or not). If the result is a floating selection, it will already be attached to the specified drawable, and a subsequent call to floating_sel_attach is not needed.", + "This procedure pastes a copy of the internal GIMP edit buffer to the specified drawable. The GIMP edit buffer will be empty unless a call was previously made to either [func@Gimp.edit_cut] or [func@Gimp.edit_copy]. The \"paste_into\" option specifies whether to clear the current image selection, or to paste the buffer \"behind\" the selection. This allows the selection to act as a mask for the pasted buffer. Anywhere that the selection mask is non-zero, the pasted buffer will show through. The pasted data may be a floating selection when relevant, layers otherwise. If the image has a floating selection at the time of pasting, the old floating selection will be anchored to its drawable before the new floating selection is added.\n" + "This procedure returns the new drawables (floating or not). If the result is a floating selection, it will already be attached to the specified drawable, and a subsequent call to [func@Gimp.floating_sel_attach] is not needed.", NULL); gimp_procedure_set_static_attribution (procedure, "Spencer Kimball & Peter Mattis", @@ -794,17 +771,11 @@ register_edit_procs (GimpPDB *pdb) FALSE, GIMP_PARAM_READWRITE)); gimp_procedure_add_return_value (procedure, - g_param_spec_int ("num-layers", - "num layers", - "The newly pasted layers", - 0, G_MAXINT32, 0, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_return_value (procedure, - gimp_param_spec_object_array ("layers", - "layers", - "The list of pasted layers.", - GIMP_TYPE_LAYER, - GIMP_PARAM_READWRITE)); + gimp_param_spec_core_object_array ("new-drawables", + "new drawables", + "The list of pasted layers.", + GIMP_TYPE_DRAWABLE, + GIMP_PARAM_READWRITE)); gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); @@ -846,17 +817,11 @@ register_edit_procs (GimpPDB *pdb) "Michael Natterer", "2005"); gimp_procedure_add_argument (procedure, - g_param_spec_int ("num-drawables", - "num drawables", - "The number of drawables", - 1, G_MAXINT32, 1, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_argument (procedure, - gimp_param_spec_object_array ("drawables", - "drawables", - "The drawables to cut from", - GIMP_TYPE_ITEM, - GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE)); + gimp_param_spec_core_object_array ("drawables", + "drawables", + "The drawables to cut from", + GIMP_TYPE_DRAWABLE, + GIMP_PARAM_READWRITE)); gimp_procedure_add_argument (procedure, gimp_param_spec_string ("buffer-name", "buffer name", @@ -889,17 +854,11 @@ register_edit_procs (GimpPDB *pdb) "Michael Natterer", "2005"); gimp_procedure_add_argument (procedure, - g_param_spec_int ("num-drawables", - "num drawables", - "The number of drawables", - 1, G_MAXINT32, 1, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_argument (procedure, - gimp_param_spec_object_array ("drawables", - "drawables", - "The drawables to copy from", - GIMP_TYPE_ITEM, - GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE)); + gimp_param_spec_core_object_array ("drawables", + "drawables", + "The drawables to copy from", + GIMP_TYPE_DRAWABLE, + GIMP_PARAM_READWRITE)); gimp_procedure_add_argument (procedure, gimp_param_spec_string ("buffer-name", "buffer name", diff --git a/app/pdb/image-cmds.c b/app/pdb/image-cmds.c index fabc3052cb..db7fdc851a 100644 --- a/app/pdb/image-cmds.c +++ b/app/pdb/image-cmds.c @@ -651,8 +651,7 @@ image_pick_color_invoker (GimpProcedure *procedure, gboolean success = TRUE; GimpValueArray *return_vals; GimpImage *image; - gint num_drawables; - const GimpItem **drawables; + const GimpDrawable **drawables; gdouble x; gdouble y; gboolean sample_merged; @@ -661,13 +660,12 @@ image_pick_color_invoker (GimpProcedure *procedure, GeglColor *color = NULL; image = g_value_get_object (gimp_value_array_index (args, 0)); - num_drawables = g_value_get_int (gimp_value_array_index (args, 1)); - drawables = (const GimpItem **) gimp_value_get_object_array (gimp_value_array_index (args, 2)); - x = g_value_get_double (gimp_value_array_index (args, 3)); - y = g_value_get_double (gimp_value_array_index (args, 4)); - sample_merged = g_value_get_boolean (gimp_value_array_index (args, 5)); - sample_average = g_value_get_boolean (gimp_value_array_index (args, 6)); - average_radius = g_value_get_double (gimp_value_array_index (args, 7)); + drawables = g_value_get_boxed (gimp_value_array_index (args, 1)); + x = g_value_get_double (gimp_value_array_index (args, 2)); + y = g_value_get_double (gimp_value_array_index (args, 3)); + sample_merged = g_value_get_boolean (gimp_value_array_index (args, 4)); + sample_average = g_value_get_boolean (gimp_value_array_index (args, 5)); + average_radius = g_value_get_double (gimp_value_array_index (args, 6)); if (success) { @@ -675,13 +673,13 @@ image_pick_color_invoker (GimpProcedure *procedure, if (! sample_merged) { - if (num_drawables == 0) + if (drawables == NULL || drawables[0] == NULL) { success = FALSE; } else { - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) if (gimp_item_get_image (GIMP_ITEM (drawables[i])) != image) { success = FALSE; @@ -700,7 +698,7 @@ image_pick_color_invoker (GimpProcedure *procedure, { GList *drawable_list = NULL; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { GimpPickable *pickable = (GimpPickable *) drawables[i]; @@ -2175,14 +2173,14 @@ image_get_selected_drawables_invoker (GimpProcedure *procedure, gboolean success = TRUE; GimpValueArray *return_vals; GimpImage *image; - gint num_drawables = 0; - GimpItem **drawables = NULL; + GimpDrawable **drawables = NULL; image = g_value_get_object (gimp_value_array_index (args, 0)); if (success) { GList *list = gimp_image_get_selected_drawables (image); + gsize num_drawables; num_drawables = g_list_length (list); @@ -2190,10 +2188,10 @@ image_get_selected_drawables_invoker (GimpProcedure *procedure, { gint i; - drawables = g_new (GimpItem *, num_drawables); + drawables = g_new0 (GimpDrawable *, num_drawables + 1); for (i = 0; i < num_drawables; i++, list = g_list_next (list)) - drawables[i] = g_object_ref (list->data); + drawables[i] = list->data; } } @@ -2201,10 +2199,7 @@ image_get_selected_drawables_invoker (GimpProcedure *procedure, error ? *error : NULL); if (success) - { - g_value_set_int (gimp_value_array_index (return_vals, 1), num_drawables); - gimp_value_take_object_array (gimp_value_array_index (return_vals, 2), GIMP_TYPE_ITEM, (GObject **) drawables, num_drawables); - } + g_value_take_boxed (gimp_value_array_index (return_vals, 1), drawables); return return_vals; } @@ -3674,17 +3669,11 @@ register_image_procs (GimpPDB *pdb) FALSE, GIMP_PARAM_READWRITE)); gimp_procedure_add_argument (procedure, - g_param_spec_int ("num-drawables", - "num drawables", - "The number of drawables", - 1, G_MAXINT32, 1, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_argument (procedure, - gimp_param_spec_object_array ("drawables", - "drawables", - "The drawables to pick from", - GIMP_TYPE_ITEM, - GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE)); + gimp_param_spec_core_object_array ("drawables", + "drawables", + "The drawables to pick from", + GIMP_TYPE_DRAWABLE, + GIMP_PARAM_READWRITE)); gimp_procedure_add_argument (procedure, g_param_spec_double ("x", "x", @@ -5087,17 +5076,11 @@ register_image_procs (GimpPDB *pdb) FALSE, GIMP_PARAM_READWRITE)); gimp_procedure_add_return_value (procedure, - g_param_spec_int ("num-drawables", - "num drawables", - "The number of selected drawables in the image", - 0, G_MAXINT32, 0, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_return_value (procedure, - gimp_param_spec_object_array ("drawables", - "drawables", - "The list of selected drawables in the image.", - GIMP_TYPE_ITEM, - GIMP_PARAM_READWRITE)); + gimp_param_spec_core_object_array ("drawables", + "drawables", + "The list of selected drawables in the image.", + GIMP_TYPE_DRAWABLE, + GIMP_PARAM_READWRITE)); gimp_pdb_register_procedure (pdb, procedure); g_object_unref (procedure); diff --git a/app/pdb/selection-cmds.c b/app/pdb/selection-cmds.c index aef87e4386..3cc57ec0dc 100644 --- a/app/pdb/selection-cmds.c +++ b/app/pdb/selection-cmds.c @@ -197,29 +197,27 @@ selection_float_invoker (GimpProcedure *procedure, { gboolean success = TRUE; GimpValueArray *return_vals; - gint num_drawables; - const GimpItem **drawables; + const GimpDrawable **drawables; gint offx; gint offy; GimpLayer *layer = NULL; - num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); - drawables = (const GimpItem **) gimp_value_get_object_array (gimp_value_array_index (args, 1)); - offx = g_value_get_int (gimp_value_array_index (args, 2)); - offy = g_value_get_int (gimp_value_array_index (args, 3)); + drawables = g_value_get_boxed (gimp_value_array_index (args, 0)); + offx = g_value_get_int (gimp_value_array_index (args, 1)); + offy = g_value_get_int (gimp_value_array_index (args, 2)); if (success) { GimpImage *image = NULL; gint i; - if (num_drawables < 1) + if (drawables == NULL || drawables[0] == NULL) { success = FALSE; } else { - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, GIMP_PDB_ITEM_CONTENT, error) || @@ -240,7 +238,7 @@ selection_float_invoker (GimpProcedure *procedure, { GList *drawable_list = NULL; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]); layer = gimp_selection_float (GIMP_SELECTION (gimp_image_get_mask (image)), @@ -694,17 +692,11 @@ register_selection_procs (GimpPDB *pdb) "Spencer Kimball & Peter Mattis", "1995-1996"); gimp_procedure_add_argument (procedure, - g_param_spec_int ("num-drawables", - "num drawables", - "The number of drawables", - 1, G_MAXINT32, 1, - GIMP_PARAM_READWRITE)); - gimp_procedure_add_argument (procedure, - gimp_param_spec_object_array ("drawables", - "drawables", - "The drawables from which to float selection", - GIMP_TYPE_ITEM, - GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE)); + gimp_param_spec_core_object_array ("drawables", + "drawables", + "The drawables from which to float selection", + GIMP_TYPE_DRAWABLE, + GIMP_PARAM_READWRITE)); gimp_procedure_add_argument (procedure, g_param_spec_int ("offx", "offx", diff --git a/libgimp/gimp.c b/libgimp/gimp.c index 3c28f160ce..a4bb3bf516 100644 --- a/libgimp/gimp.c +++ b/libgimp/gimp.c @@ -421,38 +421,39 @@ gimp_main (GType plug_in_type, { GType init_types[] = { - G_TYPE_INT, G_TYPE_PARAM_INT, - G_TYPE_UCHAR, G_TYPE_PARAM_UCHAR, + G_TYPE_INT, G_TYPE_PARAM_INT, + G_TYPE_UCHAR, G_TYPE_PARAM_UCHAR, - G_TYPE_STRING, G_TYPE_PARAM_STRING, - G_TYPE_STRV, G_TYPE_PARAM_BOXED, + G_TYPE_STRING, G_TYPE_PARAM_STRING, + G_TYPE_STRV, G_TYPE_PARAM_BOXED, - G_TYPE_BYTES, G_TYPE_PARAM_BOXED, + G_TYPE_BYTES, G_TYPE_PARAM_BOXED, - GIMP_TYPE_ARRAY, GIMP_TYPE_PARAM_ARRAY, - GIMP_TYPE_INT32_ARRAY, GIMP_TYPE_PARAM_INT32_ARRAY, - GIMP_TYPE_FLOAT_ARRAY, GIMP_TYPE_PARAM_FLOAT_ARRAY, - GIMP_TYPE_OBJECT_ARRAY, GIMP_TYPE_PARAM_OBJECT_ARRAY, + GIMP_TYPE_ARRAY, GIMP_TYPE_PARAM_ARRAY, + GIMP_TYPE_INT32_ARRAY, GIMP_TYPE_PARAM_INT32_ARRAY, + GIMP_TYPE_FLOAT_ARRAY, GIMP_TYPE_PARAM_FLOAT_ARRAY, + GIMP_TYPE_OBJECT_ARRAY, GIMP_TYPE_PARAM_OBJECT_ARRAY, + GIMP_TYPE_CORE_OBJECT_ARRAY, GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY, - GIMP_TYPE_DISPLAY, GIMP_TYPE_PARAM_DISPLAY, - GIMP_TYPE_IMAGE, GIMP_TYPE_PARAM_IMAGE, - GIMP_TYPE_ITEM, GIMP_TYPE_PARAM_ITEM, - GIMP_TYPE_DRAWABLE, GIMP_TYPE_PARAM_DRAWABLE, - GIMP_TYPE_LAYER, GIMP_TYPE_PARAM_LAYER, - GIMP_TYPE_TEXT_LAYER, GIMP_TYPE_PARAM_TEXT_LAYER, - GIMP_TYPE_GROUP_LAYER, GIMP_TYPE_PARAM_GROUP_LAYER, - GIMP_TYPE_CHANNEL, GIMP_TYPE_PARAM_CHANNEL, - GIMP_TYPE_LAYER_MASK, GIMP_TYPE_PARAM_LAYER_MASK, - GIMP_TYPE_SELECTION, GIMP_TYPE_PARAM_SELECTION, - GIMP_TYPE_PATH, GIMP_TYPE_PARAM_PATH, + GIMP_TYPE_DISPLAY, GIMP_TYPE_PARAM_DISPLAY, + GIMP_TYPE_IMAGE, GIMP_TYPE_PARAM_IMAGE, + GIMP_TYPE_ITEM, GIMP_TYPE_PARAM_ITEM, + GIMP_TYPE_DRAWABLE, GIMP_TYPE_PARAM_DRAWABLE, + GIMP_TYPE_LAYER, GIMP_TYPE_PARAM_LAYER, + GIMP_TYPE_TEXT_LAYER, GIMP_TYPE_PARAM_TEXT_LAYER, + GIMP_TYPE_GROUP_LAYER, GIMP_TYPE_PARAM_GROUP_LAYER, + GIMP_TYPE_CHANNEL, GIMP_TYPE_PARAM_CHANNEL, + GIMP_TYPE_LAYER_MASK, GIMP_TYPE_PARAM_LAYER_MASK, + GIMP_TYPE_SELECTION, GIMP_TYPE_PARAM_SELECTION, + GIMP_TYPE_PATH, GIMP_TYPE_PARAM_PATH, - GIMP_TYPE_BRUSH, GIMP_TYPE_PARAM_BRUSH, - GIMP_TYPE_FONT, GIMP_TYPE_PARAM_FONT, - GIMP_TYPE_GRADIENT, GIMP_TYPE_PARAM_GRADIENT, - GIMP_TYPE_PALETTE, GIMP_TYPE_PARAM_PALETTE, - GIMP_TYPE_PATTERN, GIMP_TYPE_PARAM_PATTERN, + GIMP_TYPE_BRUSH, GIMP_TYPE_PARAM_BRUSH, + GIMP_TYPE_FONT, GIMP_TYPE_PARAM_FONT, + GIMP_TYPE_GRADIENT, GIMP_TYPE_PARAM_GRADIENT, + GIMP_TYPE_PALETTE, GIMP_TYPE_PARAM_PALETTE, + GIMP_TYPE_PATTERN, GIMP_TYPE_PARAM_PATTERN, - GIMP_TYPE_UNIT, GIMP_TYPE_PARAM_UNIT + GIMP_TYPE_UNIT, GIMP_TYPE_PARAM_UNIT, }; gint i; diff --git a/libgimp/gimpedit_pdb.c b/libgimp/gimpedit_pdb.c index 170ae0f3a2..0934bf1f55 100644 --- a/libgimp/gimpedit_pdb.c +++ b/libgimp/gimpedit_pdb.c @@ -38,8 +38,7 @@ /** * gimp_edit_cut: - * @num_drawables: The number of drawables. - * @drawables: (array length=num_drawables) (element-type GimpItem): The drawables to cut from. + * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables to cut from. * * Cut from the specified drawables. * @@ -56,18 +55,15 @@ * Returns: TRUE if the cut was successful, FALSE if there was nothing to copy from. **/ gboolean -gimp_edit_cut (gint num_drawables, - const GimpItem **drawables) +gimp_edit_cut (const GimpDrawable **drawables) { GimpValueArray *args; GimpValueArray *return_vals; gboolean non_empty = FALSE; args = gimp_value_array_new_from_types (NULL, - G_TYPE_INT, num_drawables, - GIMP_TYPE_OBJECT_ARRAY, NULL, + GIMP_TYPE_CORE_OBJECT_ARRAY, drawables, G_TYPE_NONE); - gimp_value_set_object_array (gimp_value_array_index (args, 1), GIMP_TYPE_ITEM, (GObject **) drawables, num_drawables); return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), "gimp-edit-cut", @@ -84,8 +80,7 @@ gimp_edit_cut (gint num_drawables, /** * gimp_edit_copy: - * @num_drawables: The number of drawables to save. - * @drawables: (array length=num_drawables) (element-type GimpItem): Drawables to copy from. + * @drawables: (element-type GimpDrawable) (array zero-terminated=1): Drawables to copy from. * * Copy from the specified drawables. * @@ -103,18 +98,15 @@ gimp_edit_cut (gint num_drawables, * Returns: TRUE if the cut was successful, FALSE if there was nothing to copy from. **/ gboolean -gimp_edit_copy (gint num_drawables, - const GimpItem **drawables) +gimp_edit_copy (const GimpDrawable **drawables) { GimpValueArray *args; GimpValueArray *return_vals; gboolean non_empty = FALSE; args = gimp_value_array_new_from_types (NULL, - G_TYPE_INT, num_drawables, - GIMP_TYPE_OBJECT_ARRAY, NULL, + GIMP_TYPE_CORE_OBJECT_ARRAY, drawables, G_TYPE_NONE); - gimp_value_set_object_array (gimp_value_array_index (args, 1), GIMP_TYPE_ITEM, (GObject **) drawables, num_drawables); return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), "gimp-edit-copy", @@ -174,38 +166,36 @@ gimp_edit_copy_visible (GimpImage *image) * gimp_edit_paste: * @drawable: The drawable to paste to. * @paste_into: Clear selection, or paste behind it? - * @num_layers: (out): The newly pasted layers. * * Paste buffer to the specified drawable. * * This procedure pastes a copy of the internal GIMP edit buffer to the * specified drawable. The GIMP edit buffer will be empty unless a call - * was previously made to either gimp_edit_cut() or gimp_edit_copy(). - * The \"paste_into\" option specifies whether to clear the current - * image selection, or to paste the buffer \"behind\" the selection. - * This allows the selection to act as a mask for the pasted buffer. - * Anywhere that the selection mask is non-zero, the pasted buffer will - * show through. The pasted data may be a floating selection when - * relevant, layers otherwise. If the image has a floating selection at - * the time of pasting, the old floating selection will be anchored to - * its drawable before the new floating selection is added. - * This procedure returns the new layers (floating or not). If the + * was previously made to either [func@Gimp.edit_cut] or + * [func@Gimp.edit_copy]. The \"paste_into\" option specifies whether + * to clear the current image selection, or to paste the buffer + * \"behind\" the selection. This allows the selection to act as a mask + * for the pasted buffer. Anywhere that the selection mask is non-zero, + * the pasted buffer will show through. The pasted data may be a + * floating selection when relevant, layers otherwise. If the image has + * a floating selection at the time of pasting, the old floating + * selection will be anchored to its drawable before the new floating + * selection is added. + * This procedure returns the new drawables (floating or not). If the * result is a floating selection, it will already be attached to the - * specified drawable, and a subsequent call to floating_sel_attach is - * not needed. + * specified drawable, and a subsequent call to + * [func@Gimp.floating_sel_attach] is not needed. * - * Returns: (array length=num_layers) (element-type GimpLayer) (transfer container): + * Returns: (element-type GimpDrawable) (array zero-terminated=1) (transfer container): * The list of pasted layers. - * The returned value must be freed with g_free(). **/ -GimpLayer ** +GimpDrawable ** gimp_edit_paste (GimpDrawable *drawable, - gboolean paste_into, - gint *num_layers) + gboolean paste_into) { GimpValueArray *args; GimpValueArray *return_vals; - GimpLayer **layers = NULL; + GimpDrawable **new_drawables = NULL; args = gimp_value_array_new_from_types (NULL, GIMP_TYPE_DRAWABLE, drawable, @@ -217,17 +207,12 @@ gimp_edit_paste (GimpDrawable *drawable, args); gimp_value_array_unref (args); - *num_layers = 0; - if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS) - { - *num_layers = GIMP_VALUES_GET_INT (return_vals, 1); - { GimpObjectArray *a = g_value_get_boxed (gimp_value_array_index (return_vals, 2)); if (a) layers = g_memdup2 (a->data, a->length * sizeof (gpointer)); }; - } + new_drawables = g_value_dup_boxed (gimp_value_array_index (return_vals, 1)); gimp_value_array_unref (return_vals); - return layers; + return new_drawables; } /** @@ -269,8 +254,7 @@ gimp_edit_paste_as_new_image (void) /** * gimp_edit_named_cut: - * @num_drawables: The number of drawables. - * @drawables: (array length=num_drawables) (element-type GimpItem): The drawables to cut from. + * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables to cut from. * @buffer_name: The name of the buffer to create. * * Cut into a named buffer. @@ -287,20 +271,17 @@ gimp_edit_paste_as_new_image (void) * Since: 2.4 **/ gchar * -gimp_edit_named_cut (gint num_drawables, - const GimpItem **drawables, - const gchar *buffer_name) +gimp_edit_named_cut (const GimpDrawable **drawables, + const gchar *buffer_name) { GimpValueArray *args; GimpValueArray *return_vals; gchar *real_name = NULL; args = gimp_value_array_new_from_types (NULL, - G_TYPE_INT, num_drawables, - GIMP_TYPE_OBJECT_ARRAY, NULL, + GIMP_TYPE_CORE_OBJECT_ARRAY, drawables, G_TYPE_STRING, buffer_name, G_TYPE_NONE); - gimp_value_set_object_array (gimp_value_array_index (args, 1), GIMP_TYPE_ITEM, (GObject **) drawables, num_drawables); return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), "gimp-edit-named-cut", @@ -317,8 +298,7 @@ gimp_edit_named_cut (gint num_drawables, /** * gimp_edit_named_copy: - * @num_drawables: The number of drawables. - * @drawables: (array length=num_drawables) (element-type GimpItem): The drawables to copy from. + * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables to copy from. * @buffer_name: The name of the buffer to create. * * Copy into a named buffer. @@ -335,20 +315,17 @@ gimp_edit_named_cut (gint num_drawables, * Since: 2.4 **/ gchar * -gimp_edit_named_copy (gint num_drawables, - const GimpItem **drawables, - const gchar *buffer_name) +gimp_edit_named_copy (const GimpDrawable **drawables, + const gchar *buffer_name) { GimpValueArray *args; GimpValueArray *return_vals; gchar *real_name = NULL; args = gimp_value_array_new_from_types (NULL, - G_TYPE_INT, num_drawables, - GIMP_TYPE_OBJECT_ARRAY, NULL, + GIMP_TYPE_CORE_OBJECT_ARRAY, drawables, G_TYPE_STRING, buffer_name, G_TYPE_NONE); - gimp_value_set_object_array (gimp_value_array_index (args, 1), GIMP_TYPE_ITEM, (GObject **) drawables, num_drawables); return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), "gimp-edit-named-copy", diff --git a/libgimp/gimpedit_pdb.h b/libgimp/gimpedit_pdb.h index 4700fd0075..0fb6dc519e 100644 --- a/libgimp/gimpedit_pdb.h +++ b/libgimp/gimpedit_pdb.h @@ -32,27 +32,22 @@ G_BEGIN_DECLS /* For information look into the C source or the html documentation */ -gboolean gimp_edit_cut (gint num_drawables, - const GimpItem **drawables); -gboolean gimp_edit_copy (gint num_drawables, - const GimpItem **drawables); -gboolean gimp_edit_copy_visible (GimpImage *image); -GimpLayer** gimp_edit_paste (GimpDrawable *drawable, - gboolean paste_into, - gint *num_layers); -GimpImage* gimp_edit_paste_as_new_image (void); -gchar* gimp_edit_named_cut (gint num_drawables, - const GimpItem **drawables, - const gchar *buffer_name); -gchar* gimp_edit_named_copy (gint num_drawables, - const GimpItem **drawables, - const gchar *buffer_name); -gchar* gimp_edit_named_copy_visible (GimpImage *image, - const gchar *buffer_name); -GimpLayer* gimp_edit_named_paste (GimpDrawable *drawable, - const gchar *buffer_name, - gboolean paste_into); -GimpImage* gimp_edit_named_paste_as_new_image (const gchar *buffer_name); +gboolean gimp_edit_cut (const GimpDrawable **drawables); +gboolean gimp_edit_copy (const GimpDrawable **drawables); +gboolean gimp_edit_copy_visible (GimpImage *image); +GimpDrawable** gimp_edit_paste (GimpDrawable *drawable, + gboolean paste_into); +GimpImage* gimp_edit_paste_as_new_image (void); +gchar* gimp_edit_named_cut (const GimpDrawable **drawables, + const gchar *buffer_name); +gchar* gimp_edit_named_copy (const GimpDrawable **drawables, + const gchar *buffer_name); +gchar* gimp_edit_named_copy_visible (GimpImage *image, + const gchar *buffer_name); +GimpLayer* gimp_edit_named_paste (GimpDrawable *drawable, + const gchar *buffer_name, + gboolean paste_into); +GimpImage* gimp_edit_named_paste_as_new_image (const gchar *buffer_name); G_END_DECLS diff --git a/libgimp/gimpgpparams-body.c b/libgimp/gimpgpparams-body.c index 3e963752f6..ba3da0363b 100644 --- a/libgimp/gimpgpparams-body.c +++ b/libgimp/gimpgpparams-body.c @@ -513,6 +513,13 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec, else param_def->meta.m_resource.default_resource_id = 0; } + else if (GIMP_IS_PARAM_SPEC_CORE_OBJECT_ARRAY (pspec)) + { + param_def->param_def_type = GP_PARAM_DEF_TYPE_ID_ARRAY; + + param_def->meta.m_id_array.type_name = + (gchar *) g_type_name (GIMP_PARAM_SPEC_CORE_OBJECT_ARRAY (pspec)->object_type); + } else if (GIMP_IS_PARAM_SPEC_OBJECT_ARRAY (pspec)) { param_def->param_def_type = GP_PARAM_DEF_TYPE_ID_ARRAY; @@ -903,6 +910,59 @@ gimp_gp_param_to_value (gpointer gimp, g_value_take_boxed (value, colors); } + else if (GIMP_VALUE_HOLDS_CORE_OBJECT_ARRAY (value)) + { + GType object_type = G_TYPE_INVALID; + GObject **objects; + gint i; + + if (param->data.d_id_array.type_name != NULL) + { + /* An empty array from a NULL has an arbitrary type_name set earlier. */ + object_type = g_type_from_name (param->data.d_id_array.type_name); + } + else if (pspec != NULL) + { + object_type = GIMP_PARAM_SPEC_CORE_OBJECT_ARRAY (pspec)->object_type; + } + + if (param->data.d_id_array.size > 1 && ! g_type_is_a (object_type, G_TYPE_OBJECT)) + { + g_warning ("%s: GimpCoreObjectArray of unknown type.", G_STRFUNC); + return; + } + + /* size might be zero. */ + + objects = g_new0 (GObject *, param->data.d_id_array.size + 1); + + for (i = 0; i < param->data.d_id_array.size; i++) + { + gint id = param->data.d_id_array.data[i]; + + if (object_type == GIMP_TYPE_IMAGE) + { + objects[i] = (GObject *) get_image_by_id (gimp, id); + } + else if (g_type_is_a (object_type, GIMP_TYPE_ITEM)) + { + objects[i] = (GObject *) get_item_by_id (gimp, id); + } + else if (g_type_is_a (object_type, GIMP_TYPE_DISPLAY)) + { + objects[i] = (GObject *) get_display_by_id (gimp, id); + } + else if (g_type_is_a (object_type, GIMP_TYPE_RESOURCE)) + { + objects[i] = (GObject *) get_resource_by_id (id); + } + } + + /* Even when size is zero, set gvalue to an empty GimpObjectArray object, + * having a valid but possibly arbitrary type of its elements. + */ + g_value_set_boxed (value, objects); + } else if (GIMP_VALUE_HOLDS_OBJECT_ARRAY (value)) { GType object_type = G_TYPE_INVALID; @@ -1369,6 +1429,105 @@ gimp_value_to_gp_param (const GValue *value, else param->data.d_strv = array; } + else if (GIMP_VALUE_HOLDS_CORE_OBJECT_ARRAY (value)) + { + GObject **array = g_value_get_boxed (value); + + param->param_type = GP_PARAM_TYPE_ID_ARRAY; + param->data.d_id_array.type_name = NULL; + + if (array && array[0]) + { + GType element_type = G_TYPE_NONE; + gsize array_length; + gint i; + + for (i = 0; array[i] != NULL; i++) + { + if (element_type != G_TYPE_NONE) + { + if (! g_type_is_a (G_TYPE_FROM_INSTANCE (array[i]), element_type)) + { + g_warning ("%s: GimpCoreObjectArray with element type %s holds unsupported element of type '%s'", G_STRFUNC, + g_type_name (element_type), g_type_name (G_TYPE_FROM_INSTANCE (array[i]))); + break; + } + continue; + } + + if (GIMP_IS_IMAGE (array[i])) + { + element_type = GIMP_TYPE_IMAGE; + } + else if (GIMP_IS_ITEM (array[i])) + { + element_type = GIMP_TYPE_ITEM; + } + else if (GIMP_IS_DISPLAY (array[i])) + { + element_type = GIMP_TYPE_DISPLAY; + } + else if (GIMP_IS_RESOURCE (array[i])) + { + element_type = GIMP_TYPE_RESOURCE; + } + else + { + g_warning ("%s: GimpCoreObjectArray holds unsupported type '%s'", G_STRFUNC, + g_type_name (G_TYPE_FROM_INSTANCE (array[i]))); + break; + } + } + array_length = i; + param->data.d_id_array.size = array_length; + + if (array_length > 0) + { + if (full_copy) + param->data.d_id_array.type_name = g_strdup (g_type_name (element_type)); + else + param->data.d_id_array.type_name = (gchar *) g_type_name (element_type); + + /* must be free'd also for full_copy == FALSE */ + param->data.d_id_array.data = g_new (gint32, array_length); + } + + for (i = 0; i < array_length; i++) + { + if (GIMP_IS_IMAGE (array[i])) + { + param->data.d_id_array.data[i] = + gimp_image_get_id (GIMP_IMAGE (array[i])); + } + else if (GIMP_IS_ITEM (array[i])) + { + param->data.d_id_array.data[i] = + gimp_item_get_id (GIMP_ITEM (array[i])); + } + else if (GIMP_IS_DISPLAY (array[i])) + { + param->data.d_id_array.data[i] = + gimp_display_get_id (GIMP_DISPLAY (array[i])); + } + else if (GIMP_IS_RESOURCE (array[i])) + { + param->data.d_id_array.data[i] = get_resource_id (array[i]); + } + else + { + param->data.d_id_array.data[i] = -1; + } + } + } + else + { + /* GValue intended to hold an array of objects is NULL. + * For convenience, we allow this, meaning empty. + */ + param->data.d_id_array.size = 0; + param->data.d_id_array.data = NULL; + } + } else if (GIMP_VALUE_HOLDS_OBJECT_ARRAY (value)) { GimpObjectArray *array = g_value_get_boxed (value); diff --git a/libgimp/gimpimage.c b/libgimp/gimpimage.c index 22251f45a0..c1c0290ba3 100644 --- a/libgimp/gimpimage.c +++ b/libgimp/gimpimage.c @@ -546,14 +546,13 @@ gimp_image_list_paths (GimpImage *image) GList * gimp_image_list_selected_drawables (GimpImage *image) { - GimpItem **drawables; - gint num_drawables; - GList *list = NULL; - gint i; + GimpDrawable **drawables; + GList *list = NULL; + gint i; - drawables = gimp_image_get_selected_drawables (image, &num_drawables); + drawables = gimp_image_get_selected_drawables (image); - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) list = g_list_prepend (list, drawables[i]); g_free (drawables); diff --git a/libgimp/gimpimage_pdb.c b/libgimp/gimpimage_pdb.c index a1c8ea041f..371fdbf5fa 100644 --- a/libgimp/gimpimage_pdb.c +++ b/libgimp/gimpimage_pdb.c @@ -716,8 +716,7 @@ gimp_image_floating_sel_attached_to (GimpImage *image) /** * gimp_image_pick_color: * @image: The image. - * @num_drawables: The number of drawables. - * @drawables: (array length=num_drawables) (element-type GimpItem): The drawables to pick from. + * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables to pick from. * @x: x coordinate of upper-left corner of rectangle. * @y: y coordinate of upper-left corner of rectangle. * @sample_merged: Use the composite image, not the drawables. @@ -746,15 +745,14 @@ gimp_image_floating_sel_attached_to (GimpImage *image) * Returns: TRUE on success. **/ gboolean -gimp_image_pick_color (GimpImage *image, - gint num_drawables, - const GimpItem **drawables, - gdouble x, - gdouble y, - gboolean sample_merged, - gboolean sample_average, - gdouble average_radius, - GeglColor **color) +gimp_image_pick_color (GimpImage *image, + const GimpDrawable **drawables, + gdouble x, + gdouble y, + gboolean sample_merged, + gboolean sample_average, + gdouble average_radius, + GeglColor **color) { GimpValueArray *args; GimpValueArray *return_vals; @@ -762,15 +760,13 @@ gimp_image_pick_color (GimpImage *image, args = gimp_value_array_new_from_types (NULL, GIMP_TYPE_IMAGE, image, - G_TYPE_INT, num_drawables, - GIMP_TYPE_OBJECT_ARRAY, NULL, + GIMP_TYPE_CORE_OBJECT_ARRAY, drawables, G_TYPE_DOUBLE, x, G_TYPE_DOUBLE, y, G_TYPE_BOOLEAN, sample_merged, G_TYPE_BOOLEAN, sample_average, G_TYPE_DOUBLE, average_radius, G_TYPE_NONE); - gimp_value_set_object_array (gimp_value_array_index (args, 2), GIMP_TYPE_ITEM, (GObject **) drawables, num_drawables); return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), "gimp-image-pick-color", @@ -2473,7 +2469,6 @@ gimp_image_set_selected_paths (GimpImage *image, /** * gimp_image_get_selected_drawables: * @image: The image. - * @num_drawables: (out): The number of selected drawables in the image. * * Get the image's selected drawables * @@ -2485,19 +2480,17 @@ gimp_image_set_selected_paths (GimpImage *image, * has a layer mask and the layer mask is in edit mode, then the layer * mask is the active drawable. * - * Returns: (array length=num_drawables) (element-type GimpItem) (transfer container): + * Returns: (element-type GimpDrawable) (array zero-terminated=1) (transfer container): * The list of selected drawables in the image. - * The returned value must be freed with g_free(). * * Since: 3.0.0 **/ -GimpItem ** -gimp_image_get_selected_drawables (GimpImage *image, - gint *num_drawables) +GimpDrawable ** +gimp_image_get_selected_drawables (GimpImage *image) { GimpValueArray *args; GimpValueArray *return_vals; - GimpItem **drawables = NULL; + GimpDrawable **drawables = NULL; args = gimp_value_array_new_from_types (NULL, GIMP_TYPE_IMAGE, image, @@ -2508,13 +2501,8 @@ gimp_image_get_selected_drawables (GimpImage *image, args); gimp_value_array_unref (args); - *num_drawables = 0; - if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS) - { - *num_drawables = GIMP_VALUES_GET_INT (return_vals, 1); - { GimpObjectArray *a = g_value_get_boxed (gimp_value_array_index (return_vals, 2)); if (a) drawables = g_memdup2 (a->data, a->length * sizeof (gpointer)); }; - } + drawables = g_value_dup_boxed (gimp_value_array_index (return_vals, 1)); gimp_value_array_unref (return_vals); diff --git a/libgimp/gimpimage_pdb.h b/libgimp/gimpimage_pdb.h index 37cb911082..9ae12aac9b 100644 --- a/libgimp/gimpimage_pdb.h +++ b/libgimp/gimpimage_pdb.h @@ -58,8 +58,7 @@ gboolean gimp_image_unset_active_channel (GimpImage GimpLayer* gimp_image_get_floating_sel (GimpImage *image); GimpDrawable* gimp_image_floating_sel_attached_to (GimpImage *image); gboolean gimp_image_pick_color (GimpImage *image, - gint num_drawables, - const GimpItem **drawables, + const GimpDrawable **drawables, gdouble x, gdouble y, gboolean sample_merged, @@ -161,8 +160,7 @@ GimpPath** gimp_image_get_selected_paths (GimpImage gboolean gimp_image_set_selected_paths (GimpImage *image, gint num_paths, const GimpPath **paths); -GimpItem** gimp_image_get_selected_drawables (GimpImage *image, - gint *num_drawables); +GimpDrawable** gimp_image_get_selected_drawables (GimpImage *image); GimpSelection* gimp_image_get_selection (GimpImage *image); gboolean gimp_image_get_component_active (GimpImage *image, GimpChannelType component); diff --git a/libgimp/gimpselection.c b/libgimp/gimpselection.c index 4c9e2f5336..04f0e75fa0 100644 --- a/libgimp/gimpselection.c +++ b/libgimp/gimpselection.c @@ -73,8 +73,7 @@ gimp_selection_get_by_id (gint32 selection_id) /** * gimp_selection_float: * @image: ignored - * @n_drawables: Size of @drawables. - * @drawables: (array length=n_drawables): The drawables from which to + * @drawables: (array zero-terminated=1): The drawables from which to * float selection. * @offx: x offset for translation. * @offy: y offset for translation. @@ -92,13 +91,9 @@ gimp_selection_get_by_id (gint32 selection_id) */ GimpLayer * gimp_selection_float (GimpImage *image, - gint n_drawables, GimpDrawable **drawables, gint offx, gint offy) { - return _gimp_selection_float (n_drawables, - (const GimpItem **) drawables, - offx, - offy); + return _gimp_selection_float ((const GimpDrawable **) drawables, offx, offy); } diff --git a/libgimp/gimpselection.h b/libgimp/gimpselection.h index dd327a17ab..00c2fe937c 100644 --- a/libgimp/gimpselection.h +++ b/libgimp/gimpselection.h @@ -40,7 +40,6 @@ G_DECLARE_FINAL_TYPE (GimpSelection, gimp_selection, GIMP, SELECTION, GimpChanne GimpSelection * gimp_selection_get_by_id (gint32 selection_id); GimpLayer * gimp_selection_float (GimpImage *image, - gint n_drawables, GimpDrawable **drawables, gint offx, gint offy); diff --git a/libgimp/gimpselection_pdb.c b/libgimp/gimpselection_pdb.c index 5ac25fd8ef..f91227a784 100644 --- a/libgimp/gimpselection_pdb.c +++ b/libgimp/gimpselection_pdb.c @@ -222,8 +222,7 @@ gimp_selection_translate (GimpImage *image, /** * _gimp_selection_float: - * @num_drawables: The number of drawables. - * @drawables: (array length=num_drawables) (element-type GimpItem): The drawables from which to float selection. + * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables from which to float selection. * @offx: x offset for translation. * @offy: y offset for translation. * @@ -239,22 +238,19 @@ gimp_selection_translate (GimpImage *image, * Returns: (transfer none): The floated layer. **/ GimpLayer * -_gimp_selection_float (gint num_drawables, - const GimpItem **drawables, - gint offx, - gint offy) +_gimp_selection_float (const GimpDrawable **drawables, + gint offx, + gint offy) { GimpValueArray *args; GimpValueArray *return_vals; GimpLayer *layer = NULL; args = gimp_value_array_new_from_types (NULL, - G_TYPE_INT, num_drawables, - GIMP_TYPE_OBJECT_ARRAY, NULL, + GIMP_TYPE_CORE_OBJECT_ARRAY, drawables, G_TYPE_INT, offx, G_TYPE_INT, offy, G_TYPE_NONE); - gimp_value_set_object_array (gimp_value_array_index (args, 1), GIMP_TYPE_ITEM, (GObject **) drawables, num_drawables); return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (), "gimp-selection-float", diff --git a/libgimp/gimpselection_pdb.h b/libgimp/gimpselection_pdb.h index fcc34aeda8..8c1c96597f 100644 --- a/libgimp/gimpselection_pdb.h +++ b/libgimp/gimpselection_pdb.h @@ -32,37 +32,36 @@ G_BEGIN_DECLS /* For information look into the C source or the html documentation */ -gboolean gimp_selection_bounds (GimpImage *image, - gboolean *non_empty, - gint *x1, - gint *y1, - gint *x2, - gint *y2); -gint gimp_selection_value (GimpImage *image, - gint x, - gint y); -gboolean gimp_selection_is_empty (GimpImage *image); -gboolean gimp_selection_translate (GimpImage *image, - gint offx, - gint offy); -G_GNUC_INTERNAL GimpLayer* _gimp_selection_float (gint num_drawables, - const GimpItem **drawables, - gint offx, - gint offy); -gboolean gimp_selection_invert (GimpImage *image); -gboolean gimp_selection_sharpen (GimpImage *image); -gboolean gimp_selection_all (GimpImage *image); -gboolean gimp_selection_none (GimpImage *image); -gboolean gimp_selection_feather (GimpImage *image, - gdouble radius); -gboolean gimp_selection_border (GimpImage *image, - gint radius); -gboolean gimp_selection_grow (GimpImage *image, - gint steps); -gboolean gimp_selection_shrink (GimpImage *image, - gint steps); -gboolean gimp_selection_flood (GimpImage *image); -GimpChannel* gimp_selection_save (GimpImage *image); +gboolean gimp_selection_bounds (GimpImage *image, + gboolean *non_empty, + gint *x1, + gint *y1, + gint *x2, + gint *y2); +gint gimp_selection_value (GimpImage *image, + gint x, + gint y); +gboolean gimp_selection_is_empty (GimpImage *image); +gboolean gimp_selection_translate (GimpImage *image, + gint offx, + gint offy); +G_GNUC_INTERNAL GimpLayer* _gimp_selection_float (const GimpDrawable **drawables, + gint offx, + gint offy); +gboolean gimp_selection_invert (GimpImage *image); +gboolean gimp_selection_sharpen (GimpImage *image); +gboolean gimp_selection_all (GimpImage *image); +gboolean gimp_selection_none (GimpImage *image); +gboolean gimp_selection_feather (GimpImage *image, + gdouble radius); +gboolean gimp_selection_border (GimpImage *image, + gint radius); +gboolean gimp_selection_grow (GimpImage *image, + gint steps); +gboolean gimp_selection_shrink (GimpImage *image, + gint steps); +gboolean gimp_selection_flood (GimpImage *image); +GimpChannel* gimp_selection_save (GimpImage *image); G_END_DECLS diff --git a/libgimp/tests/test-selection-float.c b/libgimp/tests/test-selection-float.c index c9ea9f0f18..8cbd973bc4 100644 --- a/libgimp/tests/test-selection-float.c +++ b/libgimp/tests/test-selection-float.c @@ -41,17 +41,17 @@ gimp_c_test_run (GimpProcedure *procedure, /* 1. Fail with no selection */ GIMP_TEST_START("Gimp.Selection.float - no selection") - GIMP_TEST_END(gimp_selection_float (img, 1, &layer1, 10, 10) == NULL) + GIMP_TEST_END(gimp_selection_float (img, (GimpDrawable *[2]) { layer1, NULL }, 10, 10) == NULL) /* 2. Fail on a group layer */ GIMP_TEST_START("Gimp.Selection.float - group layer") - GIMP_TEST_END(gimp_selection_float (img, 1, &group1, 10, 10) == NULL) + GIMP_TEST_END(gimp_selection_float (img, (GimpDrawable *[2]) { group1, NULL }, 10, 10) == NULL) /* 3. Succeed on a normal layer */ gimp_image_select_rectangle (img, GIMP_CHANNEL_OP_REPLACE, 5, 5, 20, 20); GIMP_TEST_START("gimp_selection_float - normal layer") - float_layer = gimp_selection_float (img, 1, &layer1, 10, 10); + float_layer = gimp_selection_float (img, (GimpDrawable *[2]) { layer1, NULL }, 10, 10); GIMP_TEST_END(GIMP_IS_LAYER (float_layer)) GIMP_TEST_START("gimp_floating_sel_remove") @@ -61,7 +61,7 @@ gimp_c_test_run (GimpProcedure *procedure, gimp_image_select_rectangle (img, GIMP_CHANNEL_OP_REPLACE, 5, 5, 20, 20); GIMP_TEST_START("gimp_selection_float - layer inside group") - float_layer = gimp_selection_float (img, 1, &layer2, 10, 10); + float_layer = gimp_selection_float (img, (GimpDrawable *[2]) { layer2, NULL }, 10, 10); GIMP_TEST_END(GIMP_IS_LAYER (float_layer)) GIMP_TEST_START("gimp_floating_sel_remove") diff --git a/libgimpbase/gimpbase.def b/libgimpbase/gimpbase.def index dd735cd94c..1037305c22 100644 --- a/libgimpbase/gimpbase.def +++ b/libgimpbase/gimpbase.def @@ -38,6 +38,7 @@ EXPORTS gimp_component_type_get_type gimp_convert_palette_type_get_type gimp_convolve_type_get_type + gimp_core_object_array_get_type gimp_cpu_accel_get_support gimp_cpu_accel_set_use gimp_data_directory @@ -125,6 +126,7 @@ EXPORTS gimp_paint_application_mode_get_type gimp_param_array_get_type gimp_param_choice_get_type + gimp_param_core_object_array_get_type gimp_param_export_options_get_type gimp_param_float_array_get_type gimp_param_int32_array_get_type @@ -134,6 +136,7 @@ EXPORTS gimp_param_parasite_get_type gimp_param_spec_array gimp_param_spec_choice + gimp_param_spec_core_object_array gimp_param_spec_export_options gimp_param_spec_float_array gimp_param_spec_int32_array diff --git a/libgimpbase/gimpparamspecs.c b/libgimpbase/gimpparamspecs.c index 3dfc6df2f5..738ae3b574 100644 --- a/libgimpbase/gimpparamspecs.c +++ b/libgimpbase/gimpparamspecs.c @@ -865,6 +865,223 @@ gimp_color_array_get_length (GimpColorArray array) } +/* + * GIMP_TYPE_CORE_OBJECT_ARRAY + */ + +static GimpCoreObjectArray gimp_core_object_array_copy (GimpCoreObjectArray array); +static gsize gimp_core_object_array_get_length (GimpCoreObjectArray array); + +GType +gimp_core_object_array_get_type (void) +{ + static gsize static_g_define_type_id = 0; + + if (g_once_init_enter (&static_g_define_type_id)) + { + GType g_define_type_id = + g_boxed_type_register_static (g_intern_static_string ("GimpCoreObjectArray"), + (GBoxedCopyFunc) gimp_core_object_array_copy, + (GBoxedFreeFunc) g_free); + + g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + + return static_g_define_type_id; +} + +/** + * gimp_core_object_array_copy: + * @array: an array of core_objects. + * + * Duplicate a new #GimpCoreObjectArray, which is basically simply a + * %NULL-terminated array of [class@GObject.Object]. Note that you + * should only use this alias type for arrays of core type objects + * internally hold by `libgimp`, such as layers, channels, paths, images + * and so on, because no reference is hold to the element objects. + * + * As a consequence, the copy also makes a shallow copy of the elements. + * + * Returns: (transfer container) (array zero-terminated=1): a new #GimpCoreObjectArray. + **/ +static GimpCoreObjectArray +gimp_core_object_array_copy (GimpCoreObjectArray array) +{ + GObject **copy; + gsize length = gimp_core_object_array_get_length (array); + + copy = g_malloc0 (sizeof (GObject *) * (length + 1)); + + for (gint i = 0; i < length; i++) + copy[i] = array[i]; + + return copy; +} + +/** + * gimp_core_object_array_get_length: + * @array: an array of core_objects. + * + * Returns: the number of [class@GObject.Object] in @array. + **/ +static gsize +gimp_core_object_array_get_length (GimpCoreObjectArray array) +{ + gsize length = 0; + + while (array && array[length] != NULL) + length++; + + return length; +} + + +/* + * GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY + */ + +static void gimp_param_core_object_array_class_init (GParamSpecClass *klass); +static void gimp_param_core_object_array_init (GParamSpec *pspec); +static gboolean gimp_param_core_object_array_validate (GParamSpec *pspec, + GValue *value); +static gint gimp_param_core_object_array_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2); + +GType +gimp_param_core_object_array_get_type (void) +{ + static GType type = 0; + + if (! type) + { + const GTypeInfo info = + { + sizeof (GParamSpecClass), + NULL, NULL, + (GClassInitFunc) gimp_param_core_object_array_class_init, + NULL, NULL, + sizeof (GimpParamSpecCoreObjectArray), + 0, + (GInstanceInitFunc) gimp_param_core_object_array_init + }; + + type = g_type_register_static (G_TYPE_PARAM_BOXED, + "GimpParamCoreObjectArray", &info, 0); + } + + return type; +} + +static void +gimp_param_core_object_array_class_init (GParamSpecClass *klass) +{ + klass->value_type = GIMP_TYPE_CORE_OBJECT_ARRAY; + klass->value_validate = gimp_param_core_object_array_validate; + klass->values_cmp = gimp_param_core_object_array_values_cmp; +} + +static void +gimp_param_core_object_array_init (GParamSpec *pspec) +{ +} + +static gboolean +gimp_param_core_object_array_validate (GParamSpec *pspec, + GValue *value) +{ + GimpParamSpecCoreObjectArray *array_spec = GIMP_PARAM_SPEC_CORE_OBJECT_ARRAY (pspec); + GObject **array = value->data[0].v_pointer; + + if (array) + { + gsize length = gimp_core_object_array_get_length (array); + gsize i; + + if (length == 0) + { + g_value_set_boxed (value, NULL); + return FALSE; + } + + for (i = 0; i < length; i++) + { + if (array[i] && ! g_type_is_a (G_OBJECT_TYPE (array[i]), array_spec->object_type)) + { + g_value_set_boxed (value, NULL); + return TRUE; + } + } + } + + return FALSE; +} + +static gint +gimp_param_core_object_array_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + GObject **array1 = value1->data[0].v_pointer; + GObject **array2 = value2->data[0].v_pointer; + + /* try to return at least *something*, it's useless anyway... */ + + if (! array1) + return array2 != NULL ? -1 : 0; + else if (! array2) + return array1 != NULL ? 1 : 0; + else if (gimp_core_object_array_get_length (array1) < gimp_core_object_array_get_length (array2)) + return -1; + else if (gimp_core_object_array_get_length (array1) > gimp_core_object_array_get_length (array2)) + return 1; + + for (gsize i = 0; i < gimp_core_object_array_get_length (array1); i++) + if (array1[0] != array2[0]) + return 1; + + return 0; +} + +/** + * gimp_param_spec_core_object_array: + * @name: Canonical name of the property specified. + * @nick: Nick name of the property specified. + * @blurb: Description of the property specified. + * @object_type: GType of the array's elements. + * @flags: Flags for the property specified. + * + * Creates a new #GimpParamSpecCoreObjectArray specifying a + * [type@CoreObjectArray] property. + * + * See g_param_spec_internal() for details on property names. + * + * Returns: (transfer floating): The newly created #GimpParamSpecCoreObjectArray. + * + * Since: 3.0 + **/ +GParamSpec * +gimp_param_spec_core_object_array (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType object_type, + GParamFlags flags) +{ + GimpParamSpecCoreObjectArray *array_spec; + + g_return_val_if_fail (g_type_is_a (object_type, G_TYPE_OBJECT), NULL); + + array_spec = g_param_spec_internal (GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY, + name, nick, blurb, flags); + + g_return_val_if_fail (array_spec, NULL); + + array_spec->object_type = object_type; + + return G_PARAM_SPEC (array_spec); +} + + /* * GIMP_TYPE_OBJECT_ARRAY */ diff --git a/libgimpbase/gimpparamspecs.h b/libgimpbase/gimpparamspecs.h index 2f734836b8..c66f3366b9 100644 --- a/libgimpbase/gimpparamspecs.h +++ b/libgimpbase/gimpparamspecs.h @@ -345,6 +345,58 @@ void gimp_color_array_free (GimpColorArray array); gint gimp_color_array_get_length (GimpColorArray array); +/* + * GIMP_TYPE_CORE_OBJECT_ARRAY + */ + +/** + * GimpCoreObjectArray: + * + * A boxed type which is nothing more than an alias to a %NULL-terminated array + * of [class@GObject.Object]. No reference is being hold on contents + * because core objects are owned by `libgimp`. + * + * The reason of existence for this alias is to have common arrays of + * objects as a boxed type easy to use as plug-in's procedure argument. + * + * You should never have to interact with this type directly. + * + * Since: 3.0 + */ +typedef GObject** GimpCoreObjectArray; + +#define GIMP_TYPE_CORE_OBJECT_ARRAY (gimp_core_object_array_get_type ()) +#define GIMP_VALUE_HOLDS_CORE_OBJECT_ARRAY(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_CORE_OBJECT_ARRAY)) + +GType gimp_core_object_array_get_type (void) G_GNUC_CONST; + + +/* + * GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY + */ + +#define GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY (gimp_param_core_object_array_get_type ()) +#define GIMP_PARAM_SPEC_CORE_OBJECT_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY, GimpParamSpecCoreObjectArray)) +#define GIMP_IS_PARAM_SPEC_CORE_OBJECT_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_CORE_OBJECT_ARRAY)) + +typedef struct _GimpParamSpecCoreObjectArray GimpParamSpecCoreObjectArray; + +struct _GimpParamSpecCoreObjectArray +{ + GParamSpecBoxed parent_instance; + + GType object_type; +}; + +GType gimp_param_core_object_array_get_type (void) G_GNUC_CONST; + +GParamSpec * gimp_param_spec_core_object_array (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType object_type, + GParamFlags flags); + + /* * GIMP_TYPE_OBJECT_ARRAY */ diff --git a/pdb/app.pl b/pdb/app.pl index f4b6d63137..ab59dfd518 100644 --- a/pdb/app.pl +++ b/pdb/app.pl @@ -696,6 +696,15 @@ gimp_param_spec_object_array ("$name", "$blurb", GIMP_TYPE_ITEM, $flags) +CODE + } + elsif ($pdbtype eq 'drawablearray') { + $pspec = < 'drawables', type => 'itemarray', - desc => 'The drawables to cut from', - no_validate => 1, - array => { name => 'num_drawables', - type => '1 <= int32', - desc => "The number of drawables" } } + { name => 'drawables', type => 'drawablearray', + desc => 'The drawables to cut from' } ); @outargs = ( @@ -56,7 +52,7 @@ HELP GList *drawable_list = NULL; gint i; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, GIMP_PDB_ITEM_CONTENT, error) || @@ -127,12 +123,8 @@ HELP &std_pdb_misc; @inargs = ( - { name => 'drawables', type => 'itemarray', - desc => 'Drawables to copy from', - no_validate => 1, - array => { name => 'num_drawables', - type => '1 <= int32', - desc => "The number of drawables to save" } }, + { name => 'drawables', type => 'drawablearray', + desc => 'Drawables to copy from' } ); @outargs = ( @@ -148,7 +140,7 @@ HELP GList *drawables_list = NULL; gint i; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, 0, error)) { @@ -167,7 +159,7 @@ HELP drawables_list = g_list_prepend (drawables_list, (gpointer) drawables[i]); } - if (success && num_drawables > 0) + if (success && g_list_length (drawables_list) > 0) { GError *my_error = NULL; @@ -238,8 +230,8 @@ sub edit_paste { $help = <<'HELP'; This procedure pastes a copy of the internal GIMP edit buffer to the specified drawable. The GIMP edit buffer will be empty unless a call -was previously made to either gimp_edit_cut() or gimp_edit_copy(). The -"paste_into" option specifies whether to clear the current image +was previously made to either [func@Gimp.edit_cut] or [func@Gimp.edit_copy]. +The "paste_into" option specifies whether to clear the current image selection, or to paste the buffer "behind" the selection. This allows the selection to act as a mask for the pasted buffer. Anywhere that the selection mask is non-zero, the pasted buffer will show @@ -249,9 +241,9 @@ If the image has a floating selection at the time of pasting, the old floating selection will be anchored to its drawable before the new floating selection is added. -This procedure returns the new layers (floating or not). If the result +This procedure returns the new drawables (floating or not). If the result is a floating selection, it will already be attached to the specified -drawable, and a subsequent call to floating_sel_attach is not needed. +drawable, and a subsequent call to [func@Gimp.floating_sel_attach] is not needed. HELP &std_pdb_misc; @@ -264,10 +256,8 @@ HELP ); @outargs = ( - { name => 'layers', type => 'layerarray', - desc => 'The list of pasted layers.', - array => { name => 'num_layers', - desc => 'The newly pasted layers' } } + { name => 'new_drawables', type => 'drawablearray', + desc => 'The list of pasted layers.' } ); %invoke = ( @@ -282,6 +272,7 @@ HELP { GList *drawables = NULL; GList *list; + gint num_drawables; gint i; if (drawable != NULL) @@ -299,11 +290,11 @@ HELP if (! list) success = FALSE; - num_layers = g_list_length (list); - layers = g_new (GimpLayer *, num_layers); + num_drawables = g_list_length (list); + new_drawables = g_new0 (GimpDrawable *, num_drawables + 1); - for (i = 0; i < num_layers; i++, list = g_list_next (list)) - layers[i] = g_object_ref (list->data); + for (i = 0; i < num_drawables; i++, list = g_list_next (list)) + new_drawables[i] = g_object_ref (list->data); g_list_free (list); } @@ -359,12 +350,8 @@ HELP &mitch_pdb_misc('2005', '2.4'); @inargs = ( - { name => 'drawables', type => 'itemarray', - desc => 'The drawables to cut from', - no_validate => 1, - array => { name => 'num_drawables', - type => '1 <= int32', - desc => "The number of drawables" } }, + { name => 'drawables', type => 'drawablearray', + desc => 'The drawables to cut from' }, { name => 'buffer_name', type => 'string', non_empty => 1, desc => 'The name of the buffer to create' } ); @@ -382,7 +369,7 @@ HELP GList *drawable_list = NULL; gint i; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, GIMP_PDB_ITEM_CONTENT, error) || @@ -449,12 +436,8 @@ HELP &mitch_pdb_misc('2005', '2.4'); @inargs = ( - { name => 'drawables', type => 'itemarray', - desc => 'The drawables to copy from', - no_validate => 1, - array => { name => 'num_drawables', - type => '1 <= int32', - desc => "The number of drawables" } }, + { name => 'drawables', type => 'drawablearray', + desc => 'The drawables to copy from' }, { name => 'buffer_name', type => 'string', non_empty => 1, desc => 'The name of the buffer to create' } ); @@ -472,7 +455,7 @@ HELP GList *drawable_list = NULL; gint i; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, 0, error)) diff --git a/pdb/groups/image.pdb b/pdb/groups/image.pdb index d013b0ecfb..ed7cb11959 100644 --- a/pdb/groups/image.pdb +++ b/pdb/groups/image.pdb @@ -429,12 +429,8 @@ HELP @inargs = ( { name => 'image', type => 'image', desc => 'The image' }, - { name => 'drawables', type => 'itemarray', - desc => 'The drawables to pick from', - no_validate => 1, - array => { name => 'num_drawables', - type => '1 <= int32', - desc => "The number of drawables" } }, + { name => 'drawables', type => 'drawablearray', + desc => 'The drawables to pick from' }, { name => 'x', type => 'float', desc => 'x coordinate of upper-left corner of rectangle' }, { name => 'y', type => 'float', @@ -461,13 +457,13 @@ HELP if (! sample_merged) { - if (num_drawables == 0) + if (drawables == NULL || drawables[0] == NULL) { success = FALSE; } else { - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) if (gimp_item_get_image (GIMP_ITEM (drawables[i])) != image) { success = FALSE; @@ -486,7 +482,7 @@ HELP { GList *drawable_list = NULL; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { GimpPickable *pickable = (GimpPickable *) drawables[i]; @@ -2231,16 +2227,15 @@ HELP ); @outargs = ( - { name => 'drawables', type => 'itemarray', - desc => 'The list of selected drawables in the image.', - array => { name => 'num_drawables', - desc => 'The number of selected drawables in the image' } } + { name => 'drawables', type => 'drawablearray', + desc => 'The list of selected drawables in the image.' } ); %invoke = ( code => <<'CODE' { GList *list = gimp_image_get_selected_drawables (image); + gsize num_drawables; num_drawables = g_list_length (list); @@ -2248,10 +2243,10 @@ HELP { gint i; - drawables = g_new (GimpItem *, num_drawables); + drawables = g_new0 (GimpDrawable *, num_drawables + 1); for (i = 0; i < num_drawables; i++, list = g_list_next (list)) - drawables[i] = g_object_ref (list->data); + drawables[i] = list->data; } } CODE diff --git a/pdb/groups/selection.pdb b/pdb/groups/selection.pdb index 71d26255fb..86dd16f62e 100644 --- a/pdb/groups/selection.pdb +++ b/pdb/groups/selection.pdb @@ -181,12 +181,8 @@ HELP $lib_private = 1; @inargs = ( - { name => 'drawables', type => 'itemarray', - desc => 'The drawables from which to float selection', - no_validate => 1, - array => { name => 'num_drawables', - type => '1 <= int32', - desc => "The number of drawables" } }, + { name => 'drawables', type => 'drawablearray', + desc => 'The drawables from which to float selection' }, { name => 'offx', type => 'int32', desc => 'x offset for translation' }, { name => 'offy', type => 'int32', @@ -204,13 +200,13 @@ HELP GimpImage *image = NULL; gint i; - if (num_drawables < 1) + if (drawables == NULL || drawables[0] == NULL) { success = FALSE; } else { - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) { if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL, GIMP_PDB_ITEM_CONTENT, error) || @@ -231,7 +227,7 @@ HELP { GList *drawable_list = NULL; - for (i = 0; i < num_drawables; i++) + for (i = 0; drawables[i] != NULL; i++) drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]); layer = gimp_selection_float (GIMP_SELECTION (gimp_image_get_mask (image)), diff --git a/pdb/pdb.pl b/pdb/pdb.pl index e4bb0665d9..6af9fc796c 100644 --- a/pdb/pdb.pl +++ b/pdb/pdb.pl @@ -135,6 +135,18 @@ package Gimp::CodeGen::pdb; set_value_func => 'gimp_value_set_object_array ($value, GIMP_TYPE_ITEM, (GObject **) $var, $var_len)', take_value_func => 'gimp_value_take_object_array ($value, GIMP_TYPE_ITEM, (GObject **) $var, $var_len)' }, + drawablearray => { name => 'DRAWABLEARRAY', + gtype => 'GIMP_TYPE_CORE_OBJECT_ARRAY', + type => 'GimpDrawable **', + const_type => 'const GimpDrawable **', + init_value => 'NULL', + in_annotate => '(element-type GimpDrawable) (array zero-terminated=1)', + out_annotate => '(element-type GimpDrawable) (array zero-terminated=1) (transfer container)', + get_value_func => '$var = g_value_get_boxed ($value)', + dup_value_func => '$var = g_value_dup_boxed (gimp_value_array_index ($value))', + set_value_func => 'g_value_set_boxed ($value, $var)', + take_value_func => 'g_value_take_boxed ($value, $var)' }, + layerarray => { name => 'LAYERARRAY', gtype => 'GIMP_TYPE_OBJECT_ARRAY', type => 'GimpLayer **', diff --git a/plug-ins/common/curve-bend.c b/plug-ins/common/curve-bend.c index c078d3d886..39278ca6b5 100644 --- a/plug-ins/common/curve-bend.c +++ b/plug-ins/common/curve-bend.c @@ -593,18 +593,19 @@ p_if_selection_float_it (GimpImage *image, if (non_empty && sel_channel) { + const GimpDrawable *drawables[2] = { (GimpDrawable *) layer, NULL }; + /* selection is TRUE, make a layer (floating selection) from the selection */ - if (gimp_edit_copy (1, (const GimpItem **) &layer)) + if (gimp_edit_copy (drawables)) { - GimpLayer **layers; - gint num_layers; + GimpDrawable **layers; - layers = gimp_edit_paste (GIMP_DRAWABLE (layer), FALSE, &num_layers); + layers = gimp_edit_paste (GIMP_DRAWABLE (layer), FALSE); /* Since we explicitly copied a single layer, there should * be no more than a single layer in the paste as well. */ - layer = num_layers ? layers[0] : NULL; + layer = (GimpLayer *) (layers && layers[0] ? layers[0] : NULL); g_free (layers); } diff --git a/plug-ins/common/file-pdf-export.c b/plug-ins/common/file-pdf-export.c index 692cc6c9f7..f753c60b1e 100644 --- a/plug-ins/common/file-pdf-export.c +++ b/plug-ins/common/file-pdf-export.c @@ -713,16 +713,16 @@ pdf_export_image (GimpProcedure *procedure, gint32 n_layers; gdouble x_res, y_res; gdouble x_scale, y_scale; - GimpItem **drawables; - gint n_drawables; + GimpDrawable **drawables; gint j; - drawables = gimp_image_get_selected_drawables (image, &n_drawables); - if (n_drawables == 0) + drawables = gimp_image_get_selected_drawables (image); + if (drawables[0] == NULL) { g_free (drawables); continue; } + g_free (drawables); /* Save the state of the surface before any changes, so that * settings from one page won't affect all the others @@ -1597,9 +1597,9 @@ drawText (GimpLayer *layer, if (type == GIMP_RGBA_IMAGE) color = gimp_text_layer_get_color (GIMP_TEXT_LAYER (layer)); else - gimp_image_pick_color (gimp_item_get_image (GIMP_ITEM (layer)), 1, - (const GimpItem**) &layer, x, y, FALSE, FALSE, 0, - &color); + gimp_image_pick_color (gimp_item_get_image (GIMP_ITEM (layer)), + (const GimpDrawable*[2]) { GIMP_DRAWABLE (layer), NULL }, + x, y, FALSE, FALSE, 0, &color); /* TODO: this export plug-in is not space-aware yet, so we draw everything as * sRGB for the time being. diff --git a/plug-ins/common/file-ps.c b/plug-ins/common/file-ps.c index 05c8672aac..fe817f43c3 100644 --- a/plug-ins/common/file-ps.c +++ b/plug-ins/common/file-ps.c @@ -1289,10 +1289,9 @@ load_image (GFile *file, { GimpLayer *current_layer; gchar *name; - GimpItem **tmp_drawables; - gint n_drawables; + GimpDrawable **tmp_drawables; - tmp_drawables = gimp_image_get_selected_drawables (image_list[k], &n_drawables); + tmp_drawables = gimp_image_get_selected_drawables (image_list[k]); name = gimp_item_get_name (GIMP_ITEM (tmp_drawables[0])); diff --git a/plug-ins/file-dds/ddswrite.c b/plug-ins/file-dds/ddswrite.c index 952ef0f52e..06f761ab0d 100644 --- a/plug-ins/file-dds/ddswrite.c +++ b/plug-ins/file-dds/ddswrite.c @@ -570,12 +570,11 @@ write_dds (GFile *file, */ if (! is_duplicate_image) { - GimpImage *duplicate_image = gimp_image_duplicate (image); - GimpItem **drawables; - gint n_drawables; + GimpImage *duplicate_image = gimp_image_duplicate (image); + GimpDrawable **drawables; - drawables = gimp_image_get_selected_drawables (duplicate_image, &n_drawables); - rc = write_image (fp, duplicate_image, GIMP_DRAWABLE (drawables[0]), config); + drawables = gimp_image_get_selected_drawables (duplicate_image); + rc = write_image (fp, duplicate_image, drawables[0], config); gimp_image_delete (duplicate_image); g_free (drawables); } diff --git a/plug-ins/file-fits/fits.c b/plug-ins/file-fits/fits.c index 49bc2a5b68..b1ee485fb5 100644 --- a/plug-ins/file-fits/fits.c +++ b/plug-ins/file-fits/fits.c @@ -292,11 +292,10 @@ fits_export (GimpProcedure *procedure, gpointer run_data) { GimpImage *duplicate_image; - GimpItem **flipped_drawables; + GimpDrawable **flipped_drawables; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpExportReturn export = GIMP_EXPORT_IGNORE; GList *drawables; - gint n_drawables; GError *error = NULL; gegl_init (NULL, NULL); @@ -306,17 +305,14 @@ fits_export (GimpProcedure *procedure, export = gimp_export_options_get_image (options, &image); - drawables = gimp_image_list_layers (image); - n_drawables = g_list_length (drawables); + drawables = gimp_image_list_layers (image); /* Flip image vertical since FITS writes from bottom to top */ duplicate_image = gimp_image_duplicate (image); gimp_image_flip (duplicate_image, GIMP_ORIENTATION_VERTICAL); - flipped_drawables = - gimp_image_get_selected_drawables (duplicate_image, &n_drawables); + flipped_drawables = gimp_image_get_selected_drawables (duplicate_image); - if (! export_image (file, image, GIMP_DRAWABLE (flipped_drawables[0]), - &error)) + if (! export_image (file, image, flipped_drawables[0], &error)) status = GIMP_PDB_EXECUTION_ERROR; gimp_image_delete (duplicate_image);