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 # 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 # 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 # 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; *arg_vname = \&Gimp::CodeGen::pdb::arg_vname;
*write_file = \&Gimp::CodeGen::util::write_file; *write_file = \&Gimp::CodeGen::util::write_file;
*FILE_EXT = \$Gimp::CodeGen::util::FILE_EXT;
%testmap = (
'<' => '>',
'>' => '<',
'<=' => '>=',
'>=' => '<='
);
sub declare_args { sub declare_args {
my $proc = shift; my $proc = shift;
my $out = shift; my $out = shift;
my $result = ""; my $result = "";
foreach (@_) { foreach (@_) {
my @args = @{$proc->{$_}} if exists $proc->{$_}; my @args = @{$proc->{$_}} if exists $proc->{$_};
foreach (@args) { foreach (@args) {
my $arg = $arg_types{(&arg_parse($_->{type}))[0]}; 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 .= ' ' x 2;
$result .= $arg->{type} . &arg_vname($_) . ";\n"; $result .= $arg->{type} . &arg_vname($_) . ";\n";
if (exists $arg->{id_headers}) { if (exists $arg->{id_headers}) {
foreach (@{$arg->{id_headers}}) { foreach (@{$arg->{id_headers}}) {
$out->{headers}->{$_}++; $out->{headers}->{$_}++;
} }
} }
if (exists $_->{get}) {
$result .= ' ' x 2;
$result .= $arg_types{$_->{get}->{type}}->{type};
$result .= &arg_vname($_->{get}) . ";\n";
}
} }
} }
} }
$result; $result;
} }
sub make_args { sub make_args {
my $proc = shift; my $proc = shift;
my $result = ""; my $result = "";
my $once; my $once;
foreach (@_) { foreach (@_) {
my @args = @{$proc->{$_}} if exists $proc->{$_}; my @args = @{$proc->{$_}} if exists $proc->{$_};
if (scalar @args) { if (scalar @args) {
$result .= "\nstatic ProcArg $proc->{name}_${_}[] ="; $result .= "\nstatic ProcArg $proc->{name}_${_}[] =";
$result .= "\n{\n"; $result .= "\n{\n";
foreach my $arg (@{$proc->{$_}}) { foreach my $arg (@{$proc->{$_}}) {
my ($type) = &arg_parse($arg->{type}); my ($type) = &arg_parse($arg->{type});
$result .= ' ' x 2 . "{\n";
$result .= ' ' x 4; $result .= <<CODE;
$result .= 'PDB_' . $arg_types{$type}->{name} . ",\n"; {
$result .= ' ' x 4; PDB_$arg_types{$type}->{name},
$result .= qq/"$arg->{name}",\n/; "$arg->{name}",
$result .= ' ' x 4; "$arg->{desc}"
$result .= qq/"$arg->{desc}"\n/; },
$result .= ' ' x 2 . "},\n"; CODE
} }
$result =~ s/,\n$/\n/; $result =~ s/,\n$/\n/;
$result .= "};\n"; $result .= "};\n";
} }
} }
$result; $result;
} }
sub marshal_inargs { sub marshal_inargs {
my $proc = shift; my $proc = shift;
my $result = ""; my $result = "";
my %decls; my %decls;
my $argc = 0; my $argc = 0;
my @inargs = @{$proc->{inargs}} if exists $proc->{inargs}; my @inargs = @{$proc->{inargs}} if exists $proc->{inargs};
foreach (@inargs) { foreach (@inargs) {
my($pdbtype, @typeinfo) = &arg_parse($_->{type}); my($pdbtype, @typeinfo) = &arg_parse($_->{type});
my $arg = $arg_types{$pdbtype}; my $arg = $arg_types{$pdbtype};
my $type = &arg_ptype($arg); my $type = &arg_ptype($arg);
my $var = &arg_vname($_); my $var = &arg_vname($_);
$result .= ' ' x 2;
$result .= "if (success)\n" . ' ' x 4 if $success;
if (exists $arg->{id_func}) { if (exists $arg->{id_func}) {
$decls{$type}++; my $code = "";
$result .= "{\n" . ' ' x 6 if $success;
$result .= "${type}_value = args[$argc].value.pdb_$type;\n"; $code .= <<CODE;
$result .= ' ' x 4 if $success; if (($var = $arg->{id_func} (args[$argc].value.pdb_$type)) == NULL)
$result .= ' ' x 2; success = FALSE;
$result .= "if (($var = "; CODE
$result .= "$arg->{id_func} (${type}_value)) == NULL)\n";
$result .= ' ' x 4 unless $success; $code .= <<CODE if exists $_->{get};
$result .= "\t" if $success; else
$result .= "success = FALSE;\n"; @{[ &arg_vname($_->{get}) ]} = @{[ eval qq/"$arg->{$_->{get}->{type}}"/ ]};
$result .= ' ' x 4 . "}\n" if $success; CODE
if ($success) {
$code =~ s/^/' ' x 4/meg;
$code =~ s/^ {8}/\t/mg;
$result .= "{\n" . $code . ' ' x 4 . "}\n";
}
else {
$result .= $code;
}
$success = 1; $success = 1;
} }
else { else {
@ -107,65 +149,82 @@ sub marshal_inargs {
# FIXME: implement this # FIXME: implement this
} }
elsif ($pdbtype eq 'boolean') { elsif ($pdbtype eq 'boolean') {
$result .= "$var = "; $result .= ' ' x 2 . "$var = ";
$result .= "(args[$argc].value.pdb_$type) ? TRUE : FALSE;\n"; $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";
} }
else { else {
my $cast = ""; my $cast = "";
$cast = " ($arg->{type})" if $type eq "pointer"; $cast = " ($arg->{type})" if $type eq "pointer";
$cast = " ($arg->{type})" if $arg->{type} =~ /int(16|8)$/; $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"; $argc++; $result .= "\n";
} }
chomp $result if !$success && $argc == 1;
my $decls; $result = "\n" . $result if $result;
foreach (keys %decls) { $decls .= ' ' x 2 . "$_ ${_}_value;\n" }
$result = $decls . "\n" . $result if $decls;
$result and $result = "\n" . $result unless $decls;
$result; $result;
} }
sub marshal_outargs { sub marshal_outargs {
my $proc = shift; my $proc = shift;
my $result = <<CODE; my $result = <<CODE;
return_args = procedural_db_return_args (\&$proc->{name}_proc, success); return_args = procedural_db_return_args (\&$proc->{name}_proc, success);
CODE CODE
my $argc = 0; my $argc = 0;
my @outargs = @{$proc->{outargs}} if exists $proc->{outargs}; my @outargs = @{$proc->{outargs}} if exists $proc->{outargs};
if (scalar @outargs) { if (scalar @outargs) {
my $outargs = ""; my $outargs = "";
foreach (@{$proc->{outargs}}) { foreach (@{$proc->{outargs}}) {
my ($pdbtype) = &arg_parse($_->{type}); my ($pdbtype) = &arg_parse($_->{type});
my $arg = $arg_types{$pdbtype}; my $arg = $arg_types{$pdbtype};
my $type = &arg_ptype($arg); my $type = &arg_ptype($arg);
my $var = &arg_vname($_); my $var = &arg_vname($_);
$argc++; $outargs .= ' ' x 2; $argc++; $outargs .= ' ' x 2;
if (exists $arg->{id_ret_func}) { if (exists $arg->{id_ret_func}) {
$outargs .= "return_args[$argc].value.pdb_$type = "; $var = eval qq/"$arg->{id_ret_func}"/;
$outargs .= eval qq/"$arg->{id_ret_func}"/;
$outargs .= ";\n";
}
else {
$outargs .= "return_args[$argc].value.pdb_$type = $var;\n";
} }
$outargs .= "return_args[$argc].value.pdb_$type = $var;\n";
} }
$outargs =~ s/^/' ' x 2/meg if $success; $outargs =~ s/^/' ' x 2/meg if $success;
$outargs =~ s/^/' ' x 2/meg if $success && $argc > 1; $outargs =~ s/^/' ' x 2/meg if $success && $argc > 1;
$result .= "\n" if $success || $argc > 1; $result .= "\n" if $success || $argc > 1;
$result .= ' ' x 2 . "if (success)\n" if $success; $result .= ' ' x 2 . "if (success)\n" if $success;
$result .= ' ' x 4 . "{\n" if $success && $argc > 1; $result .= ' ' x 4 . "{\n" if $success && $argc > 1;
@ -176,6 +235,7 @@ CODE
else { else {
$result =~ s/_args =//; $result =~ s/_args =//;
} }
$result =~ s/, success\);$/, TRUE);/m unless $success; $result =~ s/, success\);$/, TRUE);/m unless $success;
$result; $result;
} }
@ -227,8 +287,10 @@ CODE
$invoker .= "\n" if $invoker && $invoker !~ /\n\n/s; $invoker .= "\n" if $invoker && $invoker !~ /\n\n/s;
my $code = $proc->{invoke}->{code}; my $code = $proc->{invoke}->{code};
chomp $code; chomp $code;
$code =~ s/\t/' ' x 8/eg; $code =~ s/\t/' ' x 8/eg;
if ($code =~ /^\s*\{\s*\n.*\n\s*\}\s*$/s && !$success) { if ($code =~ /^\s*\{\s*\n.*\n\s*\}\s*$/s && !$success) {
$code =~ s/^\s*\{\s*\n//s; $code =~ s/^\s*\{\s*\n//s;
$code =~ s/\n\s*}\s*$//s; $code =~ s/\n\s*}\s*$//s;
@ -242,7 +304,11 @@ CODE
$code = ' ' x 2 . "if (success)\n" . $code if $success; $code = ' ' x 2 . "if (success)\n" . $code if $success;
$success = ($code =~ /success =/) unless $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} .= $invoker . $code . "\n";
$out->{code} .= "\n" if $code =~ /\n/s || $invoker; $out->{code} .= "\n" if $code =~ /\n/s || $invoker;
$out->{code} .= &marshal_outargs($proc) . "}\n"; $out->{code} .= &marshal_outargs($proc) . "}\n";
@ -290,7 +356,7 @@ CODE
GPL 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"; open INTERNAL, "> $internal" or die "Can't open $cmdfile: $!\n";
print INTERNAL $gpl; print INTERNAL $gpl;
my $guard = "__INTERNAL_PROCS_H__"; my $guard = "__INTERNAL_PROCS_H__";
@ -310,7 +376,7 @@ HEADER
foreach $group (@main::groups) { foreach $group (@main::groups) {
my $out = $out{$group}; 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"; open CFILE, "> $cfile" or die "Can't open $cmdfile: $!\n";
print CFILE $gpl; print CFILE $gpl;
foreach my $header (sort keys %{$out->{headers}}) { foreach my $header (sort keys %{$out->{headers}}) {
@ -341,7 +407,7 @@ HEADER
$pcount += $out->{pcount}; $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"; open INTERNAL, "> $internal" or die "Can't open $cmdfile: $!\n";
print INTERNAL $gpl; print INTERNAL $gpl;
print INTERNAL qq/#include "app_procs.h"\n\n/; 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. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Modify this list for the groups to parse in the pdb directory # Modify this list for the groups to parse in the pdb directory
@groups = qw(gdisplay edit floating_sel undo palette gradients convert @groups = qw(gdisplay edit floating_sel undo palette gradient
channel_ops); convert channel_ops);

View File

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

View File

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

View File

@ -35,7 +35,7 @@ HELP
@inargs = ( @inargs = (
{ name => 'drawable', type => 'drawable', { 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', { name => 'wrap_around', type => 'boolean',
desc => 'wrap image around or fill vacated regions' }, desc => 'wrap image around or fill vacated regions' },
{ name => 'fill_type', type => 'enum GimpOffsetType', { name => 'fill_type', type => 'enum GimpOffsetType',

View File

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

View File

@ -36,7 +36,7 @@ HELP
@outargs = ( @outargs = (
{ name => 'display', type => 'display', { name => 'display', type => 'display',
desc => 'The new display' } desc => 'The new display', alias => 'gdisp' }
); );
%invoke = ( %invoke = (
@ -47,7 +47,7 @@ HELP
if (gimage->layers == NULL) if (gimage->layers == NULL)
success = FALSE; success = FALSE;
else else
success = ((display = gdisplay_new (gimage, scale)) != NULL); success = ((gdisp = gdisplay_new (gimage, scale)) != NULL);
} }
CODE CODE
); );
@ -65,12 +65,12 @@ HELP
@inargs = ( @inargs = (
{ name => 'display', type => 'display', { name => 'display', type => 'display',
desc => 'The display to delete' } desc => 'The display to delete', alias => 'gdisp' }
); );
%invoke = ( %invoke = (
headers => [ qw("gdisplay.h") ], 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> # "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub pdb_misc { sub pdb_misc {
$author = 'Federico Mena Quintero'; $author = $copyright = 'Federico Mena Quintero';
$copyright = $author;
$date = '1997'; $date = '1997';
} }
@ -35,11 +34,11 @@ HELP
&pdb_misc; &pdb_misc;
@outargs = ( @outargs = (
{ name => 'num_gradients', type => 'int32',
desc => 'The number of loaded gradients' },
{ name => 'gradient_names', type => 'stringarray', { name => 'gradient_names', type => 'stringarray',
desc => 'The list of gradient names', alias => 'gradients', 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 = ( %invoke = (
@ -47,9 +46,10 @@ HELP
vars => ['gradient_t *grad', 'GSList *list', 'int i = 0'], vars => ['gradient_t *grad', 'GSList *list', 'int i = 0'],
code => <<'CODE' 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) while (list)
{ {
grad = list->data; grad = list->data;
@ -71,17 +71,14 @@ HELP
&pdb_misc; &pdb_misc;
@outargs = ( @outargs = (
{ { name => 'name', type => 'string',
name => 'name', desc => 'The name of the active gradient',
type => 'string', alias => 'g_strdup (curr_gradient->name)', no_declare => 1 }
desc => 'The name of the active gradient',
alias => 'g_strdup (curr_gradient->name)', no_declare => 1
}
); );
%invoke = ( %invoke = (
headers => [ qw("gradient.h") ], headers => [ qw("gradient.h") ],
code => 'success = (curr_gradient != NULL);' code => 'success = curr_gradient != NULL;'
); );
} }
@ -104,56 +101,24 @@ HELP
); );
%invoke = ( %invoke = (
success => 'FALSE',
headers => [ qw("gradient.h") ], headers => [ qw("gradient.h") ],
vars => ['gradient_t *grad', 'GSList *list'], code => 'success = grad_set_grad_to_name (name);'
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
); );
} }
sub sample_num_arg { sub sample_num_arg {
{ name => 'num_samples', type => 'int32', { name => 'num_samples', type => $_[0] . 'int32',
desc => 'The number of samples to take', alias => 'i' } desc => 'The number of samples to take', alias => 'i' }
} }
sub sample_outargs { sub sample_outargs {
@outargs = ( @outargs = (
{ name => 'array_length', type => 'int32',
desc => 'Length of the color_samples array (4 * num_samples)' },
{ name => 'color_samples', type => 'floatarray', { name => 'color_samples', type => 'floatarray',
desc => 'Color samples: { R1, G1, B1, A1, ..., Rn, Gn, Bn, An }', 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; &pdb_misc;
@inargs = ( &sample_num_arg ); @inargs = ( &sample_num_arg('2 <= ') );
&sample_outargs; &sample_outargs;
%invoke = ( %invoke = (
@ -179,29 +144,24 @@ HELP
vars => ['gdouble pos, delta', 'gdouble r, g, b, a', 'gdouble *pv'], vars => ['gdouble pos, delta', 'gdouble r, g, b, a', 'gdouble *pv'],
code => <<'CODE' 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; grad_get_color_at(pos, &r, &g, &b, &a);
delta = 1.0 / (i - 1);
array_length = i * 4; *pv++ = r;
*pv++ = g;
*pv++ = b;
*pv++ = a;
pv = color_samples = g_new (gdouble, array_length); pos += delta;
while (i--)
{
grad_get_color_at(pos, &r, &g, &b, &a);
*pv++ = r;
*pv++ = g;
*pv++ = b;
*pv++ = a;
pos += delta;
}
} }
else
success = FALSE;
} }
CODE CODE
); );
@ -222,12 +182,12 @@ HELP
&pdb_misc; &pdb_misc;
@inargs = ( @inargs = (
&sample_num_arg,
{ {
name => 'positions', name => 'positions',
type => 'floatarray', type => 'floatarray',
desc => 'The list of positions to sample along the gradient', 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'], vars => ['gdouble r, g, b, a', 'gdouble *pv'],
code => <<'CODE' 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--) pos++;
{
grad_get_color_at(*pos, &r, &g, &b, &a);
*pv++ = r;
*pv++ = g;
*pv++ = b;
*pv++ = a;
pos++;
}
} }
else
success = FALSE;
} }
CODE 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 # shortcuts
sub tool_init_args { sub drawable_arg () {{
(image => ['image', 'The image'], name => 'drawable',
drawable => ['drawable', 'The affected drawable']); type => 'drawable',
} desc => 'The affected drawable',
get => &std_image_arg
}}
sub sample_merged_arg { sub sample_merged_arg () {{
(sample_merged => ['boolean', 'Use the composite image, not the drawable']); name => 'sample_merged',
} type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub antialias_arg { sub antialias_arg () {{
(antialias => ['boolean', 'Antialiasing $desc']); name => 'antialias',
} type => 'boolean',
desc => 'Antialiasing $desc'
}}
sub feather_select_args { sub feather_select_args () {(
(feather => ['boolean', 'Feather option for selections'], { name => 'feather', type => 'boolean',
feather_radius => ['float', 'Radius for feather operation']); desc => 'Feather option for selections' },
} { name => 'feather_radius', type => 'float',
desc => 'Radius for feather operation' }
)}
sub stroke_args { sub stroke_arg () {
(num_strokes => ['0 < int32', { name => 'strokes', type => 'floatarray',
'number of stroke control points (count each coordinate as desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
2 points)'], sn.x, sn.y }',
strokes => ['floatarray', array => { desc => 'number of stroke control points (count each
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ..., coordinate as 2 points)' } }
sn.x, sn.y }']);
} }
# The defs # The defs
@ -64,16 +71,17 @@ HELP;
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
pressure => ['0 <= float <= 100', { name => 'pressure', type => '0 <= float <= 100',
'The pressure of the airbrush strokes $desc'], desc => 'The pressure of the airbrush strokes $desc' },
&stroke_args &stroke_arg
); );
delete $inargs[0]->{get};
@invoke = ( %invoke = (
'airbrush.h', headers => [ qw("airbrush.h") ],
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);' code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
); );
} }
@ -91,35 +99,44 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
blend_mode => ['enum BlendMode', { name => 'blend_mode', type => 'enum BlendMode',
'The type of blend: $desc'], desc => 'The type of blend: $desc' },
gradient_type => ['enum PaintMode', { name => 'gradient_type', type => 'enum PaintMode',
'The paint application mode: $desc'], desc => 'The paint application mode: $desc' },
opacity => ['0 <= float <= 100', { name => 'opacity', type => '0 <= float <= 100',
'The opacity of the final blend $desc'], desc => 'The opacity of the final blend $desc' },
offset => ['0 <= float', { name => 'offset', type => '0 <= float',
'Offset relates to the starting and ending coordinates desc => 'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent specified for the blend. This parameter is mode dependent
$desc'], $desc' },
repeat => ['enum RepeatMode', 'Repeat mode: $desc'], { name => 'repeat', type => 'enum RepeatMode',
supersample => ['boolean', 'Do adaptive supersampling $desc'], desc => 'Repeat mode: $desc' },
max_depth => ['1 <= int32 <= 9', { name => 'supersample', type => 'boolean',
'Maximum recursion levels for supersampling', desc => 'Do adaptive supersampling $desc' },
'attach supersample'], { name => 'max_depth', type => '1 <= int32 <= 9',
threshold => ['0 <= float <= 4', desc => 'Maximum recursion levels for supersampling',
'Supersampling threshold', cond => 'supersample' },
'attach supersample'], { name => 'threshold', type => '0 <= float <= 4',
x1 => ['float', 'The x coordinate of this blend's starting point'], desc => 'Supersampling threshold',
y1 => ['float', 'The y coordinate of this blend's starting point'], cond => 'supersample' },
x2 => ['float', 'The x coordinate of this blend's ending point'], { name => 'x1', type => 'float',
y2 => ['float', 'The y coordinate of this blend's ending point'] 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 = ( %invoke = (
'blend.h', headers => [ qw("blend.h") ],
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);' 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; &std_pdb_misc;
my $validity = 'This parameter is only valid when there is no selection in the specified image.' my $validity = 'This parameter is only valid when there is no selection in
my $coord = "The \$a coordinate of this bucket fill's application. $validity"; the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application.
$validity";
%inargs = ( %inargs = (
&tool_init_args, &drawable_arg,
fill_mode => ['enum FillMode', 'The type of fill: $desc'], { name => 'fill_mode', type => 'enum FillMode',
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'], desc => 'The type of fill: $desc' },
opacity => ['0 <= float <= 100', { name => paint_mode, type => 'enum PaintMode',
'The opacity of the final bucket fill $desc'], desc => 'The paint application mode: $desc' },
threshold => ['0 <= float <= 255', { name => opacity, type => '0 <= float <= 100',
"The threshold determines how extensive the seed fill desc => 'The opacity of the final bucket fill $desc' },
will be. It's value is specified in terms of intensity { name => threshold, type => '0 <= float <= 255',
levels \$desc. $validity'], 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, &sample_merged_arg,
x => ['float', eval qq/{\$a = 'x';"$coord";}/], { name => x, type => 'float',
y => ['float', eval qq/{\$a = 'y';"$coord";}/] desc => eval qq/{\$a = 'x'; "$coord";}/ },
{ name => y, type => 'float',
desc => eval qq/{\$a = 'y';"$coord";}/ }
); );
@invoke = ( %invoke = (
'bucket_fill.h', headers => [ qw ("bucket_fill.h") ],
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);' 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 value) are included in the selection. The antialiasing parameter allows the
final selection mask to contain intermediate values based on close misses to 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 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 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 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. layers. In the case of a merged sampling, the supplied drawable is ignored.
@ -190,20 +216,25 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
color => ['color', 'The color to select'], { name => 'color', type => 'color',
threshold => ['0 <= int32 <= 255', desc => 'The color to select' },
'Threshold in intensity levels $desc'], { name => 'threshold', type => '0 <= int32 <= 255',
operation => ['enum Operation', 'The selection operation: $desc'], desc => 'Threshold in intensity levels $desc' },
{ name => 'operation', type => 'enum Operation',
desc => 'The selection operation: $desc' },
&antialias_arg, &antialias_arg,
&feather_select_args, &feather_select_args,
&sample_merged_arg &sample_merged_arg
); );
@invoke = ( %invoke = (
'by_color_select.h', headers => [ qw("by_color_select.h") ],
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);' code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
CODE
); );
} }
@ -214,9 +245,9 @@ BLURB
$help = <<'HELP' $help = <<'HELP'
This tool clones (copies) from the source drawable starting at the specified 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 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 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 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 src coordinates and subsequent stroke offsets exceeds the extents of the src
@ -227,18 +258,26 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
src_drawable => ['drawable', "The source drawable"], { name => 'src_drawable', type => 'drawable',
clone_type => ['enum CloneType', 'The type of clone: $desc'], desc => 'The source drawable' },
src_x => ['float', 'The x coordinate in the source image'], { name => 'clone_type', type => 'enum CloneType',
src_y => ['float', 'The y coordinate in the source image'], desc => 'The type of clone: $desc' },
&stroke_args { 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 = ( %invoke = (
'clone.h', headers => [ qw("clone.h") ],
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);' 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; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
x => ['float', 'x coordinate of upper-left corner of rectangle'], { name => 'x', type => 'float',
y => ['float', 'y coordinate of upper-left corner of rectangle'], 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, &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 = ( @outargs = (
color => ['color', 'The return color'] { name => 'color', type => 'color',
desc => 'The return color' }
); );
%invoke = ( %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 # shortcuts
sub tool_init_args { sub drawable_arg () {{
(image => ['image', 'The image'], name => 'drawable',
drawable => ['drawable', 'The affected drawable']); type => 'drawable',
} desc => 'The affected drawable',
get => &std_image_arg
}}
sub sample_merged_arg { sub sample_merged_arg () {{
(sample_merged => ['boolean', 'Use the composite image, not the drawable']); name => 'sample_merged',
} type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub antialias_arg { sub antialias_arg () {{
(antialias => ['boolean', 'Antialiasing $desc']); name => 'antialias',
} type => 'boolean',
desc => 'Antialiasing $desc'
}}
sub feather_select_args { sub feather_select_args () {(
(feather => ['boolean', 'Feather option for selections'], { name => 'feather', type => 'boolean',
feather_radius => ['float', 'Radius for feather operation']); desc => 'Feather option for selections' },
} { name => 'feather_radius', type => 'float',
desc => 'Radius for feather operation' }
)}
sub stroke_args { sub stroke_arg () {
(num_strokes => ['0 < int32', { name => 'strokes', type => 'floatarray',
'number of stroke control points (count each coordinate as desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
2 points)'], sn.x, sn.y }',
strokes => ['floatarray', array => { desc => 'number of stroke control points (count each
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ..., coordinate as 2 points)' } }
sn.x, sn.y }']);
} }
# The defs # The defs
@ -64,16 +71,17 @@ HELP;
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
pressure => ['0 <= float <= 100', { name => 'pressure', type => '0 <= float <= 100',
'The pressure of the airbrush strokes $desc'], desc => 'The pressure of the airbrush strokes $desc' },
&stroke_args &stroke_arg
); );
delete $inargs[0]->{get};
@invoke = ( %invoke = (
'airbrush.h', headers => [ qw("airbrush.h") ],
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);' code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
); );
} }
@ -91,35 +99,44 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
blend_mode => ['enum BlendMode', { name => 'blend_mode', type => 'enum BlendMode',
'The type of blend: $desc'], desc => 'The type of blend: $desc' },
gradient_type => ['enum PaintMode', { name => 'gradient_type', type => 'enum PaintMode',
'The paint application mode: $desc'], desc => 'The paint application mode: $desc' },
opacity => ['0 <= float <= 100', { name => 'opacity', type => '0 <= float <= 100',
'The opacity of the final blend $desc'], desc => 'The opacity of the final blend $desc' },
offset => ['0 <= float', { name => 'offset', type => '0 <= float',
'Offset relates to the starting and ending coordinates desc => 'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent specified for the blend. This parameter is mode dependent
$desc'], $desc' },
repeat => ['enum RepeatMode', 'Repeat mode: $desc'], { name => 'repeat', type => 'enum RepeatMode',
supersample => ['boolean', 'Do adaptive supersampling $desc'], desc => 'Repeat mode: $desc' },
max_depth => ['1 <= int32 <= 9', { name => 'supersample', type => 'boolean',
'Maximum recursion levels for supersampling', desc => 'Do adaptive supersampling $desc' },
'attach supersample'], { name => 'max_depth', type => '1 <= int32 <= 9',
threshold => ['0 <= float <= 4', desc => 'Maximum recursion levels for supersampling',
'Supersampling threshold', cond => 'supersample' },
'attach supersample'], { name => 'threshold', type => '0 <= float <= 4',
x1 => ['float', 'The x coordinate of this blend's starting point'], desc => 'Supersampling threshold',
y1 => ['float', 'The y coordinate of this blend's starting point'], cond => 'supersample' },
x2 => ['float', 'The x coordinate of this blend's ending point'], { name => 'x1', type => 'float',
y2 => ['float', 'The y coordinate of this blend's ending point'] 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 = ( %invoke = (
'blend.h', headers => [ qw("blend.h") ],
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);' 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; &std_pdb_misc;
my $validity = 'This parameter is only valid when there is no selection in the specified image.' my $validity = 'This parameter is only valid when there is no selection in
my $coord = "The \$a coordinate of this bucket fill's application. $validity"; the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application.
$validity";
%inargs = ( %inargs = (
&tool_init_args, &drawable_arg,
fill_mode => ['enum FillMode', 'The type of fill: $desc'], { name => 'fill_mode', type => 'enum FillMode',
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'], desc => 'The type of fill: $desc' },
opacity => ['0 <= float <= 100', { name => paint_mode, type => 'enum PaintMode',
'The opacity of the final bucket fill $desc'], desc => 'The paint application mode: $desc' },
threshold => ['0 <= float <= 255', { name => opacity, type => '0 <= float <= 100',
"The threshold determines how extensive the seed fill desc => 'The opacity of the final bucket fill $desc' },
will be. It's value is specified in terms of intensity { name => threshold, type => '0 <= float <= 255',
levels \$desc. $validity'], 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, &sample_merged_arg,
x => ['float', eval qq/{\$a = 'x';"$coord";}/], { name => x, type => 'float',
y => ['float', eval qq/{\$a = 'y';"$coord";}/] desc => eval qq/{\$a = 'x'; "$coord";}/ },
{ name => y, type => 'float',
desc => eval qq/{\$a = 'y';"$coord";}/ }
); );
@invoke = ( %invoke = (
'bucket_fill.h', headers => [ qw ("bucket_fill.h") ],
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);' 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 value) are included in the selection. The antialiasing parameter allows the
final selection mask to contain intermediate values based on close misses to 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 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 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 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. layers. In the case of a merged sampling, the supplied drawable is ignored.
@ -190,20 +216,25 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
color => ['color', 'The color to select'], { name => 'color', type => 'color',
threshold => ['0 <= int32 <= 255', desc => 'The color to select' },
'Threshold in intensity levels $desc'], { name => 'threshold', type => '0 <= int32 <= 255',
operation => ['enum Operation', 'The selection operation: $desc'], desc => 'Threshold in intensity levels $desc' },
{ name => 'operation', type => 'enum Operation',
desc => 'The selection operation: $desc' },
&antialias_arg, &antialias_arg,
&feather_select_args, &feather_select_args,
&sample_merged_arg &sample_merged_arg
); );
@invoke = ( %invoke = (
'by_color_select.h', headers => [ qw("by_color_select.h") ],
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);' code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
CODE
); );
} }
@ -214,9 +245,9 @@ BLURB
$help = <<'HELP' $help = <<'HELP'
This tool clones (copies) from the source drawable starting at the specified 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 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 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 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 src coordinates and subsequent stroke offsets exceeds the extents of the src
@ -227,18 +258,26 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
src_drawable => ['drawable', "The source drawable"], { name => 'src_drawable', type => 'drawable',
clone_type => ['enum CloneType', 'The type of clone: $desc'], desc => 'The source drawable' },
src_x => ['float', 'The x coordinate in the source image'], { name => 'clone_type', type => 'enum CloneType',
src_y => ['float', 'The y coordinate in the source image'], desc => 'The type of clone: $desc' },
&stroke_args { 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 = ( %invoke = (
'clone.h', headers => [ qw("clone.h") ],
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);' 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; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
x => ['float', 'x coordinate of upper-left corner of rectangle'], { name => 'x', type => 'float',
y => ['float', 'y coordinate of upper-left corner of rectangle'], 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, &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 = ( @outargs = (
color => ['color', 'The return color'] { name => 'color', type => 'color',
desc => 'The return color' }
); );
%invoke = ( %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 # shortcuts
sub tool_init_args { sub drawable_arg () {{
(image => ['image', 'The image'], name => 'drawable',
drawable => ['drawable', 'The affected drawable']); type => 'drawable',
} desc => 'The affected drawable',
get => &std_image_arg
}}
sub sample_merged_arg { sub sample_merged_arg () {{
(sample_merged => ['boolean', 'Use the composite image, not the drawable']); name => 'sample_merged',
} type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub antialias_arg { sub antialias_arg () {{
(antialias => ['boolean', 'Antialiasing $desc']); name => 'antialias',
} type => 'boolean',
desc => 'Antialiasing $desc'
}}
sub feather_select_args { sub feather_select_args () {(
(feather => ['boolean', 'Feather option for selections'], { name => 'feather', type => 'boolean',
feather_radius => ['float', 'Radius for feather operation']); desc => 'Feather option for selections' },
} { name => 'feather_radius', type => 'float',
desc => 'Radius for feather operation' }
)}
sub stroke_args { sub stroke_arg () {
(num_strokes => ['0 < int32', { name => 'strokes', type => 'floatarray',
'number of stroke control points (count each coordinate as desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
2 points)'], sn.x, sn.y }',
strokes => ['floatarray', array => { desc => 'number of stroke control points (count each
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ..., coordinate as 2 points)' } }
sn.x, sn.y }']);
} }
# The defs # The defs
@ -64,16 +71,17 @@ HELP;
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
pressure => ['0 <= float <= 100', { name => 'pressure', type => '0 <= float <= 100',
'The pressure of the airbrush strokes $desc'], desc => 'The pressure of the airbrush strokes $desc' },
&stroke_args &stroke_arg
); );
delete $inargs[0]->{get};
@invoke = ( %invoke = (
'airbrush.h', headers => [ qw("airbrush.h") ],
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);' code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
); );
} }
@ -91,35 +99,44 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
blend_mode => ['enum BlendMode', { name => 'blend_mode', type => 'enum BlendMode',
'The type of blend: $desc'], desc => 'The type of blend: $desc' },
gradient_type => ['enum PaintMode', { name => 'gradient_type', type => 'enum PaintMode',
'The paint application mode: $desc'], desc => 'The paint application mode: $desc' },
opacity => ['0 <= float <= 100', { name => 'opacity', type => '0 <= float <= 100',
'The opacity of the final blend $desc'], desc => 'The opacity of the final blend $desc' },
offset => ['0 <= float', { name => 'offset', type => '0 <= float',
'Offset relates to the starting and ending coordinates desc => 'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent specified for the blend. This parameter is mode dependent
$desc'], $desc' },
repeat => ['enum RepeatMode', 'Repeat mode: $desc'], { name => 'repeat', type => 'enum RepeatMode',
supersample => ['boolean', 'Do adaptive supersampling $desc'], desc => 'Repeat mode: $desc' },
max_depth => ['1 <= int32 <= 9', { name => 'supersample', type => 'boolean',
'Maximum recursion levels for supersampling', desc => 'Do adaptive supersampling $desc' },
'attach supersample'], { name => 'max_depth', type => '1 <= int32 <= 9',
threshold => ['0 <= float <= 4', desc => 'Maximum recursion levels for supersampling',
'Supersampling threshold', cond => 'supersample' },
'attach supersample'], { name => 'threshold', type => '0 <= float <= 4',
x1 => ['float', 'The x coordinate of this blend's starting point'], desc => 'Supersampling threshold',
y1 => ['float', 'The y coordinate of this blend's starting point'], cond => 'supersample' },
x2 => ['float', 'The x coordinate of this blend's ending point'], { name => 'x1', type => 'float',
y2 => ['float', 'The y coordinate of this blend's ending point'] 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 = ( %invoke = (
'blend.h', headers => [ qw("blend.h") ],
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);' 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; &std_pdb_misc;
my $validity = 'This parameter is only valid when there is no selection in the specified image.' my $validity = 'This parameter is only valid when there is no selection in
my $coord = "The \$a coordinate of this bucket fill's application. $validity"; the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application.
$validity";
%inargs = ( %inargs = (
&tool_init_args, &drawable_arg,
fill_mode => ['enum FillMode', 'The type of fill: $desc'], { name => 'fill_mode', type => 'enum FillMode',
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'], desc => 'The type of fill: $desc' },
opacity => ['0 <= float <= 100', { name => paint_mode, type => 'enum PaintMode',
'The opacity of the final bucket fill $desc'], desc => 'The paint application mode: $desc' },
threshold => ['0 <= float <= 255', { name => opacity, type => '0 <= float <= 100',
"The threshold determines how extensive the seed fill desc => 'The opacity of the final bucket fill $desc' },
will be. It's value is specified in terms of intensity { name => threshold, type => '0 <= float <= 255',
levels \$desc. $validity'], 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, &sample_merged_arg,
x => ['float', eval qq/{\$a = 'x';"$coord";}/], { name => x, type => 'float',
y => ['float', eval qq/{\$a = 'y';"$coord";}/] desc => eval qq/{\$a = 'x'; "$coord";}/ },
{ name => y, type => 'float',
desc => eval qq/{\$a = 'y';"$coord";}/ }
); );
@invoke = ( %invoke = (
'bucket_fill.h', headers => [ qw ("bucket_fill.h") ],
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);' 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 value) are included in the selection. The antialiasing parameter allows the
final selection mask to contain intermediate values based on close misses to 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 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 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 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. layers. In the case of a merged sampling, the supplied drawable is ignored.
@ -190,20 +216,25 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
color => ['color', 'The color to select'], { name => 'color', type => 'color',
threshold => ['0 <= int32 <= 255', desc => 'The color to select' },
'Threshold in intensity levels $desc'], { name => 'threshold', type => '0 <= int32 <= 255',
operation => ['enum Operation', 'The selection operation: $desc'], desc => 'Threshold in intensity levels $desc' },
{ name => 'operation', type => 'enum Operation',
desc => 'The selection operation: $desc' },
&antialias_arg, &antialias_arg,
&feather_select_args, &feather_select_args,
&sample_merged_arg &sample_merged_arg
); );
@invoke = ( %invoke = (
'by_color_select.h', headers => [ qw("by_color_select.h") ],
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);' code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
CODE
); );
} }
@ -214,9 +245,9 @@ BLURB
$help = <<'HELP' $help = <<'HELP'
This tool clones (copies) from the source drawable starting at the specified 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 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 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 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 src coordinates and subsequent stroke offsets exceeds the extents of the src
@ -227,18 +258,26 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
src_drawable => ['drawable', "The source drawable"], { name => 'src_drawable', type => 'drawable',
clone_type => ['enum CloneType', 'The type of clone: $desc'], desc => 'The source drawable' },
src_x => ['float', 'The x coordinate in the source image'], { name => 'clone_type', type => 'enum CloneType',
src_y => ['float', 'The y coordinate in the source image'], desc => 'The type of clone: $desc' },
&stroke_args { 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 = ( %invoke = (
'clone.h', headers => [ qw("clone.h") ],
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);' 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; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
x => ['float', 'x coordinate of upper-left corner of rectangle'], { name => 'x', type => 'float',
y => ['float', 'y coordinate of upper-left corner of rectangle'], 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, &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 = ( @outargs = (
color => ['color', 'The return color'] { name => 'color', type => 'color',
desc => 'The return color' }
); );
%invoke = ( %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 # shortcuts
sub tool_init_args { sub drawable_arg () {{
(image => ['image', 'The image'], name => 'drawable',
drawable => ['drawable', 'The affected drawable']); type => 'drawable',
} desc => 'The affected drawable',
get => &std_image_arg
}}
sub sample_merged_arg { sub sample_merged_arg () {{
(sample_merged => ['boolean', 'Use the composite image, not the drawable']); name => 'sample_merged',
} type => 'boolean',
desc => 'Use the composite image, not the drawable'
}}
sub antialias_arg { sub antialias_arg () {{
(antialias => ['boolean', 'Antialiasing $desc']); name => 'antialias',
} type => 'boolean',
desc => 'Antialiasing $desc'
}}
sub feather_select_args { sub feather_select_args () {(
(feather => ['boolean', 'Feather option for selections'], { name => 'feather', type => 'boolean',
feather_radius => ['float', 'Radius for feather operation']); desc => 'Feather option for selections' },
} { name => 'feather_radius', type => 'float',
desc => 'Radius for feather operation' }
)}
sub stroke_args { sub stroke_arg () {
(num_strokes => ['0 < int32', { name => 'strokes', type => 'floatarray',
'number of stroke control points (count each coordinate as desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
2 points)'], sn.x, sn.y }',
strokes => ['floatarray', array => { desc => 'number of stroke control points (count each
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ..., coordinate as 2 points)' } }
sn.x, sn.y }']);
} }
# The defs # The defs
@ -64,16 +71,17 @@ HELP;
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
pressure => ['0 <= float <= 100', { name => 'pressure', type => '0 <= float <= 100',
'The pressure of the airbrush strokes $desc'], desc => 'The pressure of the airbrush strokes $desc' },
&stroke_args &stroke_arg
); );
delete $inargs[0]->{get};
@invoke = ( %invoke = (
'airbrush.h', headers => [ qw("airbrush.h") ],
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);' code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
); );
} }
@ -91,35 +99,44 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
blend_mode => ['enum BlendMode', { name => 'blend_mode', type => 'enum BlendMode',
'The type of blend: $desc'], desc => 'The type of blend: $desc' },
gradient_type => ['enum PaintMode', { name => 'gradient_type', type => 'enum PaintMode',
'The paint application mode: $desc'], desc => 'The paint application mode: $desc' },
opacity => ['0 <= float <= 100', { name => 'opacity', type => '0 <= float <= 100',
'The opacity of the final blend $desc'], desc => 'The opacity of the final blend $desc' },
offset => ['0 <= float', { name => 'offset', type => '0 <= float',
'Offset relates to the starting and ending coordinates desc => 'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent specified for the blend. This parameter is mode dependent
$desc'], $desc' },
repeat => ['enum RepeatMode', 'Repeat mode: $desc'], { name => 'repeat', type => 'enum RepeatMode',
supersample => ['boolean', 'Do adaptive supersampling $desc'], desc => 'Repeat mode: $desc' },
max_depth => ['1 <= int32 <= 9', { name => 'supersample', type => 'boolean',
'Maximum recursion levels for supersampling', desc => 'Do adaptive supersampling $desc' },
'attach supersample'], { name => 'max_depth', type => '1 <= int32 <= 9',
threshold => ['0 <= float <= 4', desc => 'Maximum recursion levels for supersampling',
'Supersampling threshold', cond => 'supersample' },
'attach supersample'], { name => 'threshold', type => '0 <= float <= 4',
x1 => ['float', 'The x coordinate of this blend's starting point'], desc => 'Supersampling threshold',
y1 => ['float', 'The y coordinate of this blend's starting point'], cond => 'supersample' },
x2 => ['float', 'The x coordinate of this blend's ending point'], { name => 'x1', type => 'float',
y2 => ['float', 'The y coordinate of this blend's ending point'] 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 = ( %invoke = (
'blend.h', headers => [ qw("blend.h") ],
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);' 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; &std_pdb_misc;
my $validity = 'This parameter is only valid when there is no selection in the specified image.' my $validity = 'This parameter is only valid when there is no selection in
my $coord = "The \$a coordinate of this bucket fill's application. $validity"; the specified image.'
my $coord = "The \$a coordinate of this bucket fill's application.
$validity";
%inargs = ( %inargs = (
&tool_init_args, &drawable_arg,
fill_mode => ['enum FillMode', 'The type of fill: $desc'], { name => 'fill_mode', type => 'enum FillMode',
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'], desc => 'The type of fill: $desc' },
opacity => ['0 <= float <= 100', { name => paint_mode, type => 'enum PaintMode',
'The opacity of the final bucket fill $desc'], desc => 'The paint application mode: $desc' },
threshold => ['0 <= float <= 255', { name => opacity, type => '0 <= float <= 100',
"The threshold determines how extensive the seed fill desc => 'The opacity of the final bucket fill $desc' },
will be. It's value is specified in terms of intensity { name => threshold, type => '0 <= float <= 255',
levels \$desc. $validity'], 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, &sample_merged_arg,
x => ['float', eval qq/{\$a = 'x';"$coord";}/], { name => x, type => 'float',
y => ['float', eval qq/{\$a = 'y';"$coord";}/] desc => eval qq/{\$a = 'x'; "$coord";}/ },
{ name => y, type => 'float',
desc => eval qq/{\$a = 'y';"$coord";}/ }
); );
@invoke = ( %invoke = (
'bucket_fill.h', headers => [ qw ("bucket_fill.h") ],
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);' 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 value) are included in the selection. The antialiasing parameter allows the
final selection mask to contain intermediate values based on close misses to 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 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 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 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. layers. In the case of a merged sampling, the supplied drawable is ignored.
@ -190,20 +216,25 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
color => ['color', 'The color to select'], { name => 'color', type => 'color',
threshold => ['0 <= int32 <= 255', desc => 'The color to select' },
'Threshold in intensity levels $desc'], { name => 'threshold', type => '0 <= int32 <= 255',
operation => ['enum Operation', 'The selection operation: $desc'], desc => 'Threshold in intensity levels $desc' },
{ name => 'operation', type => 'enum Operation',
desc => 'The selection operation: $desc' },
&antialias_arg, &antialias_arg,
&feather_select_args, &feather_select_args,
&sample_merged_arg &sample_merged_arg
); );
@invoke = ( %invoke = (
'by_color_select.h', headers => [ qw("by_color_select.h") ],
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);' code => <<'CODE'
by_color_select (gimage, drawable, color, threshold, operation, antialias,
feather, feather_radius, sample_merged);
CODE
); );
} }
@ -214,9 +245,9 @@ BLURB
$help = <<'HELP' $help = <<'HELP'
This tool clones (copies) from the source drawable starting at the specified 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 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 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 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 src coordinates and subsequent stroke offsets exceeds the extents of the src
@ -227,18 +258,26 @@ HELP
&std_pdb_misc; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
src_drawable => ['drawable', "The source drawable"], { name => 'src_drawable', type => 'drawable',
clone_type => ['enum CloneType', 'The type of clone: $desc'], desc => 'The source drawable' },
src_x => ['float', 'The x coordinate in the source image'], { name => 'clone_type', type => 'enum CloneType',
src_y => ['float', 'The y coordinate in the source image'], desc => 'The type of clone: $desc' },
&stroke_args { 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 = ( %invoke = (
'clone.h', headers => [ qw("clone.h") ],
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);' 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; &std_pdb_misc;
%inargs = ( @inargs = (
&tool_init_args, &drawable_arg,
x => ['float', 'x coordinate of upper-left corner of rectangle'], { name => 'x', type => 'float',
y => ['float', 'y coordinate of upper-left corner of rectangle'], 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, &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 = ( @outargs = (
color => ['color', 'The return color'] { name => 'color', type => 'color',
desc => 'The return color' }
); );
%invoke = ( %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'; require 'util.pl';
# Squash whitespace into just single spaces between words # Squash whitespace into just single spaces between words
sub trimspace { sub trimspace { for (${$_[0]}) { s/[\n\s]+/ /g; s/^ //; s/ $//; } }
my $val = shift;
$$val =~ s/[\n\s]+/ /g;
$$val =~ s/^ //;
$$val =~ s/ $//;
}
# Trim spaces and escape quotes C-style # Trim spaces and escape quotes C-style
sub nicetext { sub nicetext {
@ -141,6 +136,37 @@ sub nicelist {
foreach (@$list) { &trimspace(\$_) } 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 # Post-process each pdb entry
while ((undef, $entry) = each %pdb) { while ((undef, $entry) = each %pdb) {
&nicetext(\$entry->{blurb}); &nicetext(\$entry->{blurb});
@ -148,16 +174,24 @@ while ((undef, $entry) = each %pdb) {
&nicetext(\$entry->{author}); &nicetext(\$entry->{author});
&nicetext(\$entry->{copyright}); &nicetext(\$entry->{copyright});
&nicetext(\$entry->{date}); &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->{inargs}) if exists $entry->{inargs};
&niceargs($entry->{outargs}) if exists $entry->{outargs}; &niceargs($entry->{outargs}) if exists $entry->{outargs};
&nicelist($entry->{invoke}{headers}) if exists $entry->{invoke}{headers}; &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 # Generate code from the modules
my $didstuff; my $didstuff;
while (@ARGV) { while (@ARGV) {
my $type = shift @ARGV; my $type = shift @ARGV;
print "\nProcessing $type...\n"; print "\nProcessing $type...\n";
if (exists $gen{$type}) { if (exists $gen{$type}) {

View File

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

View File

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