app, libgimp, pdb, plug-ins: new GimpCoreObjectArray type and drawablearray…

… 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.
This commit is contained in:
Jehan 2024-10-21 21:59:26 +02:00
parent cb4687633c
commit 38c2cd3b15
28 changed files with 739 additions and 437 deletions

View file

@ -60,12 +60,10 @@ edit_cut_invoker (GimpProcedure *procedure,
{ {
gboolean success = TRUE; gboolean success = TRUE;
GimpValueArray *return_vals; GimpValueArray *return_vals;
gint num_drawables; const GimpDrawable **drawables;
const GimpItem **drawables;
gboolean non_empty = FALSE; gboolean non_empty = FALSE;
num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); drawables = g_value_get_boxed (gimp_value_array_index (args, 0));
drawables = (const GimpItem **) gimp_value_get_object_array (gimp_value_array_index (args, 1));
if (success) if (success)
{ {
@ -73,7 +71,7 @@ edit_cut_invoker (GimpProcedure *procedure,
GList *drawable_list = NULL; GList *drawable_list = NULL;
gint i; 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, if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL,
GIMP_PDB_ITEM_CONTENT, error) || GIMP_PDB_ITEM_CONTENT, error) ||
@ -139,12 +137,10 @@ edit_copy_invoker (GimpProcedure *procedure,
{ {
gboolean success = TRUE; gboolean success = TRUE;
GimpValueArray *return_vals; GimpValueArray *return_vals;
gint num_drawables; const GimpDrawable **drawables;
const GimpItem **drawables;
gboolean non_empty = FALSE; gboolean non_empty = FALSE;
num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); drawables = g_value_get_boxed (gimp_value_array_index (args, 0));
drawables = (const GimpItem **) gimp_value_get_object_array (gimp_value_array_index (args, 1));
if (success) if (success)
{ {
@ -152,7 +148,7 @@ edit_copy_invoker (GimpProcedure *procedure,
GList *drawables_list = NULL; GList *drawables_list = NULL;
gint i; 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)) 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]); 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; GError *my_error = NULL;
@ -251,8 +247,7 @@ edit_paste_invoker (GimpProcedure *procedure,
GimpValueArray *return_vals; GimpValueArray *return_vals;
GimpDrawable *drawable; GimpDrawable *drawable;
gboolean paste_into; gboolean paste_into;
gint num_layers = 0; GimpDrawable **new_drawables = NULL;
GimpLayer **layers = NULL;
drawable = g_value_get_object (gimp_value_array_index (args, 0)); drawable = g_value_get_object (gimp_value_array_index (args, 0));
paste_into = g_value_get_boolean (gimp_value_array_index (args, 1)); 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 *drawables = NULL;
GList *list; GList *list;
gint num_drawables;
gint i; gint i;
if (drawable != NULL) if (drawable != NULL)
@ -285,11 +281,11 @@ edit_paste_invoker (GimpProcedure *procedure,
if (! list) if (! list)
success = FALSE; success = FALSE;
num_layers = g_list_length (list); num_drawables = g_list_length (list);
layers = g_new (GimpLayer *, num_layers); new_drawables = g_new0 (GimpDrawable *, num_drawables + 1);
for (i = 0; i < num_layers; i++, list = g_list_next (list)) for (i = 0; i < num_drawables; i++, list = g_list_next (list))
layers[i] = g_object_ref (list->data); new_drawables[i] = g_object_ref (list->data);
g_list_free (list); g_list_free (list);
} }
@ -301,10 +297,7 @@ edit_paste_invoker (GimpProcedure *procedure,
error ? *error : NULL); error ? *error : NULL);
if (success) if (success)
{ g_value_take_boxed (gimp_value_array_index (return_vals, 1), new_drawables);
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);
}
return return_vals; return return_vals;
} }
@ -350,14 +343,12 @@ edit_named_cut_invoker (GimpProcedure *procedure,
{ {
gboolean success = TRUE; gboolean success = TRUE;
GimpValueArray *return_vals; GimpValueArray *return_vals;
gint num_drawables; const GimpDrawable **drawables;
const GimpItem **drawables;
const gchar *buffer_name; const gchar *buffer_name;
gchar *real_name = NULL; gchar *real_name = NULL;
num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); drawables = g_value_get_boxed (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, 1));
buffer_name = g_value_get_string (gimp_value_array_index (args, 2));
if (success) if (success)
{ {
@ -365,7 +356,7 @@ edit_named_cut_invoker (GimpProcedure *procedure,
GList *drawable_list = NULL; GList *drawable_list = NULL;
gint i; 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, if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL,
GIMP_PDB_ITEM_CONTENT, error) || GIMP_PDB_ITEM_CONTENT, error) ||
@ -436,14 +427,12 @@ edit_named_copy_invoker (GimpProcedure *procedure,
{ {
gboolean success = TRUE; gboolean success = TRUE;
GimpValueArray *return_vals; GimpValueArray *return_vals;
gint num_drawables; const GimpDrawable **drawables;
const GimpItem **drawables;
const gchar *buffer_name; const gchar *buffer_name;
gchar *real_name = NULL; gchar *real_name = NULL;
num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); drawables = g_value_get_boxed (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, 1));
buffer_name = g_value_get_string (gimp_value_array_index (args, 2));
if (success) if (success)
{ {
@ -451,7 +440,7 @@ edit_named_copy_invoker (GimpProcedure *procedure,
GList *drawable_list = NULL; GList *drawable_list = NULL;
gint i; 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, if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL,
0, error)) 0, error))
@ -680,17 +669,11 @@ register_edit_procs (GimpPDB *pdb)
"Spencer Kimball & Peter Mattis", "Spencer Kimball & Peter Mattis",
"1995-1996"); "1995-1996");
gimp_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
g_param_spec_int ("num-drawables", gimp_param_spec_core_object_array ("drawables",
"num drawables", "drawables",
"The number of drawables", "The drawables to cut from",
1, G_MAXINT32, 1, GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE)); 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_procedure_add_return_value (procedure, gimp_procedure_add_return_value (procedure,
g_param_spec_boolean ("non-empty", g_param_spec_boolean ("non-empty",
"non empty", "non empty",
@ -717,17 +700,11 @@ register_edit_procs (GimpPDB *pdb)
"Spencer Kimball & Peter Mattis", "Spencer Kimball & Peter Mattis",
"1995-1996"); "1995-1996");
gimp_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
g_param_spec_int ("num-drawables", gimp_param_spec_core_object_array ("drawables",
"num drawables", "drawables",
"The number of drawables to save", "Drawables to copy from",
1, G_MAXINT32, 1, GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE)); 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_procedure_add_return_value (procedure, gimp_procedure_add_return_value (procedure,
g_param_spec_boolean ("non-empty", g_param_spec_boolean ("non-empty",
"non empty", "non empty",
@ -774,8 +751,8 @@ register_edit_procs (GimpPDB *pdb)
"gimp-edit-paste"); "gimp-edit-paste");
gimp_procedure_set_static_help (procedure, gimp_procedure_set_static_help (procedure,
"Paste buffer to the specified drawable.", "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 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 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 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); NULL);
gimp_procedure_set_static_attribution (procedure, gimp_procedure_set_static_attribution (procedure,
"Spencer Kimball & Peter Mattis", "Spencer Kimball & Peter Mattis",
@ -794,17 +771,11 @@ register_edit_procs (GimpPDB *pdb)
FALSE, FALSE,
GIMP_PARAM_READWRITE)); GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure, gimp_procedure_add_return_value (procedure,
g_param_spec_int ("num-layers", gimp_param_spec_core_object_array ("new-drawables",
"num layers", "new drawables",
"The newly pasted layers", "The list of pasted layers.",
0, G_MAXINT32, 0, GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE)); 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_pdb_register_procedure (pdb, procedure); gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure); g_object_unref (procedure);
@ -846,17 +817,11 @@ register_edit_procs (GimpPDB *pdb)
"Michael Natterer", "Michael Natterer",
"2005"); "2005");
gimp_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
g_param_spec_int ("num-drawables", gimp_param_spec_core_object_array ("drawables",
"num drawables", "drawables",
"The number of drawables", "The drawables to cut from",
1, G_MAXINT32, 1, GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE)); 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_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("buffer-name", gimp_param_spec_string ("buffer-name",
"buffer name", "buffer name",
@ -889,17 +854,11 @@ register_edit_procs (GimpPDB *pdb)
"Michael Natterer", "Michael Natterer",
"2005"); "2005");
gimp_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
g_param_spec_int ("num-drawables", gimp_param_spec_core_object_array ("drawables",
"num drawables", "drawables",
"The number of drawables", "The drawables to copy from",
1, G_MAXINT32, 1, GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE)); 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_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("buffer-name", gimp_param_spec_string ("buffer-name",
"buffer name", "buffer name",

View file

@ -651,8 +651,7 @@ image_pick_color_invoker (GimpProcedure *procedure,
gboolean success = TRUE; gboolean success = TRUE;
GimpValueArray *return_vals; GimpValueArray *return_vals;
GimpImage *image; GimpImage *image;
gint num_drawables; const GimpDrawable **drawables;
const GimpItem **drawables;
gdouble x; gdouble x;
gdouble y; gdouble y;
gboolean sample_merged; gboolean sample_merged;
@ -661,13 +660,12 @@ image_pick_color_invoker (GimpProcedure *procedure,
GeglColor *color = NULL; GeglColor *color = NULL;
image = g_value_get_object (gimp_value_array_index (args, 0)); image = g_value_get_object (gimp_value_array_index (args, 0));
num_drawables = g_value_get_int (gimp_value_array_index (args, 1)); drawables = g_value_get_boxed (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, 2));
x = g_value_get_double (gimp_value_array_index (args, 3)); y = 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, 4));
sample_merged = g_value_get_boolean (gimp_value_array_index (args, 5)); sample_average = 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, 6));
average_radius = g_value_get_double (gimp_value_array_index (args, 7));
if (success) if (success)
{ {
@ -675,13 +673,13 @@ image_pick_color_invoker (GimpProcedure *procedure,
if (! sample_merged) if (! sample_merged)
{ {
if (num_drawables == 0) if (drawables == NULL || drawables[0] == NULL)
{ {
success = FALSE; success = FALSE;
} }
else 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) if (gimp_item_get_image (GIMP_ITEM (drawables[i])) != image)
{ {
success = FALSE; success = FALSE;
@ -700,7 +698,7 @@ image_pick_color_invoker (GimpProcedure *procedure,
{ {
GList *drawable_list = NULL; GList *drawable_list = NULL;
for (i = 0; i < num_drawables; i++) for (i = 0; drawables[i] != NULL; i++)
{ {
GimpPickable *pickable = (GimpPickable *) drawables[i]; GimpPickable *pickable = (GimpPickable *) drawables[i];
@ -2175,14 +2173,14 @@ image_get_selected_drawables_invoker (GimpProcedure *procedure,
gboolean success = TRUE; gboolean success = TRUE;
GimpValueArray *return_vals; GimpValueArray *return_vals;
GimpImage *image; GimpImage *image;
gint num_drawables = 0; GimpDrawable **drawables = NULL;
GimpItem **drawables = NULL;
image = g_value_get_object (gimp_value_array_index (args, 0)); image = g_value_get_object (gimp_value_array_index (args, 0));
if (success) if (success)
{ {
GList *list = gimp_image_get_selected_drawables (image); GList *list = gimp_image_get_selected_drawables (image);
gsize num_drawables;
num_drawables = g_list_length (list); num_drawables = g_list_length (list);
@ -2190,10 +2188,10 @@ image_get_selected_drawables_invoker (GimpProcedure *procedure,
{ {
gint i; 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)) 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); error ? *error : NULL);
if (success) if (success)
{ g_value_take_boxed (gimp_value_array_index (return_vals, 1), drawables);
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);
}
return return_vals; return return_vals;
} }
@ -3674,17 +3669,11 @@ register_image_procs (GimpPDB *pdb)
FALSE, FALSE,
GIMP_PARAM_READWRITE)); GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
g_param_spec_int ("num-drawables", gimp_param_spec_core_object_array ("drawables",
"num drawables", "drawables",
"The number of drawables", "The drawables to pick from",
1, G_MAXINT32, 1, GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE)); 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_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
g_param_spec_double ("x", g_param_spec_double ("x",
"x", "x",
@ -5087,17 +5076,11 @@ register_image_procs (GimpPDB *pdb)
FALSE, FALSE,
GIMP_PARAM_READWRITE)); GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure, gimp_procedure_add_return_value (procedure,
g_param_spec_int ("num-drawables", gimp_param_spec_core_object_array ("drawables",
"num drawables", "drawables",
"The number of selected drawables in the image", "The list of selected drawables in the image.",
0, G_MAXINT32, 0, GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE)); 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_pdb_register_procedure (pdb, procedure); gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure); g_object_unref (procedure);

View file

@ -197,29 +197,27 @@ selection_float_invoker (GimpProcedure *procedure,
{ {
gboolean success = TRUE; gboolean success = TRUE;
GimpValueArray *return_vals; GimpValueArray *return_vals;
gint num_drawables; const GimpDrawable **drawables;
const GimpItem **drawables;
gint offx; gint offx;
gint offy; gint offy;
GimpLayer *layer = NULL; GimpLayer *layer = NULL;
num_drawables = g_value_get_int (gimp_value_array_index (args, 0)); drawables = g_value_get_boxed (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, 1));
offx = g_value_get_int (gimp_value_array_index (args, 2)); offy = g_value_get_int (gimp_value_array_index (args, 2));
offy = g_value_get_int (gimp_value_array_index (args, 3));
if (success) if (success)
{ {
GimpImage *image = NULL; GimpImage *image = NULL;
gint i; gint i;
if (num_drawables < 1) if (drawables == NULL || drawables[0] == NULL)
{ {
success = FALSE; success = FALSE;
} }
else 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, if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL,
GIMP_PDB_ITEM_CONTENT, error) || GIMP_PDB_ITEM_CONTENT, error) ||
@ -240,7 +238,7 @@ selection_float_invoker (GimpProcedure *procedure,
{ {
GList *drawable_list = NULL; 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]); drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]);
layer = gimp_selection_float (GIMP_SELECTION (gimp_image_get_mask (image)), layer = gimp_selection_float (GIMP_SELECTION (gimp_image_get_mask (image)),
@ -694,17 +692,11 @@ register_selection_procs (GimpPDB *pdb)
"Spencer Kimball & Peter Mattis", "Spencer Kimball & Peter Mattis",
"1995-1996"); "1995-1996");
gimp_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
g_param_spec_int ("num-drawables", gimp_param_spec_core_object_array ("drawables",
"num drawables", "drawables",
"The number of drawables", "The drawables from which to float selection",
1, G_MAXINT32, 1, GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE)); 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_procedure_add_argument (procedure, gimp_procedure_add_argument (procedure,
g_param_spec_int ("offx", g_param_spec_int ("offx",
"offx", "offx",

View file

@ -421,38 +421,39 @@ gimp_main (GType plug_in_type,
{ {
GType init_types[] = GType init_types[] =
{ {
G_TYPE_INT, G_TYPE_PARAM_INT, G_TYPE_INT, G_TYPE_PARAM_INT,
G_TYPE_UCHAR, G_TYPE_PARAM_UCHAR, G_TYPE_UCHAR, G_TYPE_PARAM_UCHAR,
G_TYPE_STRING, G_TYPE_PARAM_STRING, G_TYPE_STRING, G_TYPE_PARAM_STRING,
G_TYPE_STRV, G_TYPE_PARAM_BOXED, 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_ARRAY, GIMP_TYPE_PARAM_ARRAY,
GIMP_TYPE_INT32_ARRAY, GIMP_TYPE_PARAM_INT32_ARRAY, GIMP_TYPE_INT32_ARRAY, GIMP_TYPE_PARAM_INT32_ARRAY,
GIMP_TYPE_FLOAT_ARRAY, GIMP_TYPE_PARAM_FLOAT_ARRAY, GIMP_TYPE_FLOAT_ARRAY, GIMP_TYPE_PARAM_FLOAT_ARRAY,
GIMP_TYPE_OBJECT_ARRAY, GIMP_TYPE_PARAM_OBJECT_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_DISPLAY, GIMP_TYPE_PARAM_DISPLAY,
GIMP_TYPE_IMAGE, GIMP_TYPE_PARAM_IMAGE, GIMP_TYPE_IMAGE, GIMP_TYPE_PARAM_IMAGE,
GIMP_TYPE_ITEM, GIMP_TYPE_PARAM_ITEM, GIMP_TYPE_ITEM, GIMP_TYPE_PARAM_ITEM,
GIMP_TYPE_DRAWABLE, GIMP_TYPE_PARAM_DRAWABLE, GIMP_TYPE_DRAWABLE, GIMP_TYPE_PARAM_DRAWABLE,
GIMP_TYPE_LAYER, GIMP_TYPE_PARAM_LAYER, GIMP_TYPE_LAYER, GIMP_TYPE_PARAM_LAYER,
GIMP_TYPE_TEXT_LAYER, GIMP_TYPE_PARAM_TEXT_LAYER, GIMP_TYPE_TEXT_LAYER, GIMP_TYPE_PARAM_TEXT_LAYER,
GIMP_TYPE_GROUP_LAYER, GIMP_TYPE_PARAM_GROUP_LAYER, GIMP_TYPE_GROUP_LAYER, GIMP_TYPE_PARAM_GROUP_LAYER,
GIMP_TYPE_CHANNEL, GIMP_TYPE_PARAM_CHANNEL, GIMP_TYPE_CHANNEL, GIMP_TYPE_PARAM_CHANNEL,
GIMP_TYPE_LAYER_MASK, GIMP_TYPE_PARAM_LAYER_MASK, GIMP_TYPE_LAYER_MASK, GIMP_TYPE_PARAM_LAYER_MASK,
GIMP_TYPE_SELECTION, GIMP_TYPE_PARAM_SELECTION, GIMP_TYPE_SELECTION, GIMP_TYPE_PARAM_SELECTION,
GIMP_TYPE_PATH, GIMP_TYPE_PARAM_PATH, GIMP_TYPE_PATH, GIMP_TYPE_PARAM_PATH,
GIMP_TYPE_BRUSH, GIMP_TYPE_PARAM_BRUSH, GIMP_TYPE_BRUSH, GIMP_TYPE_PARAM_BRUSH,
GIMP_TYPE_FONT, GIMP_TYPE_PARAM_FONT, GIMP_TYPE_FONT, GIMP_TYPE_PARAM_FONT,
GIMP_TYPE_GRADIENT, GIMP_TYPE_PARAM_GRADIENT, GIMP_TYPE_GRADIENT, GIMP_TYPE_PARAM_GRADIENT,
GIMP_TYPE_PALETTE, GIMP_TYPE_PARAM_PALETTE, GIMP_TYPE_PALETTE, GIMP_TYPE_PARAM_PALETTE,
GIMP_TYPE_PATTERN, GIMP_TYPE_PARAM_PATTERN, GIMP_TYPE_PATTERN, GIMP_TYPE_PARAM_PATTERN,
GIMP_TYPE_UNIT, GIMP_TYPE_PARAM_UNIT GIMP_TYPE_UNIT, GIMP_TYPE_PARAM_UNIT,
}; };
gint i; gint i;

View file

@ -38,8 +38,7 @@
/** /**
* gimp_edit_cut: * gimp_edit_cut:
* @num_drawables: The number of drawables. * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables to cut from.
* @drawables: (array length=num_drawables) (element-type GimpItem): The drawables to cut from.
* *
* Cut from the specified drawables. * Cut from the specified drawables.
* *
@ -56,18 +55,15 @@
* Returns: TRUE if the cut was successful, FALSE if there was nothing to copy from. * Returns: TRUE if the cut was successful, FALSE if there was nothing to copy from.
**/ **/
gboolean gboolean
gimp_edit_cut (gint num_drawables, gimp_edit_cut (const GimpDrawable **drawables)
const GimpItem **drawables)
{ {
GimpValueArray *args; GimpValueArray *args;
GimpValueArray *return_vals; GimpValueArray *return_vals;
gboolean non_empty = FALSE; gboolean non_empty = FALSE;
args = gimp_value_array_new_from_types (NULL, args = gimp_value_array_new_from_types (NULL,
G_TYPE_INT, num_drawables, GIMP_TYPE_CORE_OBJECT_ARRAY, drawables,
GIMP_TYPE_OBJECT_ARRAY, NULL,
G_TYPE_NONE); 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 (), return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-edit-cut", "gimp-edit-cut",
@ -84,8 +80,7 @@ gimp_edit_cut (gint num_drawables,
/** /**
* gimp_edit_copy: * gimp_edit_copy:
* @num_drawables: The number of drawables to save. * @drawables: (element-type GimpDrawable) (array zero-terminated=1): Drawables to copy from.
* @drawables: (array length=num_drawables) (element-type GimpItem): Drawables to copy from.
* *
* Copy from the specified drawables. * 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. * Returns: TRUE if the cut was successful, FALSE if there was nothing to copy from.
**/ **/
gboolean gboolean
gimp_edit_copy (gint num_drawables, gimp_edit_copy (const GimpDrawable **drawables)
const GimpItem **drawables)
{ {
GimpValueArray *args; GimpValueArray *args;
GimpValueArray *return_vals; GimpValueArray *return_vals;
gboolean non_empty = FALSE; gboolean non_empty = FALSE;
args = gimp_value_array_new_from_types (NULL, args = gimp_value_array_new_from_types (NULL,
G_TYPE_INT, num_drawables, GIMP_TYPE_CORE_OBJECT_ARRAY, drawables,
GIMP_TYPE_OBJECT_ARRAY, NULL,
G_TYPE_NONE); 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 (), return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-edit-copy", "gimp-edit-copy",
@ -174,38 +166,36 @@ gimp_edit_copy_visible (GimpImage *image)
* gimp_edit_paste: * gimp_edit_paste:
* @drawable: The drawable to paste to. * @drawable: The drawable to paste to.
* @paste_into: Clear selection, or paste behind it? * @paste_into: Clear selection, or paste behind it?
* @num_layers: (out): The newly pasted layers.
* *
* Paste buffer to the specified drawable. * Paste buffer to the specified drawable.
* *
* This procedure pastes a copy of the internal GIMP edit buffer to the * 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 * specified drawable. The GIMP edit buffer will be empty unless a call
* was previously made to either gimp_edit_cut() or gimp_edit_copy(). * was previously made to either [func@Gimp.edit_cut] or
* The \"paste_into\" option specifies whether to clear the current * [func@Gimp.edit_copy]. The \"paste_into\" option specifies whether
* image selection, or to paste the buffer \"behind\" the selection. * to clear the current image selection, or to paste the buffer
* This allows the selection to act as a mask for the pasted buffer. * \"behind\" the selection. This allows the selection to act as a mask
* Anywhere that the selection mask is non-zero, the pasted buffer will * for the pasted buffer. Anywhere that the selection mask is non-zero,
* show through. The pasted data may be a floating selection when * the pasted buffer will show through. The pasted data may be a
* relevant, layers otherwise. If the image has a floating selection at * floating selection when relevant, layers otherwise. If the image has
* the time of pasting, the old floating selection will be anchored to * a floating selection at the time of pasting, the old floating
* its drawable before the new floating selection is added. * selection will be anchored to its drawable before the new floating
* This procedure returns the new layers (floating or not). If the * 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 * result is a floating selection, it will already be attached to the
* specified drawable, and a subsequent call to floating_sel_attach is * specified drawable, and a subsequent call to
* not needed. * [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 list of pasted layers.
* The returned value must be freed with g_free().
**/ **/
GimpLayer ** GimpDrawable **
gimp_edit_paste (GimpDrawable *drawable, gimp_edit_paste (GimpDrawable *drawable,
gboolean paste_into, gboolean paste_into)
gint *num_layers)
{ {
GimpValueArray *args; GimpValueArray *args;
GimpValueArray *return_vals; GimpValueArray *return_vals;
GimpLayer **layers = NULL; GimpDrawable **new_drawables = NULL;
args = gimp_value_array_new_from_types (NULL, args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable, GIMP_TYPE_DRAWABLE, drawable,
@ -217,17 +207,12 @@ gimp_edit_paste (GimpDrawable *drawable,
args); args);
gimp_value_array_unref (args); gimp_value_array_unref (args);
*num_layers = 0;
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS) if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
{ new_drawables = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));
*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)); };
}
gimp_value_array_unref (return_vals); 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: * gimp_edit_named_cut:
* @num_drawables: The number of drawables. * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables to cut from.
* @drawables: (array length=num_drawables) (element-type GimpItem): The drawables to cut from.
* @buffer_name: The name of the buffer to create. * @buffer_name: The name of the buffer to create.
* *
* Cut into a named buffer. * Cut into a named buffer.
@ -287,20 +271,17 @@ gimp_edit_paste_as_new_image (void)
* Since: 2.4 * Since: 2.4
**/ **/
gchar * gchar *
gimp_edit_named_cut (gint num_drawables, gimp_edit_named_cut (const GimpDrawable **drawables,
const GimpItem **drawables, const gchar *buffer_name)
const gchar *buffer_name)
{ {
GimpValueArray *args; GimpValueArray *args;
GimpValueArray *return_vals; GimpValueArray *return_vals;
gchar *real_name = NULL; gchar *real_name = NULL;
args = gimp_value_array_new_from_types (NULL, args = gimp_value_array_new_from_types (NULL,
G_TYPE_INT, num_drawables, GIMP_TYPE_CORE_OBJECT_ARRAY, drawables,
GIMP_TYPE_OBJECT_ARRAY, NULL,
G_TYPE_STRING, buffer_name, G_TYPE_STRING, buffer_name,
G_TYPE_NONE); 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 (), return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-edit-named-cut", "gimp-edit-named-cut",
@ -317,8 +298,7 @@ gimp_edit_named_cut (gint num_drawables,
/** /**
* gimp_edit_named_copy: * gimp_edit_named_copy:
* @num_drawables: The number of drawables. * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables to copy from.
* @drawables: (array length=num_drawables) (element-type GimpItem): The drawables to copy from.
* @buffer_name: The name of the buffer to create. * @buffer_name: The name of the buffer to create.
* *
* Copy into a named buffer. * Copy into a named buffer.
@ -335,20 +315,17 @@ gimp_edit_named_cut (gint num_drawables,
* Since: 2.4 * Since: 2.4
**/ **/
gchar * gchar *
gimp_edit_named_copy (gint num_drawables, gimp_edit_named_copy (const GimpDrawable **drawables,
const GimpItem **drawables, const gchar *buffer_name)
const gchar *buffer_name)
{ {
GimpValueArray *args; GimpValueArray *args;
GimpValueArray *return_vals; GimpValueArray *return_vals;
gchar *real_name = NULL; gchar *real_name = NULL;
args = gimp_value_array_new_from_types (NULL, args = gimp_value_array_new_from_types (NULL,
G_TYPE_INT, num_drawables, GIMP_TYPE_CORE_OBJECT_ARRAY, drawables,
GIMP_TYPE_OBJECT_ARRAY, NULL,
G_TYPE_STRING, buffer_name, G_TYPE_STRING, buffer_name,
G_TYPE_NONE); 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 (), return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-edit-named-copy", "gimp-edit-named-copy",

View file

@ -32,27 +32,22 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */ /* For information look into the C source or the html documentation */
gboolean gimp_edit_cut (gint num_drawables, gboolean gimp_edit_cut (const GimpDrawable **drawables);
const GimpItem **drawables); gboolean gimp_edit_copy (const GimpDrawable **drawables);
gboolean gimp_edit_copy (gint num_drawables, gboolean gimp_edit_copy_visible (GimpImage *image);
const GimpItem **drawables); GimpDrawable** gimp_edit_paste (GimpDrawable *drawable,
gboolean gimp_edit_copy_visible (GimpImage *image); gboolean paste_into);
GimpLayer** gimp_edit_paste (GimpDrawable *drawable, GimpImage* gimp_edit_paste_as_new_image (void);
gboolean paste_into, gchar* gimp_edit_named_cut (const GimpDrawable **drawables,
gint *num_layers); const gchar *buffer_name);
GimpImage* gimp_edit_paste_as_new_image (void); gchar* gimp_edit_named_copy (const GimpDrawable **drawables,
gchar* gimp_edit_named_cut (gint num_drawables, const gchar *buffer_name);
const GimpItem **drawables, gchar* gimp_edit_named_copy_visible (GimpImage *image,
const gchar *buffer_name); const gchar *buffer_name);
gchar* gimp_edit_named_copy (gint num_drawables, GimpLayer* gimp_edit_named_paste (GimpDrawable *drawable,
const GimpItem **drawables, const gchar *buffer_name,
const gchar *buffer_name); gboolean paste_into);
gchar* gimp_edit_named_copy_visible (GimpImage *image, GimpImage* gimp_edit_named_paste_as_new_image (const gchar *buffer_name);
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 G_END_DECLS

View file

@ -513,6 +513,13 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec,
else else
param_def->meta.m_resource.default_resource_id = 0; 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)) else if (GIMP_IS_PARAM_SPEC_OBJECT_ARRAY (pspec))
{ {
param_def->param_def_type = GP_PARAM_DEF_TYPE_ID_ARRAY; 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); 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)) else if (GIMP_VALUE_HOLDS_OBJECT_ARRAY (value))
{ {
GType object_type = G_TYPE_INVALID; GType object_type = G_TYPE_INVALID;
@ -1369,6 +1429,105 @@ gimp_value_to_gp_param (const GValue *value,
else else
param->data.d_strv = array; 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)) else if (GIMP_VALUE_HOLDS_OBJECT_ARRAY (value))
{ {
GimpObjectArray *array = g_value_get_boxed (value); GimpObjectArray *array = g_value_get_boxed (value);

View file

@ -546,14 +546,13 @@ gimp_image_list_paths (GimpImage *image)
GList * GList *
gimp_image_list_selected_drawables (GimpImage *image) gimp_image_list_selected_drawables (GimpImage *image)
{ {
GimpItem **drawables; GimpDrawable **drawables;
gint num_drawables; GList *list = NULL;
GList *list = NULL; gint i;
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]); list = g_list_prepend (list, drawables[i]);
g_free (drawables); g_free (drawables);

View file

@ -716,8 +716,7 @@ gimp_image_floating_sel_attached_to (GimpImage *image)
/** /**
* gimp_image_pick_color: * gimp_image_pick_color:
* @image: The image. * @image: The image.
* @num_drawables: The number of drawables. * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables to pick from.
* @drawables: (array length=num_drawables) (element-type GimpItem): The drawables to pick from.
* @x: x coordinate of upper-left corner of rectangle. * @x: x coordinate of upper-left corner of rectangle.
* @y: y 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. * @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. * Returns: TRUE on success.
**/ **/
gboolean gboolean
gimp_image_pick_color (GimpImage *image, gimp_image_pick_color (GimpImage *image,
gint num_drawables, const GimpDrawable **drawables,
const GimpItem **drawables, gdouble x,
gdouble x, gdouble y,
gdouble y, gboolean sample_merged,
gboolean sample_merged, gboolean sample_average,
gboolean sample_average, gdouble average_radius,
gdouble average_radius, GeglColor **color)
GeglColor **color)
{ {
GimpValueArray *args; GimpValueArray *args;
GimpValueArray *return_vals; GimpValueArray *return_vals;
@ -762,15 +760,13 @@ gimp_image_pick_color (GimpImage *image,
args = gimp_value_array_new_from_types (NULL, args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_IMAGE, image, GIMP_TYPE_IMAGE, image,
G_TYPE_INT, num_drawables, GIMP_TYPE_CORE_OBJECT_ARRAY, drawables,
GIMP_TYPE_OBJECT_ARRAY, NULL,
G_TYPE_DOUBLE, x, G_TYPE_DOUBLE, x,
G_TYPE_DOUBLE, y, G_TYPE_DOUBLE, y,
G_TYPE_BOOLEAN, sample_merged, G_TYPE_BOOLEAN, sample_merged,
G_TYPE_BOOLEAN, sample_average, G_TYPE_BOOLEAN, sample_average,
G_TYPE_DOUBLE, average_radius, G_TYPE_DOUBLE, average_radius,
G_TYPE_NONE); 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 (), return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-image-pick-color", "gimp-image-pick-color",
@ -2473,7 +2469,6 @@ gimp_image_set_selected_paths (GimpImage *image,
/** /**
* gimp_image_get_selected_drawables: * gimp_image_get_selected_drawables:
* @image: The image. * @image: The image.
* @num_drawables: (out): The number of selected drawables in the image.
* *
* Get the image's selected drawables * 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 * has a layer mask and the layer mask is in edit mode, then the layer
* mask is the active drawable. * 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 list of selected drawables in the image.
* The returned value must be freed with g_free().
* *
* Since: 3.0.0 * Since: 3.0.0
**/ **/
GimpItem ** GimpDrawable **
gimp_image_get_selected_drawables (GimpImage *image, gimp_image_get_selected_drawables (GimpImage *image)
gint *num_drawables)
{ {
GimpValueArray *args; GimpValueArray *args;
GimpValueArray *return_vals; GimpValueArray *return_vals;
GimpItem **drawables = NULL; GimpDrawable **drawables = NULL;
args = gimp_value_array_new_from_types (NULL, args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_IMAGE, image, GIMP_TYPE_IMAGE, image,
@ -2508,13 +2501,8 @@ gimp_image_get_selected_drawables (GimpImage *image,
args); args);
gimp_value_array_unref (args); gimp_value_array_unref (args);
*num_drawables = 0;
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS) if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
{ drawables = g_value_dup_boxed (gimp_value_array_index (return_vals, 1));
*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)); };
}
gimp_value_array_unref (return_vals); gimp_value_array_unref (return_vals);

View file

@ -58,8 +58,7 @@ gboolean gimp_image_unset_active_channel (GimpImage
GimpLayer* gimp_image_get_floating_sel (GimpImage *image); GimpLayer* gimp_image_get_floating_sel (GimpImage *image);
GimpDrawable* gimp_image_floating_sel_attached_to (GimpImage *image); GimpDrawable* gimp_image_floating_sel_attached_to (GimpImage *image);
gboolean gimp_image_pick_color (GimpImage *image, gboolean gimp_image_pick_color (GimpImage *image,
gint num_drawables, const GimpDrawable **drawables,
const GimpItem **drawables,
gdouble x, gdouble x,
gdouble y, gdouble y,
gboolean sample_merged, gboolean sample_merged,
@ -161,8 +160,7 @@ GimpPath** gimp_image_get_selected_paths (GimpImage
gboolean gimp_image_set_selected_paths (GimpImage *image, gboolean gimp_image_set_selected_paths (GimpImage *image,
gint num_paths, gint num_paths,
const GimpPath **paths); const GimpPath **paths);
GimpItem** gimp_image_get_selected_drawables (GimpImage *image, GimpDrawable** gimp_image_get_selected_drawables (GimpImage *image);
gint *num_drawables);
GimpSelection* gimp_image_get_selection (GimpImage *image); GimpSelection* gimp_image_get_selection (GimpImage *image);
gboolean gimp_image_get_component_active (GimpImage *image, gboolean gimp_image_get_component_active (GimpImage *image,
GimpChannelType component); GimpChannelType component);

View file

@ -73,8 +73,7 @@ gimp_selection_get_by_id (gint32 selection_id)
/** /**
* gimp_selection_float: * gimp_selection_float:
* @image: ignored * @image: ignored
* @n_drawables: Size of @drawables. * @drawables: (array zero-terminated=1): The drawables from which to
* @drawables: (array length=n_drawables): The drawables from which to
* float selection. * float selection.
* @offx: x offset for translation. * @offx: x offset for translation.
* @offy: y offset for translation. * @offy: y offset for translation.
@ -92,13 +91,9 @@ gimp_selection_get_by_id (gint32 selection_id)
*/ */
GimpLayer * GimpLayer *
gimp_selection_float (GimpImage *image, gimp_selection_float (GimpImage *image,
gint n_drawables,
GimpDrawable **drawables, GimpDrawable **drawables,
gint offx, gint offx,
gint offy) gint offy)
{ {
return _gimp_selection_float (n_drawables, return _gimp_selection_float ((const GimpDrawable **) drawables, offx, offy);
(const GimpItem **) drawables,
offx,
offy);
} }

View file

@ -40,7 +40,6 @@ G_DECLARE_FINAL_TYPE (GimpSelection, gimp_selection, GIMP, SELECTION, GimpChanne
GimpSelection * gimp_selection_get_by_id (gint32 selection_id); GimpSelection * gimp_selection_get_by_id (gint32 selection_id);
GimpLayer * gimp_selection_float (GimpImage *image, GimpLayer * gimp_selection_float (GimpImage *image,
gint n_drawables,
GimpDrawable **drawables, GimpDrawable **drawables,
gint offx, gint offx,
gint offy); gint offy);

View file

@ -222,8 +222,7 @@ gimp_selection_translate (GimpImage *image,
/** /**
* _gimp_selection_float: * _gimp_selection_float:
* @num_drawables: The number of drawables. * @drawables: (element-type GimpDrawable) (array zero-terminated=1): The drawables from which to float selection.
* @drawables: (array length=num_drawables) (element-type GimpItem): The drawables from which to float selection.
* @offx: x offset for translation. * @offx: x offset for translation.
* @offy: y offset for translation. * @offy: y offset for translation.
* *
@ -239,22 +238,19 @@ gimp_selection_translate (GimpImage *image,
* Returns: (transfer none): The floated layer. * Returns: (transfer none): The floated layer.
**/ **/
GimpLayer * GimpLayer *
_gimp_selection_float (gint num_drawables, _gimp_selection_float (const GimpDrawable **drawables,
const GimpItem **drawables, gint offx,
gint offx, gint offy)
gint offy)
{ {
GimpValueArray *args; GimpValueArray *args;
GimpValueArray *return_vals; GimpValueArray *return_vals;
GimpLayer *layer = NULL; GimpLayer *layer = NULL;
args = gimp_value_array_new_from_types (NULL, args = gimp_value_array_new_from_types (NULL,
G_TYPE_INT, num_drawables, GIMP_TYPE_CORE_OBJECT_ARRAY, drawables,
GIMP_TYPE_OBJECT_ARRAY, NULL,
G_TYPE_INT, offx, G_TYPE_INT, offx,
G_TYPE_INT, offy, G_TYPE_INT, offy,
G_TYPE_NONE); 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 (), return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-selection-float", "gimp-selection-float",

View file

@ -32,37 +32,36 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */ /* For information look into the C source or the html documentation */
gboolean gimp_selection_bounds (GimpImage *image, gboolean gimp_selection_bounds (GimpImage *image,
gboolean *non_empty, gboolean *non_empty,
gint *x1, gint *x1,
gint *y1, gint *y1,
gint *x2, gint *x2,
gint *y2); gint *y2);
gint gimp_selection_value (GimpImage *image, gint gimp_selection_value (GimpImage *image,
gint x, gint x,
gint y); gint y);
gboolean gimp_selection_is_empty (GimpImage *image); gboolean gimp_selection_is_empty (GimpImage *image);
gboolean gimp_selection_translate (GimpImage *image, gboolean gimp_selection_translate (GimpImage *image,
gint offx, gint offx,
gint offy); gint offy);
G_GNUC_INTERNAL GimpLayer* _gimp_selection_float (gint num_drawables, G_GNUC_INTERNAL GimpLayer* _gimp_selection_float (const GimpDrawable **drawables,
const GimpItem **drawables, gint offx,
gint offx, gint offy);
gint offy); gboolean gimp_selection_invert (GimpImage *image);
gboolean gimp_selection_invert (GimpImage *image); gboolean gimp_selection_sharpen (GimpImage *image);
gboolean gimp_selection_sharpen (GimpImage *image); gboolean gimp_selection_all (GimpImage *image);
gboolean gimp_selection_all (GimpImage *image); gboolean gimp_selection_none (GimpImage *image);
gboolean gimp_selection_none (GimpImage *image); gboolean gimp_selection_feather (GimpImage *image,
gboolean gimp_selection_feather (GimpImage *image, gdouble radius);
gdouble radius); gboolean gimp_selection_border (GimpImage *image,
gboolean gimp_selection_border (GimpImage *image, gint radius);
gint radius); gboolean gimp_selection_grow (GimpImage *image,
gboolean gimp_selection_grow (GimpImage *image, gint steps);
gint steps); gboolean gimp_selection_shrink (GimpImage *image,
gboolean gimp_selection_shrink (GimpImage *image, gint steps);
gint steps); gboolean gimp_selection_flood (GimpImage *image);
gboolean gimp_selection_flood (GimpImage *image); GimpChannel* gimp_selection_save (GimpImage *image);
GimpChannel* gimp_selection_save (GimpImage *image);
G_END_DECLS G_END_DECLS

View file

@ -41,17 +41,17 @@ gimp_c_test_run (GimpProcedure *procedure,
/* 1. Fail with no selection */ /* 1. Fail with no selection */
GIMP_TEST_START("Gimp.Selection.float - 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 */ /* 2. Fail on a group layer */
GIMP_TEST_START("Gimp.Selection.float - 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 */ /* 3. Succeed on a normal layer */
gimp_image_select_rectangle (img, GIMP_CHANNEL_OP_REPLACE, 5, 5, 20, 20); gimp_image_select_rectangle (img, GIMP_CHANNEL_OP_REPLACE, 5, 5, 20, 20);
GIMP_TEST_START("gimp_selection_float - normal layer") 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_END(GIMP_IS_LAYER (float_layer))
GIMP_TEST_START("gimp_floating_sel_remove") 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_image_select_rectangle (img, GIMP_CHANNEL_OP_REPLACE, 5, 5, 20, 20);
GIMP_TEST_START("gimp_selection_float - layer inside group") 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_END(GIMP_IS_LAYER (float_layer))
GIMP_TEST_START("gimp_floating_sel_remove") GIMP_TEST_START("gimp_floating_sel_remove")

View file

@ -38,6 +38,7 @@ EXPORTS
gimp_component_type_get_type gimp_component_type_get_type
gimp_convert_palette_type_get_type gimp_convert_palette_type_get_type
gimp_convolve_type_get_type gimp_convolve_type_get_type
gimp_core_object_array_get_type
gimp_cpu_accel_get_support gimp_cpu_accel_get_support
gimp_cpu_accel_set_use gimp_cpu_accel_set_use
gimp_data_directory gimp_data_directory
@ -125,6 +126,7 @@ EXPORTS
gimp_paint_application_mode_get_type gimp_paint_application_mode_get_type
gimp_param_array_get_type gimp_param_array_get_type
gimp_param_choice_get_type gimp_param_choice_get_type
gimp_param_core_object_array_get_type
gimp_param_export_options_get_type gimp_param_export_options_get_type
gimp_param_float_array_get_type gimp_param_float_array_get_type
gimp_param_int32_array_get_type gimp_param_int32_array_get_type
@ -134,6 +136,7 @@ EXPORTS
gimp_param_parasite_get_type gimp_param_parasite_get_type
gimp_param_spec_array gimp_param_spec_array
gimp_param_spec_choice gimp_param_spec_choice
gimp_param_spec_core_object_array
gimp_param_spec_export_options gimp_param_spec_export_options
gimp_param_spec_float_array gimp_param_spec_float_array
gimp_param_spec_int32_array gimp_param_spec_int32_array

View file

@ -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 * GIMP_TYPE_OBJECT_ARRAY
*/ */

View file

@ -345,6 +345,58 @@ void gimp_color_array_free (GimpColorArray array);
gint gimp_color_array_get_length (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 * GIMP_TYPE_OBJECT_ARRAY
*/ */

View file

@ -696,6 +696,15 @@ gimp_param_spec_object_array ("$name",
"$blurb", "$blurb",
GIMP_TYPE_ITEM, GIMP_TYPE_ITEM,
$flags) $flags)
CODE
}
elsif ($pdbtype eq 'drawablearray') {
$pspec = <<CODE;
gimp_param_spec_core_object_array ("$name",
"$nick",
"$blurb",
GIMP_TYPE_DRAWABLE,
$flags)
CODE CODE
} }
elsif ($pdbtype eq 'layerarray') { elsif ($pdbtype eq 'layerarray') {

View file

@ -35,12 +35,8 @@ HELP
&std_pdb_misc; &std_pdb_misc;
@inargs = ( @inargs = (
{ name => 'drawables', type => 'itemarray', { name => 'drawables', type => 'drawablearray',
desc => 'The drawables to cut from', desc => 'The drawables to cut from' }
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables" } }
); );
@outargs = ( @outargs = (
@ -56,7 +52,7 @@ HELP
GList *drawable_list = NULL; GList *drawable_list = NULL;
gint i; 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, if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL,
GIMP_PDB_ITEM_CONTENT, error) || GIMP_PDB_ITEM_CONTENT, error) ||
@ -127,12 +123,8 @@ HELP
&std_pdb_misc; &std_pdb_misc;
@inargs = ( @inargs = (
{ name => 'drawables', type => 'itemarray', { name => 'drawables', type => 'drawablearray',
desc => 'Drawables to copy from', desc => 'Drawables to copy from' }
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables to save" } },
); );
@outargs = ( @outargs = (
@ -148,7 +140,7 @@ HELP
GList *drawables_list = NULL; GList *drawables_list = NULL;
gint i; 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)) 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]); 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; GError *my_error = NULL;
@ -238,8 +230,8 @@ sub edit_paste {
$help = <<'HELP'; $help = <<'HELP';
This procedure pastes a copy of the internal GIMP edit buffer to the 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 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 was previously made to either [func@Gimp.edit_cut] or [func@Gimp.edit_copy].
"paste_into" option specifies whether to clear the current image The "paste_into" option specifies whether to clear the current image
selection, or to paste the buffer "behind" the selection. This allows 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 to act as a mask for the pasted buffer. Anywhere that
the selection mask is non-zero, the pasted buffer will show 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 will be anchored to its drawable before the new
floating selection is added. 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 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 HELP
&std_pdb_misc; &std_pdb_misc;
@ -264,10 +256,8 @@ HELP
); );
@outargs = ( @outargs = (
{ name => 'layers', type => 'layerarray', { name => 'new_drawables', type => 'drawablearray',
desc => 'The list of pasted layers.', desc => 'The list of pasted layers.' }
array => { name => 'num_layers',
desc => 'The newly pasted layers' } }
); );
%invoke = ( %invoke = (
@ -282,6 +272,7 @@ HELP
{ {
GList *drawables = NULL; GList *drawables = NULL;
GList *list; GList *list;
gint num_drawables;
gint i; gint i;
if (drawable != NULL) if (drawable != NULL)
@ -299,11 +290,11 @@ HELP
if (! list) if (! list)
success = FALSE; success = FALSE;
num_layers = g_list_length (list); num_drawables = g_list_length (list);
layers = g_new (GimpLayer *, num_layers); new_drawables = g_new0 (GimpDrawable *, num_drawables + 1);
for (i = 0; i < num_layers; i++, list = g_list_next (list)) for (i = 0; i < num_drawables; i++, list = g_list_next (list))
layers[i] = g_object_ref (list->data); new_drawables[i] = g_object_ref (list->data);
g_list_free (list); g_list_free (list);
} }
@ -359,12 +350,8 @@ HELP
&mitch_pdb_misc('2005', '2.4'); &mitch_pdb_misc('2005', '2.4');
@inargs = ( @inargs = (
{ name => 'drawables', type => 'itemarray', { name => 'drawables', type => 'drawablearray',
desc => 'The drawables to cut from', desc => 'The drawables to cut from' },
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables" } },
{ name => 'buffer_name', type => 'string', non_empty => 1, { name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The name of the buffer to create' } desc => 'The name of the buffer to create' }
); );
@ -382,7 +369,7 @@ HELP
GList *drawable_list = NULL; GList *drawable_list = NULL;
gint i; 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, if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL,
GIMP_PDB_ITEM_CONTENT, error) || GIMP_PDB_ITEM_CONTENT, error) ||
@ -449,12 +436,8 @@ HELP
&mitch_pdb_misc('2005', '2.4'); &mitch_pdb_misc('2005', '2.4');
@inargs = ( @inargs = (
{ name => 'drawables', type => 'itemarray', { name => 'drawables', type => 'drawablearray',
desc => 'The drawables to copy from', desc => 'The drawables to copy from' },
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables" } },
{ name => 'buffer_name', type => 'string', non_empty => 1, { name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The name of the buffer to create' } desc => 'The name of the buffer to create' }
); );
@ -472,7 +455,7 @@ HELP
GList *drawable_list = NULL; GList *drawable_list = NULL;
gint i; 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, if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL,
0, error)) 0, error))

View file

@ -429,12 +429,8 @@ HELP
@inargs = ( @inargs = (
{ name => 'image', type => 'image', { name => 'image', type => 'image',
desc => 'The image' }, desc => 'The image' },
{ name => 'drawables', type => 'itemarray', { name => 'drawables', type => 'drawablearray',
desc => 'The drawables to pick from', desc => 'The drawables to pick from' },
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables" } },
{ name => 'x', type => 'float', { name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of rectangle' }, desc => 'x coordinate of upper-left corner of rectangle' },
{ name => 'y', type => 'float', { name => 'y', type => 'float',
@ -461,13 +457,13 @@ HELP
if (! sample_merged) if (! sample_merged)
{ {
if (num_drawables == 0) if (drawables == NULL || drawables[0] == NULL)
{ {
success = FALSE; success = FALSE;
} }
else 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) if (gimp_item_get_image (GIMP_ITEM (drawables[i])) != image)
{ {
success = FALSE; success = FALSE;
@ -486,7 +482,7 @@ HELP
{ {
GList *drawable_list = NULL; GList *drawable_list = NULL;
for (i = 0; i < num_drawables; i++) for (i = 0; drawables[i] != NULL; i++)
{ {
GimpPickable *pickable = (GimpPickable *) drawables[i]; GimpPickable *pickable = (GimpPickable *) drawables[i];
@ -2231,16 +2227,15 @@ HELP
); );
@outargs = ( @outargs = (
{ name => 'drawables', type => 'itemarray', { name => 'drawables', type => 'drawablearray',
desc => 'The list of selected drawables in the image.', desc => 'The list of selected drawables in the image.' }
array => { name => 'num_drawables',
desc => 'The number of selected drawables in the image' } }
); );
%invoke = ( %invoke = (
code => <<'CODE' code => <<'CODE'
{ {
GList *list = gimp_image_get_selected_drawables (image); GList *list = gimp_image_get_selected_drawables (image);
gsize num_drawables;
num_drawables = g_list_length (list); num_drawables = g_list_length (list);
@ -2248,10 +2243,10 @@ HELP
{ {
gint i; 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)) for (i = 0; i < num_drawables; i++, list = g_list_next (list))
drawables[i] = g_object_ref (list->data); drawables[i] = list->data;
} }
} }
CODE CODE

View file

@ -181,12 +181,8 @@ HELP
$lib_private = 1; $lib_private = 1;
@inargs = ( @inargs = (
{ name => 'drawables', type => 'itemarray', { name => 'drawables', type => 'drawablearray',
desc => 'The drawables from which to float selection', desc => 'The drawables from which to float selection' },
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables" } },
{ name => 'offx', type => 'int32', { name => 'offx', type => 'int32',
desc => 'x offset for translation' }, desc => 'x offset for translation' },
{ name => 'offy', type => 'int32', { name => 'offy', type => 'int32',
@ -204,13 +200,13 @@ HELP
GimpImage *image = NULL; GimpImage *image = NULL;
gint i; gint i;
if (num_drawables < 1) if (drawables == NULL || drawables[0] == NULL)
{ {
success = FALSE; success = FALSE;
} }
else 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, if (! gimp_pdb_item_is_attached (GIMP_ITEM (drawables[i]), NULL,
GIMP_PDB_ITEM_CONTENT, error) || GIMP_PDB_ITEM_CONTENT, error) ||
@ -231,7 +227,7 @@ HELP
{ {
GList *drawable_list = NULL; 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]); drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]);
layer = gimp_selection_float (GIMP_SELECTION (gimp_image_get_mask (image)), layer = gimp_selection_float (GIMP_SELECTION (gimp_image_get_mask (image)),

View file

@ -135,6 +135,18 @@ package Gimp::CodeGen::pdb;
set_value_func => 'gimp_value_set_object_array ($value, GIMP_TYPE_ITEM, (GObject **) $var, $var_len)', 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)' }, 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', layerarray => { name => 'LAYERARRAY',
gtype => 'GIMP_TYPE_OBJECT_ARRAY', gtype => 'GIMP_TYPE_OBJECT_ARRAY',
type => 'GimpLayer **', type => 'GimpLayer **',

View file

@ -593,18 +593,19 @@ p_if_selection_float_it (GimpImage *image,
if (non_empty && sel_channel) if (non_empty && sel_channel)
{ {
const GimpDrawable *drawables[2] = { (GimpDrawable *) layer, NULL };
/* selection is TRUE, make a layer (floating selection) from /* selection is TRUE, make a layer (floating selection) from
the selection */ the selection */
if (gimp_edit_copy (1, (const GimpItem **) &layer)) if (gimp_edit_copy (drawables))
{ {
GimpLayer **layers; GimpDrawable **layers;
gint num_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 /* Since we explicitly copied a single layer, there should
* be no more than a single layer in the paste as well. * 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); g_free (layers);
} }

View file

@ -713,16 +713,16 @@ pdf_export_image (GimpProcedure *procedure,
gint32 n_layers; gint32 n_layers;
gdouble x_res, y_res; gdouble x_res, y_res;
gdouble x_scale, y_scale; gdouble x_scale, y_scale;
GimpItem **drawables; GimpDrawable **drawables;
gint n_drawables;
gint j; gint j;
drawables = gimp_image_get_selected_drawables (image, &n_drawables); drawables = gimp_image_get_selected_drawables (image);
if (n_drawables == 0) if (drawables[0] == NULL)
{ {
g_free (drawables); g_free (drawables);
continue; continue;
} }
g_free (drawables);
/* Save the state of the surface before any changes, so that /* Save the state of the surface before any changes, so that
* settings from one page won't affect all the others * settings from one page won't affect all the others
@ -1597,9 +1597,9 @@ drawText (GimpLayer *layer,
if (type == GIMP_RGBA_IMAGE) if (type == GIMP_RGBA_IMAGE)
color = gimp_text_layer_get_color (GIMP_TEXT_LAYER (layer)); color = gimp_text_layer_get_color (GIMP_TEXT_LAYER (layer));
else else
gimp_image_pick_color (gimp_item_get_image (GIMP_ITEM (layer)), 1, gimp_image_pick_color (gimp_item_get_image (GIMP_ITEM (layer)),
(const GimpItem**) &layer, x, y, FALSE, FALSE, 0, (const GimpDrawable*[2]) { GIMP_DRAWABLE (layer), NULL },
&color); x, y, FALSE, FALSE, 0, &color);
/* TODO: this export plug-in is not space-aware yet, so we draw everything as /* TODO: this export plug-in is not space-aware yet, so we draw everything as
* sRGB for the time being. * sRGB for the time being.

View file

@ -1289,10 +1289,9 @@ load_image (GFile *file,
{ {
GimpLayer *current_layer; GimpLayer *current_layer;
gchar *name; gchar *name;
GimpItem **tmp_drawables; GimpDrawable **tmp_drawables;
gint n_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])); name = gimp_item_get_name (GIMP_ITEM (tmp_drawables[0]));

View file

@ -570,12 +570,11 @@ write_dds (GFile *file,
*/ */
if (! is_duplicate_image) if (! is_duplicate_image)
{ {
GimpImage *duplicate_image = gimp_image_duplicate (image); GimpImage *duplicate_image = gimp_image_duplicate (image);
GimpItem **drawables; GimpDrawable **drawables;
gint n_drawables;
drawables = gimp_image_get_selected_drawables (duplicate_image, &n_drawables); drawables = gimp_image_get_selected_drawables (duplicate_image);
rc = write_image (fp, duplicate_image, GIMP_DRAWABLE (drawables[0]), config); rc = write_image (fp, duplicate_image, drawables[0], config);
gimp_image_delete (duplicate_image); gimp_image_delete (duplicate_image);
g_free (drawables); g_free (drawables);
} }

View file

@ -292,11 +292,10 @@ fits_export (GimpProcedure *procedure,
gpointer run_data) gpointer run_data)
{ {
GimpImage *duplicate_image; GimpImage *duplicate_image;
GimpItem **flipped_drawables; GimpDrawable **flipped_drawables;
GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpPDBStatusType status = GIMP_PDB_SUCCESS;
GimpExportReturn export = GIMP_EXPORT_IGNORE; GimpExportReturn export = GIMP_EXPORT_IGNORE;
GList *drawables; GList *drawables;
gint n_drawables;
GError *error = NULL; GError *error = NULL;
gegl_init (NULL, NULL); gegl_init (NULL, NULL);
@ -306,17 +305,14 @@ fits_export (GimpProcedure *procedure,
export = gimp_export_options_get_image (options, &image); export = gimp_export_options_get_image (options, &image);
drawables = gimp_image_list_layers (image); drawables = gimp_image_list_layers (image);
n_drawables = g_list_length (drawables);
/* Flip image vertical since FITS writes from bottom to top */ /* Flip image vertical since FITS writes from bottom to top */
duplicate_image = gimp_image_duplicate (image); duplicate_image = gimp_image_duplicate (image);
gimp_image_flip (duplicate_image, GIMP_ORIENTATION_VERTICAL); gimp_image_flip (duplicate_image, GIMP_ORIENTATION_VERTICAL);
flipped_drawables = flipped_drawables = gimp_image_get_selected_drawables (duplicate_image);
gimp_image_get_selected_drawables (duplicate_image, &n_drawables);
if (! export_image (file, image, GIMP_DRAWABLE (flipped_drawables[0]), if (! export_image (file, image, flipped_drawables[0], &error))
&error))
status = GIMP_PDB_EXECUTION_ERROR; status = GIMP_PDB_EXECUTION_ERROR;
gimp_image_delete (duplicate_image); gimp_image_delete (duplicate_image);