app, libgimp, pdb, plug-ins: PDB (gimp-layer-copy) made public.

Not sure what I had in mind with the class method copy() in libgimp
GimpLayer. The core duplicate code already takes care of returning an
object of the right type. Also the GimpTextLayer implementation was not
a perfect copy (only text, font and font size were copied). Now it is
because, again, core has all the duplication code necessary.

Finally this makes this function visible to PDB, hence Script-Fu, again.
This commit is contained in:
Jehan 2025-01-20 22:02:22 +01:00
parent 92330f7b3c
commit 957d76fd14
19 changed files with 106 additions and 187 deletions

View file

@ -303,11 +303,9 @@ layer_copy_invoker (GimpProcedure *procedure,
gboolean success = TRUE;
GimpValueArray *return_vals;
GimpLayer *layer;
gboolean add_alpha;
GimpLayer *layer_copy = NULL;
layer = g_value_get_object (gimp_value_array_index (args, 0));
add_alpha = g_value_get_boolean (gimp_value_array_index (args, 1));
if (success)
{
@ -317,9 +315,6 @@ layer_copy_invoker (GimpProcedure *procedure,
{
GimpContainer *filters;
if (add_alpha)
gimp_layer_add_alpha (layer_copy);
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (layer));
if (gimp_container_get_n_children (filters) > 0)
{
@ -1448,12 +1443,12 @@ register_layer_procs (GimpPDB *pdb)
/*
* gimp-layer-copy
*/
procedure = gimp_procedure_new (layer_copy_invoker, TRUE, TRUE);
procedure = gimp_procedure_new (layer_copy_invoker, TRUE, FALSE);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-layer-copy");
gimp_procedure_set_static_help (procedure,
"Copy a layer.",
"This procedure copies the specified layer and returns the copy. The newly copied layer is for use within the original layer's image. It should not be subsequently added to any other image. The copied layer can optionally have an added alpha channel. This is useful if the background layer in an image is being copied and added to the same image.",
"This procedure copies the specified layer and returns the copy. The newly copied layer is for use within the original layer's image. It should not be subsequently added to any other image.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Spencer Kimball & Peter Mattis",
@ -1465,16 +1460,10 @@ register_layer_procs (GimpPDB *pdb)
"The layer to copy",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_boolean ("add-alpha",
"add alpha",
"Add an alpha channel to the copied layer",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_layer ("layer-copy",
"layer copy",
"The newly copied layer",
"The newly copied layer. The object belongs to libgimp and you should not free it.",
FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);

View file

@ -25,8 +25,6 @@
#include "gimp.h"
static GimpLayer * gimp_layer_real_copy (GimpLayer *layer);
G_DEFINE_TYPE (GimpLayer, gimp_layer, GIMP_TYPE_DRAWABLE)
@ -36,7 +34,6 @@ G_DEFINE_TYPE (GimpLayer, gimp_layer, GIMP_TYPE_DRAWABLE)
static void
gimp_layer_class_init (GimpLayerClass *klass)
{
klass->copy = gimp_layer_real_copy;
}
static void
@ -73,27 +70,6 @@ gimp_layer_get_by_id (gint32 layer_id)
return NULL;
}
/**
* gimp_layer_copy:
* @layer: The layer to copy.
*
* Copy a layer.
*
* This procedure copies the specified layer and returns the copy. The
* newly copied layer is for use within the original layer's image. It
* should not be subsequently added to any other image.
*
* Returns: (transfer none): The newly copied layer.
* The object belongs to libgimp and you should not free it.
*
* Since: 3.0
*/
GimpLayer *
gimp_layer_copy (GimpLayer *layer)
{
return GIMP_LAYER_GET_CLASS (layer)->copy (layer);
}
/**
* gimp_layer_new_from_pixbuf:
* @image: The RGB image to which to add the layer.
@ -257,12 +233,3 @@ gimp_layer_new_from_surface (GimpImage *image,
return layer;
}
/* private functions */
static GimpLayer *
gimp_layer_real_copy (GimpLayer *layer)
{
return _gimp_layer_copy (layer, FALSE);
}

View file

@ -40,9 +40,6 @@ struct _GimpLayerClass
{
GimpDrawableClass parent_class;
/* virtual functions */
GimpLayer * (* copy) (GimpLayer *layer);
/* Padding for future expansion */
void (*_gimp_reserved0) (void);
void (*_gimp_reserved1) (void);
@ -71,8 +68,6 @@ GimpLayer * gimp_layer_new_from_surface (GimpImage *image,
gdouble progress_start,
gdouble progress_end) G_GNUC_WARN_UNUSED_RESULT;
GimpLayer * gimp_layer_copy (GimpLayer *layer);
G_END_DECLS

View file

@ -186,24 +186,20 @@ gimp_layer_new_from_drawable (GimpDrawable *drawable,
}
/**
* _gimp_layer_copy:
* gimp_layer_copy:
* @layer: The layer to copy.
* @add_alpha: Add an alpha channel to the copied layer.
*
* Copy a layer.
*
* This procedure copies the specified layer and returns the copy. The
* newly copied layer is for use within the original layer's image. It
* should not be subsequently added to any other image. The copied
* layer can optionally have an added alpha channel. This is useful if
* the background layer in an image is being copied and added to the
* same image.
* should not be subsequently added to any other image.
*
* Returns: (transfer none): The newly copied layer.
* Returns: (transfer none):
* The newly copied layer. The object belongs to libgimp and you should not free it.
**/
GimpLayer *
_gimp_layer_copy (GimpLayer *layer,
gboolean add_alpha)
gimp_layer_copy (GimpLayer *layer)
{
GimpValueArray *args;
GimpValueArray *return_vals;
@ -211,7 +207,6 @@ _gimp_layer_copy (GimpLayer *layer,
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_LAYER, layer,
G_TYPE_BOOLEAN, add_alpha,
G_TYPE_NONE);
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),

View file

@ -32,71 +32,70 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
GimpLayer* gimp_layer_new (GimpImage *image,
const gchar *name,
gint width,
gint height,
GimpImageType type,
gdouble opacity,
GimpLayerMode mode);
GimpLayer* gimp_layer_new_from_visible (GimpImage *image,
GimpImage *dest_image,
const gchar *name);
GimpLayer* gimp_layer_new_from_drawable (GimpDrawable *drawable,
GimpImage *dest_image);
G_GNUC_INTERNAL GimpLayer* _gimp_layer_copy (GimpLayer *layer,
gboolean add_alpha);
gboolean gimp_layer_add_alpha (GimpLayer *layer);
gboolean gimp_layer_flatten (GimpLayer *layer);
gboolean gimp_layer_scale (GimpLayer *layer,
gint new_width,
gint new_height,
gboolean local_origin);
gboolean gimp_layer_resize (GimpLayer *layer,
gint new_width,
gint new_height,
gint offx,
gint offy);
gboolean gimp_layer_resize_to_image_size (GimpLayer *layer);
gboolean gimp_layer_set_offsets (GimpLayer *layer,
gint offx,
gint offy);
GimpLayerMask* gimp_layer_create_mask (GimpLayer *layer,
GimpAddMaskType mask_type);
GimpLayerMask* gimp_layer_get_mask (GimpLayer *layer);
GimpLayer* gimp_layer_from_mask (GimpLayerMask *mask);
gboolean gimp_layer_add_mask (GimpLayer *layer,
GimpLayerMask *mask);
gboolean gimp_layer_remove_mask (GimpLayer *layer,
GimpMaskApplyMode mode);
gboolean gimp_layer_is_floating_sel (GimpLayer *layer);
gboolean gimp_layer_get_lock_alpha (GimpLayer *layer);
gboolean gimp_layer_set_lock_alpha (GimpLayer *layer,
gboolean lock_alpha);
gboolean gimp_layer_get_apply_mask (GimpLayer *layer);
gboolean gimp_layer_set_apply_mask (GimpLayer *layer,
gboolean apply_mask);
gboolean gimp_layer_get_show_mask (GimpLayer *layer);
gboolean gimp_layer_set_show_mask (GimpLayer *layer,
gboolean show_mask);
gboolean gimp_layer_get_edit_mask (GimpLayer *layer);
gboolean gimp_layer_set_edit_mask (GimpLayer *layer,
gboolean edit_mask);
gdouble gimp_layer_get_opacity (GimpLayer *layer);
gboolean gimp_layer_set_opacity (GimpLayer *layer,
gdouble opacity);
GimpLayerMode gimp_layer_get_mode (GimpLayer *layer);
gboolean gimp_layer_set_mode (GimpLayer *layer,
GimpLayerMode mode);
GimpLayerColorSpace gimp_layer_get_blend_space (GimpLayer *layer);
gboolean gimp_layer_set_blend_space (GimpLayer *layer,
GimpLayerColorSpace blend_space);
GimpLayerColorSpace gimp_layer_get_composite_space (GimpLayer *layer);
gboolean gimp_layer_set_composite_space (GimpLayer *layer,
GimpLayerColorSpace composite_space);
GimpLayerCompositeMode gimp_layer_get_composite_mode (GimpLayer *layer);
gboolean gimp_layer_set_composite_mode (GimpLayer *layer,
GimpLayerCompositeMode composite_mode);
GimpLayer* gimp_layer_new (GimpImage *image,
const gchar *name,
gint width,
gint height,
GimpImageType type,
gdouble opacity,
GimpLayerMode mode);
GimpLayer* gimp_layer_new_from_visible (GimpImage *image,
GimpImage *dest_image,
const gchar *name);
GimpLayer* gimp_layer_new_from_drawable (GimpDrawable *drawable,
GimpImage *dest_image);
GimpLayer* gimp_layer_copy (GimpLayer *layer);
gboolean gimp_layer_add_alpha (GimpLayer *layer);
gboolean gimp_layer_flatten (GimpLayer *layer);
gboolean gimp_layer_scale (GimpLayer *layer,
gint new_width,
gint new_height,
gboolean local_origin);
gboolean gimp_layer_resize (GimpLayer *layer,
gint new_width,
gint new_height,
gint offx,
gint offy);
gboolean gimp_layer_resize_to_image_size (GimpLayer *layer);
gboolean gimp_layer_set_offsets (GimpLayer *layer,
gint offx,
gint offy);
GimpLayerMask* gimp_layer_create_mask (GimpLayer *layer,
GimpAddMaskType mask_type);
GimpLayerMask* gimp_layer_get_mask (GimpLayer *layer);
GimpLayer* gimp_layer_from_mask (GimpLayerMask *mask);
gboolean gimp_layer_add_mask (GimpLayer *layer,
GimpLayerMask *mask);
gboolean gimp_layer_remove_mask (GimpLayer *layer,
GimpMaskApplyMode mode);
gboolean gimp_layer_is_floating_sel (GimpLayer *layer);
gboolean gimp_layer_get_lock_alpha (GimpLayer *layer);
gboolean gimp_layer_set_lock_alpha (GimpLayer *layer,
gboolean lock_alpha);
gboolean gimp_layer_get_apply_mask (GimpLayer *layer);
gboolean gimp_layer_set_apply_mask (GimpLayer *layer,
gboolean apply_mask);
gboolean gimp_layer_get_show_mask (GimpLayer *layer);
gboolean gimp_layer_set_show_mask (GimpLayer *layer,
gboolean show_mask);
gboolean gimp_layer_get_edit_mask (GimpLayer *layer);
gboolean gimp_layer_set_edit_mask (GimpLayer *layer,
gboolean edit_mask);
gdouble gimp_layer_get_opacity (GimpLayer *layer);
gboolean gimp_layer_set_opacity (GimpLayer *layer,
gdouble opacity);
GimpLayerMode gimp_layer_get_mode (GimpLayer *layer);
gboolean gimp_layer_set_mode (GimpLayer *layer,
GimpLayerMode mode);
GimpLayerColorSpace gimp_layer_get_blend_space (GimpLayer *layer);
gboolean gimp_layer_set_blend_space (GimpLayer *layer,
GimpLayerColorSpace blend_space);
GimpLayerColorSpace gimp_layer_get_composite_space (GimpLayer *layer);
gboolean gimp_layer_set_composite_space (GimpLayer *layer,
GimpLayerColorSpace composite_space);
GimpLayerCompositeMode gimp_layer_get_composite_mode (GimpLayer *layer);
gboolean gimp_layer_set_composite_mode (GimpLayer *layer,
GimpLayerCompositeMode composite_mode);
G_END_DECLS

View file

@ -30,8 +30,6 @@ struct _GimpTextLayer
};
static GimpLayer * gimp_text_layer_copy (GimpLayer *layer);
G_DEFINE_TYPE (GimpTextLayer, gimp_text_layer, GIMP_TYPE_LAYER)
@ -41,9 +39,6 @@ G_DEFINE_TYPE (GimpTextLayer, gimp_text_layer, GIMP_TYPE_LAYER)
static void
gimp_text_layer_class_init (GimpTextLayerClass *klass)
{
GimpLayerClass *layer_class = GIMP_LAYER_CLASS (klass);
layer_class->copy = gimp_text_layer_copy;
}
static void
@ -79,27 +74,3 @@ gimp_text_layer_get_by_id (gint32 layer_id)
return NULL;
}
/* private functions */
static GimpLayer *
gimp_text_layer_copy (GimpLayer *layer)
{
GimpTextLayer *new_layer;
gchar *text;
GimpFont *font;
gdouble size;
GimpUnit *unit;
g_return_val_if_fail (GIMP_IS_TEXT_LAYER (layer), NULL);
text = gimp_text_layer_get_text (GIMP_TEXT_LAYER (layer));
font = gimp_text_layer_get_font (GIMP_TEXT_LAYER (layer));
size = gimp_text_layer_get_font_size (GIMP_TEXT_LAYER (layer), &unit);
new_layer = gimp_text_layer_new (gimp_item_get_image (GIMP_ITEM (layer)),
text, font, size, unit);
g_free (text);
return GIMP_LAYER (new_layer);
}

View file

@ -271,25 +271,19 @@ sub layer_copy {
$help = <<'HELP';
This procedure copies the specified layer and returns the copy. The newly
copied layer is for use within the original layer's image. It should not be
subsequently added to any other image. The copied layer can optionally have an
added alpha channel. This is useful if the background layer in an image is
being copied and added to the same image.
subsequently added to any other image.
HELP
&std_pdb_misc;
$lib_private = 1;
@inargs = (
{ name => 'layer', type => 'layer',
desc => 'The layer to copy' },
{ name => 'add_alpha', type => 'boolean',
desc => 'Add an alpha channel to the copied layer' }
desc => 'The layer to copy' }
);
@outargs = (
{ name => 'layer_copy', type => 'layer',
desc => 'The newly copied layer' }
desc => 'The newly copied layer. The object belongs to libgimp and you should not free it.' }
);
%invoke = (
@ -301,9 +295,6 @@ HELP
{
GimpContainer *filters;
if (add_alpha)
gimp_layer_add_alpha (layer_copy);
filters = gimp_drawable_get_filters (GIMP_DRAWABLE (layer));
if (gimp_container_get_n_children (filters) > 0)
{

View file

@ -66,7 +66,8 @@
(if (= looped TRUE)
; add a copy of the lowest blend layer on top
(let* ((copy (car (gimp-layer-copy
(vector-ref layer-array (- num-layers 2)) TRUE))))
(vector-ref layer-array (- num-layers 2))))))
(gimp-layer-add-alpha copy)
(gimp-image-insert-layer image copy 0 0)
(set! layer-array (car (gimp-image-get-layers image)))
(set! num-layers (vector-length layer-array))
@ -108,9 +109,12 @@
(while (> frame-count 0)
(let* ((opacity (* (/ frame-count (+ frames 1)) 100))
(blur (/ (* opacity max-blur) 100))
(upper-copy (car (gimp-layer-copy upper-layer TRUE)))
(lower-copy (car (gimp-layer-copy lower-layer TRUE)))
(bg-copy (car (gimp-layer-copy bg-layer TRUE))))
(upper-copy (car (gimp-layer-copy upper-layer)))
(lower-copy (car (gimp-layer-copy lower-layer)))
(bg-copy (car (gimp-layer-copy bg-layer))))
(gimp-layer-add-alpha upper-copy)
(gimp-layer-add-alpha lower-copy)
(gimp-layer-add-alpha bg-copy)
(gimp-image-insert-layer image bg-copy 0 0)
(gimp-image-insert-layer image lower-copy 0 0)
(gimp-image-insert-layer image upper-copy 0 0)

View file

@ -71,10 +71,11 @@
;--- process image horizontal with pixel-speed
(while (< bl-x (+ source-layer-width bl-width))
(set! bl-layer (car (gimp-layer-copy source-layer TRUE)))
(set! bl-layer (car (gimp-layer-copy source-layer)))
(set! bl-layer-name (string-append "fr-nr"
(number->string frame-nr 10) ) )
(gimp-layer-add-alpha bl-layer)
(gimp-image-insert-layer img bl-layer 0 -2)
(gimp-item-set-name bl-layer bl-layer-name)
(gimp-item-set-visible bl-layer TRUE)
@ -169,7 +170,7 @@
)
;--- merge with bg layer
(set! bg-layer (car (gimp-layer-copy bg-source-layer FALSE)))
(set! bg-layer (car (gimp-layer-copy bg-source-layer)))
(gimp-image-insert-layer img bg-layer 0 -1)
(gimp-image-lower-item img bg-layer)
(set! bg-layer-name (string-append "bg-"

View file

@ -182,7 +182,8 @@
(gimp-context-set-background '(255 255 255))
(gimp-drawable-edit-fill csl-mask FILL-BACKGROUND)
(set! inset-layer (car (gimp-layer-copy layer1 TRUE)))
(set! inset-layer (car (gimp-layer-copy layer1)))
(gimp-layer-add-alpha inset-layer)
(gimp-image-insert-layer img inset-layer 0 1)
(set! il-mask (car (gimp-layer-create-mask inset-layer ADD-MASK-BLACK)))

View file

@ -220,7 +220,8 @@
(gimp-context-set-background '(255 255 255))
(gimp-drawable-edit-fill layer-mask FILL-BACKGROUND)
(set! layer2 (gimp-layer-copy layer1 #t))
(set! layer2 (gimp-layer-copy layer1))
(gimp-layer-add-alpha layer2)
(gimp-image-insert-layer img layer2 0 0)
(gimp-brush-set-shape brush BRUSH-GENERATED-CIRCLE)

View file

@ -30,7 +30,7 @@
"independent" FALSE "red" 0.7 "alpha" 0.7
"correlated" FALSE "seed" (msrg-rand) "linear" TRUE)
(set! layer-two (car (gimp-layer-copy layer-one 0)))
(set! layer-two (car (gimp-layer-copy layer-one)))
(gimp-layer-set-mode layer-two LAYER-MODE-MULTIPLY)
(gimp-image-insert-layer img layer-two 0 0)

View file

@ -105,7 +105,7 @@
(if (= inShadow TRUE)
(begin
(gimp-image-insert-layer theImage
(car (gimp-layer-copy theLayer FALSE)) 0 -1)
(car (gimp-layer-copy theLayer)) 0 -1)
(gimp-layer-scale theLayer
(- theWidth inSize) (- theHeight inSize) TRUE)
(gimp-drawable-desaturate theLayer DESATURATE-LIGHTNESS)

View file

@ -42,7 +42,7 @@
(while (> inFrames n)
(set! n (+ n 1))
(set! theFrame (car (gimp-layer-copy theLayer FALSE)))
(set! theFrame (car (gimp-layer-copy theLayer)))
(gimp-image-insert-layer theImage theFrame 0 0)
(gimp-item-set-name theFrame
(string-append "Anim Frame: "

View file

@ -32,7 +32,7 @@
"independent" FALSE "red" 0.7 "alpha" 0.7
"correlated" FALSE "seed" (msrg-rand) "linear" TRUE)
(set! layer-two (car (gimp-layer-copy layer-one 0)))
(set! layer-two (car (gimp-layer-copy layer-one)))
(gimp-layer-set-mode layer-two LAYER-MODE-MULTIPLY)
(gimp-image-insert-layer img layer-two 0 0)

View file

@ -33,7 +33,7 @@
"independent" FALSE "red" 0.7 "alpha" 0.7
"correlated" FALSE "seed" (msrg-rand) "linear" TRUE)
(set! layer-two (car (gimp-layer-copy layer-one 0)))
(set! layer-two (car (gimp-layer-copy layer-one)))
(gimp-layer-set-mode layer-two LAYER-MODE-MULTIPLY)
(gimp-image-insert-layer img layer-two 0 0)

View file

@ -37,7 +37,7 @@
"independent" FALSE "red" 0.7 "alpha" 0.7
"correlated" FALSE "seed" (msrg-rand) "linear" TRUE)
(set! layer-two (gimp-layer-copy layer-one 0))
(set! layer-two (gimp-layer-copy layer-one))
(gimp-layer-set-mode layer-two LAYER-MODE-MULTIPLY)
(gimp-image-insert-layer img layer-two 0 0)

View file

@ -48,9 +48,12 @@
(gimp-floating-sel-anchor floating-sel)
)
(set! original-layer-for-darker (car (gimp-layer-copy original-layer TRUE)))
(set! original-layer-for-lighter (car (gimp-layer-copy original-layer TRUE)))
(set! blurred-layer-for-darker (car (gimp-layer-copy original-layer TRUE)))
(set! original-layer-for-darker (car (gimp-layer-copy original-layer)))
(gimp-layer-add-alpha original-layer-for-darker)
(set! original-layer-for-lighter (car (gimp-layer-copy original-layer)))
(gimp-layer-add-alpha original-layer-for-lighter)
(set! blurred-layer-for-darker (car (gimp-layer-copy original-layer)))
(gimp-layer-add-alpha blurred-layer-for-darker)
(gimp-item-set-visible original-layer FALSE)
(gimp-display-new new-image)
@ -58,7 +61,8 @@
(gimp-image-insert-layer new-image blurred-layer-for-darker 0 -1)
(gimp-drawable-merge-new-filter blurred-layer-for-darker "gegl:gaussian-blur" 0 LAYER-MODE-REPLACE 1.0 "std-dev-x" (* 0.32 mask-size) "std-dev-y" (* 0.32 mask-size) "filter" "auto")
(set! blurred-layer-for-lighter
(car (gimp-layer-copy blurred-layer-for-darker TRUE)))
(car (gimp-layer-copy blurred-layer-for-darker)))
(gimp-layer-add-alpha blurred-layer-for-lighter)
(gimp-image-insert-layer new-image original-layer-for-darker 0 -1)
(gimp-layer-set-mode original-layer-for-darker LAYER-MODE-SUBTRACT)
(set! darker-layer

View file

@ -50,7 +50,7 @@
(while (> remaining-frames 1)
(let* (
(waves-layer (car (gimp-layer-copy source-layer TRUE)))
(waves-layer (car (gimp-layer-copy source-layer)))
(layer-name (string-append "Frame "
(number->string
(- (+ num-frames 2)
@ -62,6 +62,7 @@
(height (car (gimp-drawable-get-height waves-layer)))
(aspect (/ width height))
)
(gimp-layer-add-alpha waves-layer)
(gimp-layer-set-lock-alpha waves-layer FALSE)
(gimp-image-insert-layer image waves-layer 0 -1)
(gimp-item-set-name waves-layer layer-name)