Bunch more stuff

-Yosh
This commit is contained in:
Manish Singh 1999-03-17 23:08:08 +00:00
parent 98e1bdcac9
commit 6f55271ab7
18 changed files with 2997 additions and 331 deletions

View File

@ -24,21 +24,16 @@ $destdir = "$main::destdir/app";
*arg_ptype = \&Gimp::CodeGen::pdb::arg_ptype;
*arg_vname = \&Gimp::CodeGen::pdb::arg_vname;
*enums = \%Gimp::CodeGen::enums::enums;
*write_file = \&Gimp::CodeGen::util::write_file;
*FILE_EXT = \$Gimp::CodeGen::util::FILE_EXT;
%testmap = (
'<' => '>',
'>' => '<',
'<=' => '>=',
'>=' => '<='
);
sub declare_args {
my $proc = shift;
my $out = shift;
my $result = "";
local $result = "";
foreach (@_) {
my @args = @{$proc->{$_}} if exists $proc->{$_};
@ -51,9 +46,10 @@ sub declare_args {
}
unless (exists $_->{no_declare}) {
my $type = $arg->{type};
$result .= ' ' x 2 . $type . &arg_vname($_);
$result .= ' = NULL' if exists $_->{init} && $type =~ /\*$/;
$result .= ' ' x 2 . $arg->{type} . &arg_vname($_);
if (!exists $_->{no_init} && exists $_->{init}) {
$result .= $arg->{type} =~ /\*$/ ? ' = NULL' : '0'
}
$result .= ";\n";
if (exists $arg->{id_headers}) {
@ -61,13 +57,6 @@ sub declare_args {
$out->{headers}->{$_}++;
}
}
if (exists $_->{get}) {
my $type = $arg_types{$_->{get}->{type}}->{type};
$result .= ' ' x 2 . $type . &arg_vname($_->{get});
$result .= ' = NULL' if $type =~ /\*$/;
$result .= ";\n";
}
}
}
}
@ -88,17 +77,28 @@ sub make_args {
$result .= "\nstatic ProcArg $proc->{name}_${_}[] =";
$result .= "\n{\n";
foreach my $arg (@{$proc->{$_}}) {
my ($type) = &arg_parse($arg->{type});
local ($desc) = "";
$desc = 'TRUE or FALSE' if $type eq 'boolean';
foreach $arg (@{$proc->{$_}}) {
my ($type, $name, @remove) = &arg_parse($arg->{type});
my $desc = $arg->{desc};
my $info = $arg->{type};
for ($type) {
/array/ && do { last };
/boolean/ && do { $info = 'TRUE or FALSE'; last };
/int|float/ && do { $info =~ s/$type/$arg->{name}/e; last };
/enum/ && do { $info = $enums{$name}->{info};
foreach (@remove) {
$info =~ s/$_ \(.*?\)(, )?//
} last };
}
$desc =~ s/%%desc%%/$info/eg;
$result .= <<CODE;
{
PDB_$arg_types{$type}->{name},
"$arg->{name}",
"@{[ eval qq/"$arg->{desc}"/ ]}"
"$desc"
},
CODE
}
@ -125,61 +125,81 @@ sub marshal_inargs {
my $arg = $arg_types{$pdbtype};
my $type = &arg_ptype($arg);
my $var = &arg_vname($_);
if (exists $arg->{id_func}) {
my $test = exists $_->{on_success} ? '!=' : '==';
$result .= <<CODE;
if (($var = $arg->{id_func} (args[$argc].value.pdb_$type)) == NULL)
success = FALSE;
if (($var = $arg->{id_func} (args[$argc].value.pdb_$type)) $test NULL)
CODE
$result .= <<CODE if exists $_->{get};
$result .= <<CODE if exists $_->{on_success};
$_->{on_success}
else
@{[ &arg_vname($_->{get}) ]} = @{[ eval qq/"$arg->{$_->{get}->{type}}"/ ]};
CODE
$result .= ' ' x 4 . "success = FALSE;\n";
$success = 1;
}
else {
if ($pdbtype eq 'enum') {
# FIXME: implement this
my $code = ' ' x 2 . "$var =";
my $cast = "";
if ($type eq 'pointer' || $arg->{type} =~ /int(16|8)$/) {
$cast = " ($arg->{type})";
}
elsif ($pdbtype eq 'boolean') {
$result .= ' ' x 2 . "$var = ";
$result .= "args[$argc].value.pdb_$type ? TRUE : FALSE;\n";
$code .= "$cast args[$argc].value.pdb_$type";
$code .= ' ? TRUE : FALSE' if $pdbtype eq 'boolean';
$code .= ";\n";
if ($pdbtype eq 'string') {
$code .= ' ' x 2 . "success = $var != NULL;\n";
}
else {
my $cast = "";
elsif (defined $typeinfo[0] || defined $typeinfo[2]) {
my $tests = 0; my $extra = "";
$cast = " ($arg->{type})" if $type eq "pointer";
$cast = " ($arg->{type})" if $arg->{type} =~ /int(16|8)$/;
if ($pdbtype eq 'enum') {
my $name = pop @typeinfo;
$result .= ' ' x 2 . "$var =";
$result .= "$cast args[$argc].value.pdb_$type;\n";
foreach (@typeinfo) { $extra .= " && $var != $_" }
if ($pdbtype eq 'string') {
$result .= ' ' x 2 . "success = $var != NULL;\n";
$success = 1;
$typeinfo[0] = $enums{$name}->{start};
$typeinfo[1] = '>=';
$typeinfo[2] = $enums{$name}->{end};
$typeinfo[3] = '<=';
}
elsif (defined $typeinfo[0] || defined $typeinfo[2]) {
my $tests = 0;
$result .= ' ' x 2 . "success = ";
$code .= ' ' x 2 . "success = ";
if (defined $typeinfo[0]) {
$result .= "$var $testmap{$typeinfo[1]} $typeinfo[0]";
$tests++;
}
if (defined $typeinfo[2]) {
$result .= '|| ' if $tests;
$result .= "$var $testmap{$typeinfo[2]} $typeinfo[3]";
}
$result .= ";\n";
$success = 1;
if (defined $typeinfo[0]) {
$code .= "$var $typeinfo[1] $typeinfo[0]";
$tests++;
}
if (defined $typeinfo[2]) {
$code .= ' && ' if $tests;
$code .= "$var $typeinfo[3] $typeinfo[2]";
}
$code .= "$extra;\n";
}
if ($code =~ /success/) {
if ($success) {
$code =~ s/^/' ' x 4/meg;
$code =~ s/^ {8}/\t/mg;
$code .= ' ' x 4 . "}\n";
$result .= ' ' x 2 . "if (success)\n" . ' ' x 4 . "{\n";
}
else {
$success_init = 0;
}
$success = 1;
}
$result .= $code;
}
$argc++; $result .= "\n";
@ -240,7 +260,7 @@ sub generate {
my %out;
my $total = 0.0;
foreach my $name (@procs) {
foreach $name (@procs) {
my $proc = $main::pdb{$name};
my $out = \%{$out{$proc->{group}}};
@ -248,6 +268,7 @@ sub generate {
my @outargs = @{$proc->{outargs}} if exists $proc->{outargs};
local $success = 0;
local $success_init = 1;
$out->{pcount}++; $total++;
@ -258,7 +279,7 @@ sub generate {
CODE
if (exists $proc->{invoke}->{headers}) {
foreach my $header (@{$proc->{invoke}->{headers}}) {
foreach $header (@{$proc->{invoke}->{headers}}) {
$out->{headers}->{$header}++;
}
}
@ -300,8 +321,11 @@ CODE
$success = ($code =~ /success =/) unless $success;
if ($success) {
$out->{code} .= ' ' x 2;
$out->{code} .= "int success = $proc->{invoke}->{success};\n";
$success_init = 0 if $proc->{invoke}->{success} eq 'NONE';
$out->{code} .= ' ' x 2 . "gboolean success";
$out->{code} .= " = $proc->{invoke}->{success}" if $success_init;
$out->{code} .= ";\n";
}
$out->{code} .= $invoker . $code . "\n";
@ -376,7 +400,7 @@ HEADER
my $cfile = "$destdir/${group}_cmds.c$FILE_EXT";
open CFILE, "> $cfile" or die "Can't open $cmdfile: $!\n";
print CFILE $gpl;
foreach my $header (sort keys %{$out->{headers}}) {
foreach $header (sort keys %{$out->{headers}}) {
print CFILE "#include $header\n";
}
print CFILE "\n";

37
tools/pdbgen/enums.pl Normal file
View File

@ -0,0 +1,37 @@
# The GIMP -- an image manipulation program
# Copyright (C) 1998 Manish Singh <yosh@gimp.org>
# 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 2 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
package Gimp::CodeGen::enums;
%enums = (
ConvertPaletteType =>
{ name => 'ConvertPaletteType', base => 0,
symbols => [ qw(MAKE_PALETTE REUSE_PALETTE WEB_PALETTE MONO_PALETTE
CUSTOM_PALETTE) ] }
);
foreach $enum (values %enums) {
$enum->{start} = $enum->{symbols}->[0];
$enum->{end} = $enum->{symbols}->[$#{$enum->{symbols}}];
my $pos = 0; $enum->{info} = "";
foreach (@{$enum->{symbols}}) { $enum->{info} .= "$_ ($pos), "; $pos++ }
$enum->{info} =~ s/, $//;
}
1;

View File

@ -36,7 +36,7 @@ sub generate {
$type;
}
foreach my $name (@procs) {
foreach $name (@procs) {
my $proc = $main::pdb{$name};
my $out = \%{$out{$proc->{group}}};

View File

@ -33,49 +33,36 @@ package Gimp::CodeGen::pdb;
color => { name => 'COLOR' , type => 'guchar *' },
display => {
name => 'DISPLAY',
type => 'GDisplay *',
id_func => 'gdisplay_get_ID',
id_ret_func => '$var->ID',
id_headers => [ qw("gdisplay.h") ]
},
image => {
name => 'IMAGE',
type => 'GimpImage *',
id_func => 'pdb_id_to_image',
id_ret_func => 'pdb_image_to_id ($var)',
id_headers => [ qw("procedural_db.h") ]
},
layer => {
name => 'LAYER',
type => 'GimpLayer *',
id_func => 'layer_get_ID',
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
id_headers => [ qw("drawable.h" "layer.h") ]
},
channel => {
name => 'CHANNEL',
type => 'Channel *',
id_func => 'channel_get_ID',
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
id_headers => [ qw("drawable.h" "channel.h") ]
},
drawable => {
name => 'DRAWABLE',
type => 'GimpDrawable *',
id_func => 'gimp_drawable_get_ID',
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
id_headers => [ qw("drawable.h") ],
image => 'drawable_gimage (GIMP_DRAWABLE ($var))'
},
selection => {
name => 'SELECTION',
type => 'Channel *',
id_func => 'channel_get_ID',
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
id_headers => [ qw("drawable.h" "channel.h") ]
},
display => { name => 'DISPLAY',
type => 'GDisplay *',
id_func => 'gdisplay_get_ID',
id_ret_func => '$var->ID',
id_headers => [ qw("gdisplay.h") ] },
image => { name => 'IMAGE',
type => 'GimpImage *',
id_func => 'pdb_id_to_image',
id_ret_func => 'pdb_image_to_id ($var)',
id_headers => [ qw("procedural_db.h") ] },
layer => { name => 'LAYER',
type => 'GimpLayer *',
id_func => 'layer_get_ID',
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
id_headers => [ qw("drawable.h" "layer.h") ] },
channel => { name => 'CHANNEL',
type => 'Channel *',
id_func => 'channel_get_ID',
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
id_headers => [ qw("drawable.h" "channel.h") ] },
drawable => { name => 'DRAWABLE',
type => 'GimpDrawable *',
id_func => 'gimp_drawable_get_ID',
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
id_headers => [ qw("drawable.h") ] },
selection => { name => 'SELECTION',
type => 'Channel *',
id_func => 'channel_get_ID',
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
id_headers => [ qw("drawable.h" "channel.h") ] },
boundary => { name => 'BOUNDARY', type => 'gpointer ' }, # ??? FIXME
path => { name => 'PATH' , type => 'gpointer ' }, # ??? FIXME
@ -90,12 +77,28 @@ package Gimp::CodeGen::pdb;
# Split out the parts of an arg constraint
sub arg_parse {
my %testmap = (
'<' => '>',
'>' => '<',
'<=' => '>=',
'>=' => '<='
);
my $arg = shift;
if ($arg =~ /^enum (\w+)/) {
return ('enum', $1);
if ($arg =~ /^enum (\w+)(.*)/) {
my ($name, $remove) = ($1, $2);
my @retvals = ('enum', $name);
if ($remove && $remove =~ / \(no /) {
$remove =~ s/ \(no (.*?)\)$/$1/;
push @retvals, split(/,\s*/, $remove);
}
return @retvals;
}
if ($arg =~ /^([\d\.-].*?)? *(<=|<)? *(\w+) *(<=|<)? *([\d\.-].*?)?/) {
return ($3, $1, $2, $5, $4);
elsif ($arg =~ /^([\d\.-].*?)? *(<=|<)? *(\w+) *(<=|<)? *([\d\.-].*?)?/) {
return ($3, $1, $2 ? $testmap{$2} : $2, $5, $4 ? $testmap{$4} : $4);
}
}

View File

@ -35,12 +35,12 @@ HELP
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable to offset', get => &std_image_arg },
desc => 'The drawable to offset' },
{ name => 'wrap_around', type => 'boolean',
desc => 'wrap image around or fill vacated regions' },
{ name => 'fill_type', type => 'enum GimpOffsetType',
desc => 'fill vacated regions of drawable with background or
transparent: $desc' },
transparent: %%desc%%' },
{ name => 'offset_x', type => 'int32',
desc => 'offset by this amount in X direction' },
{ name => 'offset_y', type => 'int32',
@ -49,8 +49,12 @@ HELP
%invoke = (
headers => [ qw(channel_ops.h) ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
offset (gimage, drawable, wrap_around, fill_type, offset_x, offset_y);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
offset (gimage, drawable, wrap_around, fill_type, offset_x, offset_y);
}
CODE
);
}

View File

@ -115,14 +115,14 @@ HELP
&std_image_arg,
{ name => 'dither', type => 'boolean',
desc => 'Floyd-Steinberg dithering' },
{ name => 'palette_type', type => 'enum GimpDitherPaletteType',
desc => 'The type of palette to use: $desc' },
{ name => 'palette_type', type => 'enum ConvertPaletteType',
desc => 'The type of palette to use: %%desc%%' },
{ name => 'num_cols', type => 'int32',
desc => 'the number of colors to quantize to, ignored unless
(palette_type == 0)' },
(palette_type == MAKE_PALETTE)' },
{ name => 'palette', type => 'string',
desc => 'The name of the custom palette to use, ignored unless
(palette_type == 4)' }
(palette_type == CUSTOM_PALETTE)' }
);
%invoke = (

View File

@ -64,7 +64,7 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'fill_type', type => 'enum GimpFillType',
desc => 'The type of fill: $desc' }
desc => 'The type of fill: %%desc%%' }
);
%invoke = (

View File

@ -21,8 +21,7 @@
sub inargs {
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => "The drawable to @{[shift]}",
get => &std_image_arg }
desc => "The drawable to @{[shift]}" }
);
}
@ -30,7 +29,13 @@ sub inargs {
sub invoke {
%invoke = (
headers => [ qw("global_edit.h") ],
code => "success = @{[shift]};"
vars => ['GimpImage *gimage'],
code => <<CODE
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
success = @{[shift]};
}
CODE
);
}
@ -102,7 +107,7 @@ HELP
&invoke('layer != NULL');
$cmd = "layer = edit_paste (gimage, drawable, global_buf, paste_into);\n";
$invoke{code} = "{\n" . ' ' x 2 . $cmd . ' ' x 2 . $invoke{code} . "\n}\n";
$invoke{code} =~ s/(success.*$)/"$cmd $1"/me;
}
sub edit_clear {

View File

@ -31,10 +31,10 @@ sub invoke {
headers => [ qw("layer.h" "floating_sel.h") ],
code => <<CODE
{
if (!layer_is_floating_sel (floating_sel))
success = FALSE;
else
if (layer_is_floating_sel (floating_sel))
$cmd (floating_sel);
else
success = FALSE;
}
CODE
);
@ -123,7 +123,7 @@ HELP
&std_pdb_misc;
&inargs;
push @inargs, { name => 'undo', type => 'boolean', desc => '$desc' };
push @inargs, { name => 'undo', type => 'boolean', desc => '%%desc%%' };
&invoke;
$invoke{code} =~ s/\(floating_sel\);/(floating_sel, undo);/;
@ -139,7 +139,7 @@ HELP
&std_pdb_misc;
&inargs;
push @inargs, { name => 'undo', type => 'boolean', desc => '$desc' };
push @inargs, { name => 'undo', type => 'boolean', desc => '%%desc%%' };
&invoke;
$invoke{code} =~ s/\(floating_sel\);/(floating_sel, undo);/;

View File

@ -44,6 +44,7 @@ HELP
%invoke = (
headers => [ qw("gradient.h") ],
vars => ['gradient_t *grad', 'GSList *list', 'int i = 0'],
success => 'NONE',
code => <<'CODE'
{
gradients = g_new (gchar *, num_gradients);
@ -101,7 +102,6 @@ HELP
);
%invoke = (
success => 'FALSE',
headers => [ qw("gradient.h") ],
code => 'success = grad_set_grad_to_name (name);'
);

View File

@ -40,7 +40,7 @@ HELP
{ name => 'sample_size', type => '0 < int32 < 10000',
desc => 'The size of the sample to return when the gradient is
changed $desc',
on_fail => 'G_SAMPLE' }
on_fail => 'sample_size = G_SAMPLE;' }
);
@outargs = (

View File

@ -44,6 +44,7 @@ HELP
%invoke = (
headers => [ qw("gradient.h") ],
vars => ['gradient_t *grad', 'GSList *list', 'int i = 0'],
success => 'NONE',
code => <<'CODE'
{
gradients = g_new (gchar *, num_gradients);
@ -101,7 +102,6 @@ HELP
);
%invoke = (
success => 'FALSE',
headers => [ qw("gradient.h") ],
code => 'success = grad_set_grad_to_name (name);'
);

View File

@ -25,19 +25,37 @@ sub drawable_arg () {{
name => 'drawable',
type => 'drawable',
desc => 'The affected drawable',
get => &std_image_arg
}}
sub drawable_out_arg {
my $type = shift;
my $arg = &drawable_arg;
$arg->{desc} = "The $type drawable";
$arg;
}
sub sample_merged_arg () {{
name => 'sample_merged',
type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub operation_arg () {{
name => 'operation',
type => 'enum Selection',
desc => 'The selection operation: %%desc%%'
}}
sub threshold_arg () {{
name => 'threshold',
type => '0 <= int32 <= 255',
desc => 'Threshold in intensity levels %%desc%%'
}}
sub antialias_arg () {{
name => 'antialias',
type => 'boolean',
desc => 'Antialiasing $desc'
desc => 'Antialiasing (%%desc%%)'
}}
sub feather_select_args () {(
@ -74,10 +92,9 @@ HELP;
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure of the airbrush strokes $desc' },
desc => 'The pressure of the airbrush strokes (%%desc%%)' },
&stroke_arg
);
delete $inargs[0]->{get};
%invoke = (
headers => [ qw("airbrush.h") ],
@ -102,19 +119,19 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'blend_mode', type => 'enum BlendMode',
desc => 'The type of blend: $desc' },
desc => 'The type of blend: %%desc%%' },
{ name => 'gradient_type', type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
desc => 'The paint application mode: %%desc%%' },
{ name => 'opacity', type => '0 <= float <= 100',
desc => 'The opacity of the final blend $desc' },
desc => 'The opacity of the final blend %%desc%%' },
{ name => 'offset', type => '0 <= float',
desc => 'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent
$desc' },
%%desc%%' },
{ name => 'repeat', type => 'enum RepeatMode',
desc => 'Repeat mode: $desc' },
desc => 'Repeat mode: %%desc%%' },
{ name => 'supersample', type => 'boolean',
desc => 'Do adaptive supersampling $desc' },
desc => 'Do adaptive supersampling (%%desc%%)' },
{ name => 'max_depth', type => '1 <= int32 <= 9',
desc => 'Maximum recursion levels for supersampling',
cond => 'supersample' },
@ -133,9 +150,13 @@ HELP
%invoke = (
headers => [ qw("blend.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
}
CODE
);
}
@ -169,15 +190,15 @@ HELP;
%inargs = (
&drawable_arg,
{ name => 'fill_mode', type => 'enum FillMode',
desc => 'The type of fill: $desc' },
desc => 'The type of fill: %%desc%%' },
{ name => paint_mode, type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
desc => 'The paint application mode: %%desc%%' },
{ name => opacity, type => '0 <= float <= 100',
desc => 'The opacity of the final bucket fill $desc' },
desc => 'The opacity of the final bucket fill %%desc%%' },
{ name => threshold, type => '0 <= float <= 255',
desc => "The threshold determines how extensive the seed fill will
be. It's value is specified in terms of intensity levels
\$desc. $validity" },
%%desc%%. $validity" },
&sample_merged_arg,
{ name => x, type => 'float',
desc => eval qq/{\$a = 'x'; "$coord";}/ },
@ -187,9 +208,13 @@ HELP;
%invoke = (
headers => [ qw ("bucket_fill.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
sample_merged, x, y);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity,
threshold, sample_merged, x, y);
}
CODE
);
}
@ -220,10 +245,8 @@ HELP
&drawable_arg,
{ name => 'color', type => 'color',
desc => 'The color to select' },
{ name => 'threshold', type => '0 <= int32 <= 255',
desc => 'Threshold in intensity levels $desc' },
{ name => 'operation', type => 'enum Operation',
desc => 'The selection operation: $desc' },
&threshold_arg,
&operation_arg,
&antialias_arg,
&feather_select_args,
&sample_merged_arg
@ -231,9 +254,13 @@ HELP
%invoke = (
headers => [ qw("by_color_select.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
by_color_select (gimage, drawable, color, threshold, operation,
antialias, feather, feather_radius, sample_merged);
}
CODE
);
}
@ -263,20 +290,19 @@ HELP
{ name => 'src_drawable', type => 'drawable',
desc => 'The source drawable' },
{ name => 'clone_type', type => 'enum CloneType',
desc => 'The type of clone: $desc' },
desc => 'The type of clone: %%desc%%' },
{ 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
);
delete $inargs[0]->{get};
%invoke = (
headers => [ qw("clone.h") ],
code => <<'CODE'
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
strokes);
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y,
num_strokes, strokes);
CODE
);
}
@ -314,14 +340,18 @@ HELP
@outargs = (
{ name => 'color', type => 'color',
desc => 'The return color' }
desc => 'The return color', init => 1 }
);
%invoke = (
headers => [ qw("color_picker.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
{
if (success = get_color (gimage, drawable, (int) x, (int) y, sample_merged, save_color)
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
if (success = get_color (gimage, drawable, (int) x, (int) y,
sample_merged, save_color)
{
color = g_new (guchar, 3);
color[RED_PIX] = col_value[RED_PIX];
@ -348,9 +378,9 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure: $desc' },
desc => 'The pressure: %%desc%%' },
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
desc => 'Convolve type: $desc' },
desc => 'Convolve type: %%desc%%' },
&stroke_arg
);
@ -389,8 +419,7 @@ HELP
headers => [ qw("crop.h") ],
code => <<'CODE'
{
if (new_width > gimage->width ||
new_height > gimage->height ||
if (new_width > gimage->width || new_height > gimage->height ||
offx > (gimage->width - new_width) ||
offy > (gimage->height - new_height)
success = FALSE;
@ -422,11 +451,10 @@ HELP
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of ellipse bounding box' },
{ name => 'width', type => '0 < float',
desc => 'The width of the ellipse: $desc' },
desc => 'The width of the ellipse: %%desc%%' },
{ name => 'height', type => '0 < float',
desc => 'The height of the ellipse: $desc' },
{ name => 'operation', 'enum Selection',
desc => 'The selection operation: $desc' },
desc => 'The height of the ellipse: %%desc%%' },
&operation_arg,
&antialias_arg,
&feather_args
);
@ -434,8 +462,8 @@ HELP
%invoke = (
headers => [ qw("ellipse_select.h") ],
code => <<'CODE'
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
feather, feather_radius);
ellipse_select (gimage, (int) x, (int) y, (int) width, (int) height,
operation, antialias, feather, feather_radius);
CODE
);
}
@ -457,9 +485,9 @@ HELP
&drawable_arg,
&stroke_arg,
{ name => 'hardness', type => 'enum EraserHardness',
desc => '$desc' }
desc => '%%desc%%' }
{ name => 'method', type => 'enum EraserMethod',
desc => '$desc' }
desc => '%%desc%%' }
);
%invoke = (
@ -492,20 +520,18 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'flip_type', type => 'enum FlipType',
desc => 'Type of flip: $desc' }
desc => 'Type of flip: %%desc%%' }
);
@outargs = ( &drawable_arg );
$outargs[0]->{alias} = layer;
$outargs[0]->{desc} = 'The flipped drawable';
$outargs[0]->{no_declare} = 1;
delete $outargs[0]->{get};
@outargs = ( &drawable_out_arg('flipped') );
%invoke = (
headers => [ qw("flip_tool.h" "tranform_core.h") ],
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
@ -541,4 +567,626 @@ CODE
);
}
sub free_select {
$blurb = 'Create a polygonal selection over the specified image.';
$help = <<'HELP';
This tool creates a polygonal selection over the specified image. The polygonal
region can be either added to, subtracted from, or replace the contents of the
previous selection mask. The polygon is specified through an array of floating
point numbers and its length. The length of array must be 2n, where n is the
number of points. Each point is defined by 2 floating point values which
correspond to the x and y coordinates. If the final point does not connect to
the starting point, a connecting segment is automatically added. If the feather
option is enabled, the resulting selection is blurred before combining. The
blur is a gaussian blur with the specified feather radius.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'segs', type => 'floatarray',
desc => 'Array of points: { p1.x, p1.y, p2.x, p2.y, ...,
pn.x, pn.y}',
array => { desc => 'Number of points (count 1 coordinate as two
points)' } },
&operation_arg,
&antialias_arg,
&feather_select_args
);
%invoke = (
headers => qw("free_select.h"),
code => <<'CODE'
free_select (gimage, num_segs, segs, operation, antialias, feather,
feather_radius);
CODE
);
}
sub fuzzy_select {
$blurb = <<'BLURB';
Create a fuzzy selection starting at the specified coordinates on the specified
drawable.
BLURB
$help = <<'HELP';
This tool creates a fuzzy selection over the specified image. A fuzzy selection
is determined by a seed fill under the constraints of the specified threshold.
Essentially, the color at the specified coordinates (in the drawable) is
measured and the selection expands outwards from that point to any adjacent
pixels which are not significantly different (as determined by the threshold
value). This process continues until no more expansion is possible. The
antialiasing parameter allows the final selection mask to contain intermediate
values based on close misses to the threshold bar at pixels along the seed fill
boundary. Feathering can be enabled optionally and is controlled with the
"feather_radius" paramter. If the sample_merged parameter is non-zero, the data
of the composite image will be used instead of that for the specified drawable.
This is equivalent to sampling for colors after merging all visible layers. In
the case of a merged sampling, the supplied drawable is ignored. If the sample
is merged, the specified coordinates are relative to the image origin;
otherwise, they are relative to the drawable's origin.'
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of initial seed fill point: (image
coordinates)' },
{ name => 'y', type => 'float',
desc => 'y coordinate of initial seed fill point: (image
coordinates)' },
&threshold_arg,
&operation_arg,
&antialias_arg,
&feather_select_args,
&sample_merged_arg
);
%invoke = (
headers => qw("fuzzy_select.h"),
vars => ['GimpImage *gimage', 'Channel *new, *old_fuzzy_mask'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
new = find_contiguous_region (gimage, drawable, antialias, threshold,
x, y, sample_merged);
old_fuzzy_mask = fuzzy_mask;
fuzzy_mask = new;
drawable = sample_merged ? NULL : drawable;
fuzzy_select (gimage, drawbale, operation, feather, feather_radius);
fuzzy_mask = old_fuzzy_mask;
}
CODE
);
}
sub paintbrush {
$blurb = 'Paint in the current brush with optional fade out parameter.';
$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.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'fade_out', type => '0 < float',
desc => 'Fade out parameter: %%desc%%' },
&stroke_arg,
{ name => 'method', type => 'enum PaintMethod',
desc => '%%desc%%' }
);
%invoke = (
headers => [ qw("paintbrush.h") ],
code => <<'CODE'
paintbrush_non_gui (drawable, num_strokes, strokes, fade_out, method);
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 = (
&drawable_arg,
&stroke_arg
);
%invoke = (
headers => qw("fuzzy_select.h"),
code => 'pencil_non_gui (drawable, num_strokes, strokes);'
);
}
sub perspective {
$blurb = <<'BLURB';
Perform a possibly non-affine transformation on the specified drawable.
BLURB
$help = <<'HELP';
This tool performs a possibly non-affine transformation on the specified
drawable by allowing the corners of the original bounding box to be arbitrarily
remapped to any values. The specified drawable is remapped if no selection
exists. However, if a selection exists, the portion of the drawable which lies
under the selection is cut from the drawable and made into a floating selection
which is then remapped as specified. The interpolation parameter can be set to
TRUE to indicate that either linear or cubic interpolation should be used to
smooth the resulting remapped drawable. The return value is the ID of the
remapped drawable. If there was no selection, this will be equal to the
drawable ID supplied as input. Otherwise, this will be the newly created and
remapped drawable. The 4 coordinates specify the new locations of each corner
of the original bounding box. By specifying these values, any affine
transformation (rotation, scaling, translation) can be affected. Additionally,
these values can be specified such that the resulting transformed drawable will
appear to have been projected via a perspective transform.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
);
my $pos = 0;
foreach $where (qw(upper-left upper-right lower-left lower-right)) {
foreach (qw(x y)) {
push @inargs,
{ name => "$_$pos", type => 'float',
desc => "The new $_ coordinate of $where corner of original
bounding box",
alias => "trans_info[@{[ uc $_ ]}$pos]}", no_declare => 1 }
}
$pos++;
}
@outargs = ( &drawable_out_arg('newly mapped') );
%invoke = (
headers => [ qw("perspective_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'int new_layer', 'double cx, cy', 'double scalex, scaley',
'double trans_info[8]', 'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
/* Determine the perspective transform that maps from
* the unit cube to the trans_info coordinates
*/
perspective_find_transform (trans_info, m);
cx = float_tiles->x;
cy = float_tiles->y;
scalex = 1.0;
scaley = 1.0;
if (float_tiles->width)
scalex = 1.0 / float_tiles->width;
if (float_tiles->height)
scaley = 1.0 / float_tiles->height;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
gimp_matrix_scale (matrix, scalex, scaley);
gimp_matrix_mult (m, matrix);
/* Perspective the buffer */
new_tiles = perspective_tool_perspective (gimage, drawable, NULL,
float_tiles, interpolation,
matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub rect_select {
$blurb = 'Create a rectangular selection over the specified image;';
$help = <<'HELP';
This tool creates a rectangular selection over the specified image. The
rectangular region can be either added to, subtracted from, or replace the
contents of the previous selection mask. If the feather option is enabled, the
resulting selection is blurred before combining. The blur is a gaussian blur
with the specified feather radius.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of rectangle' },
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of rectangle' },
{ name => 'width', type => '0 < float',
desc => 'The width of the rectangle: %%desc%%' }
{ name => 'height', type => '0 < float',
desc => 'The height of the rectangle: %%desc%%' }
&operation_arg,
&feather_select_args,
);
%invoke = (
headers => [ qw("rect_select.h") ],
code => <<'CODE'
rect_select (gimage, (int) x, (int) y, (int) width, (int) height,
operation, feather, feather_radius);
CODE
);
}
sub rotate_invoker {
$blurb = <<'BLURB';
Rotate the specified drawable about its center through the specified angle.
BLURB
$help = <<'HELP';
This tool rotates the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then rotated by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting rotated drawable. The return value is the ID of the rotated drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and rotated drawable.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
{ name => 'angle', type => 'float',
desc => 'The angle of rotation (radians)' }
);
@outargs = ( &drawable_arg('rotated') );
%invoke = (
headers => [ qw("rotate_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'Layer *layer', 'int new_layer', 'double cx, cy',
'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
cx = float_tiles->x + float_tiles->width / 2.0;
cy = float_tiles->y + float_tiles->height / 2.0;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
gimp_matrix_rotate (matrix, angle);
gimp_matrix_translate (matrix, +cx, +cy);
/* Rotate the buffer */
new_tiles = rotate_tool_rotate (gimage, drawable, NULL, angle,
float_tiles, interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* Push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub scale {
$blurb = 'Scale the specified drawable.';
$help = <<'HELP';
This tool scales the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then scaled by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting scaled drawable. The return value is the ID of the scaled drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and scaled drawable.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
);
my $pos = 1;
foreach $where (qw(upper-left lower-right)) {
foreach (qw(x y)) {
push @inargs,
{ name => "$_$pos", type => 'float',
desc => "The new $_ coordinate of $where corner of newly
scaled region",
alias => "trans_info[@{[ uc $_ ]}$pos]}", no_declare => 1 }
}
$pos++;
}
@outargs = ( &drawable_out_arg('scaled') );
%invoke = (
headers => [ qw("scale_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'int new_layer', 'double scalex, scaley',
'double trans_info[4]', 'GimpMatrix matrix'],
code => <<'CODE'
{
if (trans_info[X1] < trans_info[X2] &&
trans_info[Y1] < trans_info[X2])
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
scalex = scaley = 1.0;
if (float_tiles->width)
scalex = (trans_info[X2] - trans_info[X1]) / (double) float_tiles->width
;
if (float_tiles->height)
scaley = (trans_info[Y2] - trans_info[Y1]) / (double) float_tiles->heigh
t;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, float_tiles->x, float_tiles->y);
gimp_matrix_scale (matrix, scalex, scaley);
gimp_matrix_translate (matrix, trans_info[X1], trans_info[Y1]);
/* Scale the buffer */
new_tiles = scale_tool_scale (gimage, drawable, NULL, trans_info,
float_tiles, interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* push the undo group end */
undo_push_group_end (gimage);
}
else
success = FALSE;
}
CODE
);
}
sub shear {
$blurb = <<'BLURB';
Shear the specified drawable about its center by the specified magnitude.
BLURB
$help = <<'HELP';
This tool shears the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then sheard by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting sheared drawable. The return value is the ID of the sheard drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and sheard drawable. The shear
type parameter indicates whether the shear will be applied horizontally or
vertically. The magnitude can be either positive or negative and indicates the
extent (in pixels) to shear by.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
{ name => 'shear_type', type => 'enum ShearType',
desc => 'Type of shear: %%desc%%' },
{ name => 'magnitude', type => 'float',
desc => 'The magnitude of the shear' }
);
@outargs = ( &drawable_arg('sheared') );
%invoke = (
headers => [ qw("perspective_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'Layer *layer', 'int new_layer', 'double cx, cy',
'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
cx = float_tiles->x + float_tiles->width / 2.0;
cy = float_tiles->y + float_tiles->height / 2.0;
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
/* Shear matrix */
if (shear_type == HORZ)
gimp_matrix_xshear (matrix, shear_magnitude / float_tiles->height);
else if (shear_type == VERT)
gimp_matrix_yshear (matrix, shear_magnitude / float_tiles->width);
gimp_matrix_translate (matrix, +cx, +cy);
/* Shear the buffer */
new_tiles = shear_tool_shear (gimage, drawable, NULL, float_tiles,
interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* Push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub text {
$blurb = <<'BLURB';
Add text at the specified location as a floating selection or a new layer.
BLURB
$help = <<'HELP';
This tool requires font information in the form of nine parameters: size,
foundry, family, weight, slant, set_width, spacing, registry, encoding. The
font size can either be specified in units of pixels or points, and the
appropriate metric is specified using the size_type argument. The x and y
parameters together control the placement of the new text by specifying the
upper left corner of the text bounding box. If the antialias parameter is
non-zero, the generated text will blend more smoothly with underlying layers.
This option requires more time and memory to compute than non-antialiased text;
the resulting floating selection or layer, however, will require the same
amount of memory with or without antialiasing. If the specified drawable
parameter is valid, the text will be created as a floating selection attached
to the drawable. If the drawable parameter is not valid (-1), the text will
appear as a new layer. Finally, a border can be specified around the final
rendered text. The border is measured in pixels.
HELP
&std_pdb_misc;
$author = 'Martin Edlman';
$date = '1998';
@inargs = (
&drawable_arg,
{ name => 'x', type => 'float',
desc => 'The x coordinate for the left of the text bounding box' },
{ name => 'y', type => 'float',
desc => 'The y coordinate for the top of the text bounding box' },
{ name => 'text', type => 'string',
desc => 'The text to generate',
{ name => 'border', type => '-1 <= int32',
desc => 'The size of the border: %%desc%%' }
&antialias_arg,
{ name => 'size', type => '0 < float',
desc => 'The size of text in either pixels or points' },
{ name => 'size_type', type => 'enum SizeType',
desc => 'The units of specified size: %%desc%%' }
);
foreach (qw(foundry family weight slant set-width spacing registry
encoding)) {
my $var = $_;
$var =~ s/-/_/g;
push @inargs, { name => $var, type => 'string',
desc => qq/The font $_, "*" for any/ }
}
@outargs = (
{ name => 'text_layer', type => 'layer',
desc => 'The new text layer' }
);
%invoke = (
headers => [ qw("text_tool.h") ],
vars => ['GimpImage *gimage', 'gchar *fontname[2048]'],
code => <<'CODE'
{
if (antialias)
size *= SUPERSAMPLE;
success = text_get_xlfd (size, size_type, foundry, family, weight,
slant, set_width, spacing, registry, encoding,
fontname);
if (success)
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
text_layer = text_render (gimage, drawable, x, y, fontname, text,
border, antialias);
success = text_layer != NULL;
}
}
CODE
);
}

View File

@ -25,19 +25,37 @@ sub drawable_arg () {{
name => 'drawable',
type => 'drawable',
desc => 'The affected drawable',
get => &std_image_arg
}}
sub drawable_out_arg {
my $type = shift;
my $arg = &drawable_arg;
$arg->{desc} = "The $type drawable";
$arg;
}
sub sample_merged_arg () {{
name => 'sample_merged',
type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub operation_arg () {{
name => 'operation',
type => 'enum Selection',
desc => 'The selection operation: %%desc%%'
}}
sub threshold_arg () {{
name => 'threshold',
type => '0 <= int32 <= 255',
desc => 'Threshold in intensity levels %%desc%%'
}}
sub antialias_arg () {{
name => 'antialias',
type => 'boolean',
desc => 'Antialiasing $desc'
desc => 'Antialiasing (%%desc%%)'
}}
sub feather_select_args () {(
@ -74,10 +92,9 @@ HELP;
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure of the airbrush strokes $desc' },
desc => 'The pressure of the airbrush strokes (%%desc%%)' },
&stroke_arg
);
delete $inargs[0]->{get};
%invoke = (
headers => [ qw("airbrush.h") ],
@ -102,19 +119,19 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'blend_mode', type => 'enum BlendMode',
desc => 'The type of blend: $desc' },
desc => 'The type of blend: %%desc%%' },
{ name => 'gradient_type', type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
desc => 'The paint application mode: %%desc%%' },
{ name => 'opacity', type => '0 <= float <= 100',
desc => 'The opacity of the final blend $desc' },
desc => 'The opacity of the final blend %%desc%%' },
{ name => 'offset', type => '0 <= float',
desc => 'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent
$desc' },
%%desc%%' },
{ name => 'repeat', type => 'enum RepeatMode',
desc => 'Repeat mode: $desc' },
desc => 'Repeat mode: %%desc%%' },
{ name => 'supersample', type => 'boolean',
desc => 'Do adaptive supersampling $desc' },
desc => 'Do adaptive supersampling (%%desc%%)' },
{ name => 'max_depth', type => '1 <= int32 <= 9',
desc => 'Maximum recursion levels for supersampling',
cond => 'supersample' },
@ -133,9 +150,13 @@ HELP
%invoke = (
headers => [ qw("blend.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
}
CODE
);
}
@ -169,15 +190,15 @@ HELP;
%inargs = (
&drawable_arg,
{ name => 'fill_mode', type => 'enum FillMode',
desc => 'The type of fill: $desc' },
desc => 'The type of fill: %%desc%%' },
{ name => paint_mode, type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
desc => 'The paint application mode: %%desc%%' },
{ name => opacity, type => '0 <= float <= 100',
desc => 'The opacity of the final bucket fill $desc' },
desc => 'The opacity of the final bucket fill %%desc%%' },
{ name => threshold, type => '0 <= float <= 255',
desc => "The threshold determines how extensive the seed fill will
be. It's value is specified in terms of intensity levels
\$desc. $validity" },
%%desc%%. $validity" },
&sample_merged_arg,
{ name => x, type => 'float',
desc => eval qq/{\$a = 'x'; "$coord";}/ },
@ -187,9 +208,13 @@ HELP;
%invoke = (
headers => [ qw ("bucket_fill.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
sample_merged, x, y);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity,
threshold, sample_merged, x, y);
}
CODE
);
}
@ -220,10 +245,8 @@ HELP
&drawable_arg,
{ name => 'color', type => 'color',
desc => 'The color to select' },
{ name => 'threshold', type => '0 <= int32 <= 255',
desc => 'Threshold in intensity levels $desc' },
{ name => 'operation', type => 'enum Operation',
desc => 'The selection operation: $desc' },
&threshold_arg,
&operation_arg,
&antialias_arg,
&feather_select_args,
&sample_merged_arg
@ -231,9 +254,13 @@ HELP
%invoke = (
headers => [ qw("by_color_select.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
by_color_select (gimage, drawable, color, threshold, operation,
antialias, feather, feather_radius, sample_merged);
}
CODE
);
}
@ -263,20 +290,19 @@ HELP
{ name => 'src_drawable', type => 'drawable',
desc => 'The source drawable' },
{ name => 'clone_type', type => 'enum CloneType',
desc => 'The type of clone: $desc' },
desc => 'The type of clone: %%desc%%' },
{ 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
);
delete $inargs[0]->{get};
%invoke = (
headers => [ qw("clone.h") ],
code => <<'CODE'
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
strokes);
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y,
num_strokes, strokes);
CODE
);
}
@ -314,14 +340,18 @@ HELP
@outargs = (
{ name => 'color', type => 'color',
desc => 'The return color' }
desc => 'The return color', init => 1 }
);
%invoke = (
headers => [ qw("color_picker.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
{
if (success = get_color (gimage, drawable, (int) x, (int) y, sample_merged, save_color)
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
if (success = get_color (gimage, drawable, (int) x, (int) y,
sample_merged, save_color)
{
color = g_new (guchar, 3);
color[RED_PIX] = col_value[RED_PIX];
@ -348,9 +378,9 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure: $desc' },
desc => 'The pressure: %%desc%%' },
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
desc => 'Convolve type: $desc' },
desc => 'Convolve type: %%desc%%' },
&stroke_arg
);
@ -389,8 +419,7 @@ HELP
headers => [ qw("crop.h") ],
code => <<'CODE'
{
if (new_width > gimage->width ||
new_height > gimage->height ||
if (new_width > gimage->width || new_height > gimage->height ||
offx > (gimage->width - new_width) ||
offy > (gimage->height - new_height)
success = FALSE;
@ -422,11 +451,10 @@ HELP
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of ellipse bounding box' },
{ name => 'width', type => '0 < float',
desc => 'The width of the ellipse: $desc' },
desc => 'The width of the ellipse: %%desc%%' },
{ name => 'height', type => '0 < float',
desc => 'The height of the ellipse: $desc' },
{ name => 'operation', 'enum Selection',
desc => 'The selection operation: $desc' },
desc => 'The height of the ellipse: %%desc%%' },
&operation_arg,
&antialias_arg,
&feather_args
);
@ -434,8 +462,8 @@ HELP
%invoke = (
headers => [ qw("ellipse_select.h") ],
code => <<'CODE'
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
feather, feather_radius);
ellipse_select (gimage, (int) x, (int) y, (int) width, (int) height,
operation, antialias, feather, feather_radius);
CODE
);
}
@ -457,9 +485,9 @@ HELP
&drawable_arg,
&stroke_arg,
{ name => 'hardness', type => 'enum EraserHardness',
desc => '$desc' }
desc => '%%desc%%' }
{ name => 'method', type => 'enum EraserMethod',
desc => '$desc' }
desc => '%%desc%%' }
);
%invoke = (
@ -492,20 +520,18 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'flip_type', type => 'enum FlipType',
desc => 'Type of flip: $desc' }
desc => 'Type of flip: %%desc%%' }
);
@outargs = ( &drawable_arg );
$outargs[0]->{alias} = layer;
$outargs[0]->{desc} = 'The flipped drawable';
$outargs[0]->{no_declare} = 1;
delete $outargs[0]->{get};
@outargs = ( &drawable_out_arg('flipped') );
%invoke = (
headers => [ qw("flip_tool.h" "tranform_core.h") ],
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
@ -541,4 +567,626 @@ CODE
);
}
sub free_select {
$blurb = 'Create a polygonal selection over the specified image.';
$help = <<'HELP';
This tool creates a polygonal selection over the specified image. The polygonal
region can be either added to, subtracted from, or replace the contents of the
previous selection mask. The polygon is specified through an array of floating
point numbers and its length. The length of array must be 2n, where n is the
number of points. Each point is defined by 2 floating point values which
correspond to the x and y coordinates. If the final point does not connect to
the starting point, a connecting segment is automatically added. If the feather
option is enabled, the resulting selection is blurred before combining. The
blur is a gaussian blur with the specified feather radius.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'segs', type => 'floatarray',
desc => 'Array of points: { p1.x, p1.y, p2.x, p2.y, ...,
pn.x, pn.y}',
array => { desc => 'Number of points (count 1 coordinate as two
points)' } },
&operation_arg,
&antialias_arg,
&feather_select_args
);
%invoke = (
headers => qw("free_select.h"),
code => <<'CODE'
free_select (gimage, num_segs, segs, operation, antialias, feather,
feather_radius);
CODE
);
}
sub fuzzy_select {
$blurb = <<'BLURB';
Create a fuzzy selection starting at the specified coordinates on the specified
drawable.
BLURB
$help = <<'HELP';
This tool creates a fuzzy selection over the specified image. A fuzzy selection
is determined by a seed fill under the constraints of the specified threshold.
Essentially, the color at the specified coordinates (in the drawable) is
measured and the selection expands outwards from that point to any adjacent
pixels which are not significantly different (as determined by the threshold
value). This process continues until no more expansion is possible. The
antialiasing parameter allows the final selection mask to contain intermediate
values based on close misses to the threshold bar at pixels along the seed fill
boundary. Feathering can be enabled optionally and is controlled with the
"feather_radius" paramter. If the sample_merged parameter is non-zero, the data
of the composite image will be used instead of that for the specified drawable.
This is equivalent to sampling for colors after merging all visible layers. In
the case of a merged sampling, the supplied drawable is ignored. If the sample
is merged, the specified coordinates are relative to the image origin;
otherwise, they are relative to the drawable's origin.'
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of initial seed fill point: (image
coordinates)' },
{ name => 'y', type => 'float',
desc => 'y coordinate of initial seed fill point: (image
coordinates)' },
&threshold_arg,
&operation_arg,
&antialias_arg,
&feather_select_args,
&sample_merged_arg
);
%invoke = (
headers => qw("fuzzy_select.h"),
vars => ['GimpImage *gimage', 'Channel *new, *old_fuzzy_mask'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
new = find_contiguous_region (gimage, drawable, antialias, threshold,
x, y, sample_merged);
old_fuzzy_mask = fuzzy_mask;
fuzzy_mask = new;
drawable = sample_merged ? NULL : drawable;
fuzzy_select (gimage, drawbale, operation, feather, feather_radius);
fuzzy_mask = old_fuzzy_mask;
}
CODE
);
}
sub paintbrush {
$blurb = 'Paint in the current brush with optional fade out parameter.';
$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.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'fade_out', type => '0 < float',
desc => 'Fade out parameter: %%desc%%' },
&stroke_arg,
{ name => 'method', type => 'enum PaintMethod',
desc => '%%desc%%' }
);
%invoke = (
headers => [ qw("paintbrush.h") ],
code => <<'CODE'
paintbrush_non_gui (drawable, num_strokes, strokes, fade_out, method);
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 = (
&drawable_arg,
&stroke_arg
);
%invoke = (
headers => qw("fuzzy_select.h"),
code => 'pencil_non_gui (drawable, num_strokes, strokes);'
);
}
sub perspective {
$blurb = <<'BLURB';
Perform a possibly non-affine transformation on the specified drawable.
BLURB
$help = <<'HELP';
This tool performs a possibly non-affine transformation on the specified
drawable by allowing the corners of the original bounding box to be arbitrarily
remapped to any values. The specified drawable is remapped if no selection
exists. However, if a selection exists, the portion of the drawable which lies
under the selection is cut from the drawable and made into a floating selection
which is then remapped as specified. The interpolation parameter can be set to
TRUE to indicate that either linear or cubic interpolation should be used to
smooth the resulting remapped drawable. The return value is the ID of the
remapped drawable. If there was no selection, this will be equal to the
drawable ID supplied as input. Otherwise, this will be the newly created and
remapped drawable. The 4 coordinates specify the new locations of each corner
of the original bounding box. By specifying these values, any affine
transformation (rotation, scaling, translation) can be affected. Additionally,
these values can be specified such that the resulting transformed drawable will
appear to have been projected via a perspective transform.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
);
my $pos = 0;
foreach $where (qw(upper-left upper-right lower-left lower-right)) {
foreach (qw(x y)) {
push @inargs,
{ name => "$_$pos", type => 'float',
desc => "The new $_ coordinate of $where corner of original
bounding box",
alias => "trans_info[@{[ uc $_ ]}$pos]}", no_declare => 1 }
}
$pos++;
}
@outargs = ( &drawable_out_arg('newly mapped') );
%invoke = (
headers => [ qw("perspective_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'int new_layer', 'double cx, cy', 'double scalex, scaley',
'double trans_info[8]', 'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
/* Determine the perspective transform that maps from
* the unit cube to the trans_info coordinates
*/
perspective_find_transform (trans_info, m);
cx = float_tiles->x;
cy = float_tiles->y;
scalex = 1.0;
scaley = 1.0;
if (float_tiles->width)
scalex = 1.0 / float_tiles->width;
if (float_tiles->height)
scaley = 1.0 / float_tiles->height;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
gimp_matrix_scale (matrix, scalex, scaley);
gimp_matrix_mult (m, matrix);
/* Perspective the buffer */
new_tiles = perspective_tool_perspective (gimage, drawable, NULL,
float_tiles, interpolation,
matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub rect_select {
$blurb = 'Create a rectangular selection over the specified image;';
$help = <<'HELP';
This tool creates a rectangular selection over the specified image. The
rectangular region can be either added to, subtracted from, or replace the
contents of the previous selection mask. If the feather option is enabled, the
resulting selection is blurred before combining. The blur is a gaussian blur
with the specified feather radius.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of rectangle' },
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of rectangle' },
{ name => 'width', type => '0 < float',
desc => 'The width of the rectangle: %%desc%%' }
{ name => 'height', type => '0 < float',
desc => 'The height of the rectangle: %%desc%%' }
&operation_arg,
&feather_select_args,
);
%invoke = (
headers => [ qw("rect_select.h") ],
code => <<'CODE'
rect_select (gimage, (int) x, (int) y, (int) width, (int) height,
operation, feather, feather_radius);
CODE
);
}
sub rotate_invoker {
$blurb = <<'BLURB';
Rotate the specified drawable about its center through the specified angle.
BLURB
$help = <<'HELP';
This tool rotates the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then rotated by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting rotated drawable. The return value is the ID of the rotated drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and rotated drawable.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
{ name => 'angle', type => 'float',
desc => 'The angle of rotation (radians)' }
);
@outargs = ( &drawable_arg('rotated') );
%invoke = (
headers => [ qw("rotate_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'Layer *layer', 'int new_layer', 'double cx, cy',
'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
cx = float_tiles->x + float_tiles->width / 2.0;
cy = float_tiles->y + float_tiles->height / 2.0;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
gimp_matrix_rotate (matrix, angle);
gimp_matrix_translate (matrix, +cx, +cy);
/* Rotate the buffer */
new_tiles = rotate_tool_rotate (gimage, drawable, NULL, angle,
float_tiles, interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* Push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub scale {
$blurb = 'Scale the specified drawable.';
$help = <<'HELP';
This tool scales the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then scaled by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting scaled drawable. The return value is the ID of the scaled drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and scaled drawable.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
);
my $pos = 1;
foreach $where (qw(upper-left lower-right)) {
foreach (qw(x y)) {
push @inargs,
{ name => "$_$pos", type => 'float',
desc => "The new $_ coordinate of $where corner of newly
scaled region",
alias => "trans_info[@{[ uc $_ ]}$pos]}", no_declare => 1 }
}
$pos++;
}
@outargs = ( &drawable_out_arg('scaled') );
%invoke = (
headers => [ qw("scale_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'int new_layer', 'double scalex, scaley',
'double trans_info[4]', 'GimpMatrix matrix'],
code => <<'CODE'
{
if (trans_info[X1] < trans_info[X2] &&
trans_info[Y1] < trans_info[X2])
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
scalex = scaley = 1.0;
if (float_tiles->width)
scalex = (trans_info[X2] - trans_info[X1]) / (double) float_tiles->width
;
if (float_tiles->height)
scaley = (trans_info[Y2] - trans_info[Y1]) / (double) float_tiles->heigh
t;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, float_tiles->x, float_tiles->y);
gimp_matrix_scale (matrix, scalex, scaley);
gimp_matrix_translate (matrix, trans_info[X1], trans_info[Y1]);
/* Scale the buffer */
new_tiles = scale_tool_scale (gimage, drawable, NULL, trans_info,
float_tiles, interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* push the undo group end */
undo_push_group_end (gimage);
}
else
success = FALSE;
}
CODE
);
}
sub shear {
$blurb = <<'BLURB';
Shear the specified drawable about its center by the specified magnitude.
BLURB
$help = <<'HELP';
This tool shears the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then sheard by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting sheared drawable. The return value is the ID of the sheard drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and sheard drawable. The shear
type parameter indicates whether the shear will be applied horizontally or
vertically. The magnitude can be either positive or negative and indicates the
extent (in pixels) to shear by.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
{ name => 'shear_type', type => 'enum ShearType',
desc => 'Type of shear: %%desc%%' },
{ name => 'magnitude', type => 'float',
desc => 'The magnitude of the shear' }
);
@outargs = ( &drawable_arg('sheared') );
%invoke = (
headers => [ qw("perspective_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'Layer *layer', 'int new_layer', 'double cx, cy',
'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
cx = float_tiles->x + float_tiles->width / 2.0;
cy = float_tiles->y + float_tiles->height / 2.0;
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
/* Shear matrix */
if (shear_type == HORZ)
gimp_matrix_xshear (matrix, shear_magnitude / float_tiles->height);
else if (shear_type == VERT)
gimp_matrix_yshear (matrix, shear_magnitude / float_tiles->width);
gimp_matrix_translate (matrix, +cx, +cy);
/* Shear the buffer */
new_tiles = shear_tool_shear (gimage, drawable, NULL, float_tiles,
interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* Push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub text {
$blurb = <<'BLURB';
Add text at the specified location as a floating selection or a new layer.
BLURB
$help = <<'HELP';
This tool requires font information in the form of nine parameters: size,
foundry, family, weight, slant, set_width, spacing, registry, encoding. The
font size can either be specified in units of pixels or points, and the
appropriate metric is specified using the size_type argument. The x and y
parameters together control the placement of the new text by specifying the
upper left corner of the text bounding box. If the antialias parameter is
non-zero, the generated text will blend more smoothly with underlying layers.
This option requires more time and memory to compute than non-antialiased text;
the resulting floating selection or layer, however, will require the same
amount of memory with or without antialiasing. If the specified drawable
parameter is valid, the text will be created as a floating selection attached
to the drawable. If the drawable parameter is not valid (-1), the text will
appear as a new layer. Finally, a border can be specified around the final
rendered text. The border is measured in pixels.
HELP
&std_pdb_misc;
$author = 'Martin Edlman';
$date = '1998';
@inargs = (
&drawable_arg,
{ name => 'x', type => 'float',
desc => 'The x coordinate for the left of the text bounding box' },
{ name => 'y', type => 'float',
desc => 'The y coordinate for the top of the text bounding box' },
{ name => 'text', type => 'string',
desc => 'The text to generate',
{ name => 'border', type => '-1 <= int32',
desc => 'The size of the border: %%desc%%' }
&antialias_arg,
{ name => 'size', type => '0 < float',
desc => 'The size of text in either pixels or points' },
{ name => 'size_type', type => 'enum SizeType',
desc => 'The units of specified size: %%desc%%' }
);
foreach (qw(foundry family weight slant set-width spacing registry
encoding)) {
my $var = $_;
$var =~ s/-/_/g;
push @inargs, { name => $var, type => 'string',
desc => qq/The font $_, "*" for any/ }
}
@outargs = (
{ name => 'text_layer', type => 'layer',
desc => 'The new text layer' }
);
%invoke = (
headers => [ qw("text_tool.h") ],
vars => ['GimpImage *gimage', 'gchar *fontname[2048]'],
code => <<'CODE'
{
if (antialias)
size *= SUPERSAMPLE;
success = text_get_xlfd (size, size_type, foundry, family, weight,
slant, set_width, spacing, registry, encoding,
fontname);
if (success)
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
text_layer = text_render (gimage, drawable, x, y, fontname, text,
border, antialias);
success = text_layer != NULL;
}
}
CODE
);
}

View File

@ -67,7 +67,7 @@ HELP
@outargs = (
{ name => "${type}_type", type => 'enum PDBArgType',
desc => "The type of $long_type \$desc",
desc => "The type of $long_type %%desc%%",
alias => "${type}->arg_type" },
{ name => "${type}_name", type => 'string',
desc => "The name of the $long_type",
@ -205,7 +205,7 @@ HELP
{ name => 'date', type => 'string',
desc => 'Copyright date' },
{ name => 'proc_type', type => 'enum PDBProcType',
desc => 'The procedure type: $desc' },
desc => 'The procedure type: %%desc%%' },
{ name => 'num_args', type => 'int32',
desc => 'The number of input arguments' },
{ name => 'num_values', type => 'int32',

View File

@ -25,19 +25,37 @@ sub drawable_arg () {{
name => 'drawable',
type => 'drawable',
desc => 'The affected drawable',
get => &std_image_arg
}}
sub drawable_out_arg {
my $type = shift;
my $arg = &drawable_arg;
$arg->{desc} = "The $type drawable";
$arg;
}
sub sample_merged_arg () {{
name => 'sample_merged',
type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub operation_arg () {{
name => 'operation',
type => 'enum Selection',
desc => 'The selection operation: %%desc%%'
}}
sub threshold_arg () {{
name => 'threshold',
type => '0 <= int32 <= 255',
desc => 'Threshold in intensity levels %%desc%%'
}}
sub antialias_arg () {{
name => 'antialias',
type => 'boolean',
desc => 'Antialiasing $desc'
desc => 'Antialiasing (%%desc%%)'
}}
sub feather_select_args () {(
@ -74,10 +92,9 @@ HELP;
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure of the airbrush strokes $desc' },
desc => 'The pressure of the airbrush strokes (%%desc%%)' },
&stroke_arg
);
delete $inargs[0]->{get};
%invoke = (
headers => [ qw("airbrush.h") ],
@ -102,19 +119,19 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'blend_mode', type => 'enum BlendMode',
desc => 'The type of blend: $desc' },
desc => 'The type of blend: %%desc%%' },
{ name => 'gradient_type', type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
desc => 'The paint application mode: %%desc%%' },
{ name => 'opacity', type => '0 <= float <= 100',
desc => 'The opacity of the final blend $desc' },
desc => 'The opacity of the final blend %%desc%%' },
{ name => 'offset', type => '0 <= float',
desc => 'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent
$desc' },
%%desc%%' },
{ name => 'repeat', type => 'enum RepeatMode',
desc => 'Repeat mode: $desc' },
desc => 'Repeat mode: %%desc%%' },
{ name => 'supersample', type => 'boolean',
desc => 'Do adaptive supersampling $desc' },
desc => 'Do adaptive supersampling (%%desc%%)' },
{ name => 'max_depth', type => '1 <= int32 <= 9',
desc => 'Maximum recursion levels for supersampling',
cond => 'supersample' },
@ -133,9 +150,13 @@ HELP
%invoke = (
headers => [ qw("blend.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
}
CODE
);
}
@ -169,15 +190,15 @@ HELP;
%inargs = (
&drawable_arg,
{ name => 'fill_mode', type => 'enum FillMode',
desc => 'The type of fill: $desc' },
desc => 'The type of fill: %%desc%%' },
{ name => paint_mode, type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
desc => 'The paint application mode: %%desc%%' },
{ name => opacity, type => '0 <= float <= 100',
desc => 'The opacity of the final bucket fill $desc' },
desc => 'The opacity of the final bucket fill %%desc%%' },
{ name => threshold, type => '0 <= float <= 255',
desc => "The threshold determines how extensive the seed fill will
be. It's value is specified in terms of intensity levels
\$desc. $validity" },
%%desc%%. $validity" },
&sample_merged_arg,
{ name => x, type => 'float',
desc => eval qq/{\$a = 'x'; "$coord";}/ },
@ -187,9 +208,13 @@ HELP;
%invoke = (
headers => [ qw ("bucket_fill.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
sample_merged, x, y);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity,
threshold, sample_merged, x, y);
}
CODE
);
}
@ -220,10 +245,8 @@ HELP
&drawable_arg,
{ name => 'color', type => 'color',
desc => 'The color to select' },
{ name => 'threshold', type => '0 <= int32 <= 255',
desc => 'Threshold in intensity levels $desc' },
{ name => 'operation', type => 'enum Operation',
desc => 'The selection operation: $desc' },
&threshold_arg,
&operation_arg,
&antialias_arg,
&feather_select_args,
&sample_merged_arg
@ -231,9 +254,13 @@ HELP
%invoke = (
headers => [ qw("by_color_select.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
by_color_select (gimage, drawable, color, threshold, operation,
antialias, feather, feather_radius, sample_merged);
}
CODE
);
}
@ -263,20 +290,19 @@ HELP
{ name => 'src_drawable', type => 'drawable',
desc => 'The source drawable' },
{ name => 'clone_type', type => 'enum CloneType',
desc => 'The type of clone: $desc' },
desc => 'The type of clone: %%desc%%' },
{ 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
);
delete $inargs[0]->{get};
%invoke = (
headers => [ qw("clone.h") ],
code => <<'CODE'
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
strokes);
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y,
num_strokes, strokes);
CODE
);
}
@ -314,14 +340,18 @@ HELP
@outargs = (
{ name => 'color', type => 'color',
desc => 'The return color' }
desc => 'The return color', init => 1 }
);
%invoke = (
headers => [ qw("color_picker.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
{
if (success = get_color (gimage, drawable, (int) x, (int) y, sample_merged, save_color)
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
if (success = get_color (gimage, drawable, (int) x, (int) y,
sample_merged, save_color)
{
color = g_new (guchar, 3);
color[RED_PIX] = col_value[RED_PIX];
@ -348,9 +378,9 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure: $desc' },
desc => 'The pressure: %%desc%%' },
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
desc => 'Convolve type: $desc' },
desc => 'Convolve type: %%desc%%' },
&stroke_arg
);
@ -389,8 +419,7 @@ HELP
headers => [ qw("crop.h") ],
code => <<'CODE'
{
if (new_width > gimage->width ||
new_height > gimage->height ||
if (new_width > gimage->width || new_height > gimage->height ||
offx > (gimage->width - new_width) ||
offy > (gimage->height - new_height)
success = FALSE;
@ -422,11 +451,10 @@ HELP
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of ellipse bounding box' },
{ name => 'width', type => '0 < float',
desc => 'The width of the ellipse: $desc' },
desc => 'The width of the ellipse: %%desc%%' },
{ name => 'height', type => '0 < float',
desc => 'The height of the ellipse: $desc' },
{ name => 'operation', 'enum Selection',
desc => 'The selection operation: $desc' },
desc => 'The height of the ellipse: %%desc%%' },
&operation_arg,
&antialias_arg,
&feather_args
);
@ -434,8 +462,8 @@ HELP
%invoke = (
headers => [ qw("ellipse_select.h") ],
code => <<'CODE'
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
feather, feather_radius);
ellipse_select (gimage, (int) x, (int) y, (int) width, (int) height,
operation, antialias, feather, feather_radius);
CODE
);
}
@ -457,9 +485,9 @@ HELP
&drawable_arg,
&stroke_arg,
{ name => 'hardness', type => 'enum EraserHardness',
desc => '$desc' }
desc => '%%desc%%' }
{ name => 'method', type => 'enum EraserMethod',
desc => '$desc' }
desc => '%%desc%%' }
);
%invoke = (
@ -492,20 +520,18 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'flip_type', type => 'enum FlipType',
desc => 'Type of flip: $desc' }
desc => 'Type of flip: %%desc%%' }
);
@outargs = ( &drawable_arg );
$outargs[0]->{alias} = layer;
$outargs[0]->{desc} = 'The flipped drawable';
$outargs[0]->{no_declare} = 1;
delete $outargs[0]->{get};
@outargs = ( &drawable_out_arg('flipped') );
%invoke = (
headers => [ qw("flip_tool.h" "tranform_core.h") ],
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
@ -541,4 +567,626 @@ CODE
);
}
sub free_select {
$blurb = 'Create a polygonal selection over the specified image.';
$help = <<'HELP';
This tool creates a polygonal selection over the specified image. The polygonal
region can be either added to, subtracted from, or replace the contents of the
previous selection mask. The polygon is specified through an array of floating
point numbers and its length. The length of array must be 2n, where n is the
number of points. Each point is defined by 2 floating point values which
correspond to the x and y coordinates. If the final point does not connect to
the starting point, a connecting segment is automatically added. If the feather
option is enabled, the resulting selection is blurred before combining. The
blur is a gaussian blur with the specified feather radius.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'segs', type => 'floatarray',
desc => 'Array of points: { p1.x, p1.y, p2.x, p2.y, ...,
pn.x, pn.y}',
array => { desc => 'Number of points (count 1 coordinate as two
points)' } },
&operation_arg,
&antialias_arg,
&feather_select_args
);
%invoke = (
headers => qw("free_select.h"),
code => <<'CODE'
free_select (gimage, num_segs, segs, operation, antialias, feather,
feather_radius);
CODE
);
}
sub fuzzy_select {
$blurb = <<'BLURB';
Create a fuzzy selection starting at the specified coordinates on the specified
drawable.
BLURB
$help = <<'HELP';
This tool creates a fuzzy selection over the specified image. A fuzzy selection
is determined by a seed fill under the constraints of the specified threshold.
Essentially, the color at the specified coordinates (in the drawable) is
measured and the selection expands outwards from that point to any adjacent
pixels which are not significantly different (as determined by the threshold
value). This process continues until no more expansion is possible. The
antialiasing parameter allows the final selection mask to contain intermediate
values based on close misses to the threshold bar at pixels along the seed fill
boundary. Feathering can be enabled optionally and is controlled with the
"feather_radius" paramter. If the sample_merged parameter is non-zero, the data
of the composite image will be used instead of that for the specified drawable.
This is equivalent to sampling for colors after merging all visible layers. In
the case of a merged sampling, the supplied drawable is ignored. If the sample
is merged, the specified coordinates are relative to the image origin;
otherwise, they are relative to the drawable's origin.'
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of initial seed fill point: (image
coordinates)' },
{ name => 'y', type => 'float',
desc => 'y coordinate of initial seed fill point: (image
coordinates)' },
&threshold_arg,
&operation_arg,
&antialias_arg,
&feather_select_args,
&sample_merged_arg
);
%invoke = (
headers => qw("fuzzy_select.h"),
vars => ['GimpImage *gimage', 'Channel *new, *old_fuzzy_mask'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
new = find_contiguous_region (gimage, drawable, antialias, threshold,
x, y, sample_merged);
old_fuzzy_mask = fuzzy_mask;
fuzzy_mask = new;
drawable = sample_merged ? NULL : drawable;
fuzzy_select (gimage, drawbale, operation, feather, feather_radius);
fuzzy_mask = old_fuzzy_mask;
}
CODE
);
}
sub paintbrush {
$blurb = 'Paint in the current brush with optional fade out parameter.';
$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.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'fade_out', type => '0 < float',
desc => 'Fade out parameter: %%desc%%' },
&stroke_arg,
{ name => 'method', type => 'enum PaintMethod',
desc => '%%desc%%' }
);
%invoke = (
headers => [ qw("paintbrush.h") ],
code => <<'CODE'
paintbrush_non_gui (drawable, num_strokes, strokes, fade_out, method);
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 = (
&drawable_arg,
&stroke_arg
);
%invoke = (
headers => qw("fuzzy_select.h"),
code => 'pencil_non_gui (drawable, num_strokes, strokes);'
);
}
sub perspective {
$blurb = <<'BLURB';
Perform a possibly non-affine transformation on the specified drawable.
BLURB
$help = <<'HELP';
This tool performs a possibly non-affine transformation on the specified
drawable by allowing the corners of the original bounding box to be arbitrarily
remapped to any values. The specified drawable is remapped if no selection
exists. However, if a selection exists, the portion of the drawable which lies
under the selection is cut from the drawable and made into a floating selection
which is then remapped as specified. The interpolation parameter can be set to
TRUE to indicate that either linear or cubic interpolation should be used to
smooth the resulting remapped drawable. The return value is the ID of the
remapped drawable. If there was no selection, this will be equal to the
drawable ID supplied as input. Otherwise, this will be the newly created and
remapped drawable. The 4 coordinates specify the new locations of each corner
of the original bounding box. By specifying these values, any affine
transformation (rotation, scaling, translation) can be affected. Additionally,
these values can be specified such that the resulting transformed drawable will
appear to have been projected via a perspective transform.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
);
my $pos = 0;
foreach $where (qw(upper-left upper-right lower-left lower-right)) {
foreach (qw(x y)) {
push @inargs,
{ name => "$_$pos", type => 'float',
desc => "The new $_ coordinate of $where corner of original
bounding box",
alias => "trans_info[@{[ uc $_ ]}$pos]}", no_declare => 1 }
}
$pos++;
}
@outargs = ( &drawable_out_arg('newly mapped') );
%invoke = (
headers => [ qw("perspective_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'int new_layer', 'double cx, cy', 'double scalex, scaley',
'double trans_info[8]', 'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
/* Determine the perspective transform that maps from
* the unit cube to the trans_info coordinates
*/
perspective_find_transform (trans_info, m);
cx = float_tiles->x;
cy = float_tiles->y;
scalex = 1.0;
scaley = 1.0;
if (float_tiles->width)
scalex = 1.0 / float_tiles->width;
if (float_tiles->height)
scaley = 1.0 / float_tiles->height;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
gimp_matrix_scale (matrix, scalex, scaley);
gimp_matrix_mult (m, matrix);
/* Perspective the buffer */
new_tiles = perspective_tool_perspective (gimage, drawable, NULL,
float_tiles, interpolation,
matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub rect_select {
$blurb = 'Create a rectangular selection over the specified image;';
$help = <<'HELP';
This tool creates a rectangular selection over the specified image. The
rectangular region can be either added to, subtracted from, or replace the
contents of the previous selection mask. If the feather option is enabled, the
resulting selection is blurred before combining. The blur is a gaussian blur
with the specified feather radius.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of rectangle' },
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of rectangle' },
{ name => 'width', type => '0 < float',
desc => 'The width of the rectangle: %%desc%%' }
{ name => 'height', type => '0 < float',
desc => 'The height of the rectangle: %%desc%%' }
&operation_arg,
&feather_select_args,
);
%invoke = (
headers => [ qw("rect_select.h") ],
code => <<'CODE'
rect_select (gimage, (int) x, (int) y, (int) width, (int) height,
operation, feather, feather_radius);
CODE
);
}
sub rotate_invoker {
$blurb = <<'BLURB';
Rotate the specified drawable about its center through the specified angle.
BLURB
$help = <<'HELP';
This tool rotates the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then rotated by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting rotated drawable. The return value is the ID of the rotated drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and rotated drawable.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
{ name => 'angle', type => 'float',
desc => 'The angle of rotation (radians)' }
);
@outargs = ( &drawable_arg('rotated') );
%invoke = (
headers => [ qw("rotate_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'Layer *layer', 'int new_layer', 'double cx, cy',
'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
cx = float_tiles->x + float_tiles->width / 2.0;
cy = float_tiles->y + float_tiles->height / 2.0;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
gimp_matrix_rotate (matrix, angle);
gimp_matrix_translate (matrix, +cx, +cy);
/* Rotate the buffer */
new_tiles = rotate_tool_rotate (gimage, drawable, NULL, angle,
float_tiles, interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* Push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub scale {
$blurb = 'Scale the specified drawable.';
$help = <<'HELP';
This tool scales the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then scaled by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting scaled drawable. The return value is the ID of the scaled drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and scaled drawable.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
);
my $pos = 1;
foreach $where (qw(upper-left lower-right)) {
foreach (qw(x y)) {
push @inargs,
{ name => "$_$pos", type => 'float',
desc => "The new $_ coordinate of $where corner of newly
scaled region",
alias => "trans_info[@{[ uc $_ ]}$pos]}", no_declare => 1 }
}
$pos++;
}
@outargs = ( &drawable_out_arg('scaled') );
%invoke = (
headers => [ qw("scale_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'int new_layer', 'double scalex, scaley',
'double trans_info[4]', 'GimpMatrix matrix'],
code => <<'CODE'
{
if (trans_info[X1] < trans_info[X2] &&
trans_info[Y1] < trans_info[X2])
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
scalex = scaley = 1.0;
if (float_tiles->width)
scalex = (trans_info[X2] - trans_info[X1]) / (double) float_tiles->width
;
if (float_tiles->height)
scaley = (trans_info[Y2] - trans_info[Y1]) / (double) float_tiles->heigh
t;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, float_tiles->x, float_tiles->y);
gimp_matrix_scale (matrix, scalex, scaley);
gimp_matrix_translate (matrix, trans_info[X1], trans_info[Y1]);
/* Scale the buffer */
new_tiles = scale_tool_scale (gimage, drawable, NULL, trans_info,
float_tiles, interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* push the undo group end */
undo_push_group_end (gimage);
}
else
success = FALSE;
}
CODE
);
}
sub shear {
$blurb = <<'BLURB';
Shear the specified drawable about its center by the specified magnitude.
BLURB
$help = <<'HELP';
This tool shears the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then sheard by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting sheared drawable. The return value is the ID of the sheard drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and sheard drawable. The shear
type parameter indicates whether the shear will be applied horizontally or
vertically. The magnitude can be either positive or negative and indicates the
extent (in pixels) to shear by.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
{ name => 'shear_type', type => 'enum ShearType',
desc => 'Type of shear: %%desc%%' },
{ name => 'magnitude', type => 'float',
desc => 'The magnitude of the shear' }
);
@outargs = ( &drawable_arg('sheared') );
%invoke = (
headers => [ qw("perspective_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'Layer *layer', 'int new_layer', 'double cx, cy',
'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
cx = float_tiles->x + float_tiles->width / 2.0;
cy = float_tiles->y + float_tiles->height / 2.0;
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
/* Shear matrix */
if (shear_type == HORZ)
gimp_matrix_xshear (matrix, shear_magnitude / float_tiles->height);
else if (shear_type == VERT)
gimp_matrix_yshear (matrix, shear_magnitude / float_tiles->width);
gimp_matrix_translate (matrix, +cx, +cy);
/* Shear the buffer */
new_tiles = shear_tool_shear (gimage, drawable, NULL, float_tiles,
interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* Push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub text {
$blurb = <<'BLURB';
Add text at the specified location as a floating selection or a new layer.
BLURB
$help = <<'HELP';
This tool requires font information in the form of nine parameters: size,
foundry, family, weight, slant, set_width, spacing, registry, encoding. The
font size can either be specified in units of pixels or points, and the
appropriate metric is specified using the size_type argument. The x and y
parameters together control the placement of the new text by specifying the
upper left corner of the text bounding box. If the antialias parameter is
non-zero, the generated text will blend more smoothly with underlying layers.
This option requires more time and memory to compute than non-antialiased text;
the resulting floating selection or layer, however, will require the same
amount of memory with or without antialiasing. If the specified drawable
parameter is valid, the text will be created as a floating selection attached
to the drawable. If the drawable parameter is not valid (-1), the text will
appear as a new layer. Finally, a border can be specified around the final
rendered text. The border is measured in pixels.
HELP
&std_pdb_misc;
$author = 'Martin Edlman';
$date = '1998';
@inargs = (
&drawable_arg,
{ name => 'x', type => 'float',
desc => 'The x coordinate for the left of the text bounding box' },
{ name => 'y', type => 'float',
desc => 'The y coordinate for the top of the text bounding box' },
{ name => 'text', type => 'string',
desc => 'The text to generate',
{ name => 'border', type => '-1 <= int32',
desc => 'The size of the border: %%desc%%' }
&antialias_arg,
{ name => 'size', type => '0 < float',
desc => 'The size of text in either pixels or points' },
{ name => 'size_type', type => 'enum SizeType',
desc => 'The units of specified size: %%desc%%' }
);
foreach (qw(foundry family weight slant set-width spacing registry
encoding)) {
my $var = $_;
$var =~ s/-/_/g;
push @inargs, { name => $var, type => 'string',
desc => qq/The font $_, "*" for any/ }
}
@outargs = (
{ name => 'text_layer', type => 'layer',
desc => 'The new text layer' }
);
%invoke = (
headers => [ qw("text_tool.h") ],
vars => ['GimpImage *gimage', 'gchar *fontname[2048]'],
code => <<'CODE'
{
if (antialias)
size *= SUPERSAMPLE;
success = text_get_xlfd (size, size_type, foundry, family, weight,
slant, set_width, spacing, registry, encoding,
fontname);
if (success)
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
text_layer = text_render (gimage, drawable, x, y, fontname, text,
border, antialias);
success = text_layer != NULL;
}
}
CODE
);
}

View File

@ -25,19 +25,37 @@ sub drawable_arg () {{
name => 'drawable',
type => 'drawable',
desc => 'The affected drawable',
get => &std_image_arg
}}
sub drawable_out_arg {
my $type = shift;
my $arg = &drawable_arg;
$arg->{desc} = "The $type drawable";
$arg;
}
sub sample_merged_arg () {{
name => 'sample_merged',
type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub operation_arg () {{
name => 'operation',
type => 'enum Selection',
desc => 'The selection operation: %%desc%%'
}}
sub threshold_arg () {{
name => 'threshold',
type => '0 <= int32 <= 255',
desc => 'Threshold in intensity levels %%desc%%'
}}
sub antialias_arg () {{
name => 'antialias',
type => 'boolean',
desc => 'Antialiasing $desc'
desc => 'Antialiasing (%%desc%%)'
}}
sub feather_select_args () {(
@ -74,10 +92,9 @@ HELP;
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure of the airbrush strokes $desc' },
desc => 'The pressure of the airbrush strokes (%%desc%%)' },
&stroke_arg
);
delete $inargs[0]->{get};
%invoke = (
headers => [ qw("airbrush.h") ],
@ -102,19 +119,19 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'blend_mode', type => 'enum BlendMode',
desc => 'The type of blend: $desc' },
desc => 'The type of blend: %%desc%%' },
{ name => 'gradient_type', type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
desc => 'The paint application mode: %%desc%%' },
{ name => 'opacity', type => '0 <= float <= 100',
desc => 'The opacity of the final blend $desc' },
desc => 'The opacity of the final blend %%desc%%' },
{ name => 'offset', type => '0 <= float',
desc => 'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent
$desc' },
%%desc%%' },
{ name => 'repeat', type => 'enum RepeatMode',
desc => 'Repeat mode: $desc' },
desc => 'Repeat mode: %%desc%%' },
{ name => 'supersample', type => 'boolean',
desc => 'Do adaptive supersampling $desc' },
desc => 'Do adaptive supersampling (%%desc%%)' },
{ name => 'max_depth', type => '1 <= int32 <= 9',
desc => 'Maximum recursion levels for supersampling',
cond => 'supersample' },
@ -133,9 +150,13 @@ HELP
%invoke = (
headers => [ qw("blend.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
}
CODE
);
}
@ -169,15 +190,15 @@ HELP;
%inargs = (
&drawable_arg,
{ name => 'fill_mode', type => 'enum FillMode',
desc => 'The type of fill: $desc' },
desc => 'The type of fill: %%desc%%' },
{ name => paint_mode, type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
desc => 'The paint application mode: %%desc%%' },
{ name => opacity, type => '0 <= float <= 100',
desc => 'The opacity of the final bucket fill $desc' },
desc => 'The opacity of the final bucket fill %%desc%%' },
{ name => threshold, type => '0 <= float <= 255',
desc => "The threshold determines how extensive the seed fill will
be. It's value is specified in terms of intensity levels
\$desc. $validity" },
%%desc%%. $validity" },
&sample_merged_arg,
{ name => x, type => 'float',
desc => eval qq/{\$a = 'x'; "$coord";}/ },
@ -187,9 +208,13 @@ HELP;
%invoke = (
headers => [ qw ("bucket_fill.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
sample_merged, x, y);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity,
threshold, sample_merged, x, y);
}
CODE
);
}
@ -220,10 +245,8 @@ HELP
&drawable_arg,
{ name => 'color', type => 'color',
desc => 'The color to select' },
{ name => 'threshold', type => '0 <= int32 <= 255',
desc => 'Threshold in intensity levels $desc' },
{ name => 'operation', type => 'enum Operation',
desc => 'The selection operation: $desc' },
&threshold_arg,
&operation_arg,
&antialias_arg,
&feather_select_args,
&sample_merged_arg
@ -231,9 +254,13 @@ HELP
%invoke = (
headers => [ qw("by_color_select.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
by_color_select (gimage, drawable, color, threshold, operation,
antialias, feather, feather_radius, sample_merged);
}
CODE
);
}
@ -263,20 +290,19 @@ HELP
{ name => 'src_drawable', type => 'drawable',
desc => 'The source drawable' },
{ name => 'clone_type', type => 'enum CloneType',
desc => 'The type of clone: $desc' },
desc => 'The type of clone: %%desc%%' },
{ 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
);
delete $inargs[0]->{get};
%invoke = (
headers => [ qw("clone.h") ],
code => <<'CODE'
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
strokes);
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y,
num_strokes, strokes);
CODE
);
}
@ -314,14 +340,18 @@ HELP
@outargs = (
{ name => 'color', type => 'color',
desc => 'The return color' }
desc => 'The return color', init => 1 }
);
%invoke = (
headers => [ qw("color_picker.h") ],
vars => ['GimpImage *gimage'],
code => <<'CODE'
{
if (success = get_color (gimage, drawable, (int) x, (int) y, sample_merged, save_color)
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
if (success = get_color (gimage, drawable, (int) x, (int) y,
sample_merged, save_color)
{
color = g_new (guchar, 3);
color[RED_PIX] = col_value[RED_PIX];
@ -348,9 +378,9 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure: $desc' },
desc => 'The pressure: %%desc%%' },
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
desc => 'Convolve type: $desc' },
desc => 'Convolve type: %%desc%%' },
&stroke_arg
);
@ -389,8 +419,7 @@ HELP
headers => [ qw("crop.h") ],
code => <<'CODE'
{
if (new_width > gimage->width ||
new_height > gimage->height ||
if (new_width > gimage->width || new_height > gimage->height ||
offx > (gimage->width - new_width) ||
offy > (gimage->height - new_height)
success = FALSE;
@ -422,11 +451,10 @@ HELP
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of ellipse bounding box' },
{ name => 'width', type => '0 < float',
desc => 'The width of the ellipse: $desc' },
desc => 'The width of the ellipse: %%desc%%' },
{ name => 'height', type => '0 < float',
desc => 'The height of the ellipse: $desc' },
{ name => 'operation', 'enum Selection',
desc => 'The selection operation: $desc' },
desc => 'The height of the ellipse: %%desc%%' },
&operation_arg,
&antialias_arg,
&feather_args
);
@ -434,8 +462,8 @@ HELP
%invoke = (
headers => [ qw("ellipse_select.h") ],
code => <<'CODE'
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
feather, feather_radius);
ellipse_select (gimage, (int) x, (int) y, (int) width, (int) height,
operation, antialias, feather, feather_radius);
CODE
);
}
@ -457,9 +485,9 @@ HELP
&drawable_arg,
&stroke_arg,
{ name => 'hardness', type => 'enum EraserHardness',
desc => '$desc' }
desc => '%%desc%%' }
{ name => 'method', type => 'enum EraserMethod',
desc => '$desc' }
desc => '%%desc%%' }
);
%invoke = (
@ -492,20 +520,18 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'flip_type', type => 'enum FlipType',
desc => 'Type of flip: $desc' }
desc => 'Type of flip: %%desc%%' }
);
@outargs = ( &drawable_arg );
$outargs[0]->{alias} = layer;
$outargs[0]->{desc} = 'The flipped drawable';
$outargs[0]->{no_declare} = 1;
delete $outargs[0]->{get};
@outargs = ( &drawable_out_arg('flipped') );
%invoke = (
headers => [ qw("flip_tool.h" "tranform_core.h") ],
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
@ -541,4 +567,626 @@ CODE
);
}
sub free_select {
$blurb = 'Create a polygonal selection over the specified image.';
$help = <<'HELP';
This tool creates a polygonal selection over the specified image. The polygonal
region can be either added to, subtracted from, or replace the contents of the
previous selection mask. The polygon is specified through an array of floating
point numbers and its length. The length of array must be 2n, where n is the
number of points. Each point is defined by 2 floating point values which
correspond to the x and y coordinates. If the final point does not connect to
the starting point, a connecting segment is automatically added. If the feather
option is enabled, the resulting selection is blurred before combining. The
blur is a gaussian blur with the specified feather radius.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'segs', type => 'floatarray',
desc => 'Array of points: { p1.x, p1.y, p2.x, p2.y, ...,
pn.x, pn.y}',
array => { desc => 'Number of points (count 1 coordinate as two
points)' } },
&operation_arg,
&antialias_arg,
&feather_select_args
);
%invoke = (
headers => qw("free_select.h"),
code => <<'CODE'
free_select (gimage, num_segs, segs, operation, antialias, feather,
feather_radius);
CODE
);
}
sub fuzzy_select {
$blurb = <<'BLURB';
Create a fuzzy selection starting at the specified coordinates on the specified
drawable.
BLURB
$help = <<'HELP';
This tool creates a fuzzy selection over the specified image. A fuzzy selection
is determined by a seed fill under the constraints of the specified threshold.
Essentially, the color at the specified coordinates (in the drawable) is
measured and the selection expands outwards from that point to any adjacent
pixels which are not significantly different (as determined by the threshold
value). This process continues until no more expansion is possible. The
antialiasing parameter allows the final selection mask to contain intermediate
values based on close misses to the threshold bar at pixels along the seed fill
boundary. Feathering can be enabled optionally and is controlled with the
"feather_radius" paramter. If the sample_merged parameter is non-zero, the data
of the composite image will be used instead of that for the specified drawable.
This is equivalent to sampling for colors after merging all visible layers. In
the case of a merged sampling, the supplied drawable is ignored. If the sample
is merged, the specified coordinates are relative to the image origin;
otherwise, they are relative to the drawable's origin.'
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of initial seed fill point: (image
coordinates)' },
{ name => 'y', type => 'float',
desc => 'y coordinate of initial seed fill point: (image
coordinates)' },
&threshold_arg,
&operation_arg,
&antialias_arg,
&feather_select_args,
&sample_merged_arg
);
%invoke = (
headers => qw("fuzzy_select.h"),
vars => ['GimpImage *gimage', 'Channel *new, *old_fuzzy_mask'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
new = find_contiguous_region (gimage, drawable, antialias, threshold,
x, y, sample_merged);
old_fuzzy_mask = fuzzy_mask;
fuzzy_mask = new;
drawable = sample_merged ? NULL : drawable;
fuzzy_select (gimage, drawbale, operation, feather, feather_radius);
fuzzy_mask = old_fuzzy_mask;
}
CODE
);
}
sub paintbrush {
$blurb = 'Paint in the current brush with optional fade out parameter.';
$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.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'fade_out', type => '0 < float',
desc => 'Fade out parameter: %%desc%%' },
&stroke_arg,
{ name => 'method', type => 'enum PaintMethod',
desc => '%%desc%%' }
);
%invoke = (
headers => [ qw("paintbrush.h") ],
code => <<'CODE'
paintbrush_non_gui (drawable, num_strokes, strokes, fade_out, method);
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 = (
&drawable_arg,
&stroke_arg
);
%invoke = (
headers => qw("fuzzy_select.h"),
code => 'pencil_non_gui (drawable, num_strokes, strokes);'
);
}
sub perspective {
$blurb = <<'BLURB';
Perform a possibly non-affine transformation on the specified drawable.
BLURB
$help = <<'HELP';
This tool performs a possibly non-affine transformation on the specified
drawable by allowing the corners of the original bounding box to be arbitrarily
remapped to any values. The specified drawable is remapped if no selection
exists. However, if a selection exists, the portion of the drawable which lies
under the selection is cut from the drawable and made into a floating selection
which is then remapped as specified. The interpolation parameter can be set to
TRUE to indicate that either linear or cubic interpolation should be used to
smooth the resulting remapped drawable. The return value is the ID of the
remapped drawable. If there was no selection, this will be equal to the
drawable ID supplied as input. Otherwise, this will be the newly created and
remapped drawable. The 4 coordinates specify the new locations of each corner
of the original bounding box. By specifying these values, any affine
transformation (rotation, scaling, translation) can be affected. Additionally,
these values can be specified such that the resulting transformed drawable will
appear to have been projected via a perspective transform.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
);
my $pos = 0;
foreach $where (qw(upper-left upper-right lower-left lower-right)) {
foreach (qw(x y)) {
push @inargs,
{ name => "$_$pos", type => 'float',
desc => "The new $_ coordinate of $where corner of original
bounding box",
alias => "trans_info[@{[ uc $_ ]}$pos]}", no_declare => 1 }
}
$pos++;
}
@outargs = ( &drawable_out_arg('newly mapped') );
%invoke = (
headers => [ qw("perspective_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'int new_layer', 'double cx, cy', 'double scalex, scaley',
'double trans_info[8]', 'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
/* Determine the perspective transform that maps from
* the unit cube to the trans_info coordinates
*/
perspective_find_transform (trans_info, m);
cx = float_tiles->x;
cy = float_tiles->y;
scalex = 1.0;
scaley = 1.0;
if (float_tiles->width)
scalex = 1.0 / float_tiles->width;
if (float_tiles->height)
scaley = 1.0 / float_tiles->height;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
gimp_matrix_scale (matrix, scalex, scaley);
gimp_matrix_mult (m, matrix);
/* Perspective the buffer */
new_tiles = perspective_tool_perspective (gimage, drawable, NULL,
float_tiles, interpolation,
matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub rect_select {
$blurb = 'Create a rectangular selection over the specified image;';
$help = <<'HELP';
This tool creates a rectangular selection over the specified image. The
rectangular region can be either added to, subtracted from, or replace the
contents of the previous selection mask. If the feather option is enabled, the
resulting selection is blurred before combining. The blur is a gaussian blur
with the specified feather radius.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of rectangle' },
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of rectangle' },
{ name => 'width', type => '0 < float',
desc => 'The width of the rectangle: %%desc%%' }
{ name => 'height', type => '0 < float',
desc => 'The height of the rectangle: %%desc%%' }
&operation_arg,
&feather_select_args,
);
%invoke = (
headers => [ qw("rect_select.h") ],
code => <<'CODE'
rect_select (gimage, (int) x, (int) y, (int) width, (int) height,
operation, feather, feather_radius);
CODE
);
}
sub rotate_invoker {
$blurb = <<'BLURB';
Rotate the specified drawable about its center through the specified angle.
BLURB
$help = <<'HELP';
This tool rotates the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then rotated by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting rotated drawable. The return value is the ID of the rotated drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and rotated drawable.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
{ name => 'angle', type => 'float',
desc => 'The angle of rotation (radians)' }
);
@outargs = ( &drawable_arg('rotated') );
%invoke = (
headers => [ qw("rotate_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'Layer *layer', 'int new_layer', 'double cx, cy',
'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
cx = float_tiles->x + float_tiles->width / 2.0;
cy = float_tiles->y + float_tiles->height / 2.0;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
gimp_matrix_rotate (matrix, angle);
gimp_matrix_translate (matrix, +cx, +cy);
/* Rotate the buffer */
new_tiles = rotate_tool_rotate (gimage, drawable, NULL, angle,
float_tiles, interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* Push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub scale {
$blurb = 'Scale the specified drawable.';
$help = <<'HELP';
This tool scales the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then scaled by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting scaled drawable. The return value is the ID of the scaled drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and scaled drawable.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
);
my $pos = 1;
foreach $where (qw(upper-left lower-right)) {
foreach (qw(x y)) {
push @inargs,
{ name => "$_$pos", type => 'float',
desc => "The new $_ coordinate of $where corner of newly
scaled region",
alias => "trans_info[@{[ uc $_ ]}$pos]}", no_declare => 1 }
}
$pos++;
}
@outargs = ( &drawable_out_arg('scaled') );
%invoke = (
headers => [ qw("scale_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'int new_layer', 'double scalex, scaley',
'double trans_info[4]', 'GimpMatrix matrix'],
code => <<'CODE'
{
if (trans_info[X1] < trans_info[X2] &&
trans_info[Y1] < trans_info[X2])
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
scalex = scaley = 1.0;
if (float_tiles->width)
scalex = (trans_info[X2] - trans_info[X1]) / (double) float_tiles->width
;
if (float_tiles->height)
scaley = (trans_info[Y2] - trans_info[Y1]) / (double) float_tiles->heigh
t;
/* Assemble the transformation matrix */
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, float_tiles->x, float_tiles->y);
gimp_matrix_scale (matrix, scalex, scaley);
gimp_matrix_translate (matrix, trans_info[X1], trans_info[Y1]);
/* Scale the buffer */
new_tiles = scale_tool_scale (gimage, drawable, NULL, trans_info,
float_tiles, interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* push the undo group end */
undo_push_group_end (gimage);
}
else
success = FALSE;
}
CODE
);
}
sub shear {
$blurb = <<'BLURB';
Shear the specified drawable about its center by the specified magnitude.
BLURB
$help = <<'HELP';
This tool shears the specified drawable if no selection exists. If a selection
exists, the portion of the drawable which lies under the selection is cut from
the drawable and made into a floating selection which is then sheard by the
specified amount. The interpolation parameter can be set to TRUE to indicate
that either linear or cubic interpolation should be used to smooth the
resulting sheared drawable. The return value is the ID of the sheard drawable.
If there was no selection, this will be equal to the drawable ID supplied as
input. Otherwise, this will be the newly created and sheard drawable. The shear
type parameter indicates whether the shear will be applied horizontally or
vertically. The magnitude can be either positive or negative and indicates the
extent (in pixels) to shear by.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' }
{ name => 'shear_type', type => 'enum ShearType',
desc => 'Type of shear: %%desc%%' },
{ name => 'magnitude', type => 'float',
desc => 'The magnitude of the shear' }
);
@outargs = ( &drawable_arg('sheared') );
%invoke = (
headers => [ qw("perspective_tool.h" "tranform_core.h") ],
vars => ['GimpImage *gimage', 'TileManger *float_tiles, *new_tiles',
'Layer *layer', 'int new_layer', 'double cx, cy',
'GimpMatrix matrix'],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
/* Start a transform undo group */
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
cx = float_tiles->x + float_tiles->width / 2.0;
cy = float_tiles->y + float_tiles->height / 2.0;
gimp_matrix_identity (matrix);
gimp_matrix_translate (matrix, -cx, -cy);
/* Shear matrix */
if (shear_type == HORZ)
gimp_matrix_xshear (matrix, shear_magnitude / float_tiles->height);
else if (shear_type == VERT)
gimp_matrix_yshear (matrix, shear_magnitude / float_tiles->width);
gimp_matrix_translate (matrix, +cx, +cy);
/* Shear the buffer */
new_tiles = shear_tool_shear (gimage, drawable, NULL, float_tiles,
interpolation, matrix);
/* Free the cut/copied buffer */
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
else
success = FALSE;
/* Push the undo group end */
undo_push_group_end (gimage);
}
CODE
);
}
sub text {
$blurb = <<'BLURB';
Add text at the specified location as a floating selection or a new layer.
BLURB
$help = <<'HELP';
This tool requires font information in the form of nine parameters: size,
foundry, family, weight, slant, set_width, spacing, registry, encoding. The
font size can either be specified in units of pixels or points, and the
appropriate metric is specified using the size_type argument. The x and y
parameters together control the placement of the new text by specifying the
upper left corner of the text bounding box. If the antialias parameter is
non-zero, the generated text will blend more smoothly with underlying layers.
This option requires more time and memory to compute than non-antialiased text;
the resulting floating selection or layer, however, will require the same
amount of memory with or without antialiasing. If the specified drawable
parameter is valid, the text will be created as a floating selection attached
to the drawable. If the drawable parameter is not valid (-1), the text will
appear as a new layer. Finally, a border can be specified around the final
rendered text. The border is measured in pixels.
HELP
&std_pdb_misc;
$author = 'Martin Edlman';
$date = '1998';
@inargs = (
&drawable_arg,
{ name => 'x', type => 'float',
desc => 'The x coordinate for the left of the text bounding box' },
{ name => 'y', type => 'float',
desc => 'The y coordinate for the top of the text bounding box' },
{ name => 'text', type => 'string',
desc => 'The text to generate',
{ name => 'border', type => '-1 <= int32',
desc => 'The size of the border: %%desc%%' }
&antialias_arg,
{ name => 'size', type => '0 < float',
desc => 'The size of text in either pixels or points' },
{ name => 'size_type', type => 'enum SizeType',
desc => 'The units of specified size: %%desc%%' }
);
foreach (qw(foundry family weight slant set-width spacing registry
encoding)) {
my $var = $_;
$var =~ s/-/_/g;
push @inargs, { name => $var, type => 'string',
desc => qq/The font $_, "*" for any/ }
}
@outargs = (
{ name => 'text_layer', type => 'layer',
desc => 'The new text layer' }
);
%invoke = (
headers => [ qw("text_tool.h") ],
vars => ['GimpImage *gimage', 'gchar *fontname[2048]'],
code => <<'CODE'
{
if (antialias)
size *= SUPERSAMPLE;
success = text_get_xlfd (size, size_type, foundry, family, weight,
slant, set_width, spacing, registry, encoding,
fontname);
if (success)
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
text_layer = text_render (gimage, drawable, x, y, fontname, text,
border, antialias);
success = text_layer != NULL;
}
}
CODE
);
}

View File

@ -65,7 +65,7 @@ $evalcode = <<'CODE';
$grp{$file}->{desc} = $desc if defined $desc;
$grp{$file}->{code} = $code if defined $code;
foreach my $proc (@procs) {
foreach $proc (@procs) {
# Reset all our PDB vars so previous defs don't interfere
foreach (@procvars) { eval "undef $_" }
@ -108,6 +108,7 @@ foreach $file (@groups) {
# Some important stuff
require 'pdb.pl';
require 'enums.pl';
require 'util.pl';
# Squash whitespace into just single spaces between words