1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 /* NOTE: This file is auto-generated by pdbgen.pl. */
19 
20 #include "config.h"
21 
22 #include <gegl.h>
23 
24 #include <gdk-pixbuf/gdk-pixbuf.h>
25 
26 #include "libgimpconfig/gimpconfig.h"
27 
28 #include "libgimpbase/gimpbase.h"
29 
30 #include "pdb-types.h"
31 
32 #include "core/gimp-gradients.h"
33 #include "core/gimp.h"
34 #include "core/gimpbuffer.h"
35 #include "core/gimpdrawable-bucket-fill.h"
36 #include "core/gimpdrawable-edit.h"
37 #include "core/gimpdrawable-gradient.h"
38 #include "core/gimpdrawable.h"
39 #include "core/gimpimage.h"
40 #include "core/gimpitem.h"
41 #include "core/gimpparamspecs.h"
42 #include "core/gimpprogress.h"
43 #include "core/gimpstrokeoptions.h"
44 #include "paint/gimppaintoptions.h"
45 
46 #include "gimppdb.h"
47 #include "gimppdb-utils.h"
48 #include "gimppdbcontext.h"
49 #include "gimpprocedure.h"
50 #include "internal-procs.h"
51 
52 #include "gimp-intl.h"
53 
54 
55 static GimpValueArray *
drawable_edit_clear_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)56 drawable_edit_clear_invoker (GimpProcedure         *procedure,
57                              Gimp                  *gimp,
58                              GimpContext           *context,
59                              GimpProgress          *progress,
60                              const GimpValueArray  *args,
61                              GError               **error)
62 {
63   gboolean success = TRUE;
64   GimpDrawable *drawable;
65 
66   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
67 
68   if (success)
69     {
70       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
71                                      GIMP_PDB_ITEM_CONTENT, error) &&
72           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
73         {
74           gimp_drawable_edit_clear (drawable, context);
75         }
76       else
77         success = FALSE;
78     }
79 
80   return gimp_procedure_get_return_values (procedure, success,
81                                            error ? *error : NULL);
82 }
83 
84 static GimpValueArray *
drawable_edit_fill_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)85 drawable_edit_fill_invoker (GimpProcedure         *procedure,
86                             Gimp                  *gimp,
87                             GimpContext           *context,
88                             GimpProgress          *progress,
89                             const GimpValueArray  *args,
90                             GError               **error)
91 {
92   gboolean success = TRUE;
93   GimpDrawable *drawable;
94   gint32 fill_type;
95 
96   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
97   fill_type = g_value_get_enum (gimp_value_array_index (args, 1));
98 
99   if (success)
100     {
101       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
102                                      GIMP_PDB_ITEM_CONTENT, error) &&
103           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
104         {
105           GimpFillOptions *options = gimp_fill_options_new (gimp, NULL, FALSE);
106 
107           gimp_context_set_opacity (GIMP_CONTEXT (options),
108                                     gimp_context_get_opacity (context));
109           gimp_context_set_paint_mode (GIMP_CONTEXT (options),
110                                        gimp_context_get_paint_mode (context));
111 
112           if (gimp_fill_options_set_by_fill_type (options, context,
113                                                   fill_type, error))
114             {
115               gimp_drawable_edit_fill (drawable, options, NULL);
116             }
117           else
118             success = FALSE;
119 
120           g_object_unref (options);
121         }
122       else
123         success = FALSE;
124     }
125 
126   return gimp_procedure_get_return_values (procedure, success,
127                                            error ? *error : NULL);
128 }
129 
130 static GimpValueArray *
drawable_edit_bucket_fill_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)131 drawable_edit_bucket_fill_invoker (GimpProcedure         *procedure,
132                                    Gimp                  *gimp,
133                                    GimpContext           *context,
134                                    GimpProgress          *progress,
135                                    const GimpValueArray  *args,
136                                    GError               **error)
137 {
138   gboolean success = TRUE;
139   GimpDrawable *drawable;
140   gint32 fill_type;
141   gdouble x;
142   gdouble y;
143 
144   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
145   fill_type = g_value_get_enum (gimp_value_array_index (args, 1));
146   x = g_value_get_double (gimp_value_array_index (args, 2));
147   y = g_value_get_double (gimp_value_array_index (args, 3));
148 
149   if (success)
150     {
151       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
152                                      GIMP_PDB_ITEM_CONTENT, error) &&
153           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
154         {
155           GimpFillOptions *options = gimp_fill_options_new (gimp, NULL, FALSE);
156 
157           gimp_context_set_opacity (GIMP_CONTEXT (options),
158                                     gimp_context_get_opacity (context));
159           gimp_context_set_paint_mode (GIMP_CONTEXT (options),
160                                        gimp_context_get_paint_mode (context));
161 
162           gimp_fill_options_set_antialias (options,
163                                            GIMP_PDB_CONTEXT (context)->antialias);
164 
165           if (gimp_fill_options_set_by_fill_type (options, context,
166                                                   fill_type, error))
167             {
168               gimp_drawable_bucket_fill (drawable, options,
169                                          GIMP_PDB_CONTEXT (context)->sample_transparent,
170                                          GIMP_PDB_CONTEXT (context)->sample_criterion,
171                                          GIMP_PDB_CONTEXT (context)->sample_threshold,
172                                          GIMP_PDB_CONTEXT (context)->sample_merged,
173                                          GIMP_PDB_CONTEXT (context)->diagonal_neighbors,
174                                          x, y);
175             }
176           else
177             success = FALSE;
178 
179           g_object_unref (options);
180         }
181       else
182         success = FALSE;
183     }
184 
185   return gimp_procedure_get_return_values (procedure, success,
186                                            error ? *error : NULL);
187 }
188 
189 static GimpValueArray *
drawable_edit_gradient_fill_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)190 drawable_edit_gradient_fill_invoker (GimpProcedure         *procedure,
191                                      Gimp                  *gimp,
192                                      GimpContext           *context,
193                                      GimpProgress          *progress,
194                                      const GimpValueArray  *args,
195                                      GError               **error)
196 {
197   gboolean success = TRUE;
198   GimpDrawable *drawable;
199   gint32 gradient_type;
200   gdouble offset;
201   gboolean supersample;
202   gint32 supersample_max_depth;
203   gdouble supersample_threshold;
204   gboolean dither;
205   gdouble x1;
206   gdouble y1;
207   gdouble x2;
208   gdouble y2;
209 
210   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
211   gradient_type = g_value_get_enum (gimp_value_array_index (args, 1));
212   offset = g_value_get_double (gimp_value_array_index (args, 2));
213   supersample = g_value_get_boolean (gimp_value_array_index (args, 3));
214   supersample_max_depth = g_value_get_int (gimp_value_array_index (args, 4));
215   supersample_threshold = g_value_get_double (gimp_value_array_index (args, 5));
216   dither = g_value_get_boolean (gimp_value_array_index (args, 6));
217   x1 = g_value_get_double (gimp_value_array_index (args, 7));
218   y1 = g_value_get_double (gimp_value_array_index (args, 8));
219   x2 = g_value_get_double (gimp_value_array_index (args, 9));
220   y2 = g_value_get_double (gimp_value_array_index (args, 10));
221 
222   if (success)
223     {
224       success = (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
225                                             GIMP_PDB_ITEM_CONTENT, error) &&
226                  gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error));
227 
228       if (success)
229         {
230           if (supersample)
231             {
232               if (supersample_max_depth < 1 || supersample_max_depth > 9)
233                 success = FALSE;
234 
235               if (supersample_threshold < 0.0 || supersample_threshold > 4.0)
236                 success = FALSE;
237             }
238           else
239             {
240               supersample_max_depth = CLAMP (supersample_max_depth, 1, 9);
241               supersample_threshold = CLAMP (supersample_threshold, 0.0, 4.0);
242             }
243        }
244 
245       if (success)
246         {
247           /* all options should have the same value, so pick a random one */
248           GimpPaintOptions *options =
249             gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
250                                                 "gimp-paintbrush");
251 
252           if (progress)
253             gimp_progress_start (progress, FALSE, _("Gradient"));
254 
255           gimp_drawable_gradient (drawable,
256                                   context,
257                                   gimp_context_get_gradient (context),
258                                   GIMP_PDB_CONTEXT (context)->distance_metric,
259                                   gimp_context_get_paint_mode (context),
260                                   gradient_type,
261                                   gimp_context_get_opacity (context),
262                                   offset,
263                                   options->gradient_options->gradient_repeat,
264                                   options->gradient_options->gradient_reverse,
265                                   options->gradient_options->gradient_blend_color_space,
266                                   supersample,
267                                   supersample_max_depth,
268                                   supersample_threshold,
269                                   dither,
270                                   x1, y1, x2, y2,
271                                   progress);
272 
273           if (progress)
274             gimp_progress_end (progress);
275         }
276     }
277 
278   return gimp_procedure_get_return_values (procedure, success,
279                                            error ? *error : NULL);
280 }
281 
282 static GimpValueArray *
drawable_edit_stroke_selection_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)283 drawable_edit_stroke_selection_invoker (GimpProcedure         *procedure,
284                                         Gimp                  *gimp,
285                                         GimpContext           *context,
286                                         GimpProgress          *progress,
287                                         const GimpValueArray  *args,
288                                         GError               **error)
289 {
290   gboolean success = TRUE;
291   GimpDrawable *drawable;
292 
293   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
294 
295   if (success)
296     {
297       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
298                                      GIMP_PDB_ITEM_CONTENT, error) &&
299           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
300         {
301           GimpImage         *image = gimp_item_get_image (GIMP_ITEM (drawable));
302           GimpStrokeOptions *options;
303           GimpPaintOptions  *paint_options;
304 
305           options = gimp_pdb_context_get_stroke_options (GIMP_PDB_CONTEXT (context));
306 
307           paint_options =
308             gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context), NULL);
309           paint_options = gimp_config_duplicate (GIMP_CONFIG (paint_options));
310 
311           success = gimp_item_stroke (GIMP_ITEM (gimp_image_get_mask (image)),
312                                       drawable, context, options, paint_options,
313                                       TRUE, progress, error);
314 
315           g_object_unref (paint_options);
316         }
317       else
318         success = FALSE;
319     }
320 
321   return gimp_procedure_get_return_values (procedure, success,
322                                            error ? *error : NULL);
323 }
324 
325 static GimpValueArray *
drawable_edit_stroke_item_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)326 drawable_edit_stroke_item_invoker (GimpProcedure         *procedure,
327                                    Gimp                  *gimp,
328                                    GimpContext           *context,
329                                    GimpProgress          *progress,
330                                    const GimpValueArray  *args,
331                                    GError               **error)
332 {
333   gboolean success = TRUE;
334   GimpDrawable *drawable;
335   GimpItem *item;
336 
337   drawable = gimp_value_get_drawable (gimp_value_array_index (args, 0), gimp);
338   item = gimp_value_get_item (gimp_value_array_index (args, 1), gimp);
339 
340   if (success)
341     {
342       if (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
343                                      GIMP_PDB_ITEM_CONTENT, error) &&
344           gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error) &&
345           gimp_pdb_item_is_attached (item,
346                                      gimp_item_get_image (GIMP_ITEM (drawable)),
347                                      0, error))
348         {
349           GimpStrokeOptions *options;
350           GimpPaintOptions  *paint_options;
351 
352           options = gimp_pdb_context_get_stroke_options (GIMP_PDB_CONTEXT (context));
353 
354           paint_options =
355             gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context), NULL);
356           paint_options = gimp_config_duplicate (GIMP_CONFIG (paint_options));
357 
358           success = gimp_item_stroke (item, drawable,
359                                       context, options, paint_options,
360                                       TRUE, progress, error);
361 
362           g_object_unref (paint_options);
363         }
364       else
365         success = FALSE;
366     }
367 
368   return gimp_procedure_get_return_values (procedure, success,
369                                            error ? *error : NULL);
370 }
371 
372 void
register_drawable_edit_procs(GimpPDB * pdb)373 register_drawable_edit_procs (GimpPDB *pdb)
374 {
375   GimpProcedure *procedure;
376 
377   /*
378    * gimp-drawable-edit-clear
379    */
380   procedure = gimp_procedure_new (drawable_edit_clear_invoker);
381   gimp_object_set_static_name (GIMP_OBJECT (procedure),
382                                "gimp-drawable-edit-clear");
383   gimp_procedure_set_static_strings (procedure,
384                                      "gimp-drawable-edit-clear",
385                                      "Clear selected area of drawable.",
386                                      "This procedure clears the specified drawable. If the drawable has an alpha channel, the cleared pixels will become transparent. If the drawable does not have an alpha channel, cleared pixels will be set to the background color. This procedure only affects regions within a selection if there is a selection active.\n"
387                                      "\n"
388                                      "This procedure is affected by the following context setters: 'gimp-context-set-background'.",
389                                      "Spencer Kimball & Peter Mattis",
390                                      "Spencer Kimball & Peter Mattis",
391                                      "1995-1996",
392                                      NULL);
393   gimp_procedure_add_argument (procedure,
394                                gimp_param_spec_drawable_id ("drawable",
395                                                             "drawable",
396                                                             "The drawable to clear from",
397                                                             pdb->gimp, FALSE,
398                                                             GIMP_PARAM_READWRITE));
399   gimp_pdb_register_procedure (pdb, procedure);
400   g_object_unref (procedure);
401 
402   /*
403    * gimp-drawable-edit-fill
404    */
405   procedure = gimp_procedure_new (drawable_edit_fill_invoker);
406   gimp_object_set_static_name (GIMP_OBJECT (procedure),
407                                "gimp-drawable-edit-fill");
408   gimp_procedure_set_static_strings (procedure,
409                                      "gimp-drawable-edit-fill",
410                                      "Fill selected area of drawable.",
411                                      "This procedure fills the specified drawable according to fill mode. This procedure only affects regions within a selection if there is a selection active. If you want to fill the whole drawable, regardless of the selection, use 'gimp-drawable-fill'.\n"
412                                      "\n"
413                                      "This procedure is affected by the following context setters: 'gimp-context-set-opacity', 'gimp-context-set-paint-mode', 'gimp-context-set-foreground', 'gimp-context-set-background', 'gimp-context-set-pattern'.",
414                                      "Spencer Kimball & Peter Mattis & Raphael Quinet",
415                                      "Spencer Kimball & Peter Mattis",
416                                      "1995-2000",
417                                      NULL);
418   gimp_procedure_add_argument (procedure,
419                                gimp_param_spec_drawable_id ("drawable",
420                                                             "drawable",
421                                                             "The drawable to fill to",
422                                                             pdb->gimp, FALSE,
423                                                             GIMP_PARAM_READWRITE));
424   gimp_procedure_add_argument (procedure,
425                                g_param_spec_enum ("fill-type",
426                                                   "fill type",
427                                                   "The type of fill",
428                                                   GIMP_TYPE_FILL_TYPE,
429                                                   GIMP_FILL_FOREGROUND,
430                                                   GIMP_PARAM_READWRITE));
431   gimp_pdb_register_procedure (pdb, procedure);
432   g_object_unref (procedure);
433 
434   /*
435    * gimp-drawable-edit-bucket-fill
436    */
437   procedure = gimp_procedure_new (drawable_edit_bucket_fill_invoker);
438   gimp_object_set_static_name (GIMP_OBJECT (procedure),
439                                "gimp-drawable-edit-bucket-fill");
440   gimp_procedure_set_static_strings (procedure,
441                                      "gimp-drawable-edit-bucket-fill",
442                                      "Fill the area by a seed fill starting at the specified coordinates.",
443                                      "This procedure does a seed fill at the specified coordinates, using various parameters from the current context.\n"
444                                      "In the case of merged sampling, the x and y coordinates are relative to the image's origin; otherwise, they are relative to the drawable's origin.\n"
445                                      "\n"
446                                      "This procedure is affected by the following context setters: 'gimp-context-set-opacity', 'gimp-context-set-paint-mode', 'gimp-context-set-foreground', 'gimp-context-set-background', 'gimp-context-set-pattern', 'gimp-context-set-sample-threshold', 'gimp-context-set-sample-merged', 'gimp-context-set-sample-criterion', 'gimp-context-set-diagonal-neighbors', 'gimp-context-set-antialias'.",
447                                      "Michael Natterer <mitch@gimp.org>",
448                                      "Michael Natterer",
449                                      "2018",
450                                      NULL);
451   gimp_procedure_add_argument (procedure,
452                                gimp_param_spec_drawable_id ("drawable",
453                                                             "drawable",
454                                                             "The affected drawable",
455                                                             pdb->gimp, FALSE,
456                                                             GIMP_PARAM_READWRITE));
457   gimp_procedure_add_argument (procedure,
458                                g_param_spec_enum ("fill-type",
459                                                   "fill type",
460                                                   "The type of fill",
461                                                   GIMP_TYPE_FILL_TYPE,
462                                                   GIMP_FILL_FOREGROUND,
463                                                   GIMP_PARAM_READWRITE));
464   gimp_procedure_add_argument (procedure,
465                                g_param_spec_double ("x",
466                                                     "x",
467                                                     "The x coordinate of this bucket fill's application.",
468                                                     -G_MAXDOUBLE, G_MAXDOUBLE, 0,
469                                                     GIMP_PARAM_READWRITE));
470   gimp_procedure_add_argument (procedure,
471                                g_param_spec_double ("y",
472                                                     "y",
473                                                     "The y coordinate of this bucket fill's application.",
474                                                     -G_MAXDOUBLE, G_MAXDOUBLE, 0,
475                                                     GIMP_PARAM_READWRITE));
476   gimp_pdb_register_procedure (pdb, procedure);
477   g_object_unref (procedure);
478 
479   /*
480    * gimp-drawable-edit-gradient-fill
481    */
482   procedure = gimp_procedure_new (drawable_edit_gradient_fill_invoker);
483   gimp_object_set_static_name (GIMP_OBJECT (procedure),
484                                "gimp-drawable-edit-gradient-fill");
485   gimp_procedure_set_static_strings (procedure,
486                                      "gimp-drawable-edit-gradient-fill",
487                                      "Draw a gradient between the starting and ending coordinates with the specified gradient type.",
488                                      "This tool requires information on the gradient type. It creates the specified variety of gradient using the starting and ending coordinates as defined for each gradient type. For shapeburst gradient types, the context's distance metric is also relevant and can be updated with 'gimp-context-set-distance-metric'.\n"
489                                      "\n"
490                                      "This procedure is affected by the following context setters: 'gimp-context-set-opacity', 'gimp-context-set-paint-mode', 'gimp-context-set-foreground', 'gimp-context-set-background', 'gimp-context-set-gradient' and all gradient property settings, 'gimp-context-set-distance-metric'.",
491                                      "Michael Natterer <mitch@gimp.org>",
492                                      "Michael Natterer",
493                                      "2018",
494                                      NULL);
495   gimp_procedure_add_argument (procedure,
496                                gimp_param_spec_drawable_id ("drawable",
497                                                             "drawable",
498                                                             "The affected drawable",
499                                                             pdb->gimp, FALSE,
500                                                             GIMP_PARAM_READWRITE));
501   gimp_procedure_add_argument (procedure,
502                                g_param_spec_enum ("gradient-type",
503                                                   "gradient type",
504                                                   "The type of gradient",
505                                                   GIMP_TYPE_GRADIENT_TYPE,
506                                                   GIMP_GRADIENT_LINEAR,
507                                                   GIMP_PARAM_READWRITE));
508   gimp_procedure_add_argument (procedure,
509                                g_param_spec_double ("offset",
510                                                     "offset",
511                                                     "Offset relates to the starting and ending coordinates specified for the blend. This parameter is mode dependent.",
512                                                     0, G_MAXDOUBLE, 0,
513                                                     GIMP_PARAM_READWRITE));
514   gimp_procedure_add_argument (procedure,
515                                g_param_spec_boolean ("supersample",
516                                                      "supersample",
517                                                      "Do adaptive supersampling",
518                                                      FALSE,
519                                                      GIMP_PARAM_READWRITE));
520   gimp_procedure_add_argument (procedure,
521                                gimp_param_spec_int32 ("supersample-max-depth",
522                                                       "supersample max depth",
523                                                       "Maximum recursion levels for supersampling",
524                                                       1, 9, 1,
525                                                       GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE));
526   gimp_procedure_add_argument (procedure,
527                                g_param_spec_double ("supersample-threshold",
528                                                     "supersample threshold",
529                                                     "Supersampling threshold",
530                                                     0, 4, 0,
531                                                     GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE));
532   gimp_procedure_add_argument (procedure,
533                                g_param_spec_boolean ("dither",
534                                                      "dither",
535                                                      "Use dithering to reduce banding",
536                                                      FALSE,
537                                                      GIMP_PARAM_READWRITE));
538   gimp_procedure_add_argument (procedure,
539                                g_param_spec_double ("x1",
540                                                     "x1",
541                                                     "The x coordinate of this gradient's starting point",
542                                                     -G_MAXDOUBLE, G_MAXDOUBLE, 0,
543                                                     GIMP_PARAM_READWRITE));
544   gimp_procedure_add_argument (procedure,
545                                g_param_spec_double ("y1",
546                                                     "y1",
547                                                     "The y coordinate of this gradient's starting point",
548                                                     -G_MAXDOUBLE, G_MAXDOUBLE, 0,
549                                                     GIMP_PARAM_READWRITE));
550   gimp_procedure_add_argument (procedure,
551                                g_param_spec_double ("x2",
552                                                     "x2",
553                                                     "The x coordinate of this gradient's ending point",
554                                                     -G_MAXDOUBLE, G_MAXDOUBLE, 0,
555                                                     GIMP_PARAM_READWRITE));
556   gimp_procedure_add_argument (procedure,
557                                g_param_spec_double ("y2",
558                                                     "y2",
559                                                     "The y coordinate of this gradient's ending point",
560                                                     -G_MAXDOUBLE, G_MAXDOUBLE, 0,
561                                                     GIMP_PARAM_READWRITE));
562   gimp_pdb_register_procedure (pdb, procedure);
563   g_object_unref (procedure);
564 
565   /*
566    * gimp-drawable-edit-stroke-selection
567    */
568   procedure = gimp_procedure_new (drawable_edit_stroke_selection_invoker);
569   gimp_object_set_static_name (GIMP_OBJECT (procedure),
570                                "gimp-drawable-edit-stroke-selection");
571   gimp_procedure_set_static_strings (procedure,
572                                      "gimp-drawable-edit-stroke-selection",
573                                      "Stroke the current selection",
574                                      "This procedure strokes the current selection, painting along the selection boundary with the active paint method and brush, or using a plain line with configurable properties. The paint is applied to the specified drawable regardless of the active selection.\n"
575                                      "\n"
576                                      "This procedure is affected by the following context setters: 'gimp-context-set-opacity', 'gimp-context-set-paint-mode', 'gimp-context-set-paint-method', 'gimp-context-set-stroke-method', 'gimp-context-set-foreground', 'gimp-context-set-brush' and all brush property settings, 'gimp-context-set-gradient' and all gradient property settings, 'gimp-context-set-line-width' and all line property settings, 'gimp-context-set-antialias'.",
577                                      "Spencer Kimball & Peter Mattis",
578                                      "Spencer Kimball & Peter Mattis",
579                                      "1995-1996",
580                                      NULL);
581   gimp_procedure_add_argument (procedure,
582                                gimp_param_spec_drawable_id ("drawable",
583                                                             "drawable",
584                                                             "The drawable to stroke to",
585                                                             pdb->gimp, FALSE,
586                                                             GIMP_PARAM_READWRITE));
587   gimp_pdb_register_procedure (pdb, procedure);
588   g_object_unref (procedure);
589 
590   /*
591    * gimp-drawable-edit-stroke-item
592    */
593   procedure = gimp_procedure_new (drawable_edit_stroke_item_invoker);
594   gimp_object_set_static_name (GIMP_OBJECT (procedure),
595                                "gimp-drawable-edit-stroke-item");
596   gimp_procedure_set_static_strings (procedure,
597                                      "gimp-drawable-edit-stroke-item",
598                                      "Stroke the specified item",
599                                      "This procedure strokes the specified item, painting along its outline (e.g. along a path, or along a channel's boundary), with the active paint method and brush, or using a plain line with configurable properties.\n"
600                                      "\n"
601                                      "This procedure is affected by the following context setters: 'gimp-context-set-opacity', 'gimp-context-set-paint-mode', 'gimp-context-set-paint-method', 'gimp-context-set-stroke-method', 'gimp-context-set-foreground', 'gimp-context-set-brush' and all brush property settings, 'gimp-context-set-gradient' and all gradient property settings, 'gimp-context-set-line-width' and all line property settings, 'gimp-context-set-antialias'.",
602                                      "Michael Natterer <mitch@gimp.org>",
603                                      "Michael Natterer",
604                                      "2018",
605                                      NULL);
606   gimp_procedure_add_argument (procedure,
607                                gimp_param_spec_drawable_id ("drawable",
608                                                             "drawable",
609                                                             "The drawable to stroke to",
610                                                             pdb->gimp, FALSE,
611                                                             GIMP_PARAM_READWRITE));
612   gimp_procedure_add_argument (procedure,
613                                gimp_param_spec_item_id ("item",
614                                                         "item",
615                                                         "The item to stroke",
616                                                         pdb->gimp, FALSE,
617                                                         GIMP_PARAM_READWRITE));
618   gimp_pdb_register_procedure (pdb, procedure);
619   g_object_unref (procedure);
620 }
621