app, plug-ins: port "file-gbr-save-internal" to multi-drawable API.

Similar to commit 6905b0bbef for "file-pat-save-internal". For interactive
usage, nothing is changed, but for non-interactive ones, we can now choose a
list of drawables to export.

Pending more changes, relative to the discussion in #7370.
This commit is contained in:
Jehan 2023-10-16 15:30:12 +02:00
parent 2728294063
commit 61e2faed1b
3 changed files with 102 additions and 59 deletions

View file

@ -31,11 +31,15 @@
#include "core/gimpbrush.h"
#include "core/gimpbrush-load.h"
#include "core/gimpbrush-private.h"
#include "core/gimpcontainer.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimplayer-new.h"
#include "core/gimpimage-merge.h"
#include "core/gimpimage-new.h"
#include "core/gimpimage-resize.h"
#include "core/gimplayer-new.h"
#include "core/gimpparamspecs.h"
#include "core/gimppickable.h"
#include "core/gimptempbuf.h"
#include "pdb/gimpprocedure.h"
@ -47,12 +51,14 @@
/* local function prototypes */
static GimpImage * file_gbr_brush_to_image (Gimp *gimp,
GimpBrush *brush);
static GimpBrush * file_gbr_image_to_brush (GimpImage *image,
GimpDrawable *drawable,
const gchar *name,
gdouble spacing);
static GimpImage * file_gbr_brush_to_image (Gimp *gimp,
GimpBrush *brush);
static GimpBrush * file_gbr_image_to_brush (GimpImage *image,
GimpContext *context,
gint n_drawables,
GimpDrawable **drawables,
const gchar *name,
gdouble spacing);
/* public functions */
@ -115,24 +121,26 @@ file_gbr_save_invoker (GimpProcedure *procedure,
const GimpValueArray *args,
GError **error)
{
GimpValueArray *return_vals;
GimpImage *image;
GimpDrawable *drawable;
GimpBrush *brush;
const gchar *name;
GFile *file;
gint spacing;
gboolean success;
GimpValueArray *return_vals;
GimpImage *image;
GimpDrawable **drawables;
gint n_drawables;
GimpBrush *brush;
const gchar *name;
GFile *file;
gint spacing;
gboolean success;
gimp_set_busy (gimp);
image = g_value_get_object (gimp_value_array_index (args, 1));
drawable = g_value_get_object (gimp_value_array_index (args, 2));
file = g_value_get_object (gimp_value_array_index (args, 3));
spacing = g_value_get_int (gimp_value_array_index (args, 4));
name = g_value_get_string (gimp_value_array_index (args, 5));
image = g_value_get_object (gimp_value_array_index (args, 1));
n_drawables = g_value_get_int (gimp_value_array_index (args, 2));
drawables = (GimpDrawable **) gimp_value_get_object_array (gimp_value_array_index (args, 3));
file = g_value_get_object (gimp_value_array_index (args, 4));
spacing = g_value_get_int (gimp_value_array_index (args, 5));
name = g_value_get_string (gimp_value_array_index (args, 6));
brush = file_gbr_image_to_brush (image, drawable, name, spacing);
brush = file_gbr_image_to_brush (image, context, n_drawables, drawables, name, spacing);
gimp_data_set_file (GIMP_DATA (brush), file, TRUE, TRUE);
@ -413,15 +421,48 @@ file_gbr_brush_to_image (Gimp *gimp,
}
static GimpBrush *
file_gbr_image_to_brush (GimpImage *image,
GimpDrawable *drawable,
const gchar *name,
gdouble spacing)
file_gbr_image_to_brush (GimpImage *image,
GimpContext *context,
gint n_drawables,
GimpDrawable **drawables,
const gchar *name,
gdouble spacing)
{
gint width = gimp_item_get_width (GIMP_ITEM (drawable));
gint height = gimp_item_get_height (GIMP_ITEM (drawable));
GimpBrush *brush;
GimpImage *subimage = NULL;
GimpDrawable *drawable;
gint width;
gint height;
return file_gbr_drawable_to_brush (drawable,
GEGL_RECTANGLE (0, 0, width, height),
name, spacing);
g_return_val_if_fail (n_drawables > 0, NULL);
if (n_drawables > 1)
{
GList *drawable_list = NULL;
for (gint i = 0; i < n_drawables; i++)
drawable_list = g_list_prepend (drawable_list, drawables[i]);
subimage = gimp_image_new_from_drawables (image->gimp, drawable_list, FALSE, FALSE);
g_list_free (drawable_list);
gimp_container_remove (image->gimp->images, GIMP_OBJECT (subimage));
gimp_image_resize_to_layers (subimage, context,
NULL, NULL, NULL, NULL, NULL);
drawable = GIMP_DRAWABLE (gimp_image_merge_visible_layers (subimage, context, GIMP_CLIP_TO_IMAGE,
FALSE, TRUE, NULL));
gimp_pickable_flush (GIMP_PICKABLE (subimage));
}
else
{
drawable = drawables[0];
}
width = gimp_item_get_width (GIMP_ITEM (drawable));
height = gimp_item_get_height (GIMP_ITEM (drawable));
brush = file_gbr_drawable_to_brush (drawable,
GEGL_RECTANGLE (0, 0, width, height),
name, spacing);
g_clear_object (&subimage);
return brush;
}

View file

@ -154,12 +154,17 @@ file_data_init (Gimp *gimp)
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_drawable ("drawable",
"Drawable",
"Active drawable "
"of input image",
FALSE,
GIMP_PARAM_READWRITE));
g_param_spec_int ("num-drawables",
"Num drawables",
"Number of drawables",
1, G_MAXINT, 1,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_object_array ("drawables",
"Drawables",
"Selected drawables",
GIMP_TYPE_DRAWABLE,
GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE));
gimp_procedure_add_argument (procedure,
g_param_spec_object ("file",
"File",

View file

@ -223,16 +223,6 @@ gbr_save (GimpProcedure *procedure,
break;
}
if (n_drawables != 1)
{
g_set_error (&error, G_FILE_ERROR, 0,
_("GBR format does not support multiple layers."));
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CALLING_ERROR,
error);
}
if (run_mode == GIMP_RUN_INTERACTIVE)
{
if (! save_dialog (procedure, G_OBJECT (config), image))
@ -241,25 +231,32 @@ gbr_save (GimpProcedure *procedure,
if (status == GIMP_PDB_SUCCESS)
{
GimpValueArray *save_retvals;
gint spacing;
GimpValueArray *args;
GimpValueArray *save_retvals;
GimpObjectArray *drawables_array;
gint spacing;
g_object_get (config,
"description", &description,
"spacing", &spacing,
NULL);
save_retvals =
gimp_pdb_run_procedure (gimp_get_pdb (),
"file-gbr-save-internal",
GIMP_TYPE_RUN_MODE, GIMP_RUN_NONINTERACTIVE,
GIMP_TYPE_IMAGE, image,
GIMP_TYPE_DRAWABLE, drawables[0],
G_TYPE_FILE, file,
G_TYPE_INT, spacing,
G_TYPE_STRING, description,
G_TYPE_NONE);
drawables_array = gimp_object_array_new (GIMP_TYPE_ITEM, (GObject **) drawables,
n_drawables, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_RUN_MODE, GIMP_RUN_NONINTERACTIVE,
GIMP_TYPE_IMAGE, image,
G_TYPE_INT, n_drawables,
GIMP_TYPE_OBJECT_ARRAY, drawables_array,
G_TYPE_FILE, file,
G_TYPE_INT, spacing,
G_TYPE_STRING, description,
G_TYPE_NONE);
save_retvals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
"file-gbr-save-internal",
args);
gimp_value_array_unref (args);
gimp_object_array_free (drawables_array);
g_free (description);
if (GIMP_VALUES_GET_ENUM (save_retvals, 0) != GIMP_PDB_SUCCESS)