mirror of https://github.com/GNOME/gimp.git
parent
aae3eaf0a0
commit
f3877befe7
|
@ -1,5 +1,5 @@
|
|||
# The GIMP -- an image manipulation program
|
||||
# Copyright (C) 1998 Manish Singh <yosh@gimp.org>
|
||||
# Copyright (C) 1998-1999 Manish Singh <yosh@gimp.org>
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,81 +25,123 @@ $destdir = "$main::destdir/app";
|
|||
*arg_vname = \&Gimp::CodeGen::pdb::arg_vname;
|
||||
|
||||
*write_file = \&Gimp::CodeGen::util::write_file;
|
||||
*FILE_EXT = \$Gimp::CodeGen::util::FILE_EXT;
|
||||
|
||||
%testmap = (
|
||||
'<' => '>',
|
||||
'>' => '<',
|
||||
'<=' => '>=',
|
||||
'>=' => '<='
|
||||
);
|
||||
|
||||
sub declare_args {
|
||||
my $proc = shift;
|
||||
my $out = shift;
|
||||
|
||||
my $result = "";
|
||||
|
||||
foreach (@_) {
|
||||
my @args = @{$proc->{$_}} if exists $proc->{$_};
|
||||
|
||||
foreach (@args) {
|
||||
my $arg = $arg_types{(&arg_parse($_->{type}))[0]};
|
||||
if (not exists $_->{no_declare}) {
|
||||
|
||||
if ($arg->{array} && (not exists $_->{array})) {
|
||||
warn "Array without number of elements param in $proc->{name}";
|
||||
}
|
||||
|
||||
unless (exists $_->{no_declare}) {
|
||||
$result .= ' ' x 2;
|
||||
$result .= $arg->{type} . &arg_vname($_) . ";\n";
|
||||
|
||||
if (exists $arg->{id_headers}) {
|
||||
foreach (@{$arg->{id_headers}}) {
|
||||
$out->{headers}->{$_}++;
|
||||
}
|
||||
}
|
||||
|
||||
if (exists $_->{get}) {
|
||||
$result .= ' ' x 2;
|
||||
$result .= $arg_types{$_->{get}->{type}}->{type};
|
||||
$result .= &arg_vname($_->{get}) . ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$result;
|
||||
}
|
||||
|
||||
sub make_args {
|
||||
my $proc = shift;
|
||||
|
||||
my $result = "";
|
||||
my $once;
|
||||
|
||||
foreach (@_) {
|
||||
my @args = @{$proc->{$_}} if exists $proc->{$_};
|
||||
|
||||
if (scalar @args) {
|
||||
$result .= "\nstatic ProcArg $proc->{name}_${_}[] =";
|
||||
$result .= "\n{\n";
|
||||
|
||||
foreach my $arg (@{$proc->{$_}}) {
|
||||
my ($type) = &arg_parse($arg->{type});
|
||||
$result .= ' ' x 2 . "{\n";
|
||||
$result .= ' ' x 4;
|
||||
$result .= 'PDB_' . $arg_types{$type}->{name} . ",\n";
|
||||
$result .= ' ' x 4;
|
||||
$result .= qq/"$arg->{name}",\n/;
|
||||
$result .= ' ' x 4;
|
||||
$result .= qq/"$arg->{desc}"\n/;
|
||||
$result .= ' ' x 2 . "},\n";
|
||||
|
||||
$result .= <<CODE;
|
||||
{
|
||||
PDB_$arg_types{$type}->{name},
|
||||
"$arg->{name}",
|
||||
"$arg->{desc}"
|
||||
},
|
||||
CODE
|
||||
}
|
||||
|
||||
$result =~ s/,\n$/\n/;
|
||||
$result .= "};\n";
|
||||
}
|
||||
}
|
||||
|
||||
$result;
|
||||
}
|
||||
|
||||
sub marshal_inargs {
|
||||
my $proc = shift;
|
||||
|
||||
my $result = "";
|
||||
my %decls;
|
||||
my $argc = 0;
|
||||
|
||||
my @inargs = @{$proc->{inargs}} if exists $proc->{inargs};
|
||||
|
||||
foreach (@inargs) {
|
||||
my($pdbtype, @typeinfo) = &arg_parse($_->{type});
|
||||
my $arg = $arg_types{$pdbtype};
|
||||
my $type = &arg_ptype($arg);
|
||||
my $var = &arg_vname($_);
|
||||
$result .= ' ' x 2;
|
||||
$result .= "if (success)\n" . ' ' x 4 if $success;
|
||||
|
||||
if (exists $arg->{id_func}) {
|
||||
$decls{$type}++;
|
||||
$result .= "{\n" . ' ' x 6 if $success;
|
||||
$result .= "${type}_value = args[$argc].value.pdb_$type;\n";
|
||||
$result .= ' ' x 4 if $success;
|
||||
$result .= ' ' x 2;
|
||||
$result .= "if (($var = ";
|
||||
$result .= "$arg->{id_func} (${type}_value)) == NULL)\n";
|
||||
$result .= ' ' x 4 unless $success;
|
||||
$result .= "\t" if $success;
|
||||
$result .= "success = FALSE;\n";
|
||||
$result .= ' ' x 4 . "}\n" if $success;
|
||||
my $code = "";
|
||||
|
||||
$code .= <<CODE;
|
||||
if (($var = $arg->{id_func} (args[$argc].value.pdb_$type)) == NULL)
|
||||
success = FALSE;
|
||||
CODE
|
||||
|
||||
$code .= <<CODE if exists $_->{get};
|
||||
else
|
||||
@{[ &arg_vname($_->{get}) ]} = @{[ eval qq/"$arg->{$_->{get}->{type}}"/ ]};
|
||||
CODE
|
||||
|
||||
if ($success) {
|
||||
$code =~ s/^/' ' x 4/meg;
|
||||
$code =~ s/^ {8}/\t/mg;
|
||||
$result .= "{\n" . $code . ' ' x 4 . "}\n";
|
||||
}
|
||||
else {
|
||||
$result .= $code;
|
||||
}
|
||||
|
||||
$success = 1;
|
||||
}
|
||||
else {
|
||||
|
@ -107,65 +149,82 @@ sub marshal_inargs {
|
|||
# FIXME: implement this
|
||||
}
|
||||
elsif ($pdbtype eq 'boolean') {
|
||||
$result .= "$var = ";
|
||||
$result .= "(args[$argc].value.pdb_$type) ? TRUE : FALSE;\n";
|
||||
}
|
||||
elsif (defined $typeinfo[0] || defined $typeinfo[2]) {
|
||||
my $tests = 0;
|
||||
$result .= "success = (";
|
||||
if (defined $typeinfo[0]) {
|
||||
$result .= "$var $typeinfo[1] $typeinfo[0]";
|
||||
$tests++;
|
||||
}
|
||||
if (defined $typeinfo[2]) {
|
||||
$result .= '|| ' if $tests;
|
||||
$result .= "$var $typeinfo[2] $typeinfo[3]";
|
||||
}
|
||||
$result .= ");\n";
|
||||
$result .= ' ' x 2 . "$var = ";
|
||||
$result .= "args[$argc].value.pdb_$type ? TRUE : FALSE;\n";
|
||||
}
|
||||
else {
|
||||
my $cast = "";
|
||||
|
||||
$cast = " ($arg->{type})" if $type eq "pointer";
|
||||
$cast = " ($arg->{type})" if $arg->{type} =~ /int(16|8)$/;
|
||||
$result .= "$var =$cast args[$argc].value.pdb_$type;\n";
|
||||
|
||||
$result .= ' ' x 2 . "$var =";
|
||||
$result .= "$cast args[$argc].value.pdb_$type;\n";
|
||||
|
||||
if ($pdbtype eq 'string') {
|
||||
$result .= ' ' x 2 . "success = $var != NULL;\n";
|
||||
$success = 1;
|
||||
}
|
||||
elsif (defined $typeinfo[0] || defined $typeinfo[2]) {
|
||||
my $tests = 0;
|
||||
|
||||
$result .= ' ' x 2 . "success = ";
|
||||
|
||||
if (defined $typeinfo[0]) {
|
||||
$result .= "$var $testmap{$typeinfo[1]} $typeinfo[0]";
|
||||
$tests++;
|
||||
}
|
||||
|
||||
if (defined $typeinfo[2]) {
|
||||
$result .= '|| ' if $tests;
|
||||
$result .= "$var $testmap{$typeinfo[2]} $typeinfo[3]";
|
||||
}
|
||||
|
||||
$result .= ";\n";
|
||||
|
||||
$success = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$argc++; $result .= "\n";
|
||||
}
|
||||
chomp $result if !$success && $argc == 1;
|
||||
my $decls;
|
||||
foreach (keys %decls) { $decls .= ' ' x 2 . "$_ ${_}_value;\n" }
|
||||
$result = $decls . "\n" . $result if $decls;
|
||||
$result and $result = "\n" . $result unless $decls;
|
||||
|
||||
$result = "\n" . $result if $result;
|
||||
$result;
|
||||
}
|
||||
|
||||
sub marshal_outargs {
|
||||
my $proc = shift;
|
||||
|
||||
my $result = <<CODE;
|
||||
return_args = procedural_db_return_args (\&$proc->{name}_proc, success);
|
||||
CODE
|
||||
|
||||
my $argc = 0;
|
||||
my @outargs = @{$proc->{outargs}} if exists $proc->{outargs};
|
||||
|
||||
if (scalar @outargs) {
|
||||
my $outargs = "";
|
||||
|
||||
foreach (@{$proc->{outargs}}) {
|
||||
my ($pdbtype) = &arg_parse($_->{type});
|
||||
my $arg = $arg_types{$pdbtype};
|
||||
my $type = &arg_ptype($arg);
|
||||
my $var = &arg_vname($_);
|
||||
|
||||
$argc++; $outargs .= ' ' x 2;
|
||||
|
||||
if (exists $arg->{id_ret_func}) {
|
||||
$outargs .= "return_args[$argc].value.pdb_$type = ";
|
||||
$outargs .= eval qq/"$arg->{id_ret_func}"/;
|
||||
$outargs .= ";\n";
|
||||
}
|
||||
else {
|
||||
$outargs .= "return_args[$argc].value.pdb_$type = $var;\n";
|
||||
$var = eval qq/"$arg->{id_ret_func}"/;
|
||||
}
|
||||
|
||||
$outargs .= "return_args[$argc].value.pdb_$type = $var;\n";
|
||||
}
|
||||
|
||||
$outargs =~ s/^/' ' x 2/meg if $success;
|
||||
$outargs =~ s/^/' ' x 2/meg if $success && $argc > 1;
|
||||
|
||||
$result .= "\n" if $success || $argc > 1;
|
||||
$result .= ' ' x 2 . "if (success)\n" if $success;
|
||||
$result .= ' ' x 4 . "{\n" if $success && $argc > 1;
|
||||
|
@ -176,6 +235,7 @@ CODE
|
|||
else {
|
||||
$result =~ s/_args =//;
|
||||
}
|
||||
|
||||
$result =~ s/, success\);$/, TRUE);/m unless $success;
|
||||
$result;
|
||||
}
|
||||
|
@ -227,8 +287,10 @@ CODE
|
|||
$invoker .= "\n" if $invoker && $invoker !~ /\n\n/s;
|
||||
|
||||
my $code = $proc->{invoke}->{code};
|
||||
|
||||
chomp $code;
|
||||
$code =~ s/\t/' ' x 8/eg;
|
||||
|
||||
if ($code =~ /^\s*\{\s*\n.*\n\s*\}\s*$/s && !$success) {
|
||||
$code =~ s/^\s*\{\s*\n//s;
|
||||
$code =~ s/\n\s*}\s*$//s;
|
||||
|
@ -242,7 +304,11 @@ CODE
|
|||
$code = ' ' x 2 . "if (success)\n" . $code if $success;
|
||||
$success = ($code =~ /success =/) unless $success;
|
||||
|
||||
$out->{code} .= ' ' x 2 . "int success = TRUE;\n" if $success;
|
||||
if ($success) {
|
||||
$out->{code} .= ' ' x 2;
|
||||
$out->{code} .= "int success = $proc->{invoke}->{success};\n";
|
||||
}
|
||||
|
||||
$out->{code} .= $invoker . $code . "\n";
|
||||
$out->{code} .= "\n" if $code =~ /\n/s || $invoker;
|
||||
$out->{code} .= &marshal_outargs($proc) . "}\n";
|
||||
|
@ -290,7 +356,7 @@ CODE
|
|||
|
||||
GPL
|
||||
|
||||
my $internal = "$destdir/internal_procs.h.tmp.$$";
|
||||
my $internal = "$destdir/internal_procs.h$FILE_EXT";
|
||||
open INTERNAL, "> $internal" or die "Can't open $cmdfile: $!\n";
|
||||
print INTERNAL $gpl;
|
||||
my $guard = "__INTERNAL_PROCS_H__";
|
||||
|
@ -310,7 +376,7 @@ HEADER
|
|||
foreach $group (@main::groups) {
|
||||
my $out = $out{$group};
|
||||
|
||||
my $cfile = "$destdir/${group}_cmds.c.tmp.$$";
|
||||
my $cfile = "$destdir/${group}_cmds.c$FILE_EXT";
|
||||
open CFILE, "> $cfile" or die "Can't open $cmdfile: $!\n";
|
||||
print CFILE $gpl;
|
||||
foreach my $header (sort keys %{$out->{headers}}) {
|
||||
|
@ -341,7 +407,7 @@ HEADER
|
|||
$pcount += $out->{pcount};
|
||||
}
|
||||
|
||||
$internal = "$destdir/internal_procs.c.tmp.$$";
|
||||
$internal = "$destdir/internal_procs.c$FILE_EXT";
|
||||
open INTERNAL, "> $internal" or die "Can't open $cmdfile: $!\n";
|
||||
print INTERNAL $gpl;
|
||||
print INTERNAL qq/#include "app_procs.h"\n\n/;
|
||||
|
|
|
@ -16,5 +16,5 @@
|
|||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# Modify this list for the groups to parse in the pdb directory
|
||||
@groups = qw(gdisplay edit floating_sel undo palette gradients convert
|
||||
channel_ops);
|
||||
@groups = qw(gdisplay edit floating_sel undo palette gradient
|
||||
convert channel_ops);
|
||||
|
|
|
@ -24,11 +24,18 @@ $destdir = "$main::destdir/libgimp";
|
|||
*arg_parse = \&Gimp::CodeGen::pdb::arg_parse;
|
||||
|
||||
*write_file = \&Gimp::CodeGen::util::write_file;
|
||||
*FILE_EXT = \$Gimp::CodeGen::util::FILE_EXT;
|
||||
|
||||
sub generate {
|
||||
my @procs = @{(shift)};
|
||||
my %out;
|
||||
|
||||
sub libtype {
|
||||
my ($arg, $type) = @_;
|
||||
$type =~ s/\d+// unless exists $arg->{keep_size};
|
||||
$type;
|
||||
}
|
||||
|
||||
foreach my $name (@procs) {
|
||||
my $proc = $main::pdb{$name};
|
||||
my $out = \%{$out{$proc->{group}}};
|
||||
|
@ -45,7 +52,11 @@ sub generate {
|
|||
# explicity set
|
||||
my $retarg;
|
||||
foreach (@outargs) { $retarg = $_, last if exists $_->{retval} }
|
||||
scalar @outargs and $retarg = $outargs[0] unless $retarg;
|
||||
unless ($retarg) {
|
||||
if (scalar @outargs) {
|
||||
$retarg = exists $outargs[0]->{num} ? $outargs[1] : $outargs[0];
|
||||
}
|
||||
}
|
||||
|
||||
my $rettype; my $retcol = 0;
|
||||
if ($retarg) {
|
||||
|
@ -53,8 +64,8 @@ sub generate {
|
|||
if ($type ne 'color') {
|
||||
my $arg = $arg_types{$type};
|
||||
$rettype = do {
|
||||
if (exists $arg->{id_func}) { 'gint32 ' }
|
||||
else { $arg->{type} }
|
||||
if (exists $arg->{id_func}) { 'gint32 ' }
|
||||
else { &libtype($_, $arg->{type}) }
|
||||
};
|
||||
chop $rettype unless $rettype =~ /\*$/;
|
||||
}
|
||||
|
@ -62,6 +73,8 @@ sub generate {
|
|||
# Color returns three components in pointers passed in
|
||||
$rettype = 'void'; $retcol = 1;
|
||||
}
|
||||
|
||||
$retarg->{retval} = 1;
|
||||
}
|
||||
else {
|
||||
# No return values
|
||||
|
@ -74,21 +87,28 @@ sub generate {
|
|||
my ($type) = &arg_parse($_->{type});
|
||||
my $arg = $arg_types{$type};
|
||||
my $id = exists $arg->{id_func};
|
||||
|
||||
if ($type ne 'color') {
|
||||
$arglist .= do {
|
||||
if ($id) { 'gint32 ' }
|
||||
else { $arg->{type} }
|
||||
if ($id) { 'gint32 ' }
|
||||
else { &libtype($_, $arg->{type}) }
|
||||
};
|
||||
|
||||
$arglist .= $_->{name};
|
||||
$arglist .= '_ID' if $id;
|
||||
$arglist .= ', ';
|
||||
}
|
||||
else {
|
||||
# A color needs to stick the components into a 3-element array
|
||||
$color = "\n" . ' ' x 2 . "guchar $_->{name}\[3];\n\n";
|
||||
$color .= ' ' x 2 . "$_->{name}\[0] = red;\n";
|
||||
$color .= ' ' x 2 . "$_->{name}\[1] = green;\n";
|
||||
$color .= ' ' x 2 . "$_->{name}\[2] = blue;";
|
||||
chop ($color = <<CODE);
|
||||
|
||||
guchar $_->{name}\[3];
|
||||
|
||||
$_->{name}\[0] = red;
|
||||
$_->{name}\[1] = green;
|
||||
$_->{name}\[2] = blue;
|
||||
CODE
|
||||
|
||||
$arglist .= "guchar red, guchar green, guchar blue, ";
|
||||
}
|
||||
|
||||
|
@ -101,24 +121,33 @@ sub generate {
|
|||
|
||||
# This marshals the return value(s)
|
||||
my $return_args = "";
|
||||
my $return_marshal;
|
||||
$return_marshal = "gimp_destroy_params (return_vals, nreturn_vals);";
|
||||
my $return_marshal = "gimp_destroy_params (return_vals, nreturn_vals);";
|
||||
|
||||
# We only need to bother with this if we have to return a value
|
||||
if ($rettype ne 'void' || $retcol) {
|
||||
my $argc = 1; my $once = 0;
|
||||
my $once = 0;
|
||||
my $firstvar;
|
||||
my @arraynums;
|
||||
|
||||
foreach (@outargs) {
|
||||
my ($type) = &arg_parse($_->{type});
|
||||
my $arg = $arg_types{$type};
|
||||
my $id = $arg->{id_ret_func};
|
||||
my $var;
|
||||
|
||||
$return_marshal = "" unless $once++;
|
||||
if ($type ne 'color') {
|
||||
|
||||
if (exists $_->{num}) {
|
||||
if (not exists $_->{no_lib}) {
|
||||
$arglist .= "gint \*$_->{name}, ";
|
||||
push @arraynums, $_;
|
||||
}
|
||||
}
|
||||
elsif ($type ne 'color') {
|
||||
$return_args .= "\n" . ' ' x 2;
|
||||
$return_args .= do {
|
||||
if ($id) { 'gint32 ' }
|
||||
else { $arg->{type} }
|
||||
if ($id) { 'gint32 ' }
|
||||
else { &libtype($_, $arg->{type}) }
|
||||
};
|
||||
|
||||
# The return value variable
|
||||
|
@ -131,21 +160,73 @@ sub generate {
|
|||
|
||||
# Initialize all IDs to -1
|
||||
$return_args .= " = -1" if $id;
|
||||
|
||||
# Initialize pointers to NULL
|
||||
$return_args .= " = NULL" if !$id && ($arg->{type} =~ /\*/);
|
||||
|
||||
$return_args .= ";";
|
||||
|
||||
if (exists $_->{array} && exists $_->{array}->{no_lib}) {
|
||||
$return_args .= "\n" . ' ' x 2 . "gint num_$var;";
|
||||
}
|
||||
}
|
||||
$return_marshal .= <<CODE;
|
||||
}
|
||||
|
||||
foreach (@arraynums) { $return_marshal .= "\*$_->{name} = 0;\n "; }
|
||||
$return_marshal =~ s/\n $/\n\n /s if scalar(@arraynums);
|
||||
|
||||
$return_marshal .= <<CODE;
|
||||
if (return_vals[0].data.d_status == STATUS_SUCCESS)
|
||||
CODE
|
||||
if ($type ne 'color') {
|
||||
$return_marshal .= ' ' x 4 . "$var = ";
|
||||
$return_marshal .= 'g_strdup (' if $type eq 'string';
|
||||
$return_marshal .= "return_vals[$argc].data.d_$type";
|
||||
$return_marshal .= ')' if $type eq 'string';
|
||||
$return_marshal .= ";\n";
|
||||
|
||||
$return_marshal .= ' ' x 4 . "{\n" if $#outargs;
|
||||
|
||||
my $argc = 1; my ($numpos, $numtype);
|
||||
foreach (@outargs) {
|
||||
my ($type) = &arg_parse($_->{type});
|
||||
my $arg = $arg_types{$type};
|
||||
my $id = $arg->{id_ret_func};
|
||||
my $var;
|
||||
|
||||
my $head = ""; my $foot = "";
|
||||
if ($type =~ /^string(array)?/) {
|
||||
$head = 'g_strdup (';
|
||||
$foot = ')';
|
||||
}
|
||||
|
||||
if (exists $_->{num}) {
|
||||
$numpos = $argc;
|
||||
$numtype = $type;
|
||||
}
|
||||
elsif (exists $_->{array}) {
|
||||
my $datatype = $arg->{type};
|
||||
chop $datatype;
|
||||
$datatype =~ s/ *$//;
|
||||
|
||||
$return_args .= "\n" . ' ' x 2 . "gint i;";
|
||||
|
||||
my $numvar = '*' . $_->{array}->{name};
|
||||
$numvar = "num_$_->{name}" if exists $_->{array}->{no_lib};
|
||||
|
||||
$return_marshal .= <<CODE;
|
||||
$numvar = return_vals[$numpos].data.d_$numtype;
|
||||
$_->{name} = g_new ($datatype, $numvar);
|
||||
for (i = 0; i < $numvar; i++)
|
||||
$_->{name}\[i] = ${head}return_vals[$argc].data.d_$type\[i]${foot};
|
||||
CODE
|
||||
}
|
||||
elsif ($type ne 'color') {
|
||||
# The return value variable
|
||||
$var = $_->{name};
|
||||
$var .= '_ID' if $id;
|
||||
|
||||
$return_marshal .= <<CODE
|
||||
$var = ${head}return_vals[$argc].data.d_$type${foot};
|
||||
CODE
|
||||
}
|
||||
else {
|
||||
# Colors are returned in parts using pointers
|
||||
$arglist .= "guchar \*red, guchar \*green, guchar \*blue";
|
||||
$arglist .= "guchar \*red, guchar \*green, guchar \*blue, ";
|
||||
$return_marshal .= <<CODE
|
||||
{
|
||||
\*red = return_vals[$argc].data.d_color.red;
|
||||
|
@ -154,8 +235,12 @@ CODE
|
|||
}
|
||||
CODE
|
||||
}
|
||||
|
||||
$argc++;
|
||||
}
|
||||
|
||||
$return_marshal .= ' ' x 4 . "}\n" if $#outargs;
|
||||
|
||||
$return_marshal .= <<'CODE';
|
||||
|
||||
gimp_destroy_params (return_vals, nreturn_vals);
|
||||
|
@ -169,6 +254,9 @@ CODE
|
|||
# We don't need the last comma in the declaration
|
||||
$arglist =~ s/, $//;
|
||||
}
|
||||
else {
|
||||
$arglist = "void";
|
||||
}
|
||||
|
||||
# Our function prototype for the headers
|
||||
push @{$out->{proto}}, "$rettype gimp_$name ($arglist);\n";
|
||||
|
@ -179,7 +267,7 @@ $rettype
|
|||
gimp_$name ($arglist)
|
||||
{
|
||||
GParam *return_vals;
|
||||
int nreturn_vals;$return_args$color
|
||||
gint nreturn_vals;$return_args$color
|
||||
|
||||
return_vals = gimp_run_procedure ("gimp_$name",
|
||||
\&nreturn_vals,$argpass
|
||||
|
@ -215,8 +303,8 @@ LGPL
|
|||
# We generate two files, a .h file with prototypes for all the functions
|
||||
# we make, and a .c file for the actual implementation
|
||||
while (my($group, $out) = each %out) {
|
||||
my $hfile = "$destdir/gimp${group}.h.tmp.$$";
|
||||
my $cfile = "$destdir/gimp${group}.c.tmp.$$";
|
||||
my $hfile = "$destdir/gimp${group}.h$FILE_EXT";
|
||||
my $cfile = "$destdir/gimp${group}.c$FILE_EXT";
|
||||
|
||||
my $protos;
|
||||
foreach (@{$out->{proto}}) { $protos .= $_ }
|
||||
|
|
|
@ -25,11 +25,11 @@ package Gimp::CodeGen::pdb;
|
|||
float => { name => 'FLOAT' , type => 'gdouble ' },
|
||||
string => { name => 'STRING', type => 'gchar *' },
|
||||
|
||||
int32array => { name => 'INT32ARRAY' , type => 'gint32 *' },
|
||||
int16array => { name => 'INT16ARRAY' , type => 'gint16 *' },
|
||||
int8array => { name => 'INT8ARRAY' , type => 'gint8 *' },
|
||||
floatarray => { name => 'FLOATARRAY' , type => 'gdouble *' },
|
||||
stringarray => { name => 'STRINGARRAY', type => 'gchar **' },
|
||||
int32array => { name => 'INT32ARRAY' , type => 'gint32 *' , array => 1 },
|
||||
int16array => { name => 'INT16ARRAY' , type => 'gint16 *' , array => 1 },
|
||||
int8array => { name => 'INT8ARRAY' , type => 'gint8 *' , array => 1 },
|
||||
floatarray => { name => 'FLOATARRAY' , type => 'gdouble *', array => 1 },
|
||||
stringarray => { name => 'STRINGARRAY', type => 'gchar **' , array => 1 },
|
||||
|
||||
color => { name => 'COLOR' , type => 'guchar *' },
|
||||
|
||||
|
@ -67,7 +67,7 @@ package Gimp::CodeGen::pdb;
|
|||
id_func => 'gimp_drawable_get_ID',
|
||||
id_ret_func => 'drawable_ID (GIMP_DRAWABLE ($var))',
|
||||
id_headers => [ qw("drawable.h") ],
|
||||
gimage => 'drawable_gimage (GIMP_DRAWABLE ($var))'
|
||||
image => 'drawable_gimage (GIMP_DRAWABLE ($var))'
|
||||
},
|
||||
selection => {
|
||||
name => 'SELECTION',
|
||||
|
@ -114,3 +114,5 @@ sub arg_ptype {
|
|||
|
||||
# Return the alias if defined, otherwise the name
|
||||
sub arg_vname { exists $_[0]->{alias} ? $_[0]->{alias} : $_[0]->{name} }
|
||||
|
||||
sub arg_numtype () { 'gint32 ' }
|
||||
|
|
|
@ -35,7 +35,7 @@ HELP
|
|||
|
||||
@inargs = (
|
||||
{ name => 'drawable', type => 'drawable',
|
||||
desc => 'The drawable to offset', gimage => 1 },
|
||||
desc => 'The drawable to offset', get => &std_image_arg },
|
||||
{ name => 'wrap_around', type => 'boolean',
|
||||
desc => 'wrap image around or fill vacated regions' },
|
||||
{ name => 'fill_type', type => 'enum GimpOffsetType',
|
||||
|
|
|
@ -36,7 +36,7 @@ HELP
|
|||
|
||||
@outargs = (
|
||||
{ name => 'display', type => 'display',
|
||||
desc => 'The new display' }
|
||||
desc => 'The new display', alias => 'gdisp' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
|
@ -47,7 +47,7 @@ HELP
|
|||
if (gimage->layers == NULL)
|
||||
success = FALSE;
|
||||
else
|
||||
success = ((display = gdisplay_new (gimage, scale)) != NULL);
|
||||
success = ((gdisp = gdisplay_new (gimage, scale)) != NULL);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
|
@ -65,12 +65,12 @@ HELP
|
|||
|
||||
@inargs = (
|
||||
{ name => 'display', type => 'display',
|
||||
desc => 'The display to delete' }
|
||||
desc => 'The display to delete', alias => 'gdisp' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("gdisplay.h") ],
|
||||
code => 'gtk_widget_destroy (display->shell);'
|
||||
code => 'gtk_widget_destroy (gdisp->shell);'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
|
||||
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
|
||||
|
||||
# Common arguments for image and drawable
|
||||
# Common arguments
|
||||
sub inargs {
|
||||
@inargs = (
|
||||
&std_image_arg,
|
||||
{ name => 'drawable', type => 'drawable',
|
||||
desc => "The drawable to @{[shift]}" }
|
||||
desc => "The drawable to @{[shift]}",
|
||||
get => &std_image_arg }
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -30,14 +30,7 @@ sub inargs {
|
|||
sub invoke {
|
||||
%invoke = (
|
||||
headers => [ qw("global_edit.h") ],
|
||||
code => <<CODE
|
||||
{
|
||||
if (gimage != drawable_gimage (drawable))
|
||||
success = FALSE;
|
||||
else
|
||||
success = @{[shift]};
|
||||
}
|
||||
CODE
|
||||
code => "success = @{[shift]};"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -57,7 +50,7 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
&inargs('cut from');
|
||||
&invoke('(edit_cut (gimage, drawable) != NULL)');
|
||||
&invoke('edit_cut (gimage, drawable) != NULL');
|
||||
}
|
||||
|
||||
sub edit_copy {
|
||||
|
@ -74,7 +67,7 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
&inargs('copy from');
|
||||
&invoke('(edit_copy (gimage, drawable) != NULL)');
|
||||
&invoke('edit_copy (gimage, drawable) != NULL');
|
||||
}
|
||||
|
||||
sub edit_paste {
|
||||
|
@ -107,10 +100,9 @@ HELP
|
|||
desc => 'The new floating selection', alias => 'layer' }
|
||||
);
|
||||
|
||||
&invoke('(layer != NULL)');
|
||||
&invoke('layer != NULL');
|
||||
$cmd = "layer = edit_paste (gimage, drawable, global_buf, paste_into);\n";
|
||||
$invoke{code} =~ s/(else\n)/$1 . ' ' x 4 . "{\n" . ' ' x 6 . $cmd/se;
|
||||
$invoke{code} =~ s/(success = \(.*?\n)/' ' x 2 . $1 . ' ' x 4 . "}\n"/se;
|
||||
$invoke{code} = "{\n" . ' ' x 2 . $cmd . ' ' x 2 . $invoke{code} . "\n}\n";
|
||||
}
|
||||
|
||||
sub edit_clear {
|
||||
|
|
|
@ -36,7 +36,7 @@ HELP
|
|||
|
||||
@outargs = (
|
||||
{ name => 'display', type => 'display',
|
||||
desc => 'The new display' }
|
||||
desc => 'The new display', alias => 'gdisp' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
|
@ -47,7 +47,7 @@ HELP
|
|||
if (gimage->layers == NULL)
|
||||
success = FALSE;
|
||||
else
|
||||
success = ((display = gdisplay_new (gimage, scale)) != NULL);
|
||||
success = ((gdisp = gdisplay_new (gimage, scale)) != NULL);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
|
@ -65,12 +65,12 @@ HELP
|
|||
|
||||
@inargs = (
|
||||
{ name => 'display', type => 'display',
|
||||
desc => 'The display to delete' }
|
||||
desc => 'The display to delete', alias => 'gdisp' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("gdisplay.h") ],
|
||||
code => 'gtk_widget_destroy (display->shell);'
|
||||
code => 'gtk_widget_destroy (gdisp->shell);'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
|
||||
|
||||
sub pdb_misc {
|
||||
$author = 'Federico Mena Quintero';
|
||||
$copyright = $author;
|
||||
$author = $copyright = 'Federico Mena Quintero';
|
||||
$date = '1997';
|
||||
}
|
||||
|
||||
|
@ -35,11 +34,11 @@ HELP
|
|||
&pdb_misc;
|
||||
|
||||
@outargs = (
|
||||
{ name => 'num_gradients', type => 'int32',
|
||||
desc => 'The number of loaded gradients' },
|
||||
{ name => 'gradient_names', type => 'stringarray',
|
||||
desc => 'The list of gradient names', alias => 'gradients',
|
||||
retval => 1, num_elements => '*num_gradients' }
|
||||
array => { name => 'num_gradients',
|
||||
desc => 'The number of loaded gradients',
|
||||
no_declare => 1 } }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
|
@ -47,9 +46,10 @@ HELP
|
|||
vars => ['gradient_t *grad', 'GSList *list', 'int i = 0'],
|
||||
code => <<'CODE'
|
||||
{
|
||||
gradients = g_new (char *, num_gradients);
|
||||
gradients = g_new (gchar *, num_gradients);
|
||||
|
||||
success = (list = gradients_list) != NULL;
|
||||
|
||||
success = ((list = gradients_list) != NULL);
|
||||
while (list)
|
||||
{
|
||||
grad = list->data;
|
||||
|
@ -71,17 +71,14 @@ HELP
|
|||
&pdb_misc;
|
||||
|
||||
@outargs = (
|
||||
{
|
||||
name => 'name',
|
||||
type => 'string',
|
||||
desc => 'The name of the active gradient',
|
||||
alias => 'g_strdup (curr_gradient->name)', no_declare => 1
|
||||
}
|
||||
{ name => 'name', type => 'string',
|
||||
desc => 'The name of the active gradient',
|
||||
alias => 'g_strdup (curr_gradient->name)', no_declare => 1 }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("gradient.h") ],
|
||||
code => 'success = (curr_gradient != NULL);'
|
||||
code => 'success = curr_gradient != NULL;'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -104,56 +101,24 @@ HELP
|
|||
);
|
||||
|
||||
%invoke = (
|
||||
success => 'FALSE',
|
||||
headers => [ qw("gradient.h") ],
|
||||
vars => ['gradient_t *grad', 'GSList *list'],
|
||||
code => <<'CODE'
|
||||
{
|
||||
success = (name != NULL);
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = FALSE;
|
||||
list = gradients_list;
|
||||
while (list)
|
||||
{
|
||||
grad = list->data;
|
||||
|
||||
if (strcmp (grad->name, name) == 0)
|
||||
{
|
||||
success = TRUE;
|
||||
|
||||
/* FIXME: violates functionality-GUI separation */
|
||||
if (grad->list_item != NULL)
|
||||
/* Select that gradient in the listbox */
|
||||
gtk_list_select_child (GTK_LIST (g_editor->list),
|
||||
grad->list_item);
|
||||
else
|
||||
/* Just update the current gradient */
|
||||
curr_gradient = grad;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
CODE
|
||||
code => 'success = grad_set_grad_to_name (name);'
|
||||
);
|
||||
}
|
||||
|
||||
sub sample_num_arg {
|
||||
{ name => 'num_samples', type => 'int32',
|
||||
{ name => 'num_samples', type => $_[0] . 'int32',
|
||||
desc => 'The number of samples to take', alias => 'i' }
|
||||
}
|
||||
|
||||
sub sample_outargs {
|
||||
@outargs = (
|
||||
{ name => 'array_length', type => 'int32',
|
||||
desc => 'Length of the color_samples array (4 * num_samples)' },
|
||||
{ name => 'color_samples', type => 'floatarray',
|
||||
desc => 'Color samples: { R1, G1, B1, A1, ..., Rn, Gn, Bn, An }',
|
||||
retval => 1, num_elements => '*array_length' }
|
||||
array => { name => 'array_length', no_lib => 1,
|
||||
desc => 'Length of the color_samples array (4 *
|
||||
num_samples)' } }
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -171,7 +136,7 @@ HELP
|
|||
|
||||
&pdb_misc;
|
||||
|
||||
@inargs = ( &sample_num_arg );
|
||||
@inargs = ( &sample_num_arg('2 <= ') );
|
||||
&sample_outargs;
|
||||
|
||||
%invoke = (
|
||||
|
@ -179,29 +144,24 @@ HELP
|
|||
vars => ['gdouble pos, delta', 'gdouble r, g, b, a', 'gdouble *pv'],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (i >= 2)
|
||||
pos = 0.0;
|
||||
delta = 1.0 / (i - 1);
|
||||
|
||||
array_length = i * 4;
|
||||
|
||||
pv = color_samples = g_new (gdouble, array_length);
|
||||
|
||||
while (i--)
|
||||
{
|
||||
pos = 0.0;
|
||||
delta = 1.0 / (i - 1);
|
||||
grad_get_color_at(pos, &r, &g, &b, &a);
|
||||
|
||||
array_length = i * 4;
|
||||
*pv++ = r;
|
||||
*pv++ = g;
|
||||
*pv++ = b;
|
||||
*pv++ = a;
|
||||
|
||||
pv = color_samples = g_new (gdouble, array_length);
|
||||
|
||||
while (i--)
|
||||
{
|
||||
grad_get_color_at(pos, &r, &g, &b, &a);
|
||||
|
||||
*pv++ = r;
|
||||
*pv++ = g;
|
||||
*pv++ = b;
|
||||
*pv++ = a;
|
||||
|
||||
pos += delta;
|
||||
}
|
||||
pos += delta;
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
}
|
||||
CODE
|
||||
);
|
||||
|
@ -222,12 +182,12 @@ HELP
|
|||
&pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&sample_num_arg,
|
||||
{
|
||||
name => 'positions',
|
||||
type => 'floatarray',
|
||||
desc => 'The list of positions to sample along the gradient',
|
||||
alias => 'pos'
|
||||
alias => 'pos',
|
||||
array => &sample_num_arg("")
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -238,26 +198,21 @@ HELP
|
|||
vars => ['gdouble r, g, b, a', 'gdouble *pv'],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (i >= 2)
|
||||
array_length = i * 4;
|
||||
|
||||
pv = color_samples = g_new (gdouble, array_length);
|
||||
|
||||
while (i--)
|
||||
{
|
||||
array_length = i * 4;
|
||||
grad_get_color_at(*pos, &r, &g, &b, &a);
|
||||
|
||||
pv = color_samples = g_new (gdouble, array_length);
|
||||
*pv++ = r;
|
||||
*pv++ = g;
|
||||
*pv++ = b;
|
||||
*pv++ = a;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
grad_get_color_at(*pos, &r, &g, &b, &a);
|
||||
|
||||
*pv++ = r;
|
||||
*pv++ = g;
|
||||
*pv++ = b;
|
||||
*pv++ = a;
|
||||
|
||||
pos++;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
}
|
||||
CODE
|
||||
);
|
|
@ -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;
|
|
@ -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;
|
|
@ -21,31 +21,38 @@
|
|||
|
||||
# shortcuts
|
||||
|
||||
sub tool_init_args {
|
||||
(image => ['image', 'The image'],
|
||||
drawable => ['drawable', 'The affected drawable']);
|
||||
}
|
||||
sub drawable_arg () {{
|
||||
name => 'drawable',
|
||||
type => 'drawable',
|
||||
desc => 'The affected drawable',
|
||||
get => &std_image_arg
|
||||
}}
|
||||
|
||||
sub sample_merged_arg {
|
||||
(sample_merged => ['boolean', 'Use the composite image, not the drawable']);
|
||||
}
|
||||
sub sample_merged_arg () {{
|
||||
name => 'sample_merged',
|
||||
type => 'boolean',
|
||||
desc => 'Use the composite image, not the drawable'
|
||||
}}
|
||||
|
||||
sub antialias_arg {
|
||||
(antialias => ['boolean', 'Antialiasing $desc']);
|
||||
}
|
||||
sub antialias_arg () {{
|
||||
name => 'antialias',
|
||||
type => 'boolean',
|
||||
desc => 'Antialiasing $desc'
|
||||
}}
|
||||
|
||||
sub feather_select_args {
|
||||
(feather => ['boolean', 'Feather option for selections'],
|
||||
feather_radius => ['float', 'Radius for feather operation']);
|
||||
}
|
||||
sub feather_select_args () {(
|
||||
{ name => 'feather', type => 'boolean',
|
||||
desc => 'Feather option for selections' },
|
||||
{ name => 'feather_radius', type => 'float',
|
||||
desc => 'Radius for feather operation' }
|
||||
)}
|
||||
|
||||
sub stroke_args {
|
||||
(num_strokes => ['0 < int32',
|
||||
'number of stroke control points (count each coordinate as
|
||||
2 points)'],
|
||||
strokes => ['floatarray',
|
||||
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
|
||||
sn.x, sn.y }']);
|
||||
sub stroke_arg () {
|
||||
{ name => 'strokes', type => 'floatarray',
|
||||
desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
|
||||
sn.x, sn.y }',
|
||||
array => { desc => 'number of stroke control points (count each
|
||||
coordinate as 2 points)' } }
|
||||
}
|
||||
|
||||
# The defs
|
||||
|
@ -64,16 +71,17 @@ HELP;
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
pressure => ['0 <= float <= 100',
|
||||
'The pressure of the airbrush strokes $desc'],
|
||||
&stroke_args
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'pressure', type => '0 <= float <= 100',
|
||||
desc => 'The pressure of the airbrush strokes $desc' },
|
||||
&stroke_arg
|
||||
);
|
||||
delete $inargs[0]->{get};
|
||||
|
||||
@invoke = (
|
||||
'airbrush.h',
|
||||
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
%invoke = (
|
||||
headers => [ qw("airbrush.h") ],
|
||||
code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -91,35 +99,44 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
blend_mode => ['enum BlendMode',
|
||||
'The type of blend: $desc'],
|
||||
gradient_type => ['enum PaintMode',
|
||||
'The paint application mode: $desc'],
|
||||
opacity => ['0 <= float <= 100',
|
||||
'The opacity of the final blend $desc'],
|
||||
offset => ['0 <= float',
|
||||
'Offset relates to the starting and ending coordinates
|
||||
specified for the blend. This parameter is mode dependent
|
||||
$desc'],
|
||||
repeat => ['enum RepeatMode', 'Repeat mode: $desc'],
|
||||
supersample => ['boolean', 'Do adaptive supersampling $desc'],
|
||||
max_depth => ['1 <= int32 <= 9',
|
||||
'Maximum recursion levels for supersampling',
|
||||
'attach supersample'],
|
||||
threshold => ['0 <= float <= 4',
|
||||
'Supersampling threshold',
|
||||
'attach supersample'],
|
||||
x1 => ['float', 'The x coordinate of this blend's starting point'],
|
||||
y1 => ['float', 'The y coordinate of this blend's starting point'],
|
||||
x2 => ['float', 'The x coordinate of this blend's ending point'],
|
||||
y2 => ['float', 'The y coordinate of this blend's ending point']
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'blend_mode', type => 'enum BlendMode',
|
||||
desc => 'The type of blend: $desc' },
|
||||
{ name => 'gradient_type', type => 'enum PaintMode',
|
||||
desc => 'The paint application mode: $desc' },
|
||||
{ name => 'opacity', type => '0 <= float <= 100',
|
||||
desc => 'The opacity of the final blend $desc' },
|
||||
{ name => 'offset', type => '0 <= float',
|
||||
desc => 'Offset relates to the starting and ending coordinates
|
||||
specified for the blend. This parameter is mode dependent
|
||||
$desc' },
|
||||
{ name => 'repeat', type => 'enum RepeatMode',
|
||||
desc => 'Repeat mode: $desc' },
|
||||
{ name => 'supersample', type => 'boolean',
|
||||
desc => 'Do adaptive supersampling $desc' },
|
||||
{ name => 'max_depth', type => '1 <= int32 <= 9',
|
||||
desc => 'Maximum recursion levels for supersampling',
|
||||
cond => 'supersample' },
|
||||
{ name => 'threshold', type => '0 <= float <= 4',
|
||||
desc => 'Supersampling threshold',
|
||||
cond => 'supersample' },
|
||||
{ name => 'x1', type => 'float',
|
||||
desc => "The x coordinate of this blend's starting point" },
|
||||
{ name => 'y1', type => 'float',
|
||||
desc => "The y coordinate of this blend's starting point" },
|
||||
{ name => 'x2', type => 'float',
|
||||
desc => "The x coordinate of this blend's ending point" },
|
||||
{ name => 'y2', type => 'float',
|
||||
desc => "The y coordinate of this blend's ending point" }
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'blend.h',
|
||||
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);'
|
||||
%invoke = (
|
||||
headers => [ qw("blend.h") ],
|
||||
code => <<'CODE'
|
||||
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
|
||||
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -144,27 +161,36 @@ HELP;
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
my $validity = 'This parameter is only valid when there is no selection in the specified image.'
|
||||
my $coord = "The \$a coordinate of this bucket fill's application. $validity";
|
||||
my $validity = 'This parameter is only valid when there is no selection in
|
||||
the specified image.'
|
||||
my $coord = "The \$a coordinate of this bucket fill's application.
|
||||
$validity";
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
fill_mode => ['enum FillMode', 'The type of fill: $desc'],
|
||||
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'],
|
||||
opacity => ['0 <= float <= 100',
|
||||
'The opacity of the final bucket fill $desc'],
|
||||
threshold => ['0 <= float <= 255',
|
||||
"The threshold determines how extensive the seed fill
|
||||
will be. It's value is specified in terms of intensity
|
||||
levels \$desc. $validity'],
|
||||
&drawable_arg,
|
||||
{ name => 'fill_mode', type => 'enum FillMode',
|
||||
desc => 'The type of fill: $desc' },
|
||||
{ name => paint_mode, type => 'enum PaintMode',
|
||||
desc => 'The paint application mode: $desc' },
|
||||
{ name => opacity, type => '0 <= float <= 100',
|
||||
desc => 'The opacity of the final bucket fill $desc' },
|
||||
{ name => threshold, type => '0 <= float <= 255',
|
||||
desc => "The threshold determines how extensive the seed fill will
|
||||
be. It's value is specified in terms of intensity levels
|
||||
\$desc. $validity" },
|
||||
&sample_merged_arg,
|
||||
x => ['float', eval qq/{\$a = 'x';"$coord";}/],
|
||||
y => ['float', eval qq/{\$a = 'y';"$coord";}/]
|
||||
{ name => x, type => 'float',
|
||||
desc => eval qq/{\$a = 'x'; "$coord";}/ },
|
||||
{ name => y, type => 'float',
|
||||
desc => eval qq/{\$a = 'y';"$coord";}/ }
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'bucket_fill.h',
|
||||
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);'
|
||||
%invoke = (
|
||||
headers => [ qw ("bucket_fill.h") ],
|
||||
code => <<'CODE'
|
||||
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
|
||||
sample_merged, x, y);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -182,7 +208,7 @@ sufficiently close to the specified color (as determined by the threshold
|
|||
value) are included in the selection. The antialiasing parameter allows the
|
||||
final selection mask to contain intermediate values based on close misses to
|
||||
the threshold bar. Feathering can be enabled optionally and is controlled with
|
||||
the \"feather_radius\" parameter. If the sample_merged parameter is non-zero,
|
||||
the "feather_radius" parameter. If the sample_merged parameter is non-zero,
|
||||
the data of the composite image will be used instead of that for the specified
|
||||
drawable. This is equivalent to sampling for colors after merging all visible
|
||||
layers. In the case of a merged sampling, the supplied drawable is ignored.
|
||||
|
@ -190,20 +216,25 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
color => ['color', 'The color to select'],
|
||||
threshold => ['0 <= int32 <= 255',
|
||||
'Threshold in intensity levels $desc'],
|
||||
operation => ['enum Operation', 'The selection operation: $desc'],
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'color', type => 'color',
|
||||
desc => 'The color to select' },
|
||||
{ name => 'threshold', type => '0 <= int32 <= 255',
|
||||
desc => 'Threshold in intensity levels $desc' },
|
||||
{ name => 'operation', type => 'enum Operation',
|
||||
desc => 'The selection operation: $desc' },
|
||||
&antialias_arg,
|
||||
&feather_select_args,
|
||||
&sample_merged_arg
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'by_color_select.h',
|
||||
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);'
|
||||
%invoke = (
|
||||
headers => [ qw("by_color_select.h") ],
|
||||
code => <<'CODE'
|
||||
by_color_select (gimage, drawable, color, threshold, operation, antialias,
|
||||
feather, feather_radius, sample_merged);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -214,9 +245,9 @@ BLURB
|
|||
|
||||
$help = <<'HELP'
|
||||
This tool clones (copies) from the source drawable starting at the specified
|
||||
source coordinates to the dest drawable. If the \"clone_type\" argument is set
|
||||
source coordinates to the dest drawable. If the "clone_type" argument is set
|
||||
to PATTERN-CLONE, then the current pattern is used as the source and the
|
||||
\"src_drawable\" argument is ignored. Pattern cloning assumes a tileable
|
||||
"src_drawable" argument is ignored. Pattern cloning assumes a tileable
|
||||
pattern and mods the sum of the src coordinates and subsequent stroke offsets
|
||||
with the width and height of the pattern. For image cloning, if the sum of the
|
||||
src coordinates and subsequent stroke offsets exceeds the extents of the src
|
||||
|
@ -227,18 +258,26 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
src_drawable => ['drawable', "The source drawable"],
|
||||
clone_type => ['enum CloneType', 'The type of clone: $desc'],
|
||||
src_x => ['float', 'The x coordinate in the source image'],
|
||||
src_y => ['float', 'The y coordinate in the source image'],
|
||||
&stroke_args
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'src_drawable', type => 'drawable',
|
||||
desc => 'The source drawable' },
|
||||
{ name => 'clone_type', type => 'enum CloneType',
|
||||
desc => 'The type of clone: $desc' },
|
||||
{ name => 'src_x', type => 'float',
|
||||
desc => 'The x coordinate in the source image' },
|
||||
{ name => 'src_y', type => 'float',
|
||||
desc => 'The y coordinate in the source image' },
|
||||
&stroke_arg
|
||||
);
|
||||
delete $inargs[0]->{get};
|
||||
|
||||
@invoke = (
|
||||
'clone.h',
|
||||
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);'
|
||||
%invoke = (
|
||||
headers => [ qw("clone.h") ],
|
||||
code => <<'CODE'
|
||||
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
|
||||
strokes);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -262,19 +301,244 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
x => ['float', 'x coordinate of upper-left corner of rectangle'],
|
||||
y => ['float', 'y coordinate of upper-left corner of rectangle'],
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'x', type => 'float',
|
||||
desc => 'x coordinate of upper-left corner of rectangle' },
|
||||
{ name => 'y', type => 'float',
|
||||
desc => 'y coordinate of upper-left corner of rectangle' },
|
||||
&sample_merged_arg,
|
||||
save_color => ['boolean', 'Save the color to the active palette']
|
||||
{ name => 'save_color', type => 'boolean',
|
||||
desc => 'Save the color to the active palette' }
|
||||
);
|
||||
|
||||
%outargs = (
|
||||
color => ['color', 'The return color']
|
||||
@outargs = (
|
||||
{ name => 'color', type => 'color',
|
||||
desc => 'The return color' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
'color_picker.h',
|
||||
'
|
||||
headers => [ qw("color_picker.h") ],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (success = get_color (gimage, drawable, (int) x, (int) y, sample_merged, save_color)
|
||||
{
|
||||
color = g_new (guchar, 3);
|
||||
color[RED_PIX] = col_value[RED_PIX];
|
||||
color[GREEN_PIX] = col_value[GREEN_PIX];
|
||||
color[BLUE_PIX] = col_value[BLUE_PIX];
|
||||
}
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub convolve {
|
||||
$blurb = 'Convolve (Blur, Sharpen) using the current brush.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool convolves the specified drawable with either a sharpening or blurring
|
||||
kernel. The pressure parameter controls the magnitude of the operation. Like
|
||||
the paintbrush, this tool linearly interpolates between the specified stroke
|
||||
coordinates.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'pressure', type => '0 <= float <= 100',
|
||||
desc => 'The pressure: $desc' },
|
||||
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
|
||||
desc => 'Convolve type: $desc' },
|
||||
&stroke_arg
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("convolve.h") ],
|
||||
code => 'convolve_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
);
|
||||
}
|
||||
|
||||
sub crop {
|
||||
$blurb = 'Crop the image to the specified extents.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This procedure crops the image so that it's new width and height are equal to
|
||||
the supplied parameters. Offsets are also provided which describe the position
|
||||
of the previous image's content. All channels and layers within the image are
|
||||
cropped to the new image extents; this includes the image selection mask. If
|
||||
any parameters are out of range, an error is returned.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&std_image_arg,
|
||||
{ name => 'new_width', type => '0 < int32',
|
||||
desc => 'New image width: (0 < new_width <= width)' },
|
||||
{ name => 'new_height', type => '0 < int32',
|
||||
desc => 'New image height: (0 < new_height <= height)' },
|
||||
{ name => 'offx', type => '0 <= int32',
|
||||
desc => 'x offset: (0 <= offx <= (width - new_width))' },
|
||||
{ name => 'offy', type => '0 <= int32',
|
||||
desc => 'y offset: (0 <= offy <= (height - new_height))' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("crop.h") ],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (new_width > gimage->width ||
|
||||
new_height > gimage->height ||
|
||||
offx > (gimage->width - new_width) ||
|
||||
offy > (gimage->height - new_height)
|
||||
success = FALSE;
|
||||
else
|
||||
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub ellipse_select {
|
||||
$blurb = 'Create an elliptical selection over the specified image.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool creates an elliptical selection over the specified image. The
|
||||
elliptical region can be either added to, subtracted from, or replace the
|
||||
contents of the previous selection mask. If antialiasing is turned on, the
|
||||
edges of the elliptical region will contain intermediate values which give the
|
||||
appearance of a sharper, less pixelized edge. This should be set as TRUE most
|
||||
of the time. If the feather option is enabled, the resulting selection is
|
||||
blurred before combining. The blur is a gaussian blur with the specified
|
||||
feather radius.
|
||||
HELP
|
||||
|
||||
@inargs = (
|
||||
&std_image_arg,
|
||||
{ name => 'x', type => 'float',
|
||||
desc => 'x coordinate of upper-left corner of ellipse bounding box' },
|
||||
{ name => 'y', type => 'float',
|
||||
desc => 'y coordinate of upper-left corner of ellipse bounding box' },
|
||||
{ name => 'width', type => '0 < float',
|
||||
desc => 'The width of the ellipse: $desc' },
|
||||
{ name => 'height', type => '0 < float',
|
||||
desc => 'The height of the ellipse: $desc' },
|
||||
{ name => 'operation', 'enum Selection',
|
||||
desc => 'The selection operation: $desc' },
|
||||
&antialias_arg,
|
||||
&feather_args
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("ellipse_select.h") ],
|
||||
code => <<'CODE'
|
||||
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
|
||||
feather, feather_radius);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub eraser {
|
||||
$blurb = 'Erase using the current brush.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool erases using the current brush mask. If the specified drawable
|
||||
contains an alpha channel, then the erased pixels will become transparent.
|
||||
Otherwise, the eraser tool replaces the contents of the drawable with the
|
||||
background color. Like paintbrush, this tool linearly interpolates between the
|
||||
specified stroke coordinates.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
&stroke_arg,
|
||||
{ name => 'hardness', type => 'enum EraserHardness',
|
||||
desc => '$desc' }
|
||||
{ name => 'method', type => 'enum EraserMethod',
|
||||
desc => '$desc' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("eraser.h") ],
|
||||
code => <<'CODE'
|
||||
eraser_non_gui (drawable, num_strokes, strokes, hardness, method);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub flip {
|
||||
$blurb = <<'BLURB';
|
||||
Flip the specified drawable about its center either vertically or
|
||||
horizontally.
|
||||
BLURB
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool flips the specified drawable if no selection exists. If a selection
|
||||
exists, the portion of the drawable which lies under the selection is cut from
|
||||
the drawable and made into a floating selection which is then flipd by the
|
||||
specified amount. The return value is the ID of the flipped drawable. If there
|
||||
was no selection, this will be equal to the drawable ID supplied as input.
|
||||
Otherwise, this will be the newly created and flipped drawable. The flip type
|
||||
parameter indicates whether the flip will be applied horizontally or
|
||||
vertically.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'flip_type', type => 'enum FlipType',
|
||||
desc => 'Type of flip: $desc' }
|
||||
);
|
||||
|
||||
@outargs = ( &drawable_arg );
|
||||
$outargs[0]->{alias} = layer;
|
||||
$outargs[0]->{desc} = 'The flipped drawable';
|
||||
$outargs[0]->{no_declare} = 1;
|
||||
delete $outargs[0]->{get};
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("flip_tool.h" "tranform_core.h") ],
|
||||
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
|
||||
code => <<'CODE'
|
||||
{
|
||||
/* Start a transform undo group */
|
||||
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
|
||||
|
||||
/* Cut/Copy from the specified drawable */
|
||||
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
|
||||
|
||||
/* flip the buffer */
|
||||
switch (flip_type)
|
||||
{
|
||||
case 0: /* horz */
|
||||
new_tiles = flip_tool_flip_horz (gimage, drawable, float_tiles, -1);
|
||||
break;
|
||||
case 1: /* vert */
|
||||
new_tiles = flip_tool_flip_vert (gimage, drawable, float_tiles, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* free the cut/copied buffer */
|
||||
tile_manager_destroy (float_tiles);
|
||||
|
||||
if (new_tiles)
|
||||
{
|
||||
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
|
||||
success = (layer != NULL);
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
|
||||
/* push the undo group end */
|
||||
undo_push_group_end (gimage);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,31 +21,38 @@
|
|||
|
||||
# shortcuts
|
||||
|
||||
sub tool_init_args {
|
||||
(image => ['image', 'The image'],
|
||||
drawable => ['drawable', 'The affected drawable']);
|
||||
}
|
||||
sub drawable_arg () {{
|
||||
name => 'drawable',
|
||||
type => 'drawable',
|
||||
desc => 'The affected drawable',
|
||||
get => &std_image_arg
|
||||
}}
|
||||
|
||||
sub sample_merged_arg {
|
||||
(sample_merged => ['boolean', 'Use the composite image, not the drawable']);
|
||||
}
|
||||
sub sample_merged_arg () {{
|
||||
name => 'sample_merged',
|
||||
type => 'boolean',
|
||||
desc => 'Use the composite image, not the drawable'
|
||||
}}
|
||||
|
||||
sub antialias_arg {
|
||||
(antialias => ['boolean', 'Antialiasing $desc']);
|
||||
}
|
||||
sub antialias_arg () {{
|
||||
name => 'antialias',
|
||||
type => 'boolean',
|
||||
desc => 'Antialiasing $desc'
|
||||
}}
|
||||
|
||||
sub feather_select_args {
|
||||
(feather => ['boolean', 'Feather option for selections'],
|
||||
feather_radius => ['float', 'Radius for feather operation']);
|
||||
}
|
||||
sub feather_select_args () {(
|
||||
{ name => 'feather', type => 'boolean',
|
||||
desc => 'Feather option for selections' },
|
||||
{ name => 'feather_radius', type => 'float',
|
||||
desc => 'Radius for feather operation' }
|
||||
)}
|
||||
|
||||
sub stroke_args {
|
||||
(num_strokes => ['0 < int32',
|
||||
'number of stroke control points (count each coordinate as
|
||||
2 points)'],
|
||||
strokes => ['floatarray',
|
||||
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
|
||||
sn.x, sn.y }']);
|
||||
sub stroke_arg () {
|
||||
{ name => 'strokes', type => 'floatarray',
|
||||
desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
|
||||
sn.x, sn.y }',
|
||||
array => { desc => 'number of stroke control points (count each
|
||||
coordinate as 2 points)' } }
|
||||
}
|
||||
|
||||
# The defs
|
||||
|
@ -64,16 +71,17 @@ HELP;
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
pressure => ['0 <= float <= 100',
|
||||
'The pressure of the airbrush strokes $desc'],
|
||||
&stroke_args
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'pressure', type => '0 <= float <= 100',
|
||||
desc => 'The pressure of the airbrush strokes $desc' },
|
||||
&stroke_arg
|
||||
);
|
||||
delete $inargs[0]->{get};
|
||||
|
||||
@invoke = (
|
||||
'airbrush.h',
|
||||
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
%invoke = (
|
||||
headers => [ qw("airbrush.h") ],
|
||||
code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -91,35 +99,44 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
blend_mode => ['enum BlendMode',
|
||||
'The type of blend: $desc'],
|
||||
gradient_type => ['enum PaintMode',
|
||||
'The paint application mode: $desc'],
|
||||
opacity => ['0 <= float <= 100',
|
||||
'The opacity of the final blend $desc'],
|
||||
offset => ['0 <= float',
|
||||
'Offset relates to the starting and ending coordinates
|
||||
specified for the blend. This parameter is mode dependent
|
||||
$desc'],
|
||||
repeat => ['enum RepeatMode', 'Repeat mode: $desc'],
|
||||
supersample => ['boolean', 'Do adaptive supersampling $desc'],
|
||||
max_depth => ['1 <= int32 <= 9',
|
||||
'Maximum recursion levels for supersampling',
|
||||
'attach supersample'],
|
||||
threshold => ['0 <= float <= 4',
|
||||
'Supersampling threshold',
|
||||
'attach supersample'],
|
||||
x1 => ['float', 'The x coordinate of this blend's starting point'],
|
||||
y1 => ['float', 'The y coordinate of this blend's starting point'],
|
||||
x2 => ['float', 'The x coordinate of this blend's ending point'],
|
||||
y2 => ['float', 'The y coordinate of this blend's ending point']
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'blend_mode', type => 'enum BlendMode',
|
||||
desc => 'The type of blend: $desc' },
|
||||
{ name => 'gradient_type', type => 'enum PaintMode',
|
||||
desc => 'The paint application mode: $desc' },
|
||||
{ name => 'opacity', type => '0 <= float <= 100',
|
||||
desc => 'The opacity of the final blend $desc' },
|
||||
{ name => 'offset', type => '0 <= float',
|
||||
desc => 'Offset relates to the starting and ending coordinates
|
||||
specified for the blend. This parameter is mode dependent
|
||||
$desc' },
|
||||
{ name => 'repeat', type => 'enum RepeatMode',
|
||||
desc => 'Repeat mode: $desc' },
|
||||
{ name => 'supersample', type => 'boolean',
|
||||
desc => 'Do adaptive supersampling $desc' },
|
||||
{ name => 'max_depth', type => '1 <= int32 <= 9',
|
||||
desc => 'Maximum recursion levels for supersampling',
|
||||
cond => 'supersample' },
|
||||
{ name => 'threshold', type => '0 <= float <= 4',
|
||||
desc => 'Supersampling threshold',
|
||||
cond => 'supersample' },
|
||||
{ name => 'x1', type => 'float',
|
||||
desc => "The x coordinate of this blend's starting point" },
|
||||
{ name => 'y1', type => 'float',
|
||||
desc => "The y coordinate of this blend's starting point" },
|
||||
{ name => 'x2', type => 'float',
|
||||
desc => "The x coordinate of this blend's ending point" },
|
||||
{ name => 'y2', type => 'float',
|
||||
desc => "The y coordinate of this blend's ending point" }
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'blend.h',
|
||||
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);'
|
||||
%invoke = (
|
||||
headers => [ qw("blend.h") ],
|
||||
code => <<'CODE'
|
||||
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
|
||||
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -144,27 +161,36 @@ HELP;
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
my $validity = 'This parameter is only valid when there is no selection in the specified image.'
|
||||
my $coord = "The \$a coordinate of this bucket fill's application. $validity";
|
||||
my $validity = 'This parameter is only valid when there is no selection in
|
||||
the specified image.'
|
||||
my $coord = "The \$a coordinate of this bucket fill's application.
|
||||
$validity";
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
fill_mode => ['enum FillMode', 'The type of fill: $desc'],
|
||||
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'],
|
||||
opacity => ['0 <= float <= 100',
|
||||
'The opacity of the final bucket fill $desc'],
|
||||
threshold => ['0 <= float <= 255',
|
||||
"The threshold determines how extensive the seed fill
|
||||
will be. It's value is specified in terms of intensity
|
||||
levels \$desc. $validity'],
|
||||
&drawable_arg,
|
||||
{ name => 'fill_mode', type => 'enum FillMode',
|
||||
desc => 'The type of fill: $desc' },
|
||||
{ name => paint_mode, type => 'enum PaintMode',
|
||||
desc => 'The paint application mode: $desc' },
|
||||
{ name => opacity, type => '0 <= float <= 100',
|
||||
desc => 'The opacity of the final bucket fill $desc' },
|
||||
{ name => threshold, type => '0 <= float <= 255',
|
||||
desc => "The threshold determines how extensive the seed fill will
|
||||
be. It's value is specified in terms of intensity levels
|
||||
\$desc. $validity" },
|
||||
&sample_merged_arg,
|
||||
x => ['float', eval qq/{\$a = 'x';"$coord";}/],
|
||||
y => ['float', eval qq/{\$a = 'y';"$coord";}/]
|
||||
{ name => x, type => 'float',
|
||||
desc => eval qq/{\$a = 'x'; "$coord";}/ },
|
||||
{ name => y, type => 'float',
|
||||
desc => eval qq/{\$a = 'y';"$coord";}/ }
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'bucket_fill.h',
|
||||
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);'
|
||||
%invoke = (
|
||||
headers => [ qw ("bucket_fill.h") ],
|
||||
code => <<'CODE'
|
||||
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
|
||||
sample_merged, x, y);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -182,7 +208,7 @@ sufficiently close to the specified color (as determined by the threshold
|
|||
value) are included in the selection. The antialiasing parameter allows the
|
||||
final selection mask to contain intermediate values based on close misses to
|
||||
the threshold bar. Feathering can be enabled optionally and is controlled with
|
||||
the \"feather_radius\" parameter. If the sample_merged parameter is non-zero,
|
||||
the "feather_radius" parameter. If the sample_merged parameter is non-zero,
|
||||
the data of the composite image will be used instead of that for the specified
|
||||
drawable. This is equivalent to sampling for colors after merging all visible
|
||||
layers. In the case of a merged sampling, the supplied drawable is ignored.
|
||||
|
@ -190,20 +216,25 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
color => ['color', 'The color to select'],
|
||||
threshold => ['0 <= int32 <= 255',
|
||||
'Threshold in intensity levels $desc'],
|
||||
operation => ['enum Operation', 'The selection operation: $desc'],
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'color', type => 'color',
|
||||
desc => 'The color to select' },
|
||||
{ name => 'threshold', type => '0 <= int32 <= 255',
|
||||
desc => 'Threshold in intensity levels $desc' },
|
||||
{ name => 'operation', type => 'enum Operation',
|
||||
desc => 'The selection operation: $desc' },
|
||||
&antialias_arg,
|
||||
&feather_select_args,
|
||||
&sample_merged_arg
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'by_color_select.h',
|
||||
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);'
|
||||
%invoke = (
|
||||
headers => [ qw("by_color_select.h") ],
|
||||
code => <<'CODE'
|
||||
by_color_select (gimage, drawable, color, threshold, operation, antialias,
|
||||
feather, feather_radius, sample_merged);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -214,9 +245,9 @@ BLURB
|
|||
|
||||
$help = <<'HELP'
|
||||
This tool clones (copies) from the source drawable starting at the specified
|
||||
source coordinates to the dest drawable. If the \"clone_type\" argument is set
|
||||
source coordinates to the dest drawable. If the "clone_type" argument is set
|
||||
to PATTERN-CLONE, then the current pattern is used as the source and the
|
||||
\"src_drawable\" argument is ignored. Pattern cloning assumes a tileable
|
||||
"src_drawable" argument is ignored. Pattern cloning assumes a tileable
|
||||
pattern and mods the sum of the src coordinates and subsequent stroke offsets
|
||||
with the width and height of the pattern. For image cloning, if the sum of the
|
||||
src coordinates and subsequent stroke offsets exceeds the extents of the src
|
||||
|
@ -227,18 +258,26 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
src_drawable => ['drawable', "The source drawable"],
|
||||
clone_type => ['enum CloneType', 'The type of clone: $desc'],
|
||||
src_x => ['float', 'The x coordinate in the source image'],
|
||||
src_y => ['float', 'The y coordinate in the source image'],
|
||||
&stroke_args
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'src_drawable', type => 'drawable',
|
||||
desc => 'The source drawable' },
|
||||
{ name => 'clone_type', type => 'enum CloneType',
|
||||
desc => 'The type of clone: $desc' },
|
||||
{ name => 'src_x', type => 'float',
|
||||
desc => 'The x coordinate in the source image' },
|
||||
{ name => 'src_y', type => 'float',
|
||||
desc => 'The y coordinate in the source image' },
|
||||
&stroke_arg
|
||||
);
|
||||
delete $inargs[0]->{get};
|
||||
|
||||
@invoke = (
|
||||
'clone.h',
|
||||
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);'
|
||||
%invoke = (
|
||||
headers => [ qw("clone.h") ],
|
||||
code => <<'CODE'
|
||||
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
|
||||
strokes);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -262,19 +301,244 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
x => ['float', 'x coordinate of upper-left corner of rectangle'],
|
||||
y => ['float', 'y coordinate of upper-left corner of rectangle'],
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'x', type => 'float',
|
||||
desc => 'x coordinate of upper-left corner of rectangle' },
|
||||
{ name => 'y', type => 'float',
|
||||
desc => 'y coordinate of upper-left corner of rectangle' },
|
||||
&sample_merged_arg,
|
||||
save_color => ['boolean', 'Save the color to the active palette']
|
||||
{ name => 'save_color', type => 'boolean',
|
||||
desc => 'Save the color to the active palette' }
|
||||
);
|
||||
|
||||
%outargs = (
|
||||
color => ['color', 'The return color']
|
||||
@outargs = (
|
||||
{ name => 'color', type => 'color',
|
||||
desc => 'The return color' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
'color_picker.h',
|
||||
'
|
||||
headers => [ qw("color_picker.h") ],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (success = get_color (gimage, drawable, (int) x, (int) y, sample_merged, save_color)
|
||||
{
|
||||
color = g_new (guchar, 3);
|
||||
color[RED_PIX] = col_value[RED_PIX];
|
||||
color[GREEN_PIX] = col_value[GREEN_PIX];
|
||||
color[BLUE_PIX] = col_value[BLUE_PIX];
|
||||
}
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub convolve {
|
||||
$blurb = 'Convolve (Blur, Sharpen) using the current brush.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool convolves the specified drawable with either a sharpening or blurring
|
||||
kernel. The pressure parameter controls the magnitude of the operation. Like
|
||||
the paintbrush, this tool linearly interpolates between the specified stroke
|
||||
coordinates.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'pressure', type => '0 <= float <= 100',
|
||||
desc => 'The pressure: $desc' },
|
||||
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
|
||||
desc => 'Convolve type: $desc' },
|
||||
&stroke_arg
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("convolve.h") ],
|
||||
code => 'convolve_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
);
|
||||
}
|
||||
|
||||
sub crop {
|
||||
$blurb = 'Crop the image to the specified extents.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This procedure crops the image so that it's new width and height are equal to
|
||||
the supplied parameters. Offsets are also provided which describe the position
|
||||
of the previous image's content. All channels and layers within the image are
|
||||
cropped to the new image extents; this includes the image selection mask. If
|
||||
any parameters are out of range, an error is returned.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&std_image_arg,
|
||||
{ name => 'new_width', type => '0 < int32',
|
||||
desc => 'New image width: (0 < new_width <= width)' },
|
||||
{ name => 'new_height', type => '0 < int32',
|
||||
desc => 'New image height: (0 < new_height <= height)' },
|
||||
{ name => 'offx', type => '0 <= int32',
|
||||
desc => 'x offset: (0 <= offx <= (width - new_width))' },
|
||||
{ name => 'offy', type => '0 <= int32',
|
||||
desc => 'y offset: (0 <= offy <= (height - new_height))' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("crop.h") ],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (new_width > gimage->width ||
|
||||
new_height > gimage->height ||
|
||||
offx > (gimage->width - new_width) ||
|
||||
offy > (gimage->height - new_height)
|
||||
success = FALSE;
|
||||
else
|
||||
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub ellipse_select {
|
||||
$blurb = 'Create an elliptical selection over the specified image.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool creates an elliptical selection over the specified image. The
|
||||
elliptical region can be either added to, subtracted from, or replace the
|
||||
contents of the previous selection mask. If antialiasing is turned on, the
|
||||
edges of the elliptical region will contain intermediate values which give the
|
||||
appearance of a sharper, less pixelized edge. This should be set as TRUE most
|
||||
of the time. If the feather option is enabled, the resulting selection is
|
||||
blurred before combining. The blur is a gaussian blur with the specified
|
||||
feather radius.
|
||||
HELP
|
||||
|
||||
@inargs = (
|
||||
&std_image_arg,
|
||||
{ name => 'x', type => 'float',
|
||||
desc => 'x coordinate of upper-left corner of ellipse bounding box' },
|
||||
{ name => 'y', type => 'float',
|
||||
desc => 'y coordinate of upper-left corner of ellipse bounding box' },
|
||||
{ name => 'width', type => '0 < float',
|
||||
desc => 'The width of the ellipse: $desc' },
|
||||
{ name => 'height', type => '0 < float',
|
||||
desc => 'The height of the ellipse: $desc' },
|
||||
{ name => 'operation', 'enum Selection',
|
||||
desc => 'The selection operation: $desc' },
|
||||
&antialias_arg,
|
||||
&feather_args
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("ellipse_select.h") ],
|
||||
code => <<'CODE'
|
||||
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
|
||||
feather, feather_radius);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub eraser {
|
||||
$blurb = 'Erase using the current brush.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool erases using the current brush mask. If the specified drawable
|
||||
contains an alpha channel, then the erased pixels will become transparent.
|
||||
Otherwise, the eraser tool replaces the contents of the drawable with the
|
||||
background color. Like paintbrush, this tool linearly interpolates between the
|
||||
specified stroke coordinates.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
&stroke_arg,
|
||||
{ name => 'hardness', type => 'enum EraserHardness',
|
||||
desc => '$desc' }
|
||||
{ name => 'method', type => 'enum EraserMethod',
|
||||
desc => '$desc' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("eraser.h") ],
|
||||
code => <<'CODE'
|
||||
eraser_non_gui (drawable, num_strokes, strokes, hardness, method);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub flip {
|
||||
$blurb = <<'BLURB';
|
||||
Flip the specified drawable about its center either vertically or
|
||||
horizontally.
|
||||
BLURB
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool flips the specified drawable if no selection exists. If a selection
|
||||
exists, the portion of the drawable which lies under the selection is cut from
|
||||
the drawable and made into a floating selection which is then flipd by the
|
||||
specified amount. The return value is the ID of the flipped drawable. If there
|
||||
was no selection, this will be equal to the drawable ID supplied as input.
|
||||
Otherwise, this will be the newly created and flipped drawable. The flip type
|
||||
parameter indicates whether the flip will be applied horizontally or
|
||||
vertically.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'flip_type', type => 'enum FlipType',
|
||||
desc => 'Type of flip: $desc' }
|
||||
);
|
||||
|
||||
@outargs = ( &drawable_arg );
|
||||
$outargs[0]->{alias} = layer;
|
||||
$outargs[0]->{desc} = 'The flipped drawable';
|
||||
$outargs[0]->{no_declare} = 1;
|
||||
delete $outargs[0]->{get};
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("flip_tool.h" "tranform_core.h") ],
|
||||
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
|
||||
code => <<'CODE'
|
||||
{
|
||||
/* Start a transform undo group */
|
||||
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
|
||||
|
||||
/* Cut/Copy from the specified drawable */
|
||||
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
|
||||
|
||||
/* flip the buffer */
|
||||
switch (flip_type)
|
||||
{
|
||||
case 0: /* horz */
|
||||
new_tiles = flip_tool_flip_horz (gimage, drawable, float_tiles, -1);
|
||||
break;
|
||||
case 1: /* vert */
|
||||
new_tiles = flip_tool_flip_vert (gimage, drawable, float_tiles, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* free the cut/copied buffer */
|
||||
tile_manager_destroy (float_tiles);
|
||||
|
||||
if (new_tiles)
|
||||
{
|
||||
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
|
||||
success = (layer != NULL);
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
|
||||
/* push the undo group end */
|
||||
undo_push_group_end (gimage);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,31 +21,38 @@
|
|||
|
||||
# shortcuts
|
||||
|
||||
sub tool_init_args {
|
||||
(image => ['image', 'The image'],
|
||||
drawable => ['drawable', 'The affected drawable']);
|
||||
}
|
||||
sub drawable_arg () {{
|
||||
name => 'drawable',
|
||||
type => 'drawable',
|
||||
desc => 'The affected drawable',
|
||||
get => &std_image_arg
|
||||
}}
|
||||
|
||||
sub sample_merged_arg {
|
||||
(sample_merged => ['boolean', 'Use the composite image, not the drawable']);
|
||||
}
|
||||
sub sample_merged_arg () {{
|
||||
name => 'sample_merged',
|
||||
type => 'boolean',
|
||||
desc => 'Use the composite image, not the drawable'
|
||||
}}
|
||||
|
||||
sub antialias_arg {
|
||||
(antialias => ['boolean', 'Antialiasing $desc']);
|
||||
}
|
||||
sub antialias_arg () {{
|
||||
name => 'antialias',
|
||||
type => 'boolean',
|
||||
desc => 'Antialiasing $desc'
|
||||
}}
|
||||
|
||||
sub feather_select_args {
|
||||
(feather => ['boolean', 'Feather option for selections'],
|
||||
feather_radius => ['float', 'Radius for feather operation']);
|
||||
}
|
||||
sub feather_select_args () {(
|
||||
{ name => 'feather', type => 'boolean',
|
||||
desc => 'Feather option for selections' },
|
||||
{ name => 'feather_radius', type => 'float',
|
||||
desc => 'Radius for feather operation' }
|
||||
)}
|
||||
|
||||
sub stroke_args {
|
||||
(num_strokes => ['0 < int32',
|
||||
'number of stroke control points (count each coordinate as
|
||||
2 points)'],
|
||||
strokes => ['floatarray',
|
||||
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
|
||||
sn.x, sn.y }']);
|
||||
sub stroke_arg () {
|
||||
{ name => 'strokes', type => 'floatarray',
|
||||
desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
|
||||
sn.x, sn.y }',
|
||||
array => { desc => 'number of stroke control points (count each
|
||||
coordinate as 2 points)' } }
|
||||
}
|
||||
|
||||
# The defs
|
||||
|
@ -64,16 +71,17 @@ HELP;
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
pressure => ['0 <= float <= 100',
|
||||
'The pressure of the airbrush strokes $desc'],
|
||||
&stroke_args
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'pressure', type => '0 <= float <= 100',
|
||||
desc => 'The pressure of the airbrush strokes $desc' },
|
||||
&stroke_arg
|
||||
);
|
||||
delete $inargs[0]->{get};
|
||||
|
||||
@invoke = (
|
||||
'airbrush.h',
|
||||
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
%invoke = (
|
||||
headers => [ qw("airbrush.h") ],
|
||||
code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -91,35 +99,44 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
blend_mode => ['enum BlendMode',
|
||||
'The type of blend: $desc'],
|
||||
gradient_type => ['enum PaintMode',
|
||||
'The paint application mode: $desc'],
|
||||
opacity => ['0 <= float <= 100',
|
||||
'The opacity of the final blend $desc'],
|
||||
offset => ['0 <= float',
|
||||
'Offset relates to the starting and ending coordinates
|
||||
specified for the blend. This parameter is mode dependent
|
||||
$desc'],
|
||||
repeat => ['enum RepeatMode', 'Repeat mode: $desc'],
|
||||
supersample => ['boolean', 'Do adaptive supersampling $desc'],
|
||||
max_depth => ['1 <= int32 <= 9',
|
||||
'Maximum recursion levels for supersampling',
|
||||
'attach supersample'],
|
||||
threshold => ['0 <= float <= 4',
|
||||
'Supersampling threshold',
|
||||
'attach supersample'],
|
||||
x1 => ['float', 'The x coordinate of this blend's starting point'],
|
||||
y1 => ['float', 'The y coordinate of this blend's starting point'],
|
||||
x2 => ['float', 'The x coordinate of this blend's ending point'],
|
||||
y2 => ['float', 'The y coordinate of this blend's ending point']
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'blend_mode', type => 'enum BlendMode',
|
||||
desc => 'The type of blend: $desc' },
|
||||
{ name => 'gradient_type', type => 'enum PaintMode',
|
||||
desc => 'The paint application mode: $desc' },
|
||||
{ name => 'opacity', type => '0 <= float <= 100',
|
||||
desc => 'The opacity of the final blend $desc' },
|
||||
{ name => 'offset', type => '0 <= float',
|
||||
desc => 'Offset relates to the starting and ending coordinates
|
||||
specified for the blend. This parameter is mode dependent
|
||||
$desc' },
|
||||
{ name => 'repeat', type => 'enum RepeatMode',
|
||||
desc => 'Repeat mode: $desc' },
|
||||
{ name => 'supersample', type => 'boolean',
|
||||
desc => 'Do adaptive supersampling $desc' },
|
||||
{ name => 'max_depth', type => '1 <= int32 <= 9',
|
||||
desc => 'Maximum recursion levels for supersampling',
|
||||
cond => 'supersample' },
|
||||
{ name => 'threshold', type => '0 <= float <= 4',
|
||||
desc => 'Supersampling threshold',
|
||||
cond => 'supersample' },
|
||||
{ name => 'x1', type => 'float',
|
||||
desc => "The x coordinate of this blend's starting point" },
|
||||
{ name => 'y1', type => 'float',
|
||||
desc => "The y coordinate of this blend's starting point" },
|
||||
{ name => 'x2', type => 'float',
|
||||
desc => "The x coordinate of this blend's ending point" },
|
||||
{ name => 'y2', type => 'float',
|
||||
desc => "The y coordinate of this blend's ending point" }
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'blend.h',
|
||||
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);'
|
||||
%invoke = (
|
||||
headers => [ qw("blend.h") ],
|
||||
code => <<'CODE'
|
||||
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
|
||||
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -144,27 +161,36 @@ HELP;
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
my $validity = 'This parameter is only valid when there is no selection in the specified image.'
|
||||
my $coord = "The \$a coordinate of this bucket fill's application. $validity";
|
||||
my $validity = 'This parameter is only valid when there is no selection in
|
||||
the specified image.'
|
||||
my $coord = "The \$a coordinate of this bucket fill's application.
|
||||
$validity";
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
fill_mode => ['enum FillMode', 'The type of fill: $desc'],
|
||||
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'],
|
||||
opacity => ['0 <= float <= 100',
|
||||
'The opacity of the final bucket fill $desc'],
|
||||
threshold => ['0 <= float <= 255',
|
||||
"The threshold determines how extensive the seed fill
|
||||
will be. It's value is specified in terms of intensity
|
||||
levels \$desc. $validity'],
|
||||
&drawable_arg,
|
||||
{ name => 'fill_mode', type => 'enum FillMode',
|
||||
desc => 'The type of fill: $desc' },
|
||||
{ name => paint_mode, type => 'enum PaintMode',
|
||||
desc => 'The paint application mode: $desc' },
|
||||
{ name => opacity, type => '0 <= float <= 100',
|
||||
desc => 'The opacity of the final bucket fill $desc' },
|
||||
{ name => threshold, type => '0 <= float <= 255',
|
||||
desc => "The threshold determines how extensive the seed fill will
|
||||
be. It's value is specified in terms of intensity levels
|
||||
\$desc. $validity" },
|
||||
&sample_merged_arg,
|
||||
x => ['float', eval qq/{\$a = 'x';"$coord";}/],
|
||||
y => ['float', eval qq/{\$a = 'y';"$coord";}/]
|
||||
{ name => x, type => 'float',
|
||||
desc => eval qq/{\$a = 'x'; "$coord";}/ },
|
||||
{ name => y, type => 'float',
|
||||
desc => eval qq/{\$a = 'y';"$coord";}/ }
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'bucket_fill.h',
|
||||
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);'
|
||||
%invoke = (
|
||||
headers => [ qw ("bucket_fill.h") ],
|
||||
code => <<'CODE'
|
||||
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
|
||||
sample_merged, x, y);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -182,7 +208,7 @@ sufficiently close to the specified color (as determined by the threshold
|
|||
value) are included in the selection. The antialiasing parameter allows the
|
||||
final selection mask to contain intermediate values based on close misses to
|
||||
the threshold bar. Feathering can be enabled optionally and is controlled with
|
||||
the \"feather_radius\" parameter. If the sample_merged parameter is non-zero,
|
||||
the "feather_radius" parameter. If the sample_merged parameter is non-zero,
|
||||
the data of the composite image will be used instead of that for the specified
|
||||
drawable. This is equivalent to sampling for colors after merging all visible
|
||||
layers. In the case of a merged sampling, the supplied drawable is ignored.
|
||||
|
@ -190,20 +216,25 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
color => ['color', 'The color to select'],
|
||||
threshold => ['0 <= int32 <= 255',
|
||||
'Threshold in intensity levels $desc'],
|
||||
operation => ['enum Operation', 'The selection operation: $desc'],
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'color', type => 'color',
|
||||
desc => 'The color to select' },
|
||||
{ name => 'threshold', type => '0 <= int32 <= 255',
|
||||
desc => 'Threshold in intensity levels $desc' },
|
||||
{ name => 'operation', type => 'enum Operation',
|
||||
desc => 'The selection operation: $desc' },
|
||||
&antialias_arg,
|
||||
&feather_select_args,
|
||||
&sample_merged_arg
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'by_color_select.h',
|
||||
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);'
|
||||
%invoke = (
|
||||
headers => [ qw("by_color_select.h") ],
|
||||
code => <<'CODE'
|
||||
by_color_select (gimage, drawable, color, threshold, operation, antialias,
|
||||
feather, feather_radius, sample_merged);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -214,9 +245,9 @@ BLURB
|
|||
|
||||
$help = <<'HELP'
|
||||
This tool clones (copies) from the source drawable starting at the specified
|
||||
source coordinates to the dest drawable. If the \"clone_type\" argument is set
|
||||
source coordinates to the dest drawable. If the "clone_type" argument is set
|
||||
to PATTERN-CLONE, then the current pattern is used as the source and the
|
||||
\"src_drawable\" argument is ignored. Pattern cloning assumes a tileable
|
||||
"src_drawable" argument is ignored. Pattern cloning assumes a tileable
|
||||
pattern and mods the sum of the src coordinates and subsequent stroke offsets
|
||||
with the width and height of the pattern. For image cloning, if the sum of the
|
||||
src coordinates and subsequent stroke offsets exceeds the extents of the src
|
||||
|
@ -227,18 +258,26 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
src_drawable => ['drawable', "The source drawable"],
|
||||
clone_type => ['enum CloneType', 'The type of clone: $desc'],
|
||||
src_x => ['float', 'The x coordinate in the source image'],
|
||||
src_y => ['float', 'The y coordinate in the source image'],
|
||||
&stroke_args
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'src_drawable', type => 'drawable',
|
||||
desc => 'The source drawable' },
|
||||
{ name => 'clone_type', type => 'enum CloneType',
|
||||
desc => 'The type of clone: $desc' },
|
||||
{ name => 'src_x', type => 'float',
|
||||
desc => 'The x coordinate in the source image' },
|
||||
{ name => 'src_y', type => 'float',
|
||||
desc => 'The y coordinate in the source image' },
|
||||
&stroke_arg
|
||||
);
|
||||
delete $inargs[0]->{get};
|
||||
|
||||
@invoke = (
|
||||
'clone.h',
|
||||
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);'
|
||||
%invoke = (
|
||||
headers => [ qw("clone.h") ],
|
||||
code => <<'CODE'
|
||||
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
|
||||
strokes);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -262,19 +301,244 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
x => ['float', 'x coordinate of upper-left corner of rectangle'],
|
||||
y => ['float', 'y coordinate of upper-left corner of rectangle'],
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'x', type => 'float',
|
||||
desc => 'x coordinate of upper-left corner of rectangle' },
|
||||
{ name => 'y', type => 'float',
|
||||
desc => 'y coordinate of upper-left corner of rectangle' },
|
||||
&sample_merged_arg,
|
||||
save_color => ['boolean', 'Save the color to the active palette']
|
||||
{ name => 'save_color', type => 'boolean',
|
||||
desc => 'Save the color to the active palette' }
|
||||
);
|
||||
|
||||
%outargs = (
|
||||
color => ['color', 'The return color']
|
||||
@outargs = (
|
||||
{ name => 'color', type => 'color',
|
||||
desc => 'The return color' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
'color_picker.h',
|
||||
'
|
||||
headers => [ qw("color_picker.h") ],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (success = get_color (gimage, drawable, (int) x, (int) y, sample_merged, save_color)
|
||||
{
|
||||
color = g_new (guchar, 3);
|
||||
color[RED_PIX] = col_value[RED_PIX];
|
||||
color[GREEN_PIX] = col_value[GREEN_PIX];
|
||||
color[BLUE_PIX] = col_value[BLUE_PIX];
|
||||
}
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub convolve {
|
||||
$blurb = 'Convolve (Blur, Sharpen) using the current brush.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool convolves the specified drawable with either a sharpening or blurring
|
||||
kernel. The pressure parameter controls the magnitude of the operation. Like
|
||||
the paintbrush, this tool linearly interpolates between the specified stroke
|
||||
coordinates.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'pressure', type => '0 <= float <= 100',
|
||||
desc => 'The pressure: $desc' },
|
||||
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
|
||||
desc => 'Convolve type: $desc' },
|
||||
&stroke_arg
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("convolve.h") ],
|
||||
code => 'convolve_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
);
|
||||
}
|
||||
|
||||
sub crop {
|
||||
$blurb = 'Crop the image to the specified extents.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This procedure crops the image so that it's new width and height are equal to
|
||||
the supplied parameters. Offsets are also provided which describe the position
|
||||
of the previous image's content. All channels and layers within the image are
|
||||
cropped to the new image extents; this includes the image selection mask. If
|
||||
any parameters are out of range, an error is returned.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&std_image_arg,
|
||||
{ name => 'new_width', type => '0 < int32',
|
||||
desc => 'New image width: (0 < new_width <= width)' },
|
||||
{ name => 'new_height', type => '0 < int32',
|
||||
desc => 'New image height: (0 < new_height <= height)' },
|
||||
{ name => 'offx', type => '0 <= int32',
|
||||
desc => 'x offset: (0 <= offx <= (width - new_width))' },
|
||||
{ name => 'offy', type => '0 <= int32',
|
||||
desc => 'y offset: (0 <= offy <= (height - new_height))' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("crop.h") ],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (new_width > gimage->width ||
|
||||
new_height > gimage->height ||
|
||||
offx > (gimage->width - new_width) ||
|
||||
offy > (gimage->height - new_height)
|
||||
success = FALSE;
|
||||
else
|
||||
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub ellipse_select {
|
||||
$blurb = 'Create an elliptical selection over the specified image.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool creates an elliptical selection over the specified image. The
|
||||
elliptical region can be either added to, subtracted from, or replace the
|
||||
contents of the previous selection mask. If antialiasing is turned on, the
|
||||
edges of the elliptical region will contain intermediate values which give the
|
||||
appearance of a sharper, less pixelized edge. This should be set as TRUE most
|
||||
of the time. If the feather option is enabled, the resulting selection is
|
||||
blurred before combining. The blur is a gaussian blur with the specified
|
||||
feather radius.
|
||||
HELP
|
||||
|
||||
@inargs = (
|
||||
&std_image_arg,
|
||||
{ name => 'x', type => 'float',
|
||||
desc => 'x coordinate of upper-left corner of ellipse bounding box' },
|
||||
{ name => 'y', type => 'float',
|
||||
desc => 'y coordinate of upper-left corner of ellipse bounding box' },
|
||||
{ name => 'width', type => '0 < float',
|
||||
desc => 'The width of the ellipse: $desc' },
|
||||
{ name => 'height', type => '0 < float',
|
||||
desc => 'The height of the ellipse: $desc' },
|
||||
{ name => 'operation', 'enum Selection',
|
||||
desc => 'The selection operation: $desc' },
|
||||
&antialias_arg,
|
||||
&feather_args
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("ellipse_select.h") ],
|
||||
code => <<'CODE'
|
||||
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
|
||||
feather, feather_radius);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub eraser {
|
||||
$blurb = 'Erase using the current brush.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool erases using the current brush mask. If the specified drawable
|
||||
contains an alpha channel, then the erased pixels will become transparent.
|
||||
Otherwise, the eraser tool replaces the contents of the drawable with the
|
||||
background color. Like paintbrush, this tool linearly interpolates between the
|
||||
specified stroke coordinates.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
&stroke_arg,
|
||||
{ name => 'hardness', type => 'enum EraserHardness',
|
||||
desc => '$desc' }
|
||||
{ name => 'method', type => 'enum EraserMethod',
|
||||
desc => '$desc' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("eraser.h") ],
|
||||
code => <<'CODE'
|
||||
eraser_non_gui (drawable, num_strokes, strokes, hardness, method);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub flip {
|
||||
$blurb = <<'BLURB';
|
||||
Flip the specified drawable about its center either vertically or
|
||||
horizontally.
|
||||
BLURB
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool flips the specified drawable if no selection exists. If a selection
|
||||
exists, the portion of the drawable which lies under the selection is cut from
|
||||
the drawable and made into a floating selection which is then flipd by the
|
||||
specified amount. The return value is the ID of the flipped drawable. If there
|
||||
was no selection, this will be equal to the drawable ID supplied as input.
|
||||
Otherwise, this will be the newly created and flipped drawable. The flip type
|
||||
parameter indicates whether the flip will be applied horizontally or
|
||||
vertically.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'flip_type', type => 'enum FlipType',
|
||||
desc => 'Type of flip: $desc' }
|
||||
);
|
||||
|
||||
@outargs = ( &drawable_arg );
|
||||
$outargs[0]->{alias} = layer;
|
||||
$outargs[0]->{desc} = 'The flipped drawable';
|
||||
$outargs[0]->{no_declare} = 1;
|
||||
delete $outargs[0]->{get};
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("flip_tool.h" "tranform_core.h") ],
|
||||
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
|
||||
code => <<'CODE'
|
||||
{
|
||||
/* Start a transform undo group */
|
||||
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
|
||||
|
||||
/* Cut/Copy from the specified drawable */
|
||||
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
|
||||
|
||||
/* flip the buffer */
|
||||
switch (flip_type)
|
||||
{
|
||||
case 0: /* horz */
|
||||
new_tiles = flip_tool_flip_horz (gimage, drawable, float_tiles, -1);
|
||||
break;
|
||||
case 1: /* vert */
|
||||
new_tiles = flip_tool_flip_vert (gimage, drawable, float_tiles, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* free the cut/copied buffer */
|
||||
tile_manager_destroy (float_tiles);
|
||||
|
||||
if (new_tiles)
|
||||
{
|
||||
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
|
||||
success = (layer != NULL);
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
|
||||
/* push the undo group end */
|
||||
undo_push_group_end (gimage);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,31 +21,38 @@
|
|||
|
||||
# shortcuts
|
||||
|
||||
sub tool_init_args {
|
||||
(image => ['image', 'The image'],
|
||||
drawable => ['drawable', 'The affected drawable']);
|
||||
}
|
||||
sub drawable_arg () {{
|
||||
name => 'drawable',
|
||||
type => 'drawable',
|
||||
desc => 'The affected drawable',
|
||||
get => &std_image_arg
|
||||
}}
|
||||
|
||||
sub sample_merged_arg {
|
||||
(sample_merged => ['boolean', 'Use the composite image, not the drawable']);
|
||||
}
|
||||
sub sample_merged_arg () {{
|
||||
name => 'sample_merged',
|
||||
type => 'boolean',
|
||||
desc => 'Use the composite image, not the drawable'
|
||||
}}
|
||||
|
||||
sub antialias_arg {
|
||||
(antialias => ['boolean', 'Antialiasing $desc']);
|
||||
}
|
||||
sub antialias_arg () {{
|
||||
name => 'antialias',
|
||||
type => 'boolean',
|
||||
desc => 'Antialiasing $desc'
|
||||
}}
|
||||
|
||||
sub feather_select_args {
|
||||
(feather => ['boolean', 'Feather option for selections'],
|
||||
feather_radius => ['float', 'Radius for feather operation']);
|
||||
}
|
||||
sub feather_select_args () {(
|
||||
{ name => 'feather', type => 'boolean',
|
||||
desc => 'Feather option for selections' },
|
||||
{ name => 'feather_radius', type => 'float',
|
||||
desc => 'Radius for feather operation' }
|
||||
)}
|
||||
|
||||
sub stroke_args {
|
||||
(num_strokes => ['0 < int32',
|
||||
'number of stroke control points (count each coordinate as
|
||||
2 points)'],
|
||||
strokes => ['floatarray',
|
||||
'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
|
||||
sn.x, sn.y }']);
|
||||
sub stroke_arg () {
|
||||
{ name => 'strokes', type => 'floatarray',
|
||||
desc => 'array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
|
||||
sn.x, sn.y }',
|
||||
array => { desc => 'number of stroke control points (count each
|
||||
coordinate as 2 points)' } }
|
||||
}
|
||||
|
||||
# The defs
|
||||
|
@ -64,16 +71,17 @@ HELP;
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
pressure => ['0 <= float <= 100',
|
||||
'The pressure of the airbrush strokes $desc'],
|
||||
&stroke_args
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'pressure', type => '0 <= float <= 100',
|
||||
desc => 'The pressure of the airbrush strokes $desc' },
|
||||
&stroke_arg
|
||||
);
|
||||
delete $inargs[0]->{get};
|
||||
|
||||
@invoke = (
|
||||
'airbrush.h',
|
||||
'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
%invoke = (
|
||||
headers => [ qw("airbrush.h") ],
|
||||
code => 'airbrush_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -91,35 +99,44 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
blend_mode => ['enum BlendMode',
|
||||
'The type of blend: $desc'],
|
||||
gradient_type => ['enum PaintMode',
|
||||
'The paint application mode: $desc'],
|
||||
opacity => ['0 <= float <= 100',
|
||||
'The opacity of the final blend $desc'],
|
||||
offset => ['0 <= float',
|
||||
'Offset relates to the starting and ending coordinates
|
||||
specified for the blend. This parameter is mode dependent
|
||||
$desc'],
|
||||
repeat => ['enum RepeatMode', 'Repeat mode: $desc'],
|
||||
supersample => ['boolean', 'Do adaptive supersampling $desc'],
|
||||
max_depth => ['1 <= int32 <= 9',
|
||||
'Maximum recursion levels for supersampling',
|
||||
'attach supersample'],
|
||||
threshold => ['0 <= float <= 4',
|
||||
'Supersampling threshold',
|
||||
'attach supersample'],
|
||||
x1 => ['float', 'The x coordinate of this blend's starting point'],
|
||||
y1 => ['float', 'The y coordinate of this blend's starting point'],
|
||||
x2 => ['float', 'The x coordinate of this blend's ending point'],
|
||||
y2 => ['float', 'The y coordinate of this blend's ending point']
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'blend_mode', type => 'enum BlendMode',
|
||||
desc => 'The type of blend: $desc' },
|
||||
{ name => 'gradient_type', type => 'enum PaintMode',
|
||||
desc => 'The paint application mode: $desc' },
|
||||
{ name => 'opacity', type => '0 <= float <= 100',
|
||||
desc => 'The opacity of the final blend $desc' },
|
||||
{ name => 'offset', type => '0 <= float',
|
||||
desc => 'Offset relates to the starting and ending coordinates
|
||||
specified for the blend. This parameter is mode dependent
|
||||
$desc' },
|
||||
{ name => 'repeat', type => 'enum RepeatMode',
|
||||
desc => 'Repeat mode: $desc' },
|
||||
{ name => 'supersample', type => 'boolean',
|
||||
desc => 'Do adaptive supersampling $desc' },
|
||||
{ name => 'max_depth', type => '1 <= int32 <= 9',
|
||||
desc => 'Maximum recursion levels for supersampling',
|
||||
cond => 'supersample' },
|
||||
{ name => 'threshold', type => '0 <= float <= 4',
|
||||
desc => 'Supersampling threshold',
|
||||
cond => 'supersample' },
|
||||
{ name => 'x1', type => 'float',
|
||||
desc => "The x coordinate of this blend's starting point" },
|
||||
{ name => 'y1', type => 'float',
|
||||
desc => "The y coordinate of this blend's starting point" },
|
||||
{ name => 'x2', type => 'float',
|
||||
desc => "The x coordinate of this blend's ending point" },
|
||||
{ name => 'y2', type => 'float',
|
||||
desc => "The y coordinate of this blend's ending point" }
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'blend.h',
|
||||
'blend (image, drawable, blend_mode, paint_mode, gradient_type, opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);'
|
||||
%invoke = (
|
||||
headers => [ qw("blend.h") ],
|
||||
code => <<'CODE'
|
||||
blend (gimage, drawable, blend_mode, paint_mode, gradient_type, opacity,
|
||||
offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -144,27 +161,36 @@ HELP;
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
my $validity = 'This parameter is only valid when there is no selection in the specified image.'
|
||||
my $coord = "The \$a coordinate of this bucket fill's application. $validity";
|
||||
my $validity = 'This parameter is only valid when there is no selection in
|
||||
the specified image.'
|
||||
my $coord = "The \$a coordinate of this bucket fill's application.
|
||||
$validity";
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
fill_mode => ['enum FillMode', 'The type of fill: $desc'],
|
||||
paint_mode => ['enum PaintMode', 'The paint application mode: $desc'],
|
||||
opacity => ['0 <= float <= 100',
|
||||
'The opacity of the final bucket fill $desc'],
|
||||
threshold => ['0 <= float <= 255',
|
||||
"The threshold determines how extensive the seed fill
|
||||
will be. It's value is specified in terms of intensity
|
||||
levels \$desc. $validity'],
|
||||
&drawable_arg,
|
||||
{ name => 'fill_mode', type => 'enum FillMode',
|
||||
desc => 'The type of fill: $desc' },
|
||||
{ name => paint_mode, type => 'enum PaintMode',
|
||||
desc => 'The paint application mode: $desc' },
|
||||
{ name => opacity, type => '0 <= float <= 100',
|
||||
desc => 'The opacity of the final bucket fill $desc' },
|
||||
{ name => threshold, type => '0 <= float <= 255',
|
||||
desc => "The threshold determines how extensive the seed fill will
|
||||
be. It's value is specified in terms of intensity levels
|
||||
\$desc. $validity" },
|
||||
&sample_merged_arg,
|
||||
x => ['float', eval qq/{\$a = 'x';"$coord";}/],
|
||||
y => ['float', eval qq/{\$a = 'y';"$coord";}/]
|
||||
{ name => x, type => 'float',
|
||||
desc => eval qq/{\$a = 'x'; "$coord";}/ },
|
||||
{ name => y, type => 'float',
|
||||
desc => eval qq/{\$a = 'y';"$coord";}/ }
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'bucket_fill.h',
|
||||
'bucket_fill (image, drawable, fill_mode, paint_mode, opacity, threshold, sample_merged, x, y);'
|
||||
%invoke = (
|
||||
headers => [ qw ("bucket_fill.h") ],
|
||||
code => <<'CODE'
|
||||
bucket_fill (gimage, drawable, fill_mode, paint_mode, opacity, threshold,
|
||||
sample_merged, x, y);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -182,7 +208,7 @@ sufficiently close to the specified color (as determined by the threshold
|
|||
value) are included in the selection. The antialiasing parameter allows the
|
||||
final selection mask to contain intermediate values based on close misses to
|
||||
the threshold bar. Feathering can be enabled optionally and is controlled with
|
||||
the \"feather_radius\" parameter. If the sample_merged parameter is non-zero,
|
||||
the "feather_radius" parameter. If the sample_merged parameter is non-zero,
|
||||
the data of the composite image will be used instead of that for the specified
|
||||
drawable. This is equivalent to sampling for colors after merging all visible
|
||||
layers. In the case of a merged sampling, the supplied drawable is ignored.
|
||||
|
@ -190,20 +216,25 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
color => ['color', 'The color to select'],
|
||||
threshold => ['0 <= int32 <= 255',
|
||||
'Threshold in intensity levels $desc'],
|
||||
operation => ['enum Operation', 'The selection operation: $desc'],
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'color', type => 'color',
|
||||
desc => 'The color to select' },
|
||||
{ name => 'threshold', type => '0 <= int32 <= 255',
|
||||
desc => 'Threshold in intensity levels $desc' },
|
||||
{ name => 'operation', type => 'enum Operation',
|
||||
desc => 'The selection operation: $desc' },
|
||||
&antialias_arg,
|
||||
&feather_select_args,
|
||||
&sample_merged_arg
|
||||
);
|
||||
|
||||
@invoke = (
|
||||
'by_color_select.h',
|
||||
'by_color_select (image, drawable, color, threshold, operation, antialias, feather, feather_radius, sample_merged);'
|
||||
%invoke = (
|
||||
headers => [ qw("by_color_select.h") ],
|
||||
code => <<'CODE'
|
||||
by_color_select (gimage, drawable, color, threshold, operation, antialias,
|
||||
feather, feather_radius, sample_merged);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -214,9 +245,9 @@ BLURB
|
|||
|
||||
$help = <<'HELP'
|
||||
This tool clones (copies) from the source drawable starting at the specified
|
||||
source coordinates to the dest drawable. If the \"clone_type\" argument is set
|
||||
source coordinates to the dest drawable. If the "clone_type" argument is set
|
||||
to PATTERN-CLONE, then the current pattern is used as the source and the
|
||||
\"src_drawable\" argument is ignored. Pattern cloning assumes a tileable
|
||||
"src_drawable" argument is ignored. Pattern cloning assumes a tileable
|
||||
pattern and mods the sum of the src coordinates and subsequent stroke offsets
|
||||
with the width and height of the pattern. For image cloning, if the sum of the
|
||||
src coordinates and subsequent stroke offsets exceeds the extents of the src
|
||||
|
@ -227,18 +258,26 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
src_drawable => ['drawable', "The source drawable"],
|
||||
clone_type => ['enum CloneType', 'The type of clone: $desc'],
|
||||
src_x => ['float', 'The x coordinate in the source image'],
|
||||
src_y => ['float', 'The y coordinate in the source image'],
|
||||
&stroke_args
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'src_drawable', type => 'drawable',
|
||||
desc => 'The source drawable' },
|
||||
{ name => 'clone_type', type => 'enum CloneType',
|
||||
desc => 'The type of clone: $desc' },
|
||||
{ name => 'src_x', type => 'float',
|
||||
desc => 'The x coordinate in the source image' },
|
||||
{ name => 'src_y', type => 'float',
|
||||
desc => 'The y coordinate in the source image' },
|
||||
&stroke_arg
|
||||
);
|
||||
delete $inargs[0]->{get};
|
||||
|
||||
@invoke = (
|
||||
'clone.h',
|
||||
'clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes, strokes);'
|
||||
%invoke = (
|
||||
headers => [ qw("clone.h") ],
|
||||
code => <<'CODE'
|
||||
clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, num_strokes,
|
||||
strokes);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -262,19 +301,244 @@ HELP
|
|||
|
||||
&std_pdb_misc;
|
||||
|
||||
%inargs = (
|
||||
&tool_init_args,
|
||||
x => ['float', 'x coordinate of upper-left corner of rectangle'],
|
||||
y => ['float', 'y coordinate of upper-left corner of rectangle'],
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'x', type => 'float',
|
||||
desc => 'x coordinate of upper-left corner of rectangle' },
|
||||
{ name => 'y', type => 'float',
|
||||
desc => 'y coordinate of upper-left corner of rectangle' },
|
||||
&sample_merged_arg,
|
||||
save_color => ['boolean', 'Save the color to the active palette']
|
||||
{ name => 'save_color', type => 'boolean',
|
||||
desc => 'Save the color to the active palette' }
|
||||
);
|
||||
|
||||
%outargs = (
|
||||
color => ['color', 'The return color']
|
||||
@outargs = (
|
||||
{ name => 'color', type => 'color',
|
||||
desc => 'The return color' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
'color_picker.h',
|
||||
'
|
||||
headers => [ qw("color_picker.h") ],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (success = get_color (gimage, drawable, (int) x, (int) y, sample_merged, save_color)
|
||||
{
|
||||
color = g_new (guchar, 3);
|
||||
color[RED_PIX] = col_value[RED_PIX];
|
||||
color[GREEN_PIX] = col_value[GREEN_PIX];
|
||||
color[BLUE_PIX] = col_value[BLUE_PIX];
|
||||
}
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub convolve {
|
||||
$blurb = 'Convolve (Blur, Sharpen) using the current brush.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool convolves the specified drawable with either a sharpening or blurring
|
||||
kernel. The pressure parameter controls the magnitude of the operation. Like
|
||||
the paintbrush, this tool linearly interpolates between the specified stroke
|
||||
coordinates.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'pressure', type => '0 <= float <= 100',
|
||||
desc => 'The pressure: $desc' },
|
||||
{ name => 'convolve_type', type 'enum Convolve (no CUSTOM)',
|
||||
desc => 'Convolve type: $desc' },
|
||||
&stroke_arg
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("convolve.h") ],
|
||||
code => 'convolve_non_gui (drawable, pressure, num_strokes, strokes);'
|
||||
);
|
||||
}
|
||||
|
||||
sub crop {
|
||||
$blurb = 'Crop the image to the specified extents.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This procedure crops the image so that it's new width and height are equal to
|
||||
the supplied parameters. Offsets are also provided which describe the position
|
||||
of the previous image's content. All channels and layers within the image are
|
||||
cropped to the new image extents; this includes the image selection mask. If
|
||||
any parameters are out of range, an error is returned.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&std_image_arg,
|
||||
{ name => 'new_width', type => '0 < int32',
|
||||
desc => 'New image width: (0 < new_width <= width)' },
|
||||
{ name => 'new_height', type => '0 < int32',
|
||||
desc => 'New image height: (0 < new_height <= height)' },
|
||||
{ name => 'offx', type => '0 <= int32',
|
||||
desc => 'x offset: (0 <= offx <= (width - new_width))' },
|
||||
{ name => 'offy', type => '0 <= int32',
|
||||
desc => 'y offset: (0 <= offy <= (height - new_height))' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("crop.h") ],
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (new_width > gimage->width ||
|
||||
new_height > gimage->height ||
|
||||
offx > (gimage->width - new_width) ||
|
||||
offy > (gimage->height - new_height)
|
||||
success = FALSE;
|
||||
else
|
||||
crop_image (gimage, offx, offy, offx + new_width, offy + new_height);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub ellipse_select {
|
||||
$blurb = 'Create an elliptical selection over the specified image.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool creates an elliptical selection over the specified image. The
|
||||
elliptical region can be either added to, subtracted from, or replace the
|
||||
contents of the previous selection mask. If antialiasing is turned on, the
|
||||
edges of the elliptical region will contain intermediate values which give the
|
||||
appearance of a sharper, less pixelized edge. This should be set as TRUE most
|
||||
of the time. If the feather option is enabled, the resulting selection is
|
||||
blurred before combining. The blur is a gaussian blur with the specified
|
||||
feather radius.
|
||||
HELP
|
||||
|
||||
@inargs = (
|
||||
&std_image_arg,
|
||||
{ name => 'x', type => 'float',
|
||||
desc => 'x coordinate of upper-left corner of ellipse bounding box' },
|
||||
{ name => 'y', type => 'float',
|
||||
desc => 'y coordinate of upper-left corner of ellipse bounding box' },
|
||||
{ name => 'width', type => '0 < float',
|
||||
desc => 'The width of the ellipse: $desc' },
|
||||
{ name => 'height', type => '0 < float',
|
||||
desc => 'The height of the ellipse: $desc' },
|
||||
{ name => 'operation', 'enum Selection',
|
||||
desc => 'The selection operation: $desc' },
|
||||
&antialias_arg,
|
||||
&feather_args
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("ellipse_select.h") ],
|
||||
code => <<'CODE'
|
||||
ellipse_select (gimage, (int) x, (int) y, (int) w, (int) h, op, antialias,
|
||||
feather, feather_radius);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub eraser {
|
||||
$blurb = 'Erase using the current brush.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool erases using the current brush mask. If the specified drawable
|
||||
contains an alpha channel, then the erased pixels will become transparent.
|
||||
Otherwise, the eraser tool replaces the contents of the drawable with the
|
||||
background color. Like paintbrush, this tool linearly interpolates between the
|
||||
specified stroke coordinates.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
&stroke_arg,
|
||||
{ name => 'hardness', type => 'enum EraserHardness',
|
||||
desc => '$desc' }
|
||||
{ name => 'method', type => 'enum EraserMethod',
|
||||
desc => '$desc' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("eraser.h") ],
|
||||
code => <<'CODE'
|
||||
eraser_non_gui (drawable, num_strokes, strokes, hardness, method);
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub flip {
|
||||
$blurb = <<'BLURB';
|
||||
Flip the specified drawable about its center either vertically or
|
||||
horizontally.
|
||||
BLURB
|
||||
|
||||
$help = <<'HELP';
|
||||
This tool flips the specified drawable if no selection exists. If a selection
|
||||
exists, the portion of the drawable which lies under the selection is cut from
|
||||
the drawable and made into a floating selection which is then flipd by the
|
||||
specified amount. The return value is the ID of the flipped drawable. If there
|
||||
was no selection, this will be equal to the drawable ID supplied as input.
|
||||
Otherwise, this will be the newly created and flipped drawable. The flip type
|
||||
parameter indicates whether the flip will be applied horizontally or
|
||||
vertically.
|
||||
HELP
|
||||
|
||||
&std_pdb_misc;
|
||||
|
||||
@inargs = (
|
||||
&drawable_arg,
|
||||
{ name => 'flip_type', type => 'enum FlipType',
|
||||
desc => 'Type of flip: $desc' }
|
||||
);
|
||||
|
||||
@outargs = ( &drawable_arg );
|
||||
$outargs[0]->{alias} = layer;
|
||||
$outargs[0]->{desc} = 'The flipped drawable';
|
||||
$outargs[0]->{no_declare} = 1;
|
||||
delete $outargs[0]->{get};
|
||||
|
||||
%invoke = (
|
||||
headers => [ qw("flip_tool.h" "tranform_core.h") ],
|
||||
vars => ['TileManger *float_tiles, *new_tiles', 'Layer *layer']
|
||||
code => <<'CODE'
|
||||
{
|
||||
/* Start a transform undo group */
|
||||
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
|
||||
|
||||
/* Cut/Copy from the specified drawable */
|
||||
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
|
||||
|
||||
/* flip the buffer */
|
||||
switch (flip_type)
|
||||
{
|
||||
case 0: /* horz */
|
||||
new_tiles = flip_tool_flip_horz (gimage, drawable, float_tiles, -1);
|
||||
break;
|
||||
case 1: /* vert */
|
||||
new_tiles = flip_tool_flip_vert (gimage, drawable, float_tiles, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* free the cut/copied buffer */
|
||||
tile_manager_destroy (float_tiles);
|
||||
|
||||
if (new_tiles)
|
||||
{
|
||||
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
|
||||
success = (layer != NULL);
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
|
||||
/* push the undo group end */
|
||||
undo_push_group_end (gimage);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -111,12 +111,7 @@ require 'pdb.pl';
|
|||
require 'util.pl';
|
||||
|
||||
# Squash whitespace into just single spaces between words
|
||||
sub trimspace {
|
||||
my $val = shift;
|
||||
$$val =~ s/[\n\s]+/ /g;
|
||||
$$val =~ s/^ //;
|
||||
$$val =~ s/ $//;
|
||||
}
|
||||
sub trimspace { for (${$_[0]}) { s/[\n\s]+/ /g; s/^ //; s/ $//; } }
|
||||
|
||||
# Trim spaces and escape quotes C-style
|
||||
sub nicetext {
|
||||
|
@ -141,6 +136,37 @@ sub nicelist {
|
|||
foreach (@$list) { &trimspace(\$_) }
|
||||
}
|
||||
|
||||
# Add args for array lengths
|
||||
|
||||
sub arrayexpand {
|
||||
my $args = shift;
|
||||
my $newargs;
|
||||
|
||||
foreach (@$$args) {
|
||||
if (exists $_->{array}) {
|
||||
my $arg = $_->{array};
|
||||
|
||||
$arg->{name} = 'num_' . $_->{name} unless exists $arg->{name};
|
||||
|
||||
# We can't have negative lengths, but let them set a min number
|
||||
unless (exists $arg->{type}) {
|
||||
$arg->{type} = '0 < int32';
|
||||
}
|
||||
elsif ($arg->{type} !~ /^\s*\d+\s*</) {
|
||||
$arg->{type} = '0 < ' . $arg->{type};
|
||||
}
|
||||
|
||||
$arg->{num} = 1;
|
||||
|
||||
push @$newargs, $arg;
|
||||
}
|
||||
|
||||
push @$newargs, $_;
|
||||
}
|
||||
|
||||
$$args = $newargs;
|
||||
}
|
||||
|
||||
# Post-process each pdb entry
|
||||
while ((undef, $entry) = each %pdb) {
|
||||
&nicetext(\$entry->{blurb});
|
||||
|
@ -148,16 +174,24 @@ while ((undef, $entry) = each %pdb) {
|
|||
&nicetext(\$entry->{author});
|
||||
&nicetext(\$entry->{copyright});
|
||||
&nicetext(\$entry->{date});
|
||||
|
||||
&arrayexpand(\$entry->{inargs}) if exists $entry->{inargs};
|
||||
&arrayexpand(\$entry->{outargs}) if exists $entry->{outargs};
|
||||
|
||||
&niceargs($entry->{inargs}) if exists $entry->{inargs};
|
||||
&niceargs($entry->{outargs}) if exists $entry->{outargs};
|
||||
|
||||
&nicelist($entry->{invoke}{headers}) if exists $entry->{invoke}{headers};
|
||||
&nicelist($entry->{globals}) if exists $entry->{globals}
|
||||
&nicelist($entry->{globals}) if exists $entry->{globals};
|
||||
|
||||
$entry->{invoke}{success} = 'TRUE' unless exists $entry->{invoke}{success};
|
||||
}
|
||||
|
||||
# Generate code from the modules
|
||||
my $didstuff;
|
||||
while (@ARGV) {
|
||||
my $type = shift @ARGV;
|
||||
|
||||
print "\nProcessing $type...\n";
|
||||
|
||||
if (exists $gen{$type}) {
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
# Boilerplate PDB stuff
|
||||
|
||||
sub std_pdb_misc {
|
||||
$author = 'Spencer Kimball & Peter Mattis';
|
||||
$copyright = $author;
|
||||
$author = $copyright = 'Spencer Kimball & Peter Mattis';
|
||||
$date = '1995-1996';
|
||||
}
|
||||
|
||||
sub std_image_arg () {
|
||||
{
|
||||
name => 'image',
|
||||
type => 'image',
|
||||
desc => 'The image',
|
||||
alias => 'gimage'
|
||||
}
|
||||
}
|
||||
sub std_image_arg () {{
|
||||
name => 'image',
|
||||
type => 'image',
|
||||
desc => 'The image',
|
||||
alias => 'gimage'
|
||||
}}
|
||||
|
||||
1;
|
||||
|
|
|
@ -17,14 +17,16 @@
|
|||
|
||||
package Gimp::CodeGen::util;
|
||||
|
||||
use File::Copy cp;
|
||||
use File::Compare cmp;
|
||||
use File::Copy 'cp';
|
||||
use File::Compare 'cmp';
|
||||
|
||||
$DEBUG_OUTPUT = 1;
|
||||
|
||||
$FILE_EXT = ".tmp.$$";
|
||||
|
||||
sub write_file {
|
||||
my $file = shift; my $realfile = $file;
|
||||
$realfile =~ s/\.tmp\.\d+$//;
|
||||
$realfile =~ s/$FILE_EXT//;
|
||||
if (-e $realfile) {
|
||||
if (cmp($realfile, $file)) {
|
||||
cp($realfile, "$realfile~") if $DEBUG_OUTPUT;
|
||||
|
|
Loading…
Reference in New Issue