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