1083 lines
32 KiB
Plaintext
1083 lines
32 KiB
Plaintext
|
# PIKA - Photo and Image Kooker Application
|
||
|
# 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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-airbrush");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
g_object_set (options,
|
||
|
"pressure", pressure,
|
||
|
NULL);
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 pika_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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-airbrush");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 PikaCloneType',
|
||
|
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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-clone");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
GList *src_drawables;
|
||
|
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
src_drawables = g_list_prepend (NULL, src_drawable);
|
||
|
|
||
|
g_object_set (options,
|
||
|
"clone-type", clone_type,
|
||
|
"src-drawables", src_drawables,
|
||
|
NULL);
|
||
|
|
||
|
success = paint_tools_stroke (pika, context, options, drawable,
|
||
|
num_strokes, strokes, error,
|
||
|
"undo-desc", options->paint_info->blurb,
|
||
|
"src-x", (gint) floor (src_x),
|
||
|
"src-y", (gint) floor (src_y),
|
||
|
NULL);
|
||
|
g_list_free (src_drawables);
|
||
|
}
|
||
|
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 pika_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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-clone");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 pika_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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-convolve");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 PikaConvolveType',
|
||
|
desc => 'Convolve type' },
|
||
|
&stroke_arg
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-convolve");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
g_object_set (options,
|
||
|
"type", convolve_type,
|
||
|
"rate", pressure,
|
||
|
NULL);
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 pika_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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-eraser");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 PikaBrushApplicationMode',
|
||
|
desc => 'How to apply the brush' },
|
||
|
{ name => 'method', type => 'enum PikaPaintApplicationMode',
|
||
|
desc => 'The paint method to use' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-eraser");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
g_object_set (options,
|
||
|
"application-mode", method,
|
||
|
"hard", hardness,
|
||
|
NULL);
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 PikaBrushApplicationMode',
|
||
|
desc => 'How to apply the brush' },
|
||
|
{ name => 'method', type => 'enum PikaPaintApplicationMode',
|
||
|
desc => 'The paint method to use' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-eraser");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
g_object_set (options,
|
||
|
"application-mode", method,
|
||
|
"hard", hardness,
|
||
|
"anti-erase", TRUE,
|
||
|
NULL);
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-heal");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
GList *src_drawables;
|
||
|
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
src_drawables = g_list_prepend (NULL, src_drawable);
|
||
|
|
||
|
g_object_set (options,
|
||
|
"src-drawables", src_drawables,
|
||
|
NULL);
|
||
|
|
||
|
success = paint_tools_stroke (pika, context, options, drawable,
|
||
|
num_strokes, strokes, error,
|
||
|
"undo-desc", options->paint_info->blurb,
|
||
|
"src-x", (gint) floor (src_x),
|
||
|
"src-y", (gint) floor (src_y),
|
||
|
NULL);
|
||
|
g_list_free (src_drawables);
|
||
|
}
|
||
|
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 pika_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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-heal");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 PikaPaintApplicationMode',
|
||
|
desc => 'The paint method to use' },
|
||
|
{ name => 'gradient_length', type => '0 <= float',
|
||
|
desc => 'Length of gradient to draw' }
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-paintbrush");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
PikaDynamics *pdb_dynamics = PIKA_DYNAMICS (pika_dynamics_new (context, "pdb"));
|
||
|
PikaDynamics *user_dynamics = pika_context_get_dynamics (context);
|
||
|
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
g_object_set (options,
|
||
|
"application-mode", method,
|
||
|
"fade-length", MAX (fade_out, gradient_length),
|
||
|
NULL);
|
||
|
|
||
|
if (fade_out > 0)
|
||
|
{
|
||
|
PikaDynamicsOutput *opacity_output =
|
||
|
pika_dynamics_get_output (pdb_dynamics,
|
||
|
PIKA_DYNAMICS_OUTPUT_OPACITY);
|
||
|
|
||
|
g_object_set (opacity_output,
|
||
|
"use-fade", TRUE,
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
if (gradient_length > 0)
|
||
|
{
|
||
|
PikaDynamicsOutput *color_output =
|
||
|
pika_dynamics_get_output (pdb_dynamics,
|
||
|
PIKA_DYNAMICS_OUTPUT_COLOR);
|
||
|
|
||
|
g_object_set (color_output,
|
||
|
"use-fade", TRUE,
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
pika_context_set_dynamics (context, pdb_dynamics);
|
||
|
|
||
|
success = paint_tools_stroke (pika, context, options, drawable,
|
||
|
num_strokes, strokes, error,
|
||
|
"undo-desc", options->paint_info->blurb,
|
||
|
NULL);
|
||
|
|
||
|
pika_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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-paintbrush");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-pencil");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-smudge");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
g_object_set (options,
|
||
|
"rate", pressure,
|
||
|
NULL);
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 pika_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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-smudge");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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 PikaDodgeBurnType',
|
||
|
desc => 'The type either dodge or burn' },
|
||
|
{ name => 'dodgeburn_mode', type => 'enum PikaTransferMode',
|
||
|
desc => 'The mode' },
|
||
|
&stroke_arg
|
||
|
);
|
||
|
|
||
|
%invoke = (
|
||
|
code => <<'CODE'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-dodge-burn");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
g_object_set (options,
|
||
|
"type", dodgeburn_type,
|
||
|
"mode", dodgeburn_mode,
|
||
|
"exposure", exposure,
|
||
|
NULL);
|
||
|
|
||
|
success = paint_tools_stroke (pika, 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
|
||
|
pika_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'
|
||
|
{
|
||
|
PikaPaintOptions *options =
|
||
|
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
|
||
|
"pika-dodge-burn");
|
||
|
|
||
|
if (options &&
|
||
|
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
|
||
|
PIKA_PDB_ITEM_CONTENT, error) &&
|
||
|
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
|
||
|
{
|
||
|
options = pika_config_duplicate (PIKA_CONFIG (options));
|
||
|
|
||
|
success = paint_tools_stroke (pika, context, options, drawable,
|
||
|
num_strokes, strokes, error,
|
||
|
"undo-desc", options->paint_info->blurb,
|
||
|
NULL);
|
||
|
}
|
||
|
else
|
||
|
success = FALSE;
|
||
|
}
|
||
|
CODE
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
$extra{app}->{code} = <<'CODE';
|
||
|
static const PikaCoords default_coords = PIKA_COORDS_DEFAULT_VALUES;
|
||
|
|
||
|
static gboolean
|
||
|
paint_tools_stroke (Pika *pika,
|
||
|
PikaContext *context,
|
||
|
PikaPaintOptions *options,
|
||
|
PikaDrawable *drawable,
|
||
|
gint n_strokes,
|
||
|
const gdouble *strokes,
|
||
|
GError **error,
|
||
|
const gchar *first_property_name,
|
||
|
...)
|
||
|
{
|
||
|
PikaPaintCore *core;
|
||
|
PikaCoords *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
|
||
|
*/
|
||
|
pika_context_define_properties (PIKA_CONTEXT (options),
|
||
|
PIKA_CONTEXT_PROP_MASK_PAINT,
|
||
|
FALSE);
|
||
|
pika_context_set_parent (PIKA_CONTEXT (options), context);
|
||
|
|
||
|
va_start (args, first_property_name);
|
||
|
core = PIKA_PAINT_CORE (g_object_new_valist (options->paint_info->paint_type,
|
||
|
first_property_name, args));
|
||
|
va_end (args);
|
||
|
|
||
|
coords = g_new (PikaCoords, 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 = pika_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("libpikamath/pikamath.h"
|
||
|
"libpikaconfig/pikaconfig.h"
|
||
|
"core/pikadynamics.h"
|
||
|
"core/pikapaintinfo.h"
|
||
|
"paint/pikapaintcore.h"
|
||
|
"paint/pikapaintcore-stroke.h"
|
||
|
"paint/pikapaintoptions.h"
|
||
|
"pikapdbcontext.h"
|
||
|
"pikapdb-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 = 'pikapainttools';
|
||
|
$doc_short_desc = 'Access to toolbox paint tools.';
|
||
|
$doc_long_desc = 'Functions giving access to toolbox paint tools.';
|
||
|
|
||
|
1;
|