summaryrefslogtreecommitdiffstats
path: root/pdb/groups/paint_tools.pdb
diff options
context:
space:
mode:
Diffstat (limited to 'pdb/groups/paint_tools.pdb')
-rw-r--r--pdb/groups/paint_tools.pdb1071
1 files changed, 1071 insertions, 0 deletions
diff --git a/pdb/groups/paint_tools.pdb b/pdb/groups/paint_tools.pdb
new file mode 100644
index 0000000..227ea80
--- /dev/null
+++ b/pdb/groups/paint_tools.pdb
@@ -0,0 +1,1071 @@
+# GIMP - The GNU Image Manipulation Program
+# Copyright (C) 1995 Spencer Kimball and Peter Mattis
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+# "Perlized" from C source by Manish Singh <yosh@gimp.org>
+
+sub stroke_arg () {
+ { name => 'strokes', type => 'floatarray',
+ desc => 'Array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
+ sn.x, sn.y }',
+ array => { type => '2 <= int32',
+ desc => 'Number of stroke control points (count each
+ coordinate as 2 points)' } }
+}
+
+# The defs
+
+sub airbrush {
+ $blurb = <<'BLURB';
+Paint in the current brush with varying pressure. Paint application is
+time-dependent.
+BLURB
+
+ $help = <<'HELP';
+This tool simulates the use of an airbrush. Paint pressure represents the
+relative intensity of the paint application. High pressure results in a thicker
+layer of paint while low pressure results in a thinner layer.
+HELP
+
+ &std_pdb_misc;
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ { name => 'pressure', type => '0 <= float <= 100',
+ desc => 'The pressure of the airbrush strokes' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-airbrush");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ g_object_set (options,
+ "pressure", pressure,
+ NULL);
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub airbrush_default {
+ $blurb = <<'BLURB';
+Paint in the current brush with varying pressure. Paint application is
+time-dependent.
+BLURB
+
+ $help = <<'HELP';
+This tool simulates the use of an airbrush. It is similar to gimp_airbrush()
+except that the pressure is derived from the airbrush tools options box.
+It the option has not been set the default for the option will be used.
+HELP
+
+ &andy_pdb_misc('1999');
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-airbrush");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+
+sub clone {
+ $blurb = <<'BLURB';
+Clone from the source to the dest drawable using the current brush
+BLURB
+
+ $help = <<'HELP';
+This tool clones (copies) from the source drawable starting at the specified
+source coordinates to the dest drawable. If the "clone_type" argument is set
+to PATTERN-CLONE, then the current pattern is used as the source and the
+"src_drawable" argument is ignored. Pattern cloning assumes a tileable
+pattern and mods the sum of the src coordinates and subsequent stroke offsets
+with the width and height of the pattern. For image cloning, if the sum of the
+src coordinates and subsequent stroke offsets exceeds the extents of the src
+drawable, then no paint is transferred. The clone tool is capable of
+transforming between any image types including RGB->Indexed--although
+converting from any type to indexed is significantly slower.
+HELP
+
+ &std_pdb_misc;
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ { name => 'src_drawable', type => 'drawable',
+ desc => 'The source drawable' },
+ { name => 'clone_type', type => 'enum GimpCloneType',
+ desc => 'The type of clone' },
+ { name => 'src_x', type => 'float',
+ desc => 'The x coordinate in the source image' },
+ { name => 'src_y', type => 'float',
+ desc => 'The y coordinate in the source image' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-clone");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ g_object_set (options,
+ "clone-type", clone_type,
+ NULL);
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ "src-drawable", src_drawable,
+ "src-x", (gint) floor (src_x),
+ "src-y", (gint) floor (src_y),
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub clone_default {
+ $blurb = <<'BLURB';
+Clone from the source to the dest drawable using the current brush
+BLURB
+
+ $help = <<'HELP';
+This tool clones (copies) from the source drawable starting at the specified
+source coordinates to the dest drawable. This function performs exactly
+the same as the gimp_clone() function except that the tools arguments are
+obtained from the clones option dialog. It this dialog has not been activated
+then the dialogs default values will be used.
+HELP
+
+ &andy_pdb_misc('1999');
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-clone");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+
+sub convolve_default {
+ $blurb = 'Convolve (Blur, Sharpen) using the current brush.';
+
+ $help = <<'HELP';
+This tool convolves the specified drawable with either a sharpening or blurring
+kernel. This function performs exactly the same as the gimp_convolve()
+function except that the tools arguments are obtained from the convolve
+option dialog. It this dialog has not been activated then the dialogs
+default values will be used.
+HELP
+
+ &andy_pdb_misc('1999');
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-convolve");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub convolve {
+ $blurb = 'Convolve (Blur, Sharpen) using the current brush.';
+
+ $help = <<'HELP';
+This tool convolves the specified drawable with either a sharpening or blurring
+kernel. The pressure parameter controls the magnitude of the operation. Like
+the paintbrush, this tool linearly interpolates between the specified stroke
+coordinates.
+HELP
+
+ &std_pdb_misc;
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ { name => 'pressure', type => '0 <= float <= 100',
+ desc => 'The pressure' },
+ { name => 'convolve_type', type => 'enum GimpConvolveType',
+ desc => 'Convolve type' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-convolve");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ g_object_set (options,
+ "type", convolve_type,
+ "rate", pressure,
+ NULL);
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub eraser_default {
+ $blurb = 'Erase using the current brush.';
+
+ $help = <<'HELP';
+This tool erases using the current brush mask. This function performs exactly
+the same as the gimp_eraser() function except that the tools arguments are
+obtained from the eraser option dialog. It this dialog has not been activated
+then the dialogs default values will be used.
+HELP
+
+ &andy_pdb_misc('1999');
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-eraser");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub eraser {
+ $blurb = 'Erase using the current brush.';
+
+ $help = <<'HELP';
+This tool erases using the current brush mask. If the specified drawable
+contains an alpha channel, then the erased pixels will become transparent.
+Otherwise, the eraser tool replaces the contents of the drawable with the
+background color. Like paintbrush, this tool linearly interpolates between the
+specified stroke coordinates.
+HELP
+
+ &std_pdb_misc;
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg,
+ { name => 'hardness', type => 'enum GimpBrushApplicationMode',
+ desc => 'How to apply the brush' },
+ { name => 'method', type => 'enum GimpPaintApplicationMode',
+ desc => 'The paint method to use' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-eraser");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ g_object_set (options,
+ "application-mode", method,
+ "hard", hardness,
+ NULL);
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub anti_eraser {
+ $blurb = 'Anti-erase using the current brush.';
+
+ $help = <<'HELP';
+This tool anti-erases using the current brush mask. If the specified drawable
+contains an alpha channel, then the erased pixels will become opaque.
+Otherwise, the eraser tool replaces the contents of the drawable with the
+background color. Like paintbrush, this tool linearly interpolates between the
+specified stroke coordinates.
+HELP
+
+ &std_pdb_misc;
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg,
+ { name => 'hardness', type => 'enum GimpBrushApplicationMode',
+ desc => 'How to apply the brush' },
+ { name => 'method', type => 'enum GimpPaintApplicationMode',
+ desc => 'The paint method to use' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-eraser");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ g_object_set (options,
+ "application-mode", method,
+ "hard", hardness,
+ "anti-erase", TRUE,
+ NULL);
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub heal {
+ $blurb = <<'BLURB';
+Heal from the source to the dest drawable using the current brush
+BLURB
+
+ $help = <<'HELP';
+This tool heals the source drawable starting at the specified
+source coordinates to the dest drawable. For image healing, if the sum of the
+src coordinates and subsequent stroke offsets exceeds the extents of the src
+drawable, then no paint is transferred. The healing tool is capable of
+transforming between any image types except RGB->Indexed.
+HELP
+
+ &kevins_pdb_misc('2006', '2.4');
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ { name => 'src_drawable', type => 'drawable',
+ desc => 'The source drawable' },
+ { name => 'src_x', type => 'float',
+ desc => 'The x coordinate in the source image' },
+ { name => 'src_y', type => 'float',
+ desc => 'The y coordinate in the source image' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-heal");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ "src-drawable", src_drawable,
+ "src-x", (gint) floor (src_x),
+ "src-y", (gint) floor (src_y),
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub heal_default {
+ $blurb = <<'BLURB';
+Heal from the source to the dest drawable using the current brush
+BLURB
+
+ $help = <<'HELP';
+This tool heals from the source drawable starting at the specified
+source coordinates to the dest drawable. This function performs exactly
+the same as the gimp_heal() function except that the tools arguments are
+obtained from the healing option dialog. It this dialog has not been activated
+then the dialogs default values will be used.
+HELP
+
+ &kevins_pdb_misc('2006', '2.4');
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-heal");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub paintbrush {
+ $blurb = <<'BLURB';
+Paint in the current brush with optional fade out parameter and pull colors
+from a gradient.
+BLURB
+
+ $help = <<'HELP';
+This tool is the standard paintbrush. It draws linearly interpolated lines
+through the specified stroke coordinates. It operates on the specified drawable
+in the foreground color with the active brush. The 'fade-out' parameter is
+measured in pixels and allows the brush stroke to linearly fall off. The
+pressure is set to the maximum at the beginning of the stroke. As the distance
+of the stroke nears the fade-out value, the pressure will approach zero. The
+gradient-length is the distance to spread the gradient over. It is measured in
+pixels. If the gradient-length is 0, no gradient is used.
+HELP
+
+ &std_pdb_misc;
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ { name => 'fade_out', type => '0 <= float',
+ desc => 'Fade out parameter' },
+ &stroke_arg,
+ { name => 'method', type => 'enum GimpPaintApplicationMode',
+ desc => 'The paint method to use' },
+ { name => 'gradient_length', type => '0 <= float',
+ desc => 'Length of gradient to draw' }
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-paintbrush");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ GimpDynamics *pdb_dynamics = GIMP_DYNAMICS (gimp_dynamics_new (context, "pdb"));
+ GimpDynamics *user_dynamics = gimp_context_get_dynamics (context);
+
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ g_object_set (options,
+ "application-mode", method,
+ "fade-length", MAX (fade_out, gradient_length),
+ NULL);
+
+ if (fade_out > 0)
+ {
+ GimpDynamicsOutput *opacity_output =
+ gimp_dynamics_get_output (pdb_dynamics,
+ GIMP_DYNAMICS_OUTPUT_OPACITY);
+
+ g_object_set (opacity_output,
+ "use-fade", TRUE,
+ NULL);
+ }
+
+ if (gradient_length > 0)
+ {
+ GimpDynamicsOutput *color_output =
+ gimp_dynamics_get_output (pdb_dynamics,
+ GIMP_DYNAMICS_OUTPUT_COLOR);
+
+ g_object_set (color_output,
+ "use-fade", TRUE,
+ NULL);
+ }
+
+ gimp_context_set_dynamics (context, pdb_dynamics);
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+
+ gimp_context_set_dynamics (context, user_dynamics);
+
+ g_object_unref (pdb_dynamics);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub paintbrush_default {
+ $blurb = <<'BLURB';
+Paint in the current brush. The fade out parameter and pull colors
+from a gradient parameter are set from the paintbrush options dialog. If this
+dialog has not been activated then the dialog defaults will be used.
+BLURB
+
+ $help = <<'HELP';
+This tool is similar to the standard paintbrush. It draws linearly interpolated lines
+through the specified stroke coordinates. It operates on the specified drawable
+in the foreground color with the active brush. The 'fade-out' parameter is
+measured in pixels and allows the brush stroke to linearly fall
+off (value obtained from the option dialog). The pressure is set
+to the maximum at the beginning of the stroke. As the distance
+of the stroke nears the fade-out value, the pressure will approach zero. The
+gradient-length (value obtained from the option dialog) is the
+distance to spread the gradient over. It is measured in pixels. If
+the gradient-length is 0, no gradient is used.
+HELP
+
+ &andy_pdb_misc('1999');
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-paintbrush");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub pencil {
+ $blurb = 'Paint in the current brush without sub-pixel sampling.';
+
+ $help = <<'HELP';
+This tool is the standard pencil. It draws linearly interpolated lines through
+the specified stroke coordinates. It operates on the specified drawable in the
+foreground color with the active brush. The brush mask is treated as though it
+contains only black and white values. Any value below half is treated as black;
+any above half, as white.
+HELP
+
+ &std_pdb_misc;
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-pencil");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub smudge {
+ $blurb = 'Smudge image with varying pressure.';
+
+ $help = <<'HELP';
+This tool simulates a smudge using the current brush. High pressure results
+in a greater smudge of paint while low pressure results in a lesser smudge.
+HELP
+
+ &std_pdb_misc;
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ { name => 'pressure', type => '0 <= float <= 100',
+ desc => 'The pressure of the smudge strokes' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-smudge");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ g_object_set (options,
+ "rate", pressure,
+ NULL);
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub smudge_default {
+ $blurb = <<'BLURB';
+Smudge image with varying pressure.
+BLURB
+
+ $help = <<'HELP';
+This tool simulates a smudge using the current brush. It behaves exactly
+the same as gimp_smudge() except that the pressure value is taken from the
+smudge tool options or the options default if the tools option dialog has
+not been activated.
+HELP
+
+ &andy_pdb_misc('1999');
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-smudge");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub dodgeburn {
+ $blurb = <<'BLURB';
+Dodgeburn image with varying exposure.
+BLURB
+
+ $help = <<'HELP';
+Dodgeburn. More details here later.
+HELP
+
+ &andy_pdb_misc('1999');
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ { name => 'exposure', type => '0 <= float <= 100',
+ desc => 'The exposure of the strokes' },
+ { name => 'dodgeburn_type', type => 'enum GimpDodgeBurnType',
+ desc => 'The type either dodge or burn' },
+ { name => 'dodgeburn_mode', type => 'enum GimpTransferMode',
+ desc => 'The mode' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-dodge-burn");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ g_object_set (options,
+ "type", dodgeburn_type,
+ "mode", dodgeburn_mode,
+ "exposure", exposure,
+ NULL);
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+sub dodgeburn_default {
+ $blurb = <<'BLURB';
+Dodgeburn image with varying exposure. This is the same as the
+gimp_dodgeburn() function except that the exposure, type and mode are
+taken from the tools option dialog. If the dialog has not been
+activated then the defaults as used by the dialog will be used.
+BLURB
+
+ $help = <<'HELP';
+Dodgeburn. More details here later.
+HELP
+
+ &std_pdb_misc;
+
+ @inargs = (
+ { name => 'drawable', type => 'drawable',
+ desc => 'The affected drawable' },
+ &stroke_arg
+ );
+
+ %invoke = (
+ code => <<'CODE'
+{
+ GimpPaintOptions *options =
+ gimp_pdb_context_get_paint_options (GIMP_PDB_CONTEXT (context),
+ "gimp-dodge-burn");
+
+ if (options &&
+ gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
+ GIMP_PDB_ITEM_CONTENT, error) &&
+ gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
+ {
+ options = gimp_config_duplicate (GIMP_CONFIG (options));
+
+ success = paint_tools_stroke (gimp, context, options, drawable,
+ num_strokes, strokes, error,
+ "undo-desc", options->paint_info->blurb,
+ NULL);
+ }
+ else
+ success = FALSE;
+}
+CODE
+ );
+}
+
+
+$extra{app}->{code} = <<'CODE';
+static const GimpCoords default_coords = GIMP_COORDS_DEFAULT_VALUES;
+
+static gboolean
+paint_tools_stroke (Gimp *gimp,
+ GimpContext *context,
+ GimpPaintOptions *options,
+ GimpDrawable *drawable,
+ gint n_strokes,
+ const gdouble *strokes,
+ GError **error,
+ const gchar *first_property_name,
+ ...)
+{
+ GimpPaintCore *core;
+ GimpCoords *coords;
+ gboolean retval;
+ gint i;
+ va_list args;
+
+ n_strokes /= 2; /* #doubles -> #points */
+
+ /* undefine the paint-relevant context properties and get them
+ * from the current context
+ */
+ gimp_context_define_properties (GIMP_CONTEXT (options),
+ GIMP_CONTEXT_PROP_MASK_PAINT,
+ FALSE);
+ gimp_context_set_parent (GIMP_CONTEXT (options), context);
+
+ va_start (args, first_property_name);
+ core = GIMP_PAINT_CORE (g_object_new_valist (options->paint_info->paint_type,
+ first_property_name, args));
+ va_end (args);
+
+ coords = g_new (GimpCoords, n_strokes);
+
+ for (i = 0; i < n_strokes; i++)
+ {
+ coords[i] = default_coords;
+ coords[i].x = strokes[2 * i];
+ coords[i].y = strokes[2 * i + 1];
+ }
+
+ retval = gimp_paint_core_stroke (core, drawable, options,
+ coords, n_strokes, TRUE,
+ error);
+
+ g_free (coords);
+
+ g_object_unref (core);
+ g_object_unref (options);
+
+ return retval;
+}
+CODE
+
+
+@headers = qw("libgimpmath/gimpmath.h"
+ "libgimpconfig/gimpconfig.h"
+ "core/gimpdynamics.h"
+ "core/gimppaintinfo.h"
+ "paint/gimppaintcore.h"
+ "paint/gimppaintcore-stroke.h"
+ "paint/gimppaintoptions.h"
+ "gimppdbcontext.h"
+ "gimppdb-utils.h");
+
+@procs = qw(airbrush airbrush_default
+ clone clone_default
+ convolve convolve_default
+ dodgeburn dodgeburn_default
+ eraser eraser_default
+ heal heal_default
+ paintbrush paintbrush_default
+ pencil
+ smudge smudge_default);
+
+%exports = (app => [@procs], lib => [@procs]);
+
+$desc = 'Paint Tool procedures';
+$doc_title = 'gimppainttools';
+$doc_short_desc = 'Access to toolbox paint tools.';
+$doc_long_desc = 'Functions giving access to toolbox paint tools.';
+
+1;