Checkpoint.

-Yosh
This commit is contained in:
Manish Singh 1999-03-10 18:56:56 +00:00
parent aae3eaf0a0
commit f3877befe7
18 changed files with 2154 additions and 635 deletions

View File

@ -1,5 +1,5 @@
# The GIMP -- an image manipulation program
# Copyright (C) 1998 Manish Singh <yosh@gimp.org>
# Copyright (C) 1998-1999 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
@ -25,81 +25,123 @@ $destdir = "$main::destdir/app";
*arg_vname = \&Gimp::CodeGen::pdb::arg_vname;
*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 = "";
foreach (@_) {
my @args = @{$proc->{$_}} if exists $proc->{$_};
foreach (@args) {
my $arg = $arg_types{(&arg_parse($_->{type}))[0]};
if (not exists $_->{no_declare}) {
if ($arg->{array} && (not exists $_->{array})) {
warn "Array without number of elements param in $proc->{name}";
}
unless (exists $_->{no_declare}) {
$result .= ' ' x 2;
$result .= $arg->{type} . &arg_vname($_) . ";\n";
if (exists $arg->{id_headers}) {
foreach (@{$arg->{id_headers}}) {
$out->{headers}->{$_}++;
}
}
if (exists $_->{get}) {
$result .= ' ' x 2;
$result .= $arg_types{$_->{get}->{type}}->{type};
$result .= &arg_vname($_->{get}) . ";\n";
}
}
}
}
$result;
}
sub make_args {
my $proc = shift;
my $result = "";
my $once;
foreach (@_) {
my @args = @{$proc->{$_}} if exists $proc->{$_};
if (scalar @args) {
$result .= "\nstatic ProcArg $proc->{name}_${_}[] =";
$result .= "\n{\n";
foreach my $arg (@{$proc->{$_}}) {
my ($type) = &arg_parse($arg->{type});
$result .= ' ' x 2 . "{\n";
$result .= ' ' x 4;
$result .= 'PDB_' . $arg_types{$type}->{name} . ",\n";
$result .= ' ' x 4;
$result .= qq/"$arg->{name}",\n/;
$result .= ' ' x 4;
$result .= qq/"$arg->{desc}"\n/;
$result .= ' ' x 2 . "},\n";
$result .= <<CODE;
{
PDB_$arg_types{$type}->{name},
"$arg->{name}",
"$arg->{desc}"
},
CODE
}
$result =~ s/,\n$/\n/;
$result .= "};\n";
}
}
$result;
}
sub marshal_inargs {
my $proc = shift;
my $result = "";
my %decls;
my $argc = 0;
my @inargs = @{$proc->{inargs}} if exists $proc->{inargs};
foreach (@inargs) {
my($pdbtype, @typeinfo) = &arg_parse($_->{type});
my $arg = $arg_types{$pdbtype};
my $type = &arg_ptype($arg);
my $var = &arg_vname($_);
$result .= ' ' x 2;
$result .= "if (success)\n" . ' ' x 4 if $success;
if (exists $arg->{id_func}) {
$decls{$type}++;
$result .= "{\n" . ' ' x 6 if $success;
$result .= "${type}_value = args[$argc].value.pdb_$type;\n";
$result .= ' ' x 4 if $success;
$result .= ' ' x 2;
$result .= "if (($var = ";
$result .= "$arg->{id_func} (${type}_value)) == NULL)\n";
$result .= ' ' x 4 unless $success;
$result .= "\t" if $success;
$result .= "success = FALSE;\n";
$result .= ' ' x 4 . "}\n" if $success;
my $code = "";
$code .= <<CODE;
if (($var = $arg->{id_func} (args[$argc].value.pdb_$type)) == NULL)
success = FALSE;
CODE
$code .= <<CODE if exists $_->{get};
else
@{[ &arg_vname($_->{get}) ]} = @{[ eval qq/"$arg->{$_->{get}->{type}}"/ ]};
CODE
if ($success) {
$code =~ s/^/' ' x 4/meg;
$code =~ s/^ {8}/\t/mg;
$result .= "{\n" . $code . ' ' x 4 . "}\n";
}
else {
$result .= $code;
}
$success = 1;
}
else {
@ -107,65 +149,82 @@ sub marshal_inargs {
# FIXME: implement this
}
elsif ($pdbtype eq 'boolean') {
$result .= "$var = ";
$result .= "(args[$argc].value.pdb_$type) ? TRUE : FALSE;\n";
}
elsif (defined $typeinfo[0] || defined $typeinfo[2]) {
my $tests = 0;
$result .= "success = (";
if (defined $typeinfo[0]) {
$result .= "$var $typeinfo[1] $typeinfo[0]";
$tests++;
}
if (defined $typeinfo[2]) {
$result .= '|| ' if $tests;
$result .= "$var $typeinfo[2] $typeinfo[3]";
}
$result .= ");\n";
$result .= ' ' x 2 . "$var = ";
$result .= "args[$argc].value.pdb_$type ? TRUE : FALSE;\n";
}
else {
my $cast = "";
$cast = " ($arg->{type})" if $type eq "pointer";
$cast = " ($arg->{type})" if $arg->{type} =~ /int(16|8)$/;
$result .= "$var =$cast args[$argc].value.pdb_$type;\n";
$result .= ' ' x 2 . "$var =";
$result .= "$cast args[$argc].value.pdb_$type;\n";
if ($pdbtype eq 'string') {
$result .= ' ' x 2 . "success = $var != NULL;\n";
$success = 1;
}
elsif (defined $typeinfo[0] || defined $typeinfo[2]) {
my $tests = 0;
$result .= ' ' 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;
}
}
}
$argc++; $result .= "\n";
}
chomp $result if !$success && $argc == 1;
my $decls;
foreach (keys %decls) { $decls .= ' ' x 2 . "$_ ${_}_value;\n" }
$result = $decls . "\n" . $result if $decls;
$result and $result = "\n" . $result unless $decls;
$result = "\n" . $result if $result;
$result;
}
sub marshal_outargs {
my $proc = shift;
my $result = <<CODE;
return_args = procedural_db_return_args (\&$proc->{name}_proc, success);
CODE
my $argc = 0;
my @outargs = @{$proc->{outargs}} if exists $proc->{outargs};
if (scalar @outargs) {
my $outargs = "";
foreach (@{$proc->{outargs}}) {
my ($pdbtype) = &arg_parse($_->{type});
my $arg = $arg_types{$pdbtype};
my $type = &arg_ptype($arg);
my $var = &arg_vname($_);
$argc++; $outargs .= ' ' x 2;
if (exists $arg->{id_ret_func}) {
$outargs .= "return_args[$argc].value.pdb_$type = ";
$outargs .= eval qq/"$arg->{id_ret_func}"/;
$outargs .= ";\n";
}
else {
$outargs .= "return_args[$argc].value.pdb_$type = $var;\n";
$var = eval qq/"$arg->{id_ret_func}"/;
}
$outargs .= "return_args[$argc].value.pdb_$type = $var;\n";
}
$outargs =~ s/^/' ' x 2/meg if $success;
$outargs =~ s/^/' ' x 2/meg if $success && $argc > 1;
$result .= "\n" if $success || $argc > 1;
$result .= ' ' x 2 . "if (success)\n" if $success;
$result .= ' ' x 4 . "{\n" if $success && $argc > 1;
@ -176,6 +235,7 @@ CODE
else {
$result =~ s/_args =//;
}
$result =~ s/, success\);$/, TRUE);/m unless $success;
$result;
}
@ -227,8 +287,10 @@ CODE
$invoker .= "\n" if $invoker && $invoker !~ /\n\n/s;
my $code = $proc->{invoke}->{code};
chomp $code;
$code =~ s/\t/' ' x 8/eg;
if ($code =~ /^\s*\{\s*\n.*\n\s*\}\s*$/s && !$success) {
$code =~ s/^\s*\{\s*\n//s;
$code =~ s/\n\s*}\s*$//s;
@ -242,7 +304,11 @@ CODE
$code = ' ' x 2 . "if (success)\n" . $code if $success;
$success = ($code =~ /success =/) unless $success;
$out->{code} .= ' ' x 2 . "int success = TRUE;\n" if $success;
if ($success) {
$out->{code} .= ' ' x 2;
$out->{code} .= "int success = $proc->{invoke}->{success};\n";
}
$out->{code} .= $invoker . $code . "\n";
$out->{code} .= "\n" if $code =~ /\n/s || $invoker;
$out->{code} .= &marshal_outargs($proc) . "}\n";
@ -290,7 +356,7 @@ CODE
GPL
my $internal = "$destdir/internal_procs.h.tmp.$$";
my $internal = "$destdir/internal_procs.h$FILE_EXT";
open INTERNAL, "> $internal" or die "Can't open $cmdfile: $!\n";
print INTERNAL $gpl;
my $guard = "__INTERNAL_PROCS_H__";
@ -310,7 +376,7 @@ HEADER
foreach $group (@main::groups) {
my $out = $out{$group};
my $cfile = "$destdir/${group}_cmds.c.tmp.$$";
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}}) {
@ -341,7 +407,7 @@ HEADER
$pcount += $out->{pcount};
}
$internal = "$destdir/internal_procs.c.tmp.$$";
$internal = "$destdir/internal_procs.c$FILE_EXT";
open INTERNAL, "> $internal" or die "Can't open $cmdfile: $!\n";
print INTERNAL $gpl;
print INTERNAL qq/#include "app_procs.h"\n\n/;

View File

@ -16,5 +16,5 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Modify this list for the groups to parse in the pdb directory
@groups = qw(gdisplay edit floating_sel undo palette gradients convert
channel_ops);
@groups = qw(gdisplay edit floating_sel undo palette gradient
convert channel_ops);

View File

