diff --git a/app/file-data/file-data-gbr.c b/app/file-data/file-data-gbr.c index 8bed235efe..ef3aaee5b9 100644 --- a/app/file-data/file-data-gbr.c +++ b/app/file-data/file-data-gbr.c @@ -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; } diff --git a/app/file-data/file-data.c b/app/file-data/file-data.c index 456746d236..236f2ace9e 100644 --- a/app/file-data/file-data.c +++ b/app/file-data/file-data.c @@ -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", diff --git a/plug-ins/common/file-gbr.c b/plug-ins/common/file-gbr.c index 6199a68c0e..346e65f7b0 100644 --- a/plug-ins/common/file-gbr.c +++ b/plug-ins/common/file-gbr.c @@ -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)