@ -24,11 +24,18 @@ $destdir = "$main::destdir/libgimp";
*arg_parse = \&Gimp::CodeGen::pdb::arg_parse;
*write_file = \&Gimp::CodeGen::util::write_file;
*FILE_EXT = \$Gimp::CodeGen::util::FILE_EXT;
sub generate {
my @procs = @{(shift)};
my %out;
sub libtype {
my ($arg, $type) = @_;
$type =~ s/\d+// unless exists $arg->{keep_size};
$type;
}
foreach my $name (@procs) {
my $proc = $main::pdb{$name};
my $out = \%{$out{$proc->{group}}};
@ -45,7 +52,11 @@ sub generate {
# explicity set
my $retarg;
foreach (@outargs) { $retarg = $_, last if exists $_->{retval} }
scalar @outargs and $retarg = $outargs[0] unless $retarg;
unless ($retarg) {
if (scalar @outargs) {
$retarg = exists $outargs[0]->{num} ? $outargs[1] : $outargs[0];
}
}
my $rettype; my $retcol = 0;
if ($retarg) {
@ -53,8 +64,8 @@ sub generate {
if ($type ne 'color') {
my $arg = $arg_types{$type};
$rettype = do {
if (exists $arg->{id_func}) { 'gint32 ' }
else { $arg->{type} }
if (exists $arg->{id_func}) { 'gint32 ' }
else { &libtype($_, $arg->{type}) }
};
chop $rettype unless $rettype =~ /\*$/;
}
@ -62,6 +73,8 @@ sub generate {
# Color returns three components in pointers passed in
$rettype = 'void'; $retcol = 1;
}
$retarg->{retval} = 1;
}
else {
# No return values
@ -74,21 +87,28 @@ sub generate {
my ($type) = &arg_parse($_->{type});
my $arg = $arg_types{$type};
my $id = exists $arg->{id_func};
if ($type ne 'color') {
$arglist .= do {
if ($id) { 'gint32 ' }
else { $arg->{type} }
if ($id) { 'gint32 ' }
else { &libtype($_, $arg->{type}) }
};
$arglist .= $_->{name};
$arglist .= '_ID' if $id;
$arglist .= ', ';
}
else {
# A color needs to stick the components into a 3-element array
$color = "\n" . ' ' x 2 . "guchar $_->{name}\[3];\n\n";
$color .= ' ' x 2 . "$_->{name}\[0] = red;\n";
$color .= ' ' x 2 . "$_->{name}\[1] = green;\n";
$color .= ' ' x 2 . "$_->{name}\[2] = blue;";
chop ($color = <<CODE);
guchar $_->{name}\[3];
$_->{name}\[0] = red;
$_->{name}\[1] = green;
$_->{name}\[2] = blue;
CODE
$arglist .= "guchar red, guchar green, guchar blue, ";
}
@ -101,24 +121,33 @@ sub generate {
# This marshals the return value(s)
my $return_args = "";
my $return_marshal;
$return_marshal = "gimp_destroy_params (return_vals, nreturn_vals);";
my $return_marshal = "gimp_destroy_params (return_vals, nreturn_vals);";
# We only need to bother with this if we have to return a value
if ($rettype ne 'void' || $retcol) {
my $argc = 1; my $once = 0;
my $once = 0;
my $firstvar;
my @arraynums;
foreach (@outargs) {
my ($type) = &arg_parse($_->{type});
my $arg = $arg_types{$type};
my $id = $arg->{id_ret_func};
my $var;
$return_marshal = "" unless $once++;
if ($type ne 'color') {
if (exists $_->{num}) {
if (not exists $_->{no_lib}) {
$arglist .= "gint \*$_->{name}, ";
push @arraynums, $_;
}
}
elsif ($type ne 'color') {
$return_args .= "\n" . ' ' x 2;
$return_args .= do {
if ($id) { 'gint32 ' }
else { $arg->{type} }
if ($id) { 'gint32 ' }
else { &libtype($_, $arg->{type}) }
};
# The return value variable
@ -131,21 +160,73 @@ sub generate {
# Initialize all IDs to -1
$return_args .= " = -1" if $id;
# Initialize pointers to NULL
$return_args .= " = NULL" if !$id && ($arg->{type} =~ /\*/);
$return_args .= ";";
if (exists $_->{array} && exists $_->{array}->{no_lib}) {
$return_args .= "\n" . ' ' x 2 . "gint num_$var;";
}
}
$return_marshal .= <<CODE;
}
foreach (@arraynums) { $return_marshal .= "\*$_->{name} = 0;\n "; }
$return_marshal =~ s/\n $/\n\n /s if scalar(@arraynums);
$return_marshal .= <<CODE;
if (return_vals[0].data.d_status == STATUS_SUCCESS)
CODE
if ($type ne 'color') {
$return_marshal .= ' ' x 4 . "$var = ";
$return_marshal .= 'g_strdup (' if $type eq 'string';
$return_marshal .= "return_vals[$argc].data.d_$type";
$return_marshal .= ')' if $type eq 'string';
$return_marshal .= ";\n";
$return_marshal .= ' ' x 4 . "{\n" if $#outargs;
my $argc = 1; my ($numpos, $numtype);
foreach (@outargs) {
my ($type) = &arg_parse($_->{type});
my $arg = $arg_types{$type};
my $id = $arg->{id_ret_func};
my $var;
my $head = ""; my $foot = "";
if ($type =~ /^string(array)?/) {
$head = 'g_strdup (';
$foot = ')';
}
if (exists $_->{num}) {
$numpos = $argc;
$numtype = $type;
}
elsif (exists $_->{array}) {
my $datatype = $arg->{type};
chop $datatype;
$datatype =~ s/ *$//;
$return_args .= "\n" . ' ' x 2 . "gint i;";
my $numvar = '*' . $_->{array}->{name};
$numvar = "num_$_->{name}" if exists $_->{array}->{no_lib};
$return_marshal .= <<CODE;
$numvar = return_vals[$numpos].data.d_$numtype;
$_->{name} = g_new ($datatype, $numvar);
for (i = 0; i < $numvar; i++)
$_->{name}\[i] = ${head}return_vals[$argc].data.d_$type\[i]${foot};
CODE
}
elsif ($type ne 'color') {
# The return value variable
$var = $_->{name};
$var .= '_ID' if $id;
$return_marshal .= <<CODE
$var = ${head}return_vals[$argc].data.d_$type${foot};
CODE
}
else {
# Colors are returned in parts using pointers
$arglist .= "guchar \*red, guchar \*green, guchar \*blue";
$arglist .= "guchar \*red, guchar \*green, guchar \*blue, ";
$return_marshal .= <<CODE
{
\*red = return_vals[$argc].data.d_color.red;
@ -154,8 +235,12 @@ CODE
}
CODE
}
$argc++;
}
$return_marshal .= ' ' x 4 . "}\n" if $#outargs;
$return_marshal .= <<'CODE';
gimp_destroy_params (return_vals, nreturn_vals);
@ -169,6 +254,9 @@ CODE
# We don't need the last comma in the declaration
$arglist =~ s/, $//;
}
else {
$arglist = "void";
}
# Our function prototype for the headers
push @{$out->{proto}}, "$rettype gimp_$name ($arglist);\n";
@ -179,7 +267,7 @@ $rettype
gimp_$name ($arglist)
{
GParam *return_vals;
int nreturn_vals;$return_args$color
gint nreturn_vals;$return_args$color
return_vals = gimp_run_procedure ("gimp_$name",
\&nreturn_vals,$argpass
@ -215,8 +303,8 @@ LGPL
# We generate two files, a .h file with prototypes for all the functions
# we make, and a .c file for the actual implementation
while (my($group, $out) = each %out) {
my $hfile = "$destdir/gimp${group}.h.tmp.$$";
my $cfile = "$destdir/gimp${group}.c.tmp.$$";
my $hfile = "$destdir/gimp${group}.h$FILE_EXT";
my $cfile = "$destdir/gimp${group}.c$FILE_EXT";
my $protos;
foreach (@{$out->{proto}}) { $protos .= $_ }

View File

@ -25,11 +25,11 @@ package Gimp::CodeGen::pdb;
float => { name => 'FLOAT' , type => 'gdouble ' },
string => { name => 'STRING', type => 'gchar *' },
int32array => { name => 'INT32ARRAY' , type => 'gint32 *' },
int16array => { name => 'INT16ARRAY' , type => 'gint16 *' },
int8array => { name => 'INT8ARRAY' , type => 'gint8 *' },
floatarray => { name => 'FLOATARRAY' , type => 'gdouble *' },
stringarray => { name => 'STRINGARRAY', type => 'gchar **' },
int32array => { name => 'INT32ARRAY' , type => 'gint32 *' , array => 1 },
int16array => { name => 'INT16ARRAY' , type => 'gint16 *' , array => 1 },
int8array => { name => 'INT8ARRAY' , type => 'gint8 *' , array => 1 },
floatarray => { name => 'FLOATARRAY' , type => 'gdouble *', array => 1 },
stringarray => { name => 'STRINGARRAY', type => 'gchar **' , array => 1 },
color => { name => 'COLOR' , type => 'guchar *' },
@ -67,7 +67,7 @@ package Gimp::CodeGen::pdb;
id_func => 'gimp_drawable_get_ID',
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
id_headers => [ qw("drawable.h") ],
gimage => 'drawable_gimage (GIMP_DRAWABLE ($var))'
image => 'drawable_gimage (GIMP_DRAWABLE ($var))'
},
selection => {
name => 'SELECTION',
@ -114,3 +114,5 @@ sub arg_ptype {
# Return the alias if defined, otherwise the name
sub arg_vname { exists $_[0]->{alias} ? $_[0]->{alias} : $_[0]->{name} }
sub arg_numtype () { 'gint32 ' }

View File

@ -35,7 +35,7 @@ HELP
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable to offset', gimage => 1 },
desc => 'The drawable to offset', get => &std_image_arg },
{ name => 'wrap_around', type => 'boolean',
desc => 'wrap image around or fill vacated regions' },
{ name => 'fill_type', type => 'enum GimpOffsetType',

View File

@ -36,7 +36,7 @@ HELP
@outargs = (
{ name => 'display', type => 'display',
desc => 'The new display' }
desc => 'The new display', alias => 'gdisp' }
);
%invoke = (
@ -47,7 +47,7 @@ HELP
if (gimage->layers == NULL)
success = FALSE;
else
success = ((display = gdisplay_new (gimage, scale)) != NULL);
success = ((gdisp = gdisplay_new (gimage, scale)) != NULL);
}
CODE
);
@ -65,12 +65,12 @@ HELP
@inargs = (
{ name => 'display', type => 'display',
desc => 'The display to delete' }
desc => 'The display to delete', alias => 'gdisp' }
);
%invoke = (
headers => [ qw("gdisplay.h") ],
code => 'gtk_widget_destroy (display->shell);'
code => 'gtk_widget_destroy (gdisp->shell);'
);
}

View File

@ -17,12 +17,12 @@
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
# Common arguments for image and drawable
# Common arguments
sub inargs {
@inargs = (
&std_image_arg,
{ name => 'drawable', type => 'drawable',
desc => "The drawable to @{[shift]}" }
desc => "The drawable to @{[shift]}",
get => &std_image_arg }
);
}
@ -30,14 +30,7 @@ sub inargs {
sub invoke {
%invoke = (
headers => [ qw("global_edit.h") ],
code => <<CODE
{
if (gimage != drawable_gimage (drawable))
success = FALSE;
else
success = @{[shift]};
}
CODE
code => "success = @{[shift]};"
);
}
@ -57,7 +50,7 @@ HELP
&std_pdb_misc;
&inargs('cut from');
&invoke('(edit_cut (gimage, drawable) != NULL)');
&invoke('edit_cut (gimage, drawable) != NULL');
}
sub edit_copy {
@ -74,7 +67,7 @@ HELP
&std_pdb_misc;
&inargs('copy from');
&invoke('(edit_copy (gimage, drawable) != NULL)');
&invoke('edit_copy (gimage, drawable) != NULL');
}
sub edit_paste {
@ -107,10 +100,9 @@ HELP
desc => 'The new floating selection', alias => 'layer' }
);
&invoke('(layer != NULL)');
&invoke('layer != NULL');
$cmd = "layer = edit_paste (gimage, drawable, global_buf, paste_into);\n";
$invoke{code} =~ s/(else\n)/$1 . ' ' x 4 . "{\n" . ' ' x 6 . $cmd/se;
$invoke{code} =~ s/(success = \(.*?\n)/' ' x 2 . $1 . ' ' x 4 . "}\n"/se;
$invoke{code} = "{\n" . ' ' x 2 . $cmd . ' ' x 2 . $invoke{code} . "\n}\n";
}
sub edit_clear {

View File

@ -36,7 +36,7 @@ HELP
@outargs = (
{ name => 'display', type => 'display',
desc => 'The new display' }
desc => 'The new display', alias => 'gdisp' }
);
%invoke = (
@ -47,7 +47,7 @@ HELP
if (gimage->layers == NULL)
success = FALSE;
else
success = ((display = gdisplay_new (gimage, scale)) != NULL);
success = ((gdisp = gdisplay_new (gimage, scale)) != NULL);
}
CODE
);
@ -65,12 +65,12 @@ HELP
@inargs = (
{ name => 'display', type => 'display',
desc => 'The display to delete' }
desc => 'The display to delete', alias => 'gdisp' }
);
%invoke = (
headers => [ qw("gdisplay.h") ],
code => 'gtk_widget_destroy (display->shell);'
code => 'gtk_widget_destroy (gdisp->shell);'
);
}

View File

@ -18,8 +18,7 @@
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub pdb_misc {
$author = 'Federico Mena Quintero';
$copyright = $author;
$author = $copyright = 'Federico Mena Quintero';
$date = '1997';
}
@ -35,11 +34,11 @@ HELP
&pdb_misc;
@outargs = (
{ name => 'num_gradients', type => 'int32',
desc => 'The number of loaded gradients' },
{ name => 'gradient_names', type => 'stringarray',
desc => 'The list of gradient names', alias => 'gradients',
retval => 1, num_elements => '*num_gradients' }
array => { name => 'num_gradients',
desc => 'The number of loaded gradients',
no_declare => 1 } }
);
%invoke = (
@ -47,9 +46,10 @@ HELP
vars => ['gradient_t *grad', 'GSList *list', 'int i = 0'],
code => <<'CODE'
{
gradients = g_new (char *, num_gradients);
gradients = g_new (gchar *, num_gradients);
success = (list = gradients_list) != NULL;
success = ((list = gradients_list) != NULL);
while (list)
{
grad = list->data;
@ -71,17 +71,14 @@ HELP
&pdb_misc;
@outargs = (
{
name => 'name',
type => 'string',
desc => 'The name of the active gradient',
alias => 'g_strdup (curr_gradient->name)', no_declare => 1
}
{ name => 'name', type => 'string',
desc => 'The name of the active gradient',
alias => 'g_strdup (curr_gradient->name)', no_declare => 1 }
);
%invoke = (
headers => [ qw("gradient.h") ],
code => 'success = (curr_gradient != NULL);'
code => 'success = curr_gradient != NULL;'
);
}
@ -104,56 +101,24 @@ HELP
);
%invoke = (
success => 'FALSE',
headers => [ qw("gradient.h") ],
vars => ['gradient_t *grad', 'GSList *list'],
code => <<'CODE'
{
success = (name != NULL);
if (success)
{
success = FALSE;
list = gradients_list;
while (list)
{
grad = list->data;
if (strcmp (grad->name, name) == 0)
{
success = TRUE;
/* FIXME: violates functionality-GUI separation */
if (grad->list_item != NULL)
/* Select that gradient in the listbox */
gtk_list_select_child (GTK_LIST (g_editor->list),
grad->list_item);
else
/* Just update the current gradient */
curr_gradient = grad;
break;
}
list = list->next;
}
}
}
CODE
code => 'success = grad_set_grad_to_name (name);'
);
}
sub sample_num_arg {
{ name => 'num_samples', type => 'int32',
{ name => 'num_samples', type => $_[0] . 'int32',
desc => 'The number of samples to take', alias => 'i' }
}
sub sample_outargs {
@outargs = (
{ name => 'array_length', type => 'int32',
desc => 'Length of the color_samples array (4 * num_samples)' },
{ name => 'color_samples', type => 'floatarray',
desc => 'Color samples: { R1, G1, B1, A1, ..., Rn, Gn, Bn, An }',
retval => 1, num_elements => '*array_length' }
array => { name => 'array_length', no_lib => 1,
desc => 'Length of the color_samples array (4 *
num_samples)' } }
);
}
@ -171,7 +136,7 @@ HELP
&pdb_misc;
@inargs = ( &sample_num_arg );
@inargs = ( &sample_num_arg('2 <= ') );
&sample_outargs;
%invoke = (
@ -179,29 +144,24 @@ HELP
vars => ['gdouble pos, delta', 'gdouble r, g, b, a', 'gdouble *pv'],
code => <<'CODE'
{
if (i >= 2)
pos = 0.0;
delta = 1.0 / (i - 1);
array_length = i * 4;
pv = color_samples = g_new (gdouble, array_length);
while (i--)
{
pos = 0.0;
delta = 1.0 / (i - 1);
grad_get_color_at(pos, &r, &g, &b, &a);
array_length = i * 4;
*pv++ = r;
*pv++ = g;
*pv++ = b;
*pv++ = a;
pv = color_samples = g_new (gdouble, array_length);
while (i--)
{
grad_get_color_at(pos, &r, &g, &b, &a);
*pv++ = r;
*pv++ = g;
*pv++ = b;
*pv++ = a;
pos += delta;
}
pos += delta;
}
else
success = FALSE;
}
CODE
);
@ -222,12 +182,12 @@ HELP
&pdb_misc;
@inargs = (
&sample_num_arg,
{
name => 'positions',
type => 'floatarray',
desc => 'The list of positions to sample along the gradient',
alias => 'pos'
alias => 'pos',
array => &sample_num_arg("")
}
);
@ -238,26 +198,21 @@ HELP
vars => ['gdouble r, g, b, a', 'gdouble *pv'],
code => <<'CODE'
{
if (i >= 2)
array_length = i * 4;
pv = color_samples = g_new (gdouble, array_length);
while (i--)
{
array_length = i * 4;
grad_get_color_at(*pos, &r, &g, &b, &a);
pv = color_samples = g_new (gdouble, array_length);
*pv++ = r;
*pv++ = g;
*pv++ = b;
*pv++ = a;
while (i--)
{
grad_get_color_at(*pos, &r, &g, &b, &a);
*pv++ = r;
*pv++ = g;
*pv++ = b;
*pv++ = a;
pos++;
}
pos++;
}
else
success = FALSE;
}
CODE
);

View File

@ -0,0 +1,100 @@
# The GIMP -- an image manipulation program
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub pdb_misc {
$author = $copyright = 'Andy Thomas';
$date = '1998';
}
sub get_gradient_data {
$blurb = <<'BLURB';
Retrieve information about the specified gradient (including data).
BLURB
$help = <<'HELP';
This procedure retrieves information about the gradient. This includes the
gradient name, and the sample data for the gradient.
HELP
&pdb_misc;
@inargs = (
{ name => 'name', type => 'string',
desc => 'The gradient name ("" means current active gradient)' }
{ 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' }
);
@outargs = (
{ name => 'name', type => 'string',
desc => 'The gradient name',
alias => 'g_strdup (grad->name)', no_declare => 1 },
{ name => 'grad_data', type => 'floatarray',
desc => 'The gradient sample data',
array => { name => 'width',
desc => 'The gradient sample width (r,g,b,a)',
alias => 'sample_size * 4', no_declare => 1 } }
);
%invoke = (
headers => [ qw("gradient_select.h") ],
vars => ['gradient_t *grad'],
code => <<'CODE'
{
if (name[0] == '\0')
success = (grad = curr_gradient) != NULL;
else
{
GSList *list;
success = FALSE;
list = gradients_list;
while (list)
{
grad = list->data;
if (!strcmp (grad->name, name))
{
success = TRUE;
break; /* We found it! */
}
list = list->next;
}
}
if (success)
{
gdouble *,
}
}
CODE
);
}
@procs = qw(gradients_get_gradient_data);
%exports = (app => [@procs]);
$desc = 'Gradient UI';
1;

View File

@ -0,0 +1,227 @@
# The GIMP -- an image manipulation program
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 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.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub pdb_misc {
$author = $copyright = 'Federico Mena Quintero';
$date = '1997';
}
sub gradients_get_list {
$blurb = 'Retrieve the list of loaded gradients.';
$help = <<'HELP';
This procedure returns a list of the gradients that are currently loaded in the
gradient editor. You can later use the gimp-gradients-set-active function to
set the active gradient.
HELP
&pdb_misc;
@outargs = (
{ name => 'gradient_names', type => 'stringarray',
desc => 'The list of gradient names', alias => 'gradients',
array => { name => 'num_gradients',
desc => 'The number of loaded gradients',
no_declare => 1 } }
);
%invoke = (
headers => [ qw("gradient.h") ],
vars => ['gradient_t *grad', 'GSList *list', 'int i = 0'],
code => <<'CODE'
{
gradients = g_new (gchar *, num_gradients);
success = (list = gradients_list) != NULL;
while (list)
{
grad = list->data;
gradients[i++] = g_strdup (grad->name);
list = list->next;
}
}
CODE
);
}
sub gradients_get_active {
$blurb = 'Retrieve the name of the active gradient.';
$help = <<'HELP';
This procedure returns the name of the active gradient in the gradient editor.
HELP
&pdb_misc;
@outargs = (
{ name => 'name', type => 'string',
desc => 'The name of the active gradient',
alias => 'g_strdup (curr_gradient->name)', no_declare => 1 }
);
%invoke = (
headers => [ qw("gradient.h") ],
code => 'success = curr_gradient != NULL;'
);
}
sub gradients_set_active {
$blurb = 'Sets the specified gradient as the active gradient.';
$help = <<'HELP';
This procedure lets you set the specified gradient as the active or "current"
one. The name is simply a string which corresponds to one of the loaded
gradients in the gradient editor. If no matching gradient is found, this
procedure will return an error. Otherwise, the specified gradient will become
active and will be used for subsequent custom gradient operations.
HELP
&pdb_misc;
@inargs = (
{ name => 'name', type => 'string',
desc => 'The name of the gradient to set' }
);
%invoke = (
success => 'FALSE',
headers => [ qw("gradient.h") ],
code => 'success = grad_set_grad_to_name (name);'
);
}
sub sample_num_arg {
{ name => 'num_samples', type => $_[0] . 'int32',
desc => 'The number of samples to take', alias => 'i' }
}
sub sample_outargs {
@outargs = (
{ name => 'color_samples', type => 'floatarray',
desc => 'Color samples: { R1, G1, B1, A1, ..., Rn, Gn, Bn, An }',
array => { name => 'array_length', no_lib => 1,
desc => 'Length of the color_samples array (4 *
num_samples)' } }
);
}
sub gradients_sample_uniform {
$blurb = 'Sample the active gradient in uniform parts.';
$help = <<'HELP';
This procedure samples the active gradient from the gradient editor in the
specified number of uniform parts. It returns a list of floating-point values
which correspond to the RGBA values for each sample. The minimum number of
samples to take is 2, in which case the returned colors will correspond to the
{ 0.0, 1.0 } positions in the gradient. For example, if the number of samples
is 3, the procedure will return the colors at positions { 0.0, 0.5, 1.0 }.
HELP
&pdb_misc;
@inargs = ( &sample_num_arg('2 <= ') );
&sample_outargs;
%invoke = (
headers => [ qw("gradient.h") ],
vars => ['gdouble pos, delta', 'gdouble r, g, b, a', 'gdouble *pv'],
code => <<'CODE'
{
pos = 0.0;
delta = 1.0 / (i - 1);
array_length = i * 4;
pv = color_samples = g_new (gdouble, array_length);
while (i--)
{
grad_get_color_at(pos, &r, &g, &b, &a);
*pv++ = r;
*pv++ = g;
*pv++ = b;
*pv++ = a;
pos += delta;
}
}
CODE
);
}
sub gradients_sample_custom {
$blurb = 'Sample the active gradient in custom positions.';
$help = <<'HELP';
This procedure samples the active gradient from the gradient editor in the
specified number of points. The procedure will sample the gradient in the
specified positions from the list. The left endpoint of the gradient
corresponds to position 0.0, and the right endpoint corresponds to 1.0. The
procedure returns a list of floating-point values which correspond to the RGBA
values for each sample.
HELP
&pdb_misc;
@inargs = (
{
name => 'positions',
type => 'floatarray',
desc => 'The list of positions to sample along the gradient',
alias => 'pos',
array => &sample_num_arg("")
}
);
&sample_outargs;
%invoke = (
headers => [ qw("gradient.h") ],
vars => ['gdouble r, g, b, a', 'gdouble *pv'],
code => <<'CODE'
{
array_length = i * 4;
pv = color_samples = g_new (gdouble, array_length);
while (i--)
{
grad_get_color_at(*pos, &r, &g, &b, &a);
*pv++ = r;
*pv++ = g;
*pv++ = b;
*pv++ = a;
pos++;
}
}
CODE
);
}
@procs = qw(gradients_get_list gradients_get_active gradients_set_active
gradients_sample_uniform gradients_sample_custom);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Gradients';
1;

View File

@ -21,31 +21,38 @@
# shortcuts
sub tool_init_args {
(image => ['image', 'The image'],
drawable => ['drawable', 'The affected drawable']);
}
sub drawable_arg () {{
name => 'drawable',
type => 'drawable',
desc => 'The affected drawable',
get => &std_image_arg
}}
sub sample_merged_arg {
(sample_merged => ['boolean', 'Use the composite image, not the drawable']);
}
sub sample_merged_arg () {{
name => 'sample_merged',
type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub antialias_arg {
(antialias => ['boolean', 'Antialiasing $desc']);
}
sub antialias_arg () {{
name => 'antialias',
type => 'boolean',
desc => 'Antialiasing $desc'
}}
sub feather_select_args {
(feather => ['boolean', 'Feather option for selections'],
feather_radius => ['float', 'Radius for feather operation']);
}
sub feather_select_args () {(
{ name => 'feather', type => 'boolean',
desc => 'Feather option for selections' },
{ name => 'feather_radius', type => 'float',
desc => 'Radius for feather operation' }
)}
sub stroke_args {
(num_strokes => ['0 < int32',
'number of stroke control points (count each coordinate as
2 points)'],
strokes => ['floatarray',
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
sn.x, sn.y }']);
sub stroke_arg () {
{ name => 'strokes', type => 'floatarray',
desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
sn.x, sn.y }',
array => { desc => 'number of stroke control points (count each
coordinate as 2 points)' } }
}
# The defs
@ -64,16 +71,17 @@ HELP;
&std_pdb_misc;
%inargs = (
&tool_init_args,
pressure => ['0 <= float <= 100',
'The pressure of the airbrush strokes $desc'],
&stroke_args
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure of the airbrush strokes $desc' },
&stroke_arg
);
delete $inargs[0]->{get};
@invoke = (
'airbrush.h',
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
%invoke = (
headers => [ qw("airbrush.h") ],
code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
);
}
@ -91,35 +99,44 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
blend_mode => ['enum BlendMode',
'The type of blend: $desc'],
gradient_type => ['enum PaintMode',
'The paint application mode: $desc'],
opacity => ['0 <= float <= 100',
'The opacity of the final blend $desc'],
offset => ['0 <= float',
'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent
$desc'],
repeat => ['enum RepeatMode', 'Repeat mode: $desc'],
supersample => ['boolean', 'Do adaptive supersampling $desc'],
max_depth => ['1 <= int32 <= 9',
'Maximum recursion levels for supersampling',
'attach supersample'],
threshold => ['0 <= float <= 4',
'Supersampling threshold',
'attach supersample'],
x1 => ['float', 'The x coordinate of this blend's starting point'],
y1 => ['float', 'The y coordinate of this blend's starting point'],
x2 => ['float', 'The x coordinate of this blend's ending point'],
y2 => ['float', 'The y coordinate of this blend's ending point']
@inargs = (
&drawable_arg,
{ name => 'blend_mode', type => 'enum BlendMode',
desc => 'The type of blend: $desc' },
{ name => 'gradient_type', type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
{ name => 'opacity', type => '0 <= float <= 100',
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' },
{ name => 'repeat', type => 'enum RepeatMode',
desc => 'Repeat mode: $desc' },
{ name => 'supersample', type => 'boolean',
desc => 'Do adaptive supersampling $desc' },
{ name => 'max_depth', type => '1 <= int32 <= 9',
desc => 'Maximum recursion levels for supersampling',
cond => 'supersample' },
{ name => 'threshold', type => '0 <= float <= 4',
desc => 'Supersampling threshold',
cond => 'supersample' },
{ name => 'x1', type => 'float',
desc => "The x coordinate of this blend's starting point" },
{ name => 'y1', type => 'float',
desc => "The y coordinate of this blend's starting point" },
{ name => 'x2', type => 'float',
desc => "The x coordinate of this blend's ending point" },
{ name => 'y2', type => 'float',
desc => "The y coordinate of this blend's ending point" }
);
@invoke = (
'blend.h',
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);'
%invoke = (
headers => [ qw("blend.h") ],
code => <<'CODE'
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
CODE
);
}
@ -144,27 +161,36 @@ HELP;
&std_pdb_misc;
my $validity = 'This parameter is only valid when there is no selection in the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application. $validity";
my $validity = 'This parameter is only valid when there is no selection in
the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application.
$validity";
%inargs = (
&tool_init_args,
fill_mode => ['enum FillMode', 'The type of fill: $desc'],
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'],
opacity => ['0 <= float <= 100',
'The opacity of the final bucket fill $desc'],
threshold => ['0 <= float <= 255',
"The threshold determines how extensive the seed fill
will be. It's value is specified in terms of intensity
levels \$desc. $validity'],
&drawable_arg,
{ name => 'fill_mode', type => 'enum FillMode',
desc => 'The type of fill: $desc' },
{ name => paint_mode, type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
{ name => opacity, type => '0 <= float <= 100',
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" },
&sample_merged_arg,
x => ['float', eval qq/{\$a = 'x';"$coord";}/],
y => ['float', eval qq/{\$a = 'y';"$coord";}/]
{ name => x, type => 'float',
desc => eval qq/{\$a = 'x'; "$coord";}/ },
{ name => y, type => 'float',
desc => eval qq/{\$a = 'y';"$coord";}/ }
);
@invoke = (
'bucket_fill.h',
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);'
%invoke = (
headers => [ qw ("bucket_fill.h") ],
code => <<'CODE'
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
sample_merged, x, y);
CODE
);
}
@ -182,7 +208,7 @@ sufficiently close to the specified color (as determined by the threshold
value) are included in the selection. The antialiasing parameter allows the
final selection mask to contain intermediate values based on close misses to
the threshold bar. Feathering can be enabled optionally and is controlled with
the \"feather_radius\" parameter. If the sample_merged parameter is non-zero,
the "feather_radius" parameter. 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.
@ -190,20 +216,25 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
color => ['color', 'The color to select'],
threshold => ['0 <= int32 <= 255',
'Threshold in intensity levels $desc'],
operation => ['enum Operation', 'The selection operation: $desc'],
@inargs = (
&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' },
&antialias_arg,
&feather_select_args,
&sample_merged_arg
);
@invoke = (
'by_color_select.h',
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);'
%invoke = (
headers => [ qw("by_color_select.h") ],
code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
CODE
);
}
@ -214,9 +245,9 @@ BLURB
$help = <<'HELP'
This tool clones (copies) from the source drawable starting at the specified
source coordinates to the dest drawable. If the \"clone_type\" argument is set
source coordinates to the dest drawable. If the "clone_type" argument is set
to PATTERN-CLONE, then the current pattern is used as the source and the
\"src_drawable\" argument is ignored. Pattern cloning assumes a tileable
"src_drawable" argument is ignored. Pattern cloning assumes a tileable
pattern and mods the sum of the src coordinates and subsequent stroke offsets
with the width and height of the pattern. For image cloning, if the sum of the
src coordinates and subsequent stroke offsets exceeds the extents of the src
@ -227,18 +258,26 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
src_drawable => ['drawable', "The source drawable"],
clone_type => ['enum CloneType', 'The type of clone: $desc'],
src_x => ['float', 'The x coordinate in the source image'],
src_y => ['float', 'The y coordinate in the source image'],
&stroke_args
@inargs = (
&drawable_arg,
{ name => 'src_drawable', type => 'drawable',
desc => 'The source drawable' },
{ name => 'clone_type', type => 'enum CloneType',
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 = (
'clone.h',
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);'
%invoke = (
headers => [ qw("clone.h") ],
code => <<'CODE'
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
strokes);
CODE
);
}
@ -262,19 +301,244 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
x => ['float', 'x coordinate of upper-left corner of rectangle'],
y => ['float', 'y coordinate of upper-left corner of rectangle'],
@inargs = (
&drawable_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' },
&sample_merged_arg,
save_color => ['boolean', 'Save the color to the active palette']
{ name => 'save_color', type => 'boolean',
desc => 'Save the color to the active palette' }
);
%outargs = (
color => ['color', 'The return color']
@outargs = (
{ name => 'color', type => 'color',
desc => 'The return color' }
);
%invoke = (
'color_picker.h',
'
headers => [ qw("color_picker.h") ],
code => <<'CODE'
{
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];
color[GREEN_PIX] = col_value[GREEN_PIX];
color[BLUE_PIX] = col_value[BLUE_PIX];
}
}
CODE
);
}
sub convolve {
$blurb = 'Convolve (Blur, Sharpen) using the current brush.';
$help = <<'HELP';
This tool convolves the specified drawable with either a sharpening or blurring
kernel. The pressure parameter controls the magnitude of the operation. Like
the paintbrush, this tool linearly interpolates between the specified stroke
coordinates.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure: $desc' },
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
desc => 'Convolve type: $desc' },
&stroke_arg
);
%invoke = (
headers => [ qw("convolve.h") ],
code => 'convolve_non_gui (drawable, pressure, num_strokes, strokes);'
);
}
sub crop {
$blurb = 'Crop the image to the specified extents.';
$help = <<'HELP';
This procedure crops the image so that it's new width and height are equal to
the supplied parameters. Offsets are also provided which describe the position
of the previous image's content. All channels and layers within the image are
cropped to the new image extents; this includes the image selection mask. If
any parameters are out of range, an error is returned.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'new_width', type => '0 < int32',
desc => 'New image width: (0 < new_width <= width)' },
{ name => 'new_height', type => '0 < int32',
desc => 'New image height: (0 < new_height <= height)' },
{ name => 'offx', type => '0 <= int32',
desc => 'x offset: (0 <= offx <= (width - new_width))' },
{ name => 'offy', type => '0 <= int32',
desc => 'y offset: (0 <= offy <= (height - new_height))' }
);
%invoke = (
headers => [ qw("crop.h") ],
code => <<'CODE'
{
if (new_width > gimage->width ||
new_height > gimage->height ||
offx > (gimage->width - new_width) ||
offy > (gimage->height - new_height)
success = FALSE;
else
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
}
CODE
);
}
sub ellipse_select {
$blurb = 'Create an elliptical selection over the specified image.';
$help = <<'HELP';
This tool creates an elliptical selection over the specified image. The
elliptical region can be either added to, subtracted from, or replace the
contents of the previous selection mask. If antialiasing is turned on, the
edges of the elliptical region will contain intermediate values which give the
appearance of a sharper, less pixelized edge. This should be set as TRUE most
of the time. 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
@inargs = (
&std_image_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of ellipse bounding box' },
{ 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' },
{ name => 'height', type => '0 < float',
desc => 'The height of the ellipse: $desc' },
{ name => 'operation', 'enum Selection',
desc => 'The selection operation: $desc' },
&antialias_arg,
&feather_args
);
%invoke = (
headers => [ qw("ellipse_select.h") ],
code => <<'CODE'
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
feather, feather_radius);
CODE
);
}
sub eraser {
$blurb = 'Erase using the current brush.';
$help = <<'HELP';
This tool erases using the current brush mask. If the specified drawable
contains an alpha channel, then the erased pixels will become transparent.
Otherwise, the eraser tool replaces the contents of the drawable with the
background color. Like paintbrush, this tool linearly interpolates between the
specified stroke coordinates.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
&stroke_arg,
{ name => 'hardness', type => 'enum EraserHardness',
desc => '$desc' }
{ name => 'method', type => 'enum EraserMethod',
desc => '$desc' }
);
%invoke = (
headers => [ qw("eraser.h") ],
code => <<'CODE'
eraser_non_gui (drawable, num_strokes, strokes, hardness, method);
CODE
);
}
sub flip {
$blurb = <<'BLURB';
Flip the specified drawable about its center either vertically or
horizontally.
BLURB
$help = <<'HELP';
This tool flips 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 flipd by the
specified amount. The return value is the ID of the flipped 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 flipped drawable. The flip type
parameter indicates whether the flip will be applied horizontally or
vertically.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'flip_type', type => 'enum FlipType',
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};
%invoke = (
headers => [ qw("flip_tool.h" "tranform_core.h") ],
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
code => <<'CODE'
{
/* 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);
/* flip the buffer */
switch (flip_type)
{
case 0: /* horz */
new_tiles = flip_tool_flip_horz (gimage, drawable, float_tiles, -1);
break;
case 1: /* vert */
new_tiles = flip_tool_flip_vert (gimage, drawable, float_tiles, -1);
break;
}
/* 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
);
}

View File

@ -21,31 +21,38 @@
# shortcuts
sub tool_init_args {
(image => ['image', 'The image'],
drawable => ['drawable', 'The affected drawable']);
}
sub drawable_arg () {{
name => 'drawable',
type => 'drawable',
desc => 'The affected drawable',
get => &std_image_arg
}}
sub sample_merged_arg {
(sample_merged => ['boolean', 'Use the composite image, not the drawable']);
}
sub sample_merged_arg () {{
name => 'sample_merged',
type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub antialias_arg {
(antialias => ['boolean', 'Antialiasing $desc']);
}
sub antialias_arg () {{
name => 'antialias',
type => 'boolean',
desc => 'Antialiasing $desc'
}}
sub feather_select_args {
(feather => ['boolean', 'Feather option for selections'],
feather_radius => ['float', 'Radius for feather operation']);
}
sub feather_select_args () {(
{ name => 'feather', type => 'boolean',
desc => 'Feather option for selections' },
{ name => 'feather_radius', type => 'float',
desc => 'Radius for feather operation' }
)}
sub stroke_args {
(num_strokes => ['0 < int32',
'number of stroke control points (count each coordinate as
2 points)'],
strokes => ['floatarray',
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
sn.x, sn.y }']);
sub stroke_arg () {
{ name => 'strokes', type => 'floatarray',
desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
sn.x, sn.y }',
array => { desc => 'number of stroke control points (count each
coordinate as 2 points)' } }
}
# The defs
@ -64,16 +71,17 @@ HELP;
&std_pdb_misc;
%inargs = (
&tool_init_args,
pressure => ['0 <= float <= 100',
'The pressure of the airbrush strokes $desc'],
&stroke_args
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure of the airbrush strokes $desc' },
&stroke_arg
);
delete $inargs[0]->{get};
@invoke = (
'airbrush.h',
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
%invoke = (
headers => [ qw("airbrush.h") ],
code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
);
}
@ -91,35 +99,44 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
blend_mode => ['enum BlendMode',
'The type of blend: $desc'],
gradient_type => ['enum PaintMode',
'The paint application mode: $desc'],
opacity => ['0 <= float <= 100',
'The opacity of the final blend $desc'],
offset => ['0 <= float',
'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent
$desc'],
repeat => ['enum RepeatMode', 'Repeat mode: $desc'],
supersample => ['boolean', 'Do adaptive supersampling $desc'],
max_depth => ['1 <= int32 <= 9',
'Maximum recursion levels for supersampling',
'attach supersample'],
threshold => ['0 <= float <= 4',
'Supersampling threshold',
'attach supersample'],
x1 => ['float', 'The x coordinate of this blend's starting point'],
y1 => ['float', 'The y coordinate of this blend's starting point'],
x2 => ['float', 'The x coordinate of this blend's ending point'],
y2 => ['float', 'The y coordinate of this blend's ending point']
@inargs = (
&drawable_arg,
{ name => 'blend_mode', type => 'enum BlendMode',
desc => 'The type of blend: $desc' },
{ name => 'gradient_type', type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
{ name => 'opacity', type => '0 <= float <= 100',
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' },
{ name => 'repeat', type => 'enum RepeatMode',
desc => 'Repeat mode: $desc' },
{ name => 'supersample', type => 'boolean',
desc => 'Do adaptive supersampling $desc' },
{ name => 'max_depth', type => '1 <= int32 <= 9',
desc => 'Maximum recursion levels for supersampling',
cond => 'supersample' },
{ name => 'threshold', type => '0 <= float <= 4',
desc => 'Supersampling threshold',
cond => 'supersample' },
{ name => 'x1', type => 'float',
desc => "The x coordinate of this blend's starting point" },
{ name => 'y1', type => 'float',
desc => "The y coordinate of this blend's starting point" },
{ name => 'x2', type => 'float',
desc => "The x coordinate of this blend's ending point" },
{ name => 'y2', type => 'float',
desc => "The y coordinate of this blend's ending point" }
);
@invoke = (
'blend.h',
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);'
%invoke = (
headers => [ qw("blend.h") ],
code => <<'CODE'
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
CODE
);
}
@ -144,27 +161,36 @@ HELP;
&std_pdb_misc;
my $validity = 'This parameter is only valid when there is no selection in the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application. $validity";
my $validity = 'This parameter is only valid when there is no selection in
the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application.
$validity";
%inargs = (
&tool_init_args,
fill_mode => ['enum FillMode', 'The type of fill: $desc'],
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'],
opacity => ['0 <= float <= 100',
'The opacity of the final bucket fill $desc'],
threshold => ['0 <= float <= 255',
"The threshold determines how extensive the seed fill
will be. It's value is specified in terms of intensity
levels \$desc. $validity'],
&drawable_arg,
{ name => 'fill_mode', type => 'enum FillMode',
desc => 'The type of fill: $desc' },
{ name => paint_mode, type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
{ name => opacity, type => '0 <= float <= 100',
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" },
&sample_merged_arg,
x => ['float', eval qq/{\$a = 'x';"$coord";}/],
y => ['float', eval qq/{\$a = 'y';"$coord";}/]
{ name => x, type => 'float',
desc => eval qq/{\$a = 'x'; "$coord";}/ },
{ name => y, type => 'float',
desc => eval qq/{\$a = 'y';"$coord";}/ }
);
@invoke = (
'bucket_fill.h',
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);'
%invoke = (
headers => [ qw ("bucket_fill.h") ],
code => <<'CODE'
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
sample_merged, x, y);
CODE
);
}
@ -182,7 +208,7 @@ sufficiently close to the specified color (as determined by the threshold
value) are included in the selection. The antialiasing parameter allows the
final selection mask to contain intermediate values based on close misses to
the threshold bar. Feathering can be enabled optionally and is controlled with
the \"feather_radius\" parameter. If the sample_merged parameter is non-zero,
the "feather_radius" parameter. 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.
@ -190,20 +216,25 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
color => ['color', 'The color to select'],
threshold => ['0 <= int32 <= 255',
'Threshold in intensity levels $desc'],
operation => ['enum Operation', 'The selection operation: $desc'],
@inargs = (
&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' },
&antialias_arg,
&feather_select_args,
&sample_merged_arg
);
@invoke = (
'by_color_select.h',
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);'
%invoke = (
headers => [ qw("by_color_select.h") ],
code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
CODE
);
}
@ -214,9 +245,9 @@ BLURB
$help = <<'HELP'
This tool clones (copies) from the source drawable starting at the specified
source coordinates to the dest drawable. If the \"clone_type\" argument is set
source coordinates to the dest drawable. If the "clone_type" argument is set
to PATTERN-CLONE, then the current pattern is used as the source and the
\"src_drawable\" argument is ignored. Pattern cloning assumes a tileable
"src_drawable" argument is ignored. Pattern cloning assumes a tileable
pattern and mods the sum of the src coordinates and subsequent stroke offsets
with the width and height of the pattern. For image cloning, if the sum of the
src coordinates and subsequent stroke offsets exceeds the extents of the src
@ -227,18 +258,26 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
src_drawable => ['drawable', "The source drawable"],
clone_type => ['enum CloneType', 'The type of clone: $desc'],
src_x => ['float', 'The x coordinate in the source image'],
src_y => ['float', 'The y coordinate in the source image'],
&stroke_args
@inargs = (
&drawable_arg,
{ name => 'src_drawable', type => 'drawable',
desc => 'The source drawable' },
{ name => 'clone_type', type => 'enum CloneType',
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 = (
'clone.h',
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);'
%invoke = (
headers => [ qw("clone.h") ],
code => <<'CODE'
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
strokes);
CODE
);
}
@ -262,19 +301,244 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
x => ['float', 'x coordinate of upper-left corner of rectangle'],
y => ['float', 'y coordinate of upper-left corner of rectangle'],
@inargs = (
&drawable_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' },
&sample_merged_arg,
save_color => ['boolean', 'Save the color to the active palette']
{ name => 'save_color', type => 'boolean',
desc => 'Save the color to the active palette' }
);
%outargs = (
color => ['color', 'The return color']
@outargs = (
{ name => 'color', type => 'color',
desc => 'The return color' }
);
%invoke = (
'color_picker.h',
'
headers => [ qw("color_picker.h") ],
code => <<'CODE'
{
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];
color[GREEN_PIX] = col_value[GREEN_PIX];
color[BLUE_PIX] = col_value[BLUE_PIX];
}
}
CODE
);
}
sub convolve {
$blurb = 'Convolve (Blur, Sharpen) using the current brush.';
$help = <<'HELP';
This tool convolves the specified drawable with either a sharpening or blurring
kernel. The pressure parameter controls the magnitude of the operation. Like
the paintbrush, this tool linearly interpolates between the specified stroke
coordinates.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure: $desc' },
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
desc => 'Convolve type: $desc' },
&stroke_arg
);
%invoke = (
headers => [ qw("convolve.h") ],
code => 'convolve_non_gui (drawable, pressure, num_strokes, strokes);'
);
}
sub crop {
$blurb = 'Crop the image to the specified extents.';
$help = <<'HELP';
This procedure crops the image so that it's new width and height are equal to
the supplied parameters. Offsets are also provided which describe the position
of the previous image's content. All channels and layers within the image are
cropped to the new image extents; this includes the image selection mask. If
any parameters are out of range, an error is returned.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'new_width', type => '0 < int32',
desc => 'New image width: (0 < new_width <= width)' },
{ name => 'new_height', type => '0 < int32',
desc => 'New image height: (0 < new_height <= height)' },
{ name => 'offx', type => '0 <= int32',
desc => 'x offset: (0 <= offx <= (width - new_width))' },
{ name => 'offy', type => '0 <= int32',
desc => 'y offset: (0 <= offy <= (height - new_height))' }
);
%invoke = (
headers => [ qw("crop.h") ],
code => <<'CODE'
{
if (new_width > gimage->width ||
new_height > gimage->height ||
offx > (gimage->width - new_width) ||
offy > (gimage->height - new_height)
success = FALSE;
else
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
}
CODE
);
}
sub ellipse_select {
$blurb = 'Create an elliptical selection over the specified image.';
$help = <<'HELP';
This tool creates an elliptical selection over the specified image. The
elliptical region can be either added to, subtracted from, or replace the
contents of the previous selection mask. If antialiasing is turned on, the
edges of the elliptical region will contain intermediate values which give the
appearance of a sharper, less pixelized edge. This should be set as TRUE most
of the time. 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
@inargs = (
&std_image_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of ellipse bounding box' },
{ 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' },
{ name => 'height', type => '0 < float',
desc => 'The height of the ellipse: $desc' },
{ name => 'operation', 'enum Selection',
desc => 'The selection operation: $desc' },
&antialias_arg,
&feather_args
);
%invoke = (
headers => [ qw("ellipse_select.h") ],
code => <<'CODE'
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
feather, feather_radius);
CODE
);
}
sub eraser {
$blurb = 'Erase using the current brush.';
$help = <<'HELP';
This tool erases using the current brush mask. If the specified drawable
contains an alpha channel, then the erased pixels will become transparent.
Otherwise, the eraser tool replaces the contents of the drawable with the
background color. Like paintbrush, this tool linearly interpolates between the
specified stroke coordinates.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
&stroke_arg,
{ name => 'hardness', type => 'enum EraserHardness',
desc => '$desc' }
{ name => 'method', type => 'enum EraserMethod',
desc => '$desc' }
);
%invoke = (
headers => [ qw("eraser.h") ],
code => <<'CODE'
eraser_non_gui (drawable, num_strokes, strokes, hardness, method);
CODE
);
}
sub flip {
$blurb = <<'BLURB';
Flip the specified drawable about its center either vertically or
horizontally.
BLURB
$help = <<'HELP';
This tool flips 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 flipd by the
specified amount. The return value is the ID of the flipped 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 flipped drawable. The flip type
parameter indicates whether the flip will be applied horizontally or
vertically.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'flip_type', type => 'enum FlipType',
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};
%invoke = (
headers => [ qw("flip_tool.h" "tranform_core.h") ],
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
code => <<'CODE'
{
/* 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);
/* flip the buffer */
switch (flip_type)
{
case 0: /* horz */
new_tiles = flip_tool_flip_horz (gimage, drawable, float_tiles, -1);
break;
case 1: /* vert */
new_tiles = flip_tool_flip_vert (gimage, drawable, float_tiles, -1);
break;
}
/* 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
);
}

View File

@ -21,31 +21,38 @@
# shortcuts
sub tool_init_args {
(image => ['image', 'The image'],
drawable => ['drawable', 'The affected drawable']);
}
sub drawable_arg () {{
name => 'drawable',
type => 'drawable',
desc => 'The affected drawable',
get => &std_image_arg
}}
sub sample_merged_arg {
(sample_merged => ['boolean', 'Use the composite image, not the drawable']);
}
sub sample_merged_arg () {{
name => 'sample_merged',
type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub antialias_arg {
(antialias => ['boolean', 'Antialiasing $desc']);
}
sub antialias_arg () {{
name => 'antialias',
type => 'boolean',
desc => 'Antialiasing $desc'
}}
sub feather_select_args {
(feather => ['boolean', 'Feather option for selections'],
feather_radius => ['float', 'Radius for feather operation']);
}
sub feather_select_args () {(
{ name => 'feather', type => 'boolean',
desc => 'Feather option for selections' },
{ name => 'feather_radius', type => 'float',
desc => 'Radius for feather operation' }
)}
sub stroke_args {
(num_strokes => ['0 < int32',
'number of stroke control points (count each coordinate as
2 points)'],
strokes => ['floatarray',
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
sn.x, sn.y }']);
sub stroke_arg () {
{ name => 'strokes', type => 'floatarray',
desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
sn.x, sn.y }',
array => { desc => 'number of stroke control points (count each
coordinate as 2 points)' } }
}
# The defs
@ -64,16 +71,17 @@ HELP;
&std_pdb_misc;
%inargs = (
&tool_init_args,
pressure => ['0 <= float <= 100',
'The pressure of the airbrush strokes $desc'],
&stroke_args
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure of the airbrush strokes $desc' },
&stroke_arg
);
delete $inargs[0]->{get};
@invoke = (
'airbrush.h',
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
%invoke = (
headers => [ qw("airbrush.h") ],
code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
);
}
@ -91,35 +99,44 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
blend_mode => ['enum BlendMode',
'The type of blend: $desc'],
gradient_type => ['enum PaintMode',
'The paint application mode: $desc'],
opacity => ['0 <= float <= 100',
'The opacity of the final blend $desc'],
offset => ['0 <= float',
'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent
$desc'],
repeat => ['enum RepeatMode', 'Repeat mode: $desc'],
supersample => ['boolean', 'Do adaptive supersampling $desc'],
max_depth => ['1 <= int32 <= 9',
'Maximum recursion levels for supersampling',
'attach supersample'],
threshold => ['0 <= float <= 4',
'Supersampling threshold',
'attach supersample'],
x1 => ['float', 'The x coordinate of this blend's starting point'],
y1 => ['float', 'The y coordinate of this blend's starting point'],
x2 => ['float', 'The x coordinate of this blend's ending point'],
y2 => ['float', 'The y coordinate of this blend's ending point']
@inargs = (
&drawable_arg,
{ name => 'blend_mode', type => 'enum BlendMode',
desc => 'The type of blend: $desc' },
{ name => 'gradient_type', type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
{ name => 'opacity', type => '0 <= float <= 100',
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' },
{ name => 'repeat', type => 'enum RepeatMode',
desc => 'Repeat mode: $desc' },
{ name => 'supersample', type => 'boolean',
desc => 'Do adaptive supersampling $desc' },
{ name => 'max_depth', type => '1 <= int32 <= 9',
desc => 'Maximum recursion levels for supersampling',
cond => 'supersample' },
{ name => 'threshold', type => '0 <= float <= 4',
desc => 'Supersampling threshold',
cond => 'supersample' },
{ name => 'x1', type => 'float',
desc => "The x coordinate of this blend's starting point" },
{ name => 'y1', type => 'float',
desc => "The y coordinate of this blend's starting point" },
{ name => 'x2', type => 'float',
desc => "The x coordinate of this blend's ending point" },
{ name => 'y2', type => 'float',
desc => "The y coordinate of this blend's ending point" }
);
@invoke = (
'blend.h',
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);'
%invoke = (
headers => [ qw("blend.h") ],
code => <<'CODE'
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
CODE
);
}
@ -144,27 +161,36 @@ HELP;
&std_pdb_misc;
my $validity = 'This parameter is only valid when there is no selection in the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application. $validity";
my $validity = 'This parameter is only valid when there is no selection in
the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application.
$validity";
%inargs = (
&tool_init_args,
fill_mode => ['enum FillMode', 'The type of fill: $desc'],
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'],
opacity => ['0 <= float <= 100',
'The opacity of the final bucket fill $desc'],
threshold => ['0 <= float <= 255',
"The threshold determines how extensive the seed fill
will be. It's value is specified in terms of intensity
levels \$desc. $validity'],
&drawable_arg,
{ name => 'fill_mode', type => 'enum FillMode',
desc => 'The type of fill: $desc' },
{ name => paint_mode, type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
{ name => opacity, type => '0 <= float <= 100',
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" },
&sample_merged_arg,
x => ['float', eval qq/{\$a = 'x';"$coord";}/],
y => ['float', eval qq/{\$a = 'y';"$coord";}/]
{ name => x, type => 'float',
desc => eval qq/{\$a = 'x'; "$coord";}/ },
{ name => y, type => 'float',
desc => eval qq/{\$a = 'y';"$coord";}/ }
);
@invoke = (
'bucket_fill.h',
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);'
%invoke = (
headers => [ qw ("bucket_fill.h") ],
code => <<'CODE'
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
sample_merged, x, y);
CODE
);
}
@ -182,7 +208,7 @@ sufficiently close to the specified color (as determined by the threshold
value) are included in the selection. The antialiasing parameter allows the
final selection mask to contain intermediate values based on close misses to
the threshold bar. Feathering can be enabled optionally and is controlled with
the \"feather_radius\" parameter. If the sample_merged parameter is non-zero,
the "feather_radius" parameter. 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.
@ -190,20 +216,25 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
color => ['color', 'The color to select'],
threshold => ['0 <= int32 <= 255',
'Threshold in intensity levels $desc'],
operation => ['enum Operation', 'The selection operation: $desc'],
@inargs = (
&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' },
&antialias_arg,
&feather_select_args,
&sample_merged_arg
);
@invoke = (
'by_color_select.h',
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);'
%invoke = (
headers => [ qw("by_color_select.h") ],
code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
CODE
);
}
@ -214,9 +245,9 @@ BLURB
$help = <<'HELP'
This tool clones (copies) from the source drawable starting at the specified
source coordinates to the dest drawable. If the \"clone_type\" argument is set
source coordinates to the dest drawable. If the "clone_type" argument is set
to PATTERN-CLONE, then the current pattern is used as the source and the
\"src_drawable\" argument is ignored. Pattern cloning assumes a tileable
"src_drawable" argument is ignored. Pattern cloning assumes a tileable
pattern and mods the sum of the src coordinates and subsequent stroke offsets
with the width and height of the pattern. For image cloning, if the sum of the
src coordinates and subsequent stroke offsets exceeds the extents of the src
@ -227,18 +258,26 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
src_drawable => ['drawable', "The source drawable"],
clone_type => ['enum CloneType', 'The type of clone: $desc'],
src_x => ['float', 'The x coordinate in the source image'],
src_y => ['float', 'The y coordinate in the source image'],
&stroke_args
@inargs = (
&drawable_arg,
{ name => 'src_drawable', type => 'drawable',
desc => 'The source drawable' },
{ name => 'clone_type', type => 'enum CloneType',
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 = (
'clone.h',
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);'
%invoke = (
headers => [ qw("clone.h") ],
code => <<'CODE'
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
strokes);
CODE
);
}
@ -262,19 +301,244 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
x => ['float', 'x coordinate of upper-left corner of rectangle'],
y => ['float', 'y coordinate of upper-left corner of rectangle'],
@inargs = (
&drawable_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' },
&sample_merged_arg,
save_color => ['boolean', 'Save the color to the active palette']
{ name => 'save_color', type => 'boolean',
desc => 'Save the color to the active palette' }
);
%outargs = (
color => ['color', 'The return color']
@outargs = (
{ name => 'color', type => 'color',
desc => 'The return color' }
);
%invoke = (
'color_picker.h',
'
headers => [ qw("color_picker.h") ],
code => <<'CODE'
{
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];
color[GREEN_PIX] = col_value[GREEN_PIX];
color[BLUE_PIX] = col_value[BLUE_PIX];
}
}
CODE
);
}
sub convolve {
$blurb = 'Convolve (Blur, Sharpen) using the current brush.';
$help = <<'HELP';
This tool convolves the specified drawable with either a sharpening or blurring
kernel. The pressure parameter controls the magnitude of the operation. Like
the paintbrush, this tool linearly interpolates between the specified stroke
coordinates.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure: $desc' },
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
desc => 'Convolve type: $desc' },
&stroke_arg
);
%invoke = (
headers => [ qw("convolve.h") ],
code => 'convolve_non_gui (drawable, pressure, num_strokes, strokes);'
);
}
sub crop {
$blurb = 'Crop the image to the specified extents.';
$help = <<'HELP';
This procedure crops the image so that it's new width and height are equal to
the supplied parameters. Offsets are also provided which describe the position
of the previous image's content. All channels and layers within the image are
cropped to the new image extents; this includes the image selection mask. If
any parameters are out of range, an error is returned.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'new_width', type => '0 < int32',
desc => 'New image width: (0 < new_width <= width)' },
{ name => 'new_height', type => '0 < int32',
desc => 'New image height: (0 < new_height <= height)' },
{ name => 'offx', type => '0 <= int32',
desc => 'x offset: (0 <= offx <= (width - new_width))' },
{ name => 'offy', type => '0 <= int32',
desc => 'y offset: (0 <= offy <= (height - new_height))' }
);
%invoke = (
headers => [ qw("crop.h") ],
code => <<'CODE'
{
if (new_width > gimage->width ||
new_height > gimage->height ||
offx > (gimage->width - new_width) ||
offy > (gimage->height - new_height)
success = FALSE;
else
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
}
CODE
);
}
sub ellipse_select {
$blurb = 'Create an elliptical selection over the specified image.';
$help = <<'HELP';
This tool creates an elliptical selection over the specified image. The
elliptical region can be either added to, subtracted from, or replace the
contents of the previous selection mask. If antialiasing is turned on, the
edges of the elliptical region will contain intermediate values which give the
appearance of a sharper, less pixelized edge. This should be set as TRUE most
of the time. 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
@inargs = (
&std_image_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of ellipse bounding box' },
{ 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' },
{ name => 'height', type => '0 < float',
desc => 'The height of the ellipse: $desc' },
{ name => 'operation', 'enum Selection',
desc => 'The selection operation: $desc' },
&antialias_arg,
&feather_args
);
%invoke = (
headers => [ qw("ellipse_select.h") ],
code => <<'CODE'
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
feather, feather_radius);
CODE
);
}
sub eraser {
$blurb = 'Erase using the current brush.';
$help = <<'HELP';
This tool erases using the current brush mask. If the specified drawable
contains an alpha channel, then the erased pixels will become transparent.
Otherwise, the eraser tool replaces the contents of the drawable with the
background color. Like paintbrush, this tool linearly interpolates between the
specified stroke coordinates.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
&stroke_arg,
{ name => 'hardness', type => 'enum EraserHardness',
desc => '$desc' }
{ name => 'method', type => 'enum EraserMethod',
desc => '$desc' }
);
%invoke = (
headers => [ qw("eraser.h") ],
code => <<'CODE'
eraser_non_gui (drawable, num_strokes, strokes, hardness, method);
CODE
);
}
sub flip {
$blurb = <<'BLURB';
Flip the specified drawable about its center either vertically or
horizontally.
BLURB
$help = <<'HELP';
This tool flips 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 flipd by the
specified amount. The return value is the ID of the flipped 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 flipped drawable. The flip type
parameter indicates whether the flip will be applied horizontally or
vertically.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'flip_type', type => 'enum FlipType',
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};
%invoke = (
headers => [ qw("flip_tool.h" "tranform_core.h") ],
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
code => <<'CODE'
{
/* 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);
/* flip the buffer */
switch (flip_type)
{
case 0: /* horz */
new_tiles = flip_tool_flip_horz (gimage, drawable, float_tiles, -1);
break;
case 1: /* vert */
new_tiles = flip_tool_flip_vert (gimage, drawable, float_tiles, -1);
break;
}
/* 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
);
}

View File

@ -21,31 +21,38 @@
# shortcuts
sub tool_init_args {
(image => ['image', 'The image'],
drawable => ['drawable', 'The affected drawable']);
}
sub drawable_arg () {{
name => 'drawable',
type => 'drawable',
desc => 'The affected drawable',
get => &std_image_arg
}}
sub sample_merged_arg {
(sample_merged => ['boolean', 'Use the composite image, not the drawable']);
}
sub sample_merged_arg () {{
name => 'sample_merged',
type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub antialias_arg {
(antialias => ['boolean', 'Antialiasing $desc']);
}
sub antialias_arg () {{
name => 'antialias',
type => 'boolean',
desc => 'Antialiasing $desc'
}}
sub feather_select_args {
(feather => ['boolean', 'Feather option for selections'],
feather_radius => ['float', 'Radius for feather operation']);
}
sub feather_select_args () {(
{ name => 'feather', type => 'boolean',
desc => 'Feather option for selections' },
{ name => 'feather_radius', type => 'float',
desc => 'Radius for feather operation' }
)}
sub stroke_args {
(num_strokes => ['0 < int32',
'number of stroke control points (count each coordinate as
2 points)'],
strokes => ['floatarray',
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
sn.x, sn.y }']);
sub stroke_arg () {
{ name => 'strokes', type => 'floatarray',
desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
sn.x, sn.y }',
array => { desc => 'number of stroke control points (count each
coordinate as 2 points)' } }
}
# The defs
@ -64,16 +71,17 @@ HELP;
&std_pdb_misc;
%inargs = (
&tool_init_args,
pressure => ['0 <= float <= 100',
'The pressure of the airbrush strokes $desc'],
&stroke_args
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure of the airbrush strokes $desc' },
&stroke_arg
);
delete $inargs[0]->{get};
@invoke = (
'airbrush.h',
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
%invoke = (
headers => [ qw("airbrush.h") ],
code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
);
}
@ -91,35 +99,44 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
blend_mode => ['enum BlendMode',
'The type of blend: $desc'],
gradient_type => ['enum PaintMode',
'The paint application mode: $desc'],
opacity => ['0 <= float <= 100',
'The opacity of the final blend $desc'],
offset => ['0 <= float',
'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent
$desc'],
repeat => ['enum RepeatMode', 'Repeat mode: $desc'],
supersample => ['boolean', 'Do adaptive supersampling $desc'],
max_depth => ['1 <= int32 <= 9',
'Maximum recursion levels for supersampling',
'attach supersample'],
threshold => ['0 <= float <= 4',
'Supersampling threshold',
'attach supersample'],
x1 => ['float', 'The x coordinate of this blend's starting point'],
y1 => ['float', 'The y coordinate of this blend's starting point'],
x2 => ['float', 'The x coordinate of this blend's ending point'],
y2 => ['float', 'The y coordinate of this blend's ending point']
@inargs = (
&drawable_arg,
{ name => 'blend_mode', type => 'enum BlendMode',
desc => 'The type of blend: $desc' },
{ name => 'gradient_type', type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
{ name => 'opacity', type => '0 <= float <= 100',
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' },
{ name => 'repeat', type => 'enum RepeatMode',
desc => 'Repeat mode: $desc' },
{ name => 'supersample', type => 'boolean',
desc => 'Do adaptive supersampling $desc' },
{ name => 'max_depth', type => '1 <= int32 <= 9',
desc => 'Maximum recursion levels for supersampling',
cond => 'supersample' },
{ name => 'threshold', type => '0 <= float <= 4',
desc => 'Supersampling threshold',
cond => 'supersample' },
{ name => 'x1', type => 'float',
desc => "The x coordinate of this blend's starting point" },
{ name => 'y1', type => 'float',
desc => "The y coordinate of this blend's starting point" },
{ name => 'x2', type => 'float',
desc => "The x coordinate of this blend's ending point" },
{ name => 'y2', type => 'float',
desc => "The y coordinate of this blend's ending point" }
);
@invoke = (
'blend.h',
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);'
%invoke = (
headers => [ qw("blend.h") ],
code => <<'CODE'
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
CODE
);
}
@ -144,27 +161,36 @@ HELP;
&std_pdb_misc;
my $validity = 'This parameter is only valid when there is no selection in the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application. $validity";
my $validity = 'This parameter is only valid when there is no selection in
the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application.
$validity";
%inargs = (
&tool_init_args,
fill_mode => ['enum FillMode', 'The type of fill: $desc'],
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'],
opacity => ['0 <= float <= 100',
'The opacity of the final bucket fill $desc'],
threshold => ['0 <= float <= 255',
"The threshold determines how extensive the seed fill
will be. It's value is specified in terms of intensity
levels \$desc. $validity'],
&drawable_arg,
{ name => 'fill_mode', type => 'enum FillMode',
desc => 'The type of fill: $desc' },
{ name => paint_mode, type => 'enum PaintMode',
desc => 'The paint application mode: $desc' },
{ name => opacity, type => '0 <= float <= 100',
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" },
&sample_merged_arg,
x => ['float', eval qq/{\$a = 'x';"$coord";}/],
y => ['float', eval qq/{\$a = 'y';"$coord";}/]
{ name => x, type => 'float',
desc => eval qq/{\$a = 'x'; "$coord";}/ },
{ name => y, type => 'float',
desc => eval qq/{\$a = 'y';"$coord";}/ }
);
@invoke = (
'bucket_fill.h',
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);'
%invoke = (
headers => [ qw ("bucket_fill.h") ],
code => <<'CODE'
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
sample_merged, x, y);
CODE
);
}
@ -182,7 +208,7 @@ sufficiently close to the specified color (as determined by the threshold
value) are included in the selection. The antialiasing parameter allows the
final selection mask to contain intermediate values based on close misses to
the threshold bar. Feathering can be enabled optionally and is controlled with
the \"feather_radius\" parameter. If the sample_merged parameter is non-zero,
the "feather_radius" parameter. 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.
@ -190,20 +216,25 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
color => ['color', 'The color to select'],
threshold => ['0 <= int32 <= 255',
'Threshold in intensity levels $desc'],
operation => ['enum Operation', 'The selection operation: $desc'],
@inargs = (
&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' },
&antialias_arg,
&feather_select_args,
&sample_merged_arg
);
@invoke = (
'by_color_select.h',
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);'
%invoke = (
headers => [ qw("by_color_select.h") ],
code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
CODE
);
}
@ -214,9 +245,9 @@ BLURB
$help = <<'HELP'
This tool clones (copies) from the source drawable starting at the specified
source coordinates to the dest drawable. If the \"clone_type\" argument is set
source coordinates to the dest drawable. If the "clone_type" argument is set
to PATTERN-CLONE, then the current pattern is used as the source and the
\"src_drawable\" argument is ignored. Pattern cloning assumes a tileable
"src_drawable" argument is ignored. Pattern cloning assumes a tileable
pattern and mods the sum of the src coordinates and subsequent stroke offsets
with the width and height of the pattern. For image cloning, if the sum of the
src coordinates and subsequent stroke offsets exceeds the extents of the src
@ -227,18 +258,26 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
src_drawable => ['drawable', "The source drawable"],
clone_type => ['enum CloneType', 'The type of clone: $desc'],
src_x => ['float', 'The x coordinate in the source image'],
src_y => ['float', 'The y coordinate in the source image'],
&stroke_args
@inargs = (
&drawable_arg,
{ name => 'src_drawable', type => 'drawable',
desc => 'The source drawable' },
{ name => 'clone_type', type => 'enum CloneType',
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 = (
'clone.h',
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);'
%invoke = (
headers => [ qw("clone.h") ],
code => <<'CODE'
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
strokes);
CODE
);
}
@ -262,19 +301,244 @@ HELP
&std_pdb_misc;
%inargs = (
&tool_init_args,
x => ['float', 'x coordinate of upper-left corner of rectangle'],
y => ['float', 'y coordinate of upper-left corner of rectangle'],
@inargs = (
&drawable_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' },
&sample_merged_arg,
save_color => ['boolean', 'Save the color to the active palette']
{ name => 'save_color', type => 'boolean',
desc => 'Save the color to the active palette' }
);
%outargs = (
color => ['color', 'The return color']
@outargs = (
{ name => 'color', type => 'color',
desc => 'The return color' }
);
%invoke = (
'color_picker.h',
'
headers => [ qw("color_picker.h") ],
code => <<'CODE'
{
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];
color[GREEN_PIX] = col_value[GREEN_PIX];
color[BLUE_PIX] = col_value[BLUE_PIX];
}
}
CODE
);
}
sub convolve {
$blurb = 'Convolve (Blur, Sharpen) using the current brush.';
$help = <<'HELP';
This tool convolves the specified drawable with either a sharpening or blurring
kernel. The pressure parameter controls the magnitude of the operation. Like
the paintbrush, this tool linearly interpolates between the specified stroke
coordinates.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'pressure', type => '0 <= float <= 100',
desc => 'The pressure: $desc' },
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
desc => 'Convolve type: $desc' },
&stroke_arg
);
%invoke = (
headers => [ qw("convolve.h") ],
code => 'convolve_non_gui (drawable, pressure, num_strokes, strokes);'
);
}
sub crop {
$blurb = 'Crop the image to the specified extents.';
$help = <<'HELP';
This procedure crops the image so that it's new width and height are equal to
the supplied parameters. Offsets are also provided which describe the position
of the previous image's content. All channels and layers within the image are
cropped to the new image extents; this includes the image selection mask. If
any parameters are out of range, an error is returned.
HELP
&std_pdb_misc;
@inargs = (
&std_image_arg,
{ name => 'new_width', type => '0 < int32',
desc => 'New image width: (0 < new_width <= width)' },
{ name => 'new_height', type => '0 < int32',
desc => 'New image height: (0 < new_height <= height)' },
{ name => 'offx', type => '0 <= int32',
desc => 'x offset: (0 <= offx <= (width - new_width))' },
{ name => 'offy', type => '0 <= int32',
desc => 'y offset: (0 <= offy <= (height - new_height))' }
);
%invoke = (
headers => [ qw("crop.h") ],
code => <<'CODE'
{
if (new_width > gimage->width ||
new_height > gimage->height ||
offx > (gimage->width - new_width) ||
offy > (gimage->height - new_height)
success = FALSE;
else
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
}
CODE
);
}
sub ellipse_select {
$blurb = 'Create an elliptical selection over the specified image.';
$help = <<'HELP';
This tool creates an elliptical selection over the specified image. The
elliptical region can be either added to, subtracted from, or replace the
contents of the previous selection mask. If antialiasing is turned on, the
edges of the elliptical region will contain intermediate values which give the
appearance of a sharper, less pixelized edge. This should be set as TRUE most
of the time. 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
@inargs = (
&std_image_arg,
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of ellipse bounding box' },
{ 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' },
{ name => 'height', type => '0 < float',
desc => 'The height of the ellipse: $desc' },
{ name => 'operation', 'enum Selection',
desc => 'The selection operation: $desc' },
&antialias_arg,
&feather_args
);
%invoke = (
headers => [ qw("ellipse_select.h") ],
code => <<'CODE'
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
feather, feather_radius);
CODE
);
}
sub eraser {
$blurb = 'Erase using the current brush.';
$help = <<'HELP';
This tool erases using the current brush mask. If the specified drawable
contains an alpha channel, then the erased pixels will become transparent.
Otherwise, the eraser tool replaces the contents of the drawable with the
background color. Like paintbrush, this tool linearly interpolates between the
specified stroke coordinates.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
&stroke_arg,
{ name => 'hardness', type => 'enum EraserHardness',
desc => '$desc' }
{ name => 'method', type => 'enum EraserMethod',
desc => '$desc' }
);
%invoke = (
headers => [ qw("eraser.h") ],
code => <<'CODE'
eraser_non_gui (drawable, num_strokes, strokes, hardness, method);
CODE
);
}
sub flip {
$blurb = <<'BLURB';
Flip the specified drawable about its center either vertically or
horizontally.
BLURB
$help = <<'HELP';
This tool flips 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 flipd by the
specified amount. The return value is the ID of the flipped 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 flipped drawable. The flip type
parameter indicates whether the flip will be applied horizontally or
vertically.
HELP
&std_pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'flip_type', type => 'enum FlipType',
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};
%invoke = (
headers => [ qw("flip_tool.h" "tranform_core.h") ],
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
code => <<'CODE'
{
/* 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);
/* flip the buffer */
switch (flip_type)
{
case 0: /* horz */
new_tiles = flip_tool_flip_horz (gimage, drawable, float_tiles, -1);
break;
case 1: /* vert */
new_tiles = flip_tool_flip_vert (gimage, drawable, float_tiles, -1);
break;
}
/* 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
);
}

View File

@ -111,12 +111,7 @@ require 'pdb.pl';
require 'util.pl';
# Squash whitespace into just single spaces between words
sub trimspace {
my $val = shift;
$$val =~ s/[\n\s]+/ /g;
$$val =~ s/^ //;
$$val =~ s/ $//;
}
sub trimspace { for (${$_[0]}) { s/[\n\s]+/ /g; s/^ //; s/ $//; } }
# Trim spaces and escape quotes C-style
sub nicetext {
@ -141,6 +136,37 @@ sub nicelist {
foreach (@$list) { &trimspace(\$_) }
}
# Add args for array lengths
sub arrayexpand {
my $args = shift;
my $newargs;
foreach (@$$args) {
if (exists $_->{array}) {
my $arg = $_->{array};
$arg->{name} = 'num_' . $_->{name} unless exists $arg->{name};
# We can't have negative lengths, but let them set a min number
unless (exists $arg->{type}) {
$arg->{type} = '0 < int32';
}
elsif ($arg->{type} !~ /^\s*\d+\s*</) {
$arg->{type} = '0 < ' . $arg->{type};
}
$arg->{num} = 1;
push @$newargs, $arg;
}
push @$newargs, $_;
}
$$args = $newargs;
}
# Post-process each pdb entry
while ((undef, $entry) = each %pdb) {
&nicetext(\$entry->{blurb});
@ -148,16 +174,24 @@ while ((undef, $entry) = each %pdb) {
&nicetext(\$entry->{author});
&nicetext(\$entry->{copyright});
&nicetext(\$entry->{date});
&arrayexpand(\$entry->{inargs}) if exists $entry->{inargs};
&arrayexpand(\$entry->{outargs}) if exists $entry->{outargs};
&niceargs($entry->{inargs}) if exists $entry->{inargs};
&niceargs($entry->{outargs}) if exists $entry->{outargs};
&nicelist($entry->{invoke}{headers}) if exists $entry->{invoke}{headers};
&nicelist($entry->{globals}) if exists $entry->{globals}
&nicelist($entry->{globals}) if exists $entry->{globals};
$entry->{invoke}{success} = 'TRUE' unless exists $entry->{invoke}{success};
}
# Generate code from the modules
my $didstuff;
while (@ARGV) {
my $type = shift @ARGV;
print "\nProcessing $type...\n";
if (exists $gen{$type}) {

View File

@ -1,18 +1,15 @@
# Boilerplate PDB stuff
sub std_pdb_misc {
$author = 'Spencer Kimball & Peter Mattis';
$copyright = $author;
$author = $copyright = 'Spencer Kimball & Peter Mattis';
$date = '1995-1996';
}
sub std_image_arg () {
{
name => 'image',
type => 'image',
desc => 'The image',
alias => 'gimage'
}
}
sub std_image_arg () {{
name => 'image',
type => 'image',
desc => 'The image',
alias => 'gimage'
}}
1;

View File

@ -17,14 +17,16 @@
package Gimp::CodeGen::util;
use File::Copy cp;
use File::Compare cmp;
use File::Copy 'cp';
use File::Compare 'cmp';
$DEBUG_OUTPUT = 1;
$FILE_EXT = ".tmp.$$";
sub write_file {
my $file = shift; my $realfile = $file;
$realfile =~ s/\.tmp\.\d+$//;
$realfile =~ s/$FILE_EXT//;
if (-e $realfile) {
if (cmp($realfile, $file)) {
cp($realfile, "$realfile~") if $DEBUG_OUTPUT;