Initial checkin of Pika from heckimp

This commit is contained in:
2023-09-25 15:35:21 -07:00
commit 891e999216
6761 changed files with 5240685 additions and 0 deletions

111
pdb/README Normal file
View File

@ -0,0 +1,111 @@
Some mostly unfinished docs are here.
-Yosh
This document describes the tool PDBGEN.
If you added or modified .pdb files do not run this tool manually but
run make instead! It will call pdbgen.pl then to generate the files
into the right output directories.
PDBGEN
------------------
What is this?
PDBGEN is a tool to automate much of the drudge work of making PDB interfaces
to PIKA internals. Right now, it generates PDB description records,
argument marshallers (with sanity checking) for the app side, as well
as libpika wrappers for C plugins. It's written so that extending it
to provide support for CORBA and other languages suited to static
autogeneration.
Invoking PDBGEN from the command line:
1. Change into the ./pdb directory.
2. $ ./pdbgen.pl DIRNAME
where DIRNAME is either "lib" or "app", depending on which set of files
you want to generate. The files are written into $destdir/app or $destdir/libpika.
$destdir is the environment variable destdir. If it's not set,
then it's the ./pdb directory. Make sure the directories
$destdir/app and $destdir/libpika already exist and you have write permissions.
Otherwise the code generator will fail and exit.
It's up to you to diff the file you changed. When you're happy with
the generated file, copy it into the actual ./app/ or ./libpika/ directory
where it finally gets built.
Anatomy of a PDB descriptor:
PDB descriptors are Perl code. You define a subroutine, which corresponds
to the PDB function you want to create. You then fill certain special
variables to fully describe all the information pdbgen needs to generate
code. Since it's perl, you can do practically whatever perl lets you
do to help you do this. However, at the simplest level, you don't need
to know perl at all to make PDB descriptors.
Annotated description:
For example, we will look at pika_display_new, specified in gdisplay.pdb.
sub display_new {
We start with the name of our PDB function (not including the "pika_" prefix).
$blurb = 'Create a new display for the specified image.';
This directly corresponds to the "blurb" field in the ProcRecord.
$help = <<'HELP';
Creates a new display for the specified image. If the image already has a
display, another is added. Multiple displays are handled transparently by the
PIKA. The newly created display is returned and can be subsequently destroyed
with a call to 'pika-display-delete'. This procedure only makes sense for use
with the PIKA UI.
HELP
This is the help field. Notice because it is a long string, we used HERE
document syntax to split it over multiple lines. Any extra whitespace
in $blurb or $help, including newlines, is automatically stripped, so you
don't have to worry about that.
&std_pdb_misc;
This is the "author", "copyright", and "date" fields. Since S&P are quite
common, they get a special shortcut which fills these in for you. Stuff
like this is defined in stddefs.pdb.
@inargs = ( &std_image_arg );
You specify arguments in a list. Again, your basic image is very common,
so it gets a shortcut.
@outargs = (
{ name => 'display', type => 'display',
desc => 'The new display', alias => 'gdisp', init => 1 }
);
This is a real argument. It has a name, type, description at a minimum.
"alias" lets you use the alias name in your invoker code, but the real
name is still shown in the ProcRecord. This is useful not only as a
shorthand, but for grabbing variables defined somewhere else (or constants),
in conjunction with the "no_declare" flag. "init" simply says initialize
this variable to a dummy value (in this case to placate gcc warnings)
%invoke = (
headers => [ qw("gdisplay.h") ],
These are the headers needed for the functions you call.
vars => [ 'guint scale = 0x101' ],
Extra variables can be put here for your invoker.
code => <<'CODE'
{
if (gimage->layers == NULL)
success = FALSE;
else
success = ((gdisp = gdisplay_new (gimage, scale)) != NULL);
}
CODE
The actual invoker code. Since it's a multiline block, we put curly braces
in the beginning.

507
pdb/README_NEW_PDB_PROC Normal file
View File

@ -0,0 +1,507 @@
Creating new PDB procedures
===========================
Barak Itkin <lightningismyname@gmail.com>
version 1.0, August 2010
////
This document is an asciidoc document. It can be read as is, or you can
print it as a formatted HTML page by running
asciidoc README_NEW_PDB_PROC
This will generate the file README_NEW_PDB_PROC.html.
Note that inline code parts are marked with + signs around them.
////
This tutorial will show you the basics of creating a new procedure and
adding it to PIKA's PDB.
Introduction
------------
What are PDB procedures?
~~~~~~~~~~~~~~~~~~~~~~~~
A *PDB procedure* is a process which is registered in the Procedure
Data-Base. Procedures registered in the database are available to all
the PIKA plugins/scripts.
What should I want to add to the PDB?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let's say a new feature was added to PIKA, and your plugin/script wants
to use it. In order to do so, this function should be publicly available
(most functions are only available to PIKA's core, and in order to
expose them externally we have to add them to the PDB).
Anything I should know before continuing this tutorial?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Yes. You should know
https://en.wikipedia.org/wiki/C_%28programming_language%29[C Programming]
(C is the language in which PIKA is coded), know a bit of
https://library.gnome.org/devel/glib/stable/[Glib] (the library which
PIKA uses for many of it's data-structures). In addition, you should
know enough about the PIKA core for implementing your function (this is
not a programming tutorial, this is only a technical tutorial) or at
least have the intuition to understand enough from the code you see, to
copy paste and modify the parts you need (In fact, this is how I made my
first addition to the PDB :D However in most cases it's better to know
what you are doing).
The basics of PDB procedures
----------------------------
Since adding a function to the PDB can be tedious (you would need to
modify 3 or more different source files), a scripting framework was
developed to add functions to the PDB by writing them once. To see how
function are implemented in the PDB, take a look in
https://gitlab.gnome.org/GNOME/pika/tree/master/pdb/groups[pdb/groups].
You can see many files with the .pdb suffix - these are special template
files which include the actual source of the PDB functions. Let's take a
quick look at one of these - text_layer_get_text in
https://gitlab.gnome.org/GNOME/pika/tree/master/pdb/groups/text_layer.pdb[pdb/groups/text_layer.pdb].
[source,perl]
----
sub text_layer_get_text {
$blurb = 'Get the text from a text layer as string.';
$help = <<'HELP';
This procedure returns the text from a text layer as a string.
HELP
&marcus_pdb_misc('2008', '2.6');
@inargs = (
{ name => 'layer', type => 'layer',
desc => 'The text layer' }
);
@outargs = (
{ name => 'text', type => 'string',
desc => 'The text from the specified text layer.' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_layer_is_text_layer (layer, FALSE, error))
{
g_object_get (pika_text_layer_get_text (PIKA_TEXT_LAYER (layer)),
"text", &text,
NULL);
}
else
{
success = FALSE;
}
}
CODE
);
}
----
As you can see, all the function is wrapped inside the following wrapper:
[source,perl]
----
sub text_layer_get_text {
...
}
----
That's the first line, declaring the name of the new PDB function (it
will be renamed to +pika_text_layer_get_text+ automatically), and
opening the braces for it's content.
Description of the procedure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At the beginning of the PDB function, you'll find lines similar to these:
[source,perl]
----
$blurb = 'Get the text from a text layer as string.';
$help = <<'HELP';
This procedure returns the text from a text layer as a string.
HELP
----
Every procedure has a blurb string and a help string. A blurb is a short
string summarizing what the function does, and the help is a longer
string in which you describe your function in more depth.
A one line string can be specified by simply putting it between braces
(like the blurb string). A longer string, which can possibly spread over
several lines, must be written in a special way:
[source,perl]
----
<<'HELP';
This procedure returns the text from a text layer as a string.
HELP
----
The +<<'*HELP*'+ practically mean that the content of the string will be
specified in the next lines and it will continue until reaching a line
which has the content +HELP+ in it (without any spaces before/after it,
and without anything else in that line).
Now, the next line is:
[source,perl]
----
&marcus_pdb_misc('2008', '2.6');
----
If you contribute a function to the PIKA PDB, you credit yourself in the
source code. The above line is for an author which contributed many
functions and he now has a simple macro to credit him. For us regular
users, if we want to specify the credit to ourself we should replace the
above line with the following lines:
[source,perl]
----
$author = 'Elvis Presley <the_king@rock.com>';
$copyright = 'Elvis Presley';
$date = '2010';
$since = '2.8';
----
Replace the values of +$author+ and +$copyright+ with your own name and
email, replace the value of +$date+ with the date in which you wrote the
function (most functions only specify the year, so try to keep with this
standard instead of adding a full date). And finally, replace the value
of +$since+ with the version of PIKA which will be the first to include
this function. For example, if PIKA 2.6 was released, and 2.8 wasn't
released yet. then new functionality will be added in 2.8 (new
functionality is only added inside new major version releases) and you
should specify 2.8.
In and Out Arguments
~~~~~~~~~~~~~~~~~~~~
After the header of the function which contains it's description, you'll
find these lines:
[source,perl]
----
@inargs = (
{ name => 'layer', type => 'layer',
desc => 'The text layer' }
);
@outargs = (
{ name => 'text', type => 'string',
desc => 'The text from the specified text layer.' }
);
----
Here we specify the input arguments of this procedure, together with the
returned arguments. As you can see, each argument has a name, a type and
a description. The name will be used later in our code and it should be
meaningful and be a valid name for a variable in C.
The type is one of the types listed in
https://gitlab.gnome.org/GNOME/pika/tree/master/pdb/pdb.pl[pdb/pdb.pl]
inside the +%arg_types+ array. In
https://gitlab.gnome.org/GNOME/pika/tree/master/pdb/pdb.pl[pdb/pdb.pl]
you can see the corresponding C type for each of the types we specify.
For example, +layer+ type (inside the .pdb file) becomes a variable with
the C type of +PikaLayer *+, and +string+ becomes +gchar *+.
If I want to add another input variable to the function, it'll look like this:
[source,perl]
----
@inargs = (
{ name => 'layer', type => 'layer',
desc => 'The text layer' },
{ name => 'temp', type => 'int32',
desc => 'My silly number' }
);
@outargs = (
{ name => 'text', type => 'string',
desc => 'The text from the specified text layer.' }
);
----
Don't forget to add comma between arguments!
The actual code
~~~~~~~~~~~~~~~
After specifying the arguments we will specify the actual code of the
function inside the following wrapper:
[source,perl]
----
%invoke = (
code => <<'CODE'
...
CODE
);
----
Now finally, let's take a look at the actual code:
[source,c]
----
{
if (pika_pdb_layer_is_text_layer (layer, FALSE, error))
{
g_object_get (pika_text_layer_get_text (PIKA_TEXT_LAYER (layer)),
"text", &text,
NULL);
}
else
{
success = FALSE;
}
}
----
This is a simple code in C - nothing fancy. However, this code uses
functions from inside PIKA's core (hacking on the PIKA core will be the
content for a different guide). The variables +text+ and +layer+, inside
the C code, correspond to the variables we specified in the input/output
arguments (since they have exactly the same name):
[source,c]
----
@inargs = (
{ name => 'layer', type => 'layer',
desc => 'The text layer' }
);
@outargs = (
{ name => 'text', type => 'string',
desc => 'The text from the specified text layer.' }
);
----
If for some reason, our function can fail (for example, in the code
above the second line checks if the passed parameter is indeed a text
layer and not just any layer) then we should add an indication that it
failed by setting the variable +success+ to have the value +FALSE+.
Now, we need to do two more things to finish our function: add it to
the function list, and configure the includes correctly.
Registering the function inside the PDB file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At the end of the PDB file, you should find the following segments:
[source,perl]
----
@headers = qw("libpikabase/pikabase.h"
"core/pikacontext.h"
"text/pikatext.h"
"text/pikatextlayer.h"
"pikapdb-utils.h"
"pikapdberror.h"
"pika-intl.h");
@procs = qw(text_layer_new
text_layer_get_text
text_layer_set_text
...
);
----
Inside the +@headers+ there is a list of various header files from the
pika source. If your code requires a header which is not specified, add
it there.
Inside the +@procs+ there is a list of the procedures which are exported
by the file. *Make sure you add your procedure to the list!*
Advanced details
----------------
enum arguments
~~~~~~~~~~~~~~
In some cases you would like to have arguments which have a value from
an enum (enumeration). Instead of just declaring these as integer values
and telling in your description which value corresponds to which number,
this can be done automatically for you if the desired enum is one of the
enums which are already used by PIKA.
To make it clearer, let's take a look at +layer_get_mode+ in
https://gitlab.gnome.org/GNOME/pika/tree/master/pdb/groups/layer.pdb[pdb/groups/layer.pdb]:
[source,perl]
----
@outargs = (
{ name => 'mode', type => 'enum PikaLayerModeEffects',
desc => 'The layer combination mode' }
);
----
If we take a look at the same procedure as it shows up in the procedure
browser (+pika_layer_get_mode+), we will see the following return values:
[options="header",cols="1,1,11"]
|=======================================================================
|Name |Type |Description
|mode |INT32 |
The layer combination mode { NORMAL-MODE (0), DISSOLVE-MODE (1),
BEHIND-MODE (2), MULTIPLY-MODE (3), SCREEN-MODE (4), OVERLAY-MODE (5),
DIFFERENCE-MODE (6), ADDITION-MODE (7), SUBTRACT-MODE (8),
DARKEN-ONLY-MODE (9), LIGHTEN-ONLY-MODE (10), HUE-MODE (11),
SATURATION-MODE (12), COLOR-MODE (13), VALUE-MODE (14),
DIVIDE-MODE (15), DODGE-MODE (16), BURN-MODE (17), HARDLIGHT-MODE (18),
SOFTLIGHT-MODE (19), GRAIN-EXTRACT-MODE (20), GRAIN-MERGE-MODE (21),
COLOR-ERASE-MODE (22), ERASE-MODE (23), REPLACE-MODE (24),
ANTI-ERASE-MODE (25) }
|=======================================================================
As you can see, all the values of the enum were listed (the source file
containing this enum is
https://gitlab.gnome.org/GNOME/pika/tree/master/app/base/base-enums.h[app/base/base-enums.h])
in it's description, and the type for this argument was declared as an
integer value (reminder: enumeration values in C are actually mapped to
numbers, unlike languages such as Java where enumeration values are
indeed a new type in the language).
Limiting the range of numerical arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In some cases you would like to limit the range of numerical values
passed as parameters for your PDB function. For example, the width of
newly created images should be limited to be at least 1 (since images
with 0 width don't make sense...) and it also should be limited to some
maximal width (so that it won't be bigger than the maximal size PIKA
supports).
We can add this sort of range limitations inside the declaration of the
function, and by that we can make sure it won't be called with values
out of range (PIKA will make sure the values are inside the specified
range before it calls our function). To see an example, let's take look
at the procedure image_new from
https://gitlab.gnome.org/GNOME/pika/tree/master/pdb/groups/image.pdb[pdb/groups/image.pdb]:
[source,perl]
----
@inargs = (
{ name => 'width', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
desc => 'The width of the image' },
{ name => 'height', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
desc => 'The height of the image' },
{ name => 'type', type => 'enum PikaImageBaseType',
desc => 'The type of image' }
);
----
As you can see, inside the +*type*+ field of the first two parameters,
we added a limitation on the range of the parameter. The lower
limitation is a simple number, and the upper limitation is a constant
macro (+PIKA_MAX_IMAGE_SIZE+) defined in
https://gitlab.gnome.org/GNOME/pika/tree/master/libpikabase/pikalimits.h[libpikabase/pikalimits.h].
In order to make sure this constand will indeed be defined when parsing
this function, the file
https://gitlab.gnome.org/GNOME/pika/tree/master/libpikabase/pikabase.h[libpikabase/pikabase.h]
(which includes
https://gitlab.gnome.org/GNOME/pika/tree/master/libpikabase/pikalimits.h[libpikabase/pikalimits.h])
was added to the +@headers+ section of the pdb file.
Now, if you take a look at the code part of this function you won't see
any check that the value is indeed inside the specified range. As we
said, PIKA takes care of this automatically for us so we don't need to
add the check ourselves. Inside the procedure browser, this procedure
would show up like this:
[options="header",cols="1,1,11"]
|=======================================================================
|Name |Type |Description
|width |INT32 |The width of the image (1 \<= width \<= 262144)
|height |INT32 |The height of the image (1 \<= height \<= 262144)
|type |INT32 |The type of image { RGB (0), GRAY (1), INDEXED (2) }
|=======================================================================
Array arguments
~~~~~~~~~~~~~~~
In some cases you will want a function which returns an array or a
function which receives an array. Array arguments are specified in a
special way which is a bit different than the other arguments. To see
how array arguments are specified, let's take a look at the +@outargs+
of +vectors_stroke_get_points+ from
https://gitlab.gnome.org/GNOME/pika/tree/master/pdb/groups/vectors.pdb[pdb/groups/vectors.pdb]:
[source,perl]
----
@outargs = (
{ name => 'type', type => 'enum PikaVectorsStrokeType',
desc => 'type of the stroke (always PIKA_VECTORS_STROKE_TYPE_BEZIER for now).' },
{ name => 'controlpoints', type => 'floatarray',
desc => 'List of the control points for the stroke (x0, y0, x1, y1, ...).',
array => { name => 'num_points',
desc => 'The number of floats returned.' } },
{ name => 'closed', type => 'boolean',
desc => 'Whether the stroke is closed or not.' }
);
----
As you can see, the second argument which is of type +floatarray+ is
specified in a different way than the other arguments; In addition to
+name+, +type+ and +desc+, it also has an +*array*+ part. This part
will declare another parameter for this function which will hold the
length of the array (Reminder: in C you need the length of an array
since unlike languages such as python, the length of an array isn't kept
by default).
As a result of this declaration, two arguments will be created (in this
order):
--
. +*num_points*+ - a parameter of type +gint32+ which will hold the
length of the array.
. +*controlpoints*+ - a parameter of type +gdouble*+ which will point to
the first element in the array.
--
Like all the other arguments which are declared in the +@outargs+ and
+@intargs+ parts, their name value will be the name of the variable in
the code part. If you'll look at the code part of this function,
you'll be able to find these lines:
[source,c]
----
num_points = points_array->len;
controlpoints = g_new (gdouble, num_points * 2);
----
As you can see from the code above, the +controlpoints+ argument starts
just as a pointer to a double (array) - you have to do the allocation of
the array yourself. However, if we would specify an array as an input
argument, then the pointer will point to its beginning.
Summary
-------
Hey! Now what - how do I see my function?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compile PIKA again from the source, and pass the flag --with-pdbgen to
the configure script (or to the autogen script if using the autogen
script).
Conclusions
~~~~~~~~~~~
Now that you know how a PDB function looks like, you should be able to
add new ones of your own if PIKA needs them (ask on the development list
before working on a new function like this, since you need to see if the
developers agree that it's needed!).
Don't forget to include the functions inside the right files! Under
https://gitlab.gnome.org/GNOME/pika/tree/master/pdb/groups[pdb/groups]
you can see many files (fonts.pdb, brush.pdb, layer.pdb, etc.) - *make
sure you add your function in the place which logically suites it!*

1081
pdb/app.pl Normal file

File diff suppressed because it is too large Load Diff

260
pdb/enumcode.pl Normal file
View File

@ -0,0 +1,260 @@
#!/usr/bin/perl -w
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1999-2003 Manish Singh <yosh@gimp.org>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUTFILE 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, see <https://www.gnu.org/licenses/>.
BEGIN {
$srcdir = $ENV{srcdir} || '.';
$destdir = $ENV{destdir} || '.';
$builddir = $ENV{builddir} || '.';
}
use lib $srcdir;
require 'enums.pl';
require 'util.pl';
*enums = \%Pika::CodeGen::enums::enums;
*write_file = \&Pika::CodeGen::util::write_file;
*FILE_EXT = \$Pika::CodeGen::util::FILE_EXT;
my $enumfile = "$builddir/libpika/pikaenums.h$FILE_EXT";
open ENUMFILE, "> $enumfile" or die "Can't open $enumfile: $!\n";
print ENUMFILE <<'LGPL';
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
/* NOTE: This file is autogenerated by enumcode.pl */
LGPL
my $guard = "__PIKA_ENUMS_H__";
print ENUMFILE <<HEADER;
#ifndef $guard
#define $guard
G_BEGIN_DECLS
HEADER
foreach (sort keys %enums) {
if (! ($enums{$_}->{header} =~ /libpika/) &&
! $enums{$_}->{external}) {
my $gtype = $func = $_;
for ($gtype) { s/Pika//; s/([A-Z][^A-Z]+)/\U$1\E_/g; s/_$// }
for ($func) { s/Pika//; s/([A-Z][^A-Z]+)/\L$1\E_/g; s/_$// }
print ENUMFILE "\n#define PIKA_TYPE_$gtype (pika_$func\_get_type ())\n\n";
print ENUMFILE "GType pika_$func\_get_type (void) G_GNUC_CONST;\n\n";
print ENUMFILE "/**\n";
print ENUMFILE " * $_:\n";
my $enum = $enums{$_};
foreach $symbol (@{$enum->{symbols}}) {
print ENUMFILE " * @" . $symbol . ": " . $symbol . "\n";
}
print ENUMFILE " *\n";
print ENUMFILE " * Extracted from app/" . $enums{$_}->{header} . "\n";
print ENUMFILE " **/\n";
print ENUMFILE "typedef enum\n{\n";
my $body = "";
foreach $symbol (@{$enum->{symbols}}) {
my $sym = $symbol;
$body .= " $sym";
$body .= " = $enum->{mapping}->{$symbol}" if !$enum->{contig};
$body .= ",\n";
}
$body =~ s/,\n$//s;
$body .= "\n} ";
$body .= "$_;\n\n";
print ENUMFILE $body
}
}
print ENUMFILE <<HEADER;
void pika_enums_init (void);
const gchar ** pika_enums_get_type_names (gint *n_type_names);
G_END_DECLS
#endif /* $guard */
HEADER
close ENUMFILE;
&write_file($enumfile, "$destdir/libpika");
$enumfile = "$builddir/libpika/pikaenums.c.tail$FILE_EXT";
open ENUMFILE, "> $enumfile" or die "Can't open $enumfile: $!\n";
print ENUMFILE <<CODE;
typedef GType (* PikaGetTypeFunc) (void);
static const PikaGetTypeFunc get_type_funcs[] =
{
CODE
my $first = 1;
foreach (sort keys %enums) {
if (! ($_ =~ /PikaUnit/)) {
my $enum = $enums{$_};
my $func = $_;
my $gegl_enum = ($func =~ /Gegl/);
for ($func) { s/Pika//; s/Gegl//; s/PDB/Pdb/;
s/([A-Z][^A-Z]+)/\L$1\E_/g; s/_$// }
print ENUMFILE ",\n" unless $first;
if ($gegl_enum) {
print ENUMFILE " gegl_$func\_get_type";
} else {
print ENUMFILE " pika_$func\_get_type";
}
$first = 0;
}
}
print ENUMFILE "\n" unless $first;
print ENUMFILE <<CODE;
};
static const gchar * const type_names[] =
{
CODE
$first = 1;
foreach (sort keys %enums) {
if (! ($_ =~ /PikaUnit/)) {
my $enum = $enums{$_};
my $gtype = $_;
print ENUMFILE ",\n" unless $first;
print ENUMFILE " \"$gtype\"";
$first = 0;
}
}
print ENUMFILE "\n" unless $first;
print ENUMFILE <<CODE;
};
static gboolean enums_initialized = FALSE;
#if 0
/* keep around as documentation how to do compat enums */
GType pika_convert_dither_type_compat_get_type (void);
#endif
/**
* pika_enums_init:
*
* This function makes sure all the enum types are registered
* with the #GType system. This is intended for use by language
* bindings that need the symbols early, before pika_main is run.
* It's not necessary for plug-ins to call this directly, because
* the normal plug-in initialization code will handle it implicitly.
*
* Since: 2.4
**/
void
pika_enums_init (void)
{
const PikaGetTypeFunc *funcs = get_type_funcs;
#if 0
GQuark quark;
#endif
gint i;
if (enums_initialized)
return;
for (i = 0; i < G_N_ELEMENTS (get_type_funcs); i++, funcs++)
{
GType type = (*funcs) ();
g_type_class_ref (type);
}
#if 0
/* keep around as documentation how to do compat enums */
/* keep compat enum code in sync with app/app.c (app_libs_init) */
quark = g_quark_from_static_string ("pika-compat-enum");
g_type_set_qdata (PIKA_TYPE_CONVERT_DITHER_TYPE, quark,
(gpointer) pika_convert_dither_type_compat_get_type ());
#endif
pika_base_compat_enums_init ();
enums_initialized = TRUE;
}
/**
* pika_enums_get_type_names:
* \@n_type_names: (out): return location for the number of names
*
* This function gives access to the list of enums registered by libpika.
* The returned array is static and must not be modified.
*
* Returns: (array length=n_type_names) (transfer none): an array with type names
*
* Since: 2.2
**/
const gchar **
pika_enums_get_type_names (gint *n_type_names)
{
g_return_val_if_fail (n_type_names != NULL, NULL);
*n_type_names = G_N_ELEMENTS (type_names);
return (const gchar **) type_names;
}
CODE
close ENUMFILE;
&write_file($enumfile, "$destdir/libpika");

268
pdb/enumgen.pl Normal file
View File

@ -0,0 +1,268 @@
#!/usr/bin/perl -w
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1999-2003 Manish Singh <yosh@gimp.org>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUTFILE 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, see <https://www.gnu.org/licenses/>.
BEGIN {
$srcdir = $ENV{srcdir} || '.';
$destdir = $ENV{destdir} || '.';
$builddir = $ENV{builddir} || '.';
}
use lib $srcdir;
use Text::Wrap qw(wrap $columns);
$columns = 77;
#BEGIN { require 'util.pl' }
require 'util.pl';
*write_file = \&Pika::CodeGen::util::write_file;
*FILE_EXT = \$Pika::CodeGen::util::FILE_EXT;
my $header = <<'HEADER';
:# PIKA - Photo and Image Kooker Application
:# Copyright (C) 1999-2003 Manish Singh <yosh@gimp.org>
:
:# This program is free software: you can redistribute it and/or modify
:# it under the terms of the GNU General Public License as published by
:# the Free Software Foundation; either version 3 of the License, or
:# (at your option) any later version.
:
:# This program is distributed in the hope that it will be useful,
:# but WITHOUTFILE 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, see <https://www.gnu.org/licenses/>.
:
:# autogenerated by enumgen.pl
:
:package Pika::CodeGen::enums;
:
:%enums = (
HEADER
my $external;
open my $EXTERNAL, "enums-external.pl";
{
local $/;
$external = <$EXTERNAL>;
}
close $EXTERNAL;
my $footer = <<'FOOTER';
:);
:
:foreach $e (values %enums) {
: $e->{info} = "";
: foreach (@{$e->{symbols}}) {
: $e->{info} .= "$_ ($e->{mapping}->{$_}), "
: }
: $e->{info} =~ s/, $//;
:}
:
:1;
FOOTER
my ($enumname, $contig, $symbols, @mapping, $before);
# Most of this enum parsing stuff was swiped from makeenums.pl in GTK+
sub parse_options {
my $opts = shift;
my @opts;
for $opt (split /\s*,\s*/, $opts) {
$opt =~ s/^\s*//;
$opt =~ s/\s*$//;
my ($key,$val) = $opt =~ /([-\w]+)(?:=(.+))?/;
defined $val or $val = 1;
push @opts, $key, $val;
}
@opts;
}
sub parse_entries {
my $file = shift;
my $file_name = shift;
my $looking_for_name = 0;
while (<$file>) {
# Read lines until we have no open comments
while (m@/\*([^*]|\*(?!/))*$@) {
my $new;
defined ($new = <$file>) || die "Unmatched comment in $ARGV";
$_ .= $new;
}
# strip comments w/o options
s@/\*(?!<)
([^*]+|\*(?!/))*
\*/@@gx;
s@\n@ @;
next if m@^\s*$@;
if ($looking_for_name) {
if (/^\s*(\w+)/) {
$enumname = $1;
return 1;
}
}
# Handle include files
if (/^\#include\s*<([^>]*)>/ ) {
my $file= "../$1";
open NEWFILE, $file or die "Cannot open include file $file: $!\n";
if (&parse_entries (\*NEWFILE, $NEWFILE)) {
return 1;
} else {
next;
}
}
if (/^\s*\}\s*(\w+)/) {
$enumname = $1;
return 1;
}
if (/^\s*\}/) {
$looking_for_name = 1;
next;
}
if (m@^\s*
(\w+)\s* # name
(?:=( # value
(?:[^,/]|/(?!\*))*
))?,?\s*
(?:/\*< # options
(([^*]|\*(?!/))*)
>\s*\*/)?,?
\s*$
@x) {
my ($name, $value, $options) = ($1, $2, $3);
if (defined $options) {
my %options = parse_options($options);
next if defined $options{"pdb-skip"};
}
$symbols .= $name . ' ';
# Figure out a default value (not really foolproof)
$value = $before + 1 if !defined $value;
$value =~ s/\s*$//s;
$value =~ s/^\s*//s;
push @mapping, $name, $value;
my $test = $before + 1;
# Warnings in our eval should be fatal so they set $@
local $SIG{__WARN__} = sub { die $_[0] };
# Try to get a numeric value
eval "\$test = $value * 1;";
# Assume noncontiguous if it's not a number
$contig = 0 if $contig && ($@ || $test - 1 != $before);
$before = $test;
} elsif (m@^\s*\#@) {
# ignore preprocessor directives
} else {
print STDERR "$0: $file_name:$.: Failed to parse `$_'\n";
}
}
return 0;
}
my $code = "";
while (<>) {
if (eof) {
close (ARGV); # reset line numbering
}
# read lines until we have no open comments
while (m@/\*([^*]|\*(?!/))*$@) {
my $new;
defined ($new = <>) || die "Unmatched comment in $ARGV";
$_ .= $new;
}
# strip comments w/o options
s@/\*(?!<)
([^*]+|\*(?!/))*
\*/@@gx;
if (m@^\s*typedef\s+enum\s*
({)?\s*
(?:/\*<
(([^*]|\*(?!/))*)
>\s*\*/)?
@x) {
if (defined $2) {
my %options = parse_options($2);
next if defined $options{"pdb-skip"};
}
# Didn't have trailing '{' look on next lines
if (!defined $1) {
while (<>) {
if (s/^\s*\{//) {
last;
}
}
}
$symbols = ""; $contig = 1; $before = -1; @mapping = ();
# Now parse the entries
&parse_entries (\*ARGV, $ARGV);
$symbols =~ s/\s*$//s;
$symbols = wrap("\t\t\t ", "\t\t\t " , $symbols);
$symbols =~ s/^\s*//s;
my $mapping = ""; $pos = 1;
foreach (@mapping) {
$mapping .= $pos++ % 2 ? "$_ => " : "'$_',\n\t\t ";
}
$mapping =~ s/,\n\s*$//s;
$ARGV =~ s@(?:(?:..|app)/)*@@;
$code .= <<ENTRY;
: $enumname =>
: { contig => $contig,
: header => '$ARGV',
: symbols => [ qw($symbols) ],
: mapping => { $mapping }
: },
ENTRY
}
}
$code =~ s/,\n$/\n/s;
foreach ($header, $code, $footer) { s/^://mg }
$outfile = "$builddir/pdb/enums.pl$FILE_EXT";
open OUTFILE, "> $outfile";
print OUTFILE $header, $external, $code, $footer;
close OUTFILE;
&write_file($outfile, "$destdir/pdb");

10
pdb/enums-external.pl Normal file
View File

@ -0,0 +1,10 @@
GeglDistanceMetric =>
{ contig => 1,
external => 1,
symbols => [ qw(GEGL_DISTANCE_METRIC_EUCLIDEAN
GEGL_DISTANCE_METRIC_MANHATTAN
GEGL_DISTANCE_METRIC_CHEBYSHEV) ],
mapping => { GEGL_DISTANCE_METRIC_EUCLIDEAN => '0',
GEGL_DISTANCE_METRIC_MANHATTAN => '1',
GEGL_DISTANCE_METRIC_CHEBYSHEV => '2' }
},

844
pdb/enums.pl Normal file
View File

@ -0,0 +1,844 @@
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1999-2003 Manish Singh <yosh@gimp.org>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUTFILE 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, see <https://www.gnu.org/licenses/>.
# autogenerated by enumgen.pl
package Pika::CodeGen::enums;
%enums = (
GeglDistanceMetric =>
{ contig => 1,
external => 1,
symbols => [ qw(GEGL_DISTANCE_METRIC_EUCLIDEAN
GEGL_DISTANCE_METRIC_MANHATTAN
GEGL_DISTANCE_METRIC_CHEBYSHEV) ],
mapping => { GEGL_DISTANCE_METRIC_EUCLIDEAN => '0',
GEGL_DISTANCE_METRIC_MANHATTAN => '1',
GEGL_DISTANCE_METRIC_CHEBYSHEV => '2' }
},
PikaAddMaskType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_ADD_MASK_WHITE PIKA_ADD_MASK_BLACK
PIKA_ADD_MASK_ALPHA PIKA_ADD_MASK_ALPHA_TRANSFER
PIKA_ADD_MASK_SELECTION PIKA_ADD_MASK_COPY
PIKA_ADD_MASK_CHANNEL) ],
mapping => { PIKA_ADD_MASK_WHITE => '0',
PIKA_ADD_MASK_BLACK => '1',
PIKA_ADD_MASK_ALPHA => '2',
PIKA_ADD_MASK_ALPHA_TRANSFER => '3',
PIKA_ADD_MASK_SELECTION => '4',
PIKA_ADD_MASK_COPY => '5',
PIKA_ADD_MASK_CHANNEL => '6' }
},
PikaBrushGeneratedShape =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_BRUSH_GENERATED_CIRCLE
PIKA_BRUSH_GENERATED_SQUARE
PIKA_BRUSH_GENERATED_DIAMOND) ],
mapping => { PIKA_BRUSH_GENERATED_CIRCLE => '0',
PIKA_BRUSH_GENERATED_SQUARE => '1',
PIKA_BRUSH_GENERATED_DIAMOND => '2' }
},
PikaCapStyle =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_CAP_BUTT PIKA_CAP_ROUND PIKA_CAP_SQUARE) ],
mapping => { PIKA_CAP_BUTT => '0',
PIKA_CAP_ROUND => '1',
PIKA_CAP_SQUARE => '2' }
},
PikaChannelOps =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_CHANNEL_OP_ADD PIKA_CHANNEL_OP_SUBTRACT
PIKA_CHANNEL_OP_REPLACE PIKA_CHANNEL_OP_INTERSECT) ],
mapping => { PIKA_CHANNEL_OP_ADD => '0',
PIKA_CHANNEL_OP_SUBTRACT => '1',
PIKA_CHANNEL_OP_REPLACE => '2',
PIKA_CHANNEL_OP_INTERSECT => '3' }
},
PikaChannelType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_CHANNEL_RED PIKA_CHANNEL_GREEN
PIKA_CHANNEL_BLUE PIKA_CHANNEL_GRAY
PIKA_CHANNEL_INDEXED PIKA_CHANNEL_ALPHA) ],
mapping => { PIKA_CHANNEL_RED => '0',
PIKA_CHANNEL_GREEN => '1',
PIKA_CHANNEL_BLUE => '2',
PIKA_CHANNEL_GRAY => '3',
PIKA_CHANNEL_INDEXED => '4',
PIKA_CHANNEL_ALPHA => '5' }
},
PikaCloneType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_CLONE_IMAGE PIKA_CLONE_PATTERN) ],
mapping => { PIKA_CLONE_IMAGE => '0',
PIKA_CLONE_PATTERN => '1' }
},
PikaColorTag =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_COLOR_TAG_NONE PIKA_COLOR_TAG_BLUE
PIKA_COLOR_TAG_GREEN PIKA_COLOR_TAG_YELLOW
PIKA_COLOR_TAG_ORANGE PIKA_COLOR_TAG_BROWN
PIKA_COLOR_TAG_RED PIKA_COLOR_TAG_VIOLET
PIKA_COLOR_TAG_GRAY) ],
mapping => { PIKA_COLOR_TAG_NONE => '0',
PIKA_COLOR_TAG_BLUE => '1',
PIKA_COLOR_TAG_GREEN => '2',
PIKA_COLOR_TAG_YELLOW => '3',
PIKA_COLOR_TAG_ORANGE => '4',
PIKA_COLOR_TAG_BROWN => '5',
PIKA_COLOR_TAG_RED => '6',
PIKA_COLOR_TAG_VIOLET => '7',
PIKA_COLOR_TAG_GRAY => '8' }
},
PikaComponentType =>
{ contig => 0,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_COMPONENT_TYPE_U8 PIKA_COMPONENT_TYPE_U16
PIKA_COMPONENT_TYPE_U32 PIKA_COMPONENT_TYPE_HALF
PIKA_COMPONENT_TYPE_FLOAT
PIKA_COMPONENT_TYPE_DOUBLE) ],
mapping => { PIKA_COMPONENT_TYPE_U8 => '100',
PIKA_COMPONENT_TYPE_U16 => '200',
PIKA_COMPONENT_TYPE_U32 => '300',
PIKA_COMPONENT_TYPE_HALF => '500',
PIKA_COMPONENT_TYPE_FLOAT => '600',
PIKA_COMPONENT_TYPE_DOUBLE => '700' }
},
PikaConvertPaletteType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_CONVERT_PALETTE_GENERATE
PIKA_CONVERT_PALETTE_WEB PIKA_CONVERT_PALETTE_MONO
PIKA_CONVERT_PALETTE_CUSTOM) ],
mapping => { PIKA_CONVERT_PALETTE_GENERATE => '0',
PIKA_CONVERT_PALETTE_WEB => '1',
PIKA_CONVERT_PALETTE_MONO => '2',
PIKA_CONVERT_PALETTE_CUSTOM => '3' }
},
PikaConvolveType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_CONVOLVE_BLUR PIKA_CONVOLVE_SHARPEN) ],
mapping => { PIKA_CONVOLVE_BLUR => '0',
PIKA_CONVOLVE_SHARPEN => '1' }
},
PikaDesaturateMode =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_DESATURATE_LIGHTNESS PIKA_DESATURATE_LUMA
PIKA_DESATURATE_AVERAGE PIKA_DESATURATE_LUMINANCE
PIKA_DESATURATE_VALUE) ],
mapping => { PIKA_DESATURATE_LIGHTNESS => '0',
PIKA_DESATURATE_LUMA => '1',
PIKA_DESATURATE_AVERAGE => '2',
PIKA_DESATURATE_LUMINANCE => '3',
PIKA_DESATURATE_VALUE => '4' }
},
PikaDodgeBurnType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_DODGE_BURN_TYPE_DODGE
PIKA_DODGE_BURN_TYPE_BURN) ],
mapping => { PIKA_DODGE_BURN_TYPE_DODGE => '0',
PIKA_DODGE_BURN_TYPE_BURN => '1' }
},
PikaFillType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_FILL_FOREGROUND PIKA_FILL_BACKGROUND
PIKA_FILL_CIELAB_MIDDLE_GRAY PIKA_FILL_WHITE
PIKA_FILL_TRANSPARENT PIKA_FILL_PATTERN) ],
mapping => { PIKA_FILL_FOREGROUND => '0',
PIKA_FILL_BACKGROUND => '1',
PIKA_FILL_CIELAB_MIDDLE_GRAY => '2',
PIKA_FILL_WHITE => '3',
PIKA_FILL_TRANSPARENT => '4',
PIKA_FILL_PATTERN => '5' }
},
PikaForegroundExtractMode =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_FOREGROUND_EXTRACT_MATTING) ],
mapping => { PIKA_FOREGROUND_EXTRACT_MATTING => '0' }
},
PikaGradientBlendColorSpace =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_GRADIENT_BLEND_RGB_PERCEPTUAL
PIKA_GRADIENT_BLEND_RGB_LINEAR
PIKA_GRADIENT_BLEND_CIE_LAB) ],
mapping => { PIKA_GRADIENT_BLEND_RGB_PERCEPTUAL => '0',
PIKA_GRADIENT_BLEND_RGB_LINEAR => '1',
PIKA_GRADIENT_BLEND_CIE_LAB => '2' }
},
PikaGradientSegmentColor =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_GRADIENT_SEGMENT_RGB
PIKA_GRADIENT_SEGMENT_HSV_CCW
PIKA_GRADIENT_SEGMENT_HSV_CW) ],
mapping => { PIKA_GRADIENT_SEGMENT_RGB => '0',
PIKA_GRADIENT_SEGMENT_HSV_CCW => '1',
PIKA_GRADIENT_SEGMENT_HSV_CW => '2' }
},
PikaGradientSegmentType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_GRADIENT_SEGMENT_LINEAR
PIKA_GRADIENT_SEGMENT_CURVED
PIKA_GRADIENT_SEGMENT_SINE
PIKA_GRADIENT_SEGMENT_SPHERE_INCREASING
PIKA_GRADIENT_SEGMENT_SPHERE_DECREASING
PIKA_GRADIENT_SEGMENT_STEP) ],
mapping => { PIKA_GRADIENT_SEGMENT_LINEAR => '0',
PIKA_GRADIENT_SEGMENT_CURVED => '1',
PIKA_GRADIENT_SEGMENT_SINE => '2',
PIKA_GRADIENT_SEGMENT_SPHERE_INCREASING => '3',
PIKA_GRADIENT_SEGMENT_SPHERE_DECREASING => '4',
PIKA_GRADIENT_SEGMENT_STEP => '5' }
},
PikaGradientType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_GRADIENT_LINEAR PIKA_GRADIENT_BILINEAR
PIKA_GRADIENT_RADIAL PIKA_GRADIENT_SQUARE
PIKA_GRADIENT_CONICAL_SYMMETRIC
PIKA_GRADIENT_CONICAL_ASYMMETRIC
PIKA_GRADIENT_SHAPEBURST_ANGULAR
PIKA_GRADIENT_SHAPEBURST_SPHERICAL
PIKA_GRADIENT_SHAPEBURST_DIMPLED
PIKA_GRADIENT_SPIRAL_CLOCKWISE
PIKA_GRADIENT_SPIRAL_ANTICLOCKWISE) ],
mapping => { PIKA_GRADIENT_LINEAR => '0',
PIKA_GRADIENT_BILINEAR => '1',
PIKA_GRADIENT_RADIAL => '2',
PIKA_GRADIENT_SQUARE => '3',
PIKA_GRADIENT_CONICAL_SYMMETRIC => '4',
PIKA_GRADIENT_CONICAL_ASYMMETRIC => '5',
PIKA_GRADIENT_SHAPEBURST_ANGULAR => '6',
PIKA_GRADIENT_SHAPEBURST_SPHERICAL => '7',
PIKA_GRADIENT_SHAPEBURST_DIMPLED => '8',
PIKA_GRADIENT_SPIRAL_CLOCKWISE => '9',
PIKA_GRADIENT_SPIRAL_ANTICLOCKWISE => '10' }
},
PikaGridStyle =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_GRID_DOTS PIKA_GRID_INTERSECTIONS
PIKA_GRID_ON_OFF_DASH PIKA_GRID_DOUBLE_DASH
PIKA_GRID_SOLID) ],
mapping => { PIKA_GRID_DOTS => '0',
PIKA_GRID_INTERSECTIONS => '1',
PIKA_GRID_ON_OFF_DASH => '2',
PIKA_GRID_DOUBLE_DASH => '3',
PIKA_GRID_SOLID => '4' }
},
PikaHueRange =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_HUE_RANGE_ALL PIKA_HUE_RANGE_RED
PIKA_HUE_RANGE_YELLOW PIKA_HUE_RANGE_GREEN
PIKA_HUE_RANGE_CYAN PIKA_HUE_RANGE_BLUE
PIKA_HUE_RANGE_MAGENTA) ],
mapping => { PIKA_HUE_RANGE_ALL => '0',
PIKA_HUE_RANGE_RED => '1',
PIKA_HUE_RANGE_YELLOW => '2',
PIKA_HUE_RANGE_GREEN => '3',
PIKA_HUE_RANGE_CYAN => '4',
PIKA_HUE_RANGE_BLUE => '5',
PIKA_HUE_RANGE_MAGENTA => '6' }
},
PikaIconType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_ICON_TYPE_ICON_NAME PIKA_ICON_TYPE_PIXBUF
PIKA_ICON_TYPE_IMAGE_FILE) ],
mapping => { PIKA_ICON_TYPE_ICON_NAME => '0',
PIKA_ICON_TYPE_PIXBUF => '1',
PIKA_ICON_TYPE_IMAGE_FILE => '2' }
},
PikaImageBaseType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_RGB PIKA_GRAY PIKA_INDEXED) ],
mapping => { PIKA_RGB => '0',
PIKA_GRAY => '1',
PIKA_INDEXED => '2' }
},
PikaImageType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_RGB_IMAGE PIKA_RGBA_IMAGE PIKA_GRAY_IMAGE
PIKA_GRAYA_IMAGE PIKA_INDEXED_IMAGE
PIKA_INDEXEDA_IMAGE) ],
mapping => { PIKA_RGB_IMAGE => '0',
PIKA_RGBA_IMAGE => '1',
PIKA_GRAY_IMAGE => '2',
PIKA_GRAYA_IMAGE => '3',
PIKA_INDEXED_IMAGE => '4',
PIKA_INDEXEDA_IMAGE => '5' }
},
PikaInkBlobType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_INK_BLOB_TYPE_CIRCLE
PIKA_INK_BLOB_TYPE_SQUARE
PIKA_INK_BLOB_TYPE_DIAMOND) ],
mapping => { PIKA_INK_BLOB_TYPE_CIRCLE => '0',
PIKA_INK_BLOB_TYPE_SQUARE => '1',
PIKA_INK_BLOB_TYPE_DIAMOND => '2' }
},
PikaInterpolationType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_INTERPOLATION_NONE PIKA_INTERPOLATION_LINEAR
PIKA_INTERPOLATION_CUBIC PIKA_INTERPOLATION_NOHALO
PIKA_INTERPOLATION_LOHALO) ],
mapping => { PIKA_INTERPOLATION_NONE => '0',
PIKA_INTERPOLATION_LINEAR => '1',
PIKA_INTERPOLATION_CUBIC => '2',
PIKA_INTERPOLATION_NOHALO => '3',
PIKA_INTERPOLATION_LOHALO => '4' }
},
PikaJoinStyle =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_JOIN_MITER PIKA_JOIN_ROUND PIKA_JOIN_BEVEL) ],
mapping => { PIKA_JOIN_MITER => '0',
PIKA_JOIN_ROUND => '1',
PIKA_JOIN_BEVEL => '2' }
},
PikaMaskApplyMode =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_MASK_APPLY PIKA_MASK_DISCARD) ],
mapping => { PIKA_MASK_APPLY => '0',
PIKA_MASK_DISCARD => '1' }
},
PikaMergeType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_EXPAND_AS_NECESSARY PIKA_CLIP_TO_IMAGE
PIKA_CLIP_TO_BOTTOM_LAYER PIKA_FLATTEN_IMAGE) ],
mapping => { PIKA_EXPAND_AS_NECESSARY => '0',
PIKA_CLIP_TO_IMAGE => '1',
PIKA_CLIP_TO_BOTTOM_LAYER => '2',
PIKA_FLATTEN_IMAGE => '3' }
},
PikaMessageHandlerType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_MESSAGE_BOX PIKA_CONSOLE PIKA_ERROR_CONSOLE) ],
mapping => { PIKA_MESSAGE_BOX => '0',
PIKA_CONSOLE => '1',
PIKA_ERROR_CONSOLE => '2' }
},
PikaOffsetType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_OFFSET_BACKGROUND PIKA_OFFSET_TRANSPARENT
PIKA_OFFSET_WRAP_AROUND) ],
mapping => { PIKA_OFFSET_BACKGROUND => '0',
PIKA_OFFSET_TRANSPARENT => '1',
PIKA_OFFSET_WRAP_AROUND => '2' }
},
PikaOrientationType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_ORIENTATION_HORIZONTAL
PIKA_ORIENTATION_VERTICAL PIKA_ORIENTATION_UNKNOWN) ],
mapping => { PIKA_ORIENTATION_HORIZONTAL => '0',
PIKA_ORIENTATION_VERTICAL => '1',
PIKA_ORIENTATION_UNKNOWN => '2' }
},
PikaPaintApplicationMode =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_PAINT_CONSTANT PIKA_PAINT_INCREMENTAL) ],
mapping => { PIKA_PAINT_CONSTANT => '0',
PIKA_PAINT_INCREMENTAL => '1' }
},
PikaPDBErrorHandler =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_PDB_ERROR_HANDLER_INTERNAL
PIKA_PDB_ERROR_HANDLER_PLUGIN) ],
mapping => { PIKA_PDB_ERROR_HANDLER_INTERNAL => '0',
PIKA_PDB_ERROR_HANDLER_PLUGIN => '1' }
},
PikaPDBProcType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_PDB_PROC_TYPE_INTERNAL
PIKA_PDB_PROC_TYPE_PLUGIN
PIKA_PDB_PROC_TYPE_EXTENSION
PIKA_PDB_PROC_TYPE_TEMPORARY) ],
mapping => { PIKA_PDB_PROC_TYPE_INTERNAL => '0',
PIKA_PDB_PROC_TYPE_PLUGIN => '1',
PIKA_PDB_PROC_TYPE_EXTENSION => '2',
PIKA_PDB_PROC_TYPE_TEMPORARY => '3' }
},
PikaPDBStatusType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_PDB_EXECUTION_ERROR PIKA_PDB_CALLING_ERROR
PIKA_PDB_PASS_THROUGH PIKA_PDB_SUCCESS
PIKA_PDB_CANCEL) ],
mapping => { PIKA_PDB_EXECUTION_ERROR => '0',
PIKA_PDB_CALLING_ERROR => '1',
PIKA_PDB_PASS_THROUGH => '2',
PIKA_PDB_SUCCESS => '3',
PIKA_PDB_CANCEL => '4' }
},
PikaPrecision =>
{ contig => 0,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_PRECISION_U8_LINEAR
PIKA_PRECISION_U8_NON_LINEAR
PIKA_PRECISION_U8_PERCEPTUAL
PIKA_PRECISION_U16_LINEAR
PIKA_PRECISION_U16_NON_LINEAR
PIKA_PRECISION_U16_PERCEPTUAL
PIKA_PRECISION_U32_LINEAR
PIKA_PRECISION_U32_NON_LINEAR
PIKA_PRECISION_U32_PERCEPTUAL
PIKA_PRECISION_HALF_LINEAR
PIKA_PRECISION_HALF_NON_LINEAR
PIKA_PRECISION_HALF_PERCEPTUAL
PIKA_PRECISION_FLOAT_LINEAR
PIKA_PRECISION_FLOAT_NON_LINEAR
PIKA_PRECISION_FLOAT_PERCEPTUAL
PIKA_PRECISION_DOUBLE_LINEAR
PIKA_PRECISION_DOUBLE_NON_LINEAR
PIKA_PRECISION_DOUBLE_PERCEPTUAL
PIKA_PRECISION_U8_GAMMA PIKA_PRECISION_U16_GAMMA
PIKA_PRECISION_U32_GAMMA PIKA_PRECISION_HALF_GAMMA
PIKA_PRECISION_FLOAT_GAMMA
PIKA_PRECISION_DOUBLE_GAMMA) ],
mapping => { PIKA_PRECISION_U8_LINEAR => '100',
PIKA_PRECISION_U8_NON_LINEAR => '150',
PIKA_PRECISION_U8_PERCEPTUAL => '175',
PIKA_PRECISION_U16_LINEAR => '200',
PIKA_PRECISION_U16_NON_LINEAR => '250',
PIKA_PRECISION_U16_PERCEPTUAL => '275',
PIKA_PRECISION_U32_LINEAR => '300',
PIKA_PRECISION_U32_NON_LINEAR => '350',
PIKA_PRECISION_U32_PERCEPTUAL => '375',
PIKA_PRECISION_HALF_LINEAR => '500',
PIKA_PRECISION_HALF_NON_LINEAR => '550',
PIKA_PRECISION_HALF_PERCEPTUAL => '575',
PIKA_PRECISION_FLOAT_LINEAR => '600',
PIKA_PRECISION_FLOAT_NON_LINEAR => '650',
PIKA_PRECISION_FLOAT_PERCEPTUAL => '675',
PIKA_PRECISION_DOUBLE_LINEAR => '700',
PIKA_PRECISION_DOUBLE_NON_LINEAR => '750',
PIKA_PRECISION_DOUBLE_PERCEPTUAL => '775',
PIKA_PRECISION_U8_GAMMA => 'PIKA_PRECISION_U8_NON_LINEAR',
PIKA_PRECISION_U16_GAMMA => 'PIKA_PRECISION_U16_NON_LINEAR',
PIKA_PRECISION_U32_GAMMA => 'PIKA_PRECISION_U32_NON_LINEAR',
PIKA_PRECISION_HALF_GAMMA => 'PIKA_PRECISION_HALF_NON_LINEAR',
PIKA_PRECISION_FLOAT_GAMMA => 'PIKA_PRECISION_FLOAT_NON_LINEAR',
PIKA_PRECISION_DOUBLE_GAMMA => 'PIKA_PRECISION_DOUBLE_NON_LINEAR' }
},
PikaProgressCommand =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_PROGRESS_COMMAND_START
PIKA_PROGRESS_COMMAND_END
PIKA_PROGRESS_COMMAND_SET_TEXT
PIKA_PROGRESS_COMMAND_SET_VALUE
PIKA_PROGRESS_COMMAND_PULSE
PIKA_PROGRESS_COMMAND_GET_WINDOW) ],
mapping => { PIKA_PROGRESS_COMMAND_START => '0',
PIKA_PROGRESS_COMMAND_END => '1',
PIKA_PROGRESS_COMMAND_SET_TEXT => '2',
PIKA_PROGRESS_COMMAND_SET_VALUE => '3',
PIKA_PROGRESS_COMMAND_PULSE => '4',
PIKA_PROGRESS_COMMAND_GET_WINDOW => '5' }
},
PikaRepeatMode =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_REPEAT_NONE PIKA_REPEAT_SAWTOOTH
PIKA_REPEAT_TRIANGULAR PIKA_REPEAT_TRUNCATE) ],
mapping => { PIKA_REPEAT_NONE => '0',
PIKA_REPEAT_SAWTOOTH => '1',
PIKA_REPEAT_TRIANGULAR => '2',
PIKA_REPEAT_TRUNCATE => '3' }
},
PikaRotationType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_ROTATE_90 PIKA_ROTATE_180 PIKA_ROTATE_270) ],
mapping => { PIKA_ROTATE_90 => '0',
PIKA_ROTATE_180 => '1',
PIKA_ROTATE_270 => '2' }
},
PikaRunMode =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_RUN_INTERACTIVE PIKA_RUN_NONINTERACTIVE
PIKA_RUN_WITH_LAST_VALS) ],
mapping => { PIKA_RUN_INTERACTIVE => '0',
PIKA_RUN_NONINTERACTIVE => '1',
PIKA_RUN_WITH_LAST_VALS => '2' }
},
PikaSelectCriterion =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_SELECT_CRITERION_COMPOSITE
PIKA_SELECT_CRITERION_RGB_RED
PIKA_SELECT_CRITERION_RGB_GREEN
PIKA_SELECT_CRITERION_RGB_BLUE
PIKA_SELECT_CRITERION_HSV_HUE
PIKA_SELECT_CRITERION_HSV_SATURATION
PIKA_SELECT_CRITERION_HSV_VALUE
PIKA_SELECT_CRITERION_LCH_LIGHTNESS
PIKA_SELECT_CRITERION_LCH_CHROMA
PIKA_SELECT_CRITERION_LCH_HUE
PIKA_SELECT_CRITERION_ALPHA) ],
mapping => { PIKA_SELECT_CRITERION_COMPOSITE => '0',
PIKA_SELECT_CRITERION_RGB_RED => '1',
PIKA_SELECT_CRITERION_RGB_GREEN => '2',
PIKA_SELECT_CRITERION_RGB_BLUE => '3',
PIKA_SELECT_CRITERION_HSV_HUE => '4',
PIKA_SELECT_CRITERION_HSV_SATURATION => '5',
PIKA_SELECT_CRITERION_HSV_VALUE => '6',
PIKA_SELECT_CRITERION_LCH_LIGHTNESS => '7',
PIKA_SELECT_CRITERION_LCH_CHROMA => '8',
PIKA_SELECT_CRITERION_LCH_HUE => '9',
PIKA_SELECT_CRITERION_ALPHA => '10' }
},
PikaSizeType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_PIXELS PIKA_POINTS) ],
mapping => { PIKA_PIXELS => '0',
PIKA_POINTS => '1' }
},
PikaStackTraceMode =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_STACK_TRACE_NEVER PIKA_STACK_TRACE_QUERY
PIKA_STACK_TRACE_ALWAYS) ],
mapping => { PIKA_STACK_TRACE_NEVER => '0',
PIKA_STACK_TRACE_QUERY => '1',
PIKA_STACK_TRACE_ALWAYS => '2' }
},
PikaStrokeMethod =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_STROKE_LINE PIKA_STROKE_PAINT_METHOD) ],
mapping => { PIKA_STROKE_LINE => '0',
PIKA_STROKE_PAINT_METHOD => '1' }
},
PikaTextDirection =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_TEXT_DIRECTION_LTR PIKA_TEXT_DIRECTION_RTL
PIKA_TEXT_DIRECTION_TTB_RTL
PIKA_TEXT_DIRECTION_TTB_RTL_UPRIGHT
PIKA_TEXT_DIRECTION_TTB_LTR
PIKA_TEXT_DIRECTION_TTB_LTR_UPRIGHT) ],
mapping => { PIKA_TEXT_DIRECTION_LTR => '0',
PIKA_TEXT_DIRECTION_RTL => '1',
PIKA_TEXT_DIRECTION_TTB_RTL => '2',
PIKA_TEXT_DIRECTION_TTB_RTL_UPRIGHT => '3',
PIKA_TEXT_DIRECTION_TTB_LTR => '4',
PIKA_TEXT_DIRECTION_TTB_LTR_UPRIGHT => '5' }
},
PikaTextHintStyle =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_TEXT_HINT_STYLE_NONE
PIKA_TEXT_HINT_STYLE_SLIGHT
PIKA_TEXT_HINT_STYLE_MEDIUM
PIKA_TEXT_HINT_STYLE_FULL) ],
mapping => { PIKA_TEXT_HINT_STYLE_NONE => '0',
PIKA_TEXT_HINT_STYLE_SLIGHT => '1',
PIKA_TEXT_HINT_STYLE_MEDIUM => '2',
PIKA_TEXT_HINT_STYLE_FULL => '3' }
},
PikaTextJustification =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_TEXT_JUSTIFY_LEFT PIKA_TEXT_JUSTIFY_RIGHT
PIKA_TEXT_JUSTIFY_CENTER PIKA_TEXT_JUSTIFY_FILL) ],
mapping => { PIKA_TEXT_JUSTIFY_LEFT => '0',
PIKA_TEXT_JUSTIFY_RIGHT => '1',
PIKA_TEXT_JUSTIFY_CENTER => '2',
PIKA_TEXT_JUSTIFY_FILL => '3' }
},
PikaTransferMode =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_TRANSFER_SHADOWS PIKA_TRANSFER_MIDTONES
PIKA_TRANSFER_HIGHLIGHTS) ],
mapping => { PIKA_TRANSFER_SHADOWS => '0',
PIKA_TRANSFER_MIDTONES => '1',
PIKA_TRANSFER_HIGHLIGHTS => '2' }
},
PikaTransformDirection =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_TRANSFORM_FORWARD PIKA_TRANSFORM_BACKWARD) ],
mapping => { PIKA_TRANSFORM_FORWARD => '0',
PIKA_TRANSFORM_BACKWARD => '1' }
},
PikaTransformResize =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_TRANSFORM_RESIZE_ADJUST
PIKA_TRANSFORM_RESIZE_CLIP
PIKA_TRANSFORM_RESIZE_CROP
PIKA_TRANSFORM_RESIZE_CROP_WITH_ASPECT) ],
mapping => { PIKA_TRANSFORM_RESIZE_ADJUST => '0',
PIKA_TRANSFORM_RESIZE_CLIP => '1',
PIKA_TRANSFORM_RESIZE_CROP => '2',
PIKA_TRANSFORM_RESIZE_CROP_WITH_ASPECT => '3' }
},
PikaUnit =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_UNIT_PIXEL PIKA_UNIT_INCH PIKA_UNIT_MM
PIKA_UNIT_POINT PIKA_UNIT_PICA PIKA_UNIT_END) ],
mapping => { PIKA_UNIT_PIXEL => '0',
PIKA_UNIT_INCH => '1',
PIKA_UNIT_MM => '2',
PIKA_UNIT_POINT => '3',
PIKA_UNIT_PICA => '4',
PIKA_UNIT_END => '5' }
},
PikaVectorsStrokeType =>
{ contig => 1,
header => 'libpikabase/pikabaseenums.h',
symbols => [ qw(PIKA_VECTORS_STROKE_TYPE_BEZIER) ],
mapping => { PIKA_VECTORS_STROKE_TYPE_BEZIER => '0' }
},
PikaColorManagementMode =>
{ contig => 1,
header => 'libpikaconfig/pikaconfigenums.h',
symbols => [ qw(PIKA_COLOR_MANAGEMENT_OFF
PIKA_COLOR_MANAGEMENT_DISPLAY
PIKA_COLOR_MANAGEMENT_SOFTPROOF) ],
mapping => { PIKA_COLOR_MANAGEMENT_OFF => '0',
PIKA_COLOR_MANAGEMENT_DISPLAY => '1',
PIKA_COLOR_MANAGEMENT_SOFTPROOF => '2' }
},
PikaColorRenderingIntent =>
{ contig => 1,
header => 'libpikaconfig/pikaconfigenums.h',
symbols => [ qw(PIKA_COLOR_RENDERING_INTENT_PERCEPTUAL
PIKA_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC
PIKA_COLOR_RENDERING_INTENT_SATURATION
PIKA_COLOR_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC) ],
mapping => { PIKA_COLOR_RENDERING_INTENT_PERCEPTUAL => '0',
PIKA_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC => '1',
PIKA_COLOR_RENDERING_INTENT_SATURATION => '2',
PIKA_COLOR_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC => '3' }
},
PikaLayerColorSpace =>
{ contig => 1,
header => 'operations/operations-enums.h',
symbols => [ qw(PIKA_LAYER_COLOR_SPACE_AUTO
PIKA_LAYER_COLOR_SPACE_RGB_LINEAR
PIKA_LAYER_COLOR_SPACE_RGB_PERCEPTUAL) ],
mapping => { PIKA_LAYER_COLOR_SPACE_AUTO => '0',
PIKA_LAYER_COLOR_SPACE_RGB_LINEAR => '1',
PIKA_LAYER_COLOR_SPACE_RGB_PERCEPTUAL => '2' }
},
PikaLayerCompositeMode =>
{ contig => 1,
header => 'operations/operations-enums.h',
symbols => [ qw(PIKA_LAYER_COMPOSITE_AUTO
PIKA_LAYER_COMPOSITE_UNION
PIKA_LAYER_COMPOSITE_CLIP_TO_BACKDROP
PIKA_LAYER_COMPOSITE_CLIP_TO_LAYER
PIKA_LAYER_COMPOSITE_INTERSECTION) ],
mapping => { PIKA_LAYER_COMPOSITE_AUTO => '0',
PIKA_LAYER_COMPOSITE_UNION => '1',
PIKA_LAYER_COMPOSITE_CLIP_TO_BACKDROP => '2',
PIKA_LAYER_COMPOSITE_CLIP_TO_LAYER => '3',
PIKA_LAYER_COMPOSITE_INTERSECTION => '4' }
},
PikaLayerMode =>
{ contig => 1,
header => 'operations/operations-enums.h',
symbols => [ qw(PIKA_LAYER_MODE_NORMAL_LEGACY
PIKA_LAYER_MODE_DISSOLVE
PIKA_LAYER_MODE_BEHIND_LEGACY
PIKA_LAYER_MODE_MULTIPLY_LEGACY
PIKA_LAYER_MODE_SCREEN_LEGACY
PIKA_LAYER_MODE_OVERLAY_LEGACY
PIKA_LAYER_MODE_DIFFERENCE_LEGACY
PIKA_LAYER_MODE_ADDITION_LEGACY
PIKA_LAYER_MODE_SUBTRACT_LEGACY
PIKA_LAYER_MODE_DARKEN_ONLY_LEGACY
PIKA_LAYER_MODE_LIGHTEN_ONLY_LEGACY
PIKA_LAYER_MODE_HSV_HUE_LEGACY
PIKA_LAYER_MODE_HSV_SATURATION_LEGACY
PIKA_LAYER_MODE_HSL_COLOR_LEGACY
PIKA_LAYER_MODE_HSV_VALUE_LEGACY
PIKA_LAYER_MODE_DIVIDE_LEGACY
PIKA_LAYER_MODE_DODGE_LEGACY
PIKA_LAYER_MODE_BURN_LEGACY
PIKA_LAYER_MODE_HARDLIGHT_LEGACY
PIKA_LAYER_MODE_SOFTLIGHT_LEGACY
PIKA_LAYER_MODE_GRAIN_EXTRACT_LEGACY
PIKA_LAYER_MODE_GRAIN_MERGE_LEGACY
PIKA_LAYER_MODE_COLOR_ERASE_LEGACY
PIKA_LAYER_MODE_OVERLAY PIKA_LAYER_MODE_LCH_HUE
PIKA_LAYER_MODE_LCH_CHROMA
PIKA_LAYER_MODE_LCH_COLOR
PIKA_LAYER_MODE_LCH_LIGHTNESS
PIKA_LAYER_MODE_NORMAL PIKA_LAYER_MODE_BEHIND
PIKA_LAYER_MODE_MULTIPLY PIKA_LAYER_MODE_SCREEN
PIKA_LAYER_MODE_DIFFERENCE
PIKA_LAYER_MODE_ADDITION PIKA_LAYER_MODE_SUBTRACT
PIKA_LAYER_MODE_DARKEN_ONLY
PIKA_LAYER_MODE_LIGHTEN_ONLY
PIKA_LAYER_MODE_HSV_HUE
PIKA_LAYER_MODE_HSV_SATURATION
PIKA_LAYER_MODE_HSL_COLOR
PIKA_LAYER_MODE_HSV_VALUE PIKA_LAYER_MODE_DIVIDE
PIKA_LAYER_MODE_DODGE PIKA_LAYER_MODE_BURN
PIKA_LAYER_MODE_HARDLIGHT
PIKA_LAYER_MODE_SOFTLIGHT
PIKA_LAYER_MODE_GRAIN_EXTRACT
PIKA_LAYER_MODE_GRAIN_MERGE
PIKA_LAYER_MODE_VIVID_LIGHT
PIKA_LAYER_MODE_PIN_LIGHT
PIKA_LAYER_MODE_LINEAR_LIGHT
PIKA_LAYER_MODE_HARD_MIX PIKA_LAYER_MODE_EXCLUSION
PIKA_LAYER_MODE_LINEAR_BURN
PIKA_LAYER_MODE_LUMA_DARKEN_ONLY
PIKA_LAYER_MODE_LUMA_LIGHTEN_ONLY
PIKA_LAYER_MODE_LUMINANCE
PIKA_LAYER_MODE_COLOR_ERASE PIKA_LAYER_MODE_ERASE
PIKA_LAYER_MODE_MERGE PIKA_LAYER_MODE_SPLIT
PIKA_LAYER_MODE_PASS_THROUGH) ],
mapping => { PIKA_LAYER_MODE_NORMAL_LEGACY => '0',
PIKA_LAYER_MODE_DISSOLVE => '1',
PIKA_LAYER_MODE_BEHIND_LEGACY => '2',
PIKA_LAYER_MODE_MULTIPLY_LEGACY => '3',
PIKA_LAYER_MODE_SCREEN_LEGACY => '4',
PIKA_LAYER_MODE_OVERLAY_LEGACY => '5',
PIKA_LAYER_MODE_DIFFERENCE_LEGACY => '6',
PIKA_LAYER_MODE_ADDITION_LEGACY => '7',
PIKA_LAYER_MODE_SUBTRACT_LEGACY => '8',
PIKA_LAYER_MODE_DARKEN_ONLY_LEGACY => '9',
PIKA_LAYER_MODE_LIGHTEN_ONLY_LEGACY => '10',
PIKA_LAYER_MODE_HSV_HUE_LEGACY => '11',
PIKA_LAYER_MODE_HSV_SATURATION_LEGACY => '12',
PIKA_LAYER_MODE_HSL_COLOR_LEGACY => '13',
PIKA_LAYER_MODE_HSV_VALUE_LEGACY => '14',
PIKA_LAYER_MODE_DIVIDE_LEGACY => '15',
PIKA_LAYER_MODE_DODGE_LEGACY => '16',
PIKA_LAYER_MODE_BURN_LEGACY => '17',
PIKA_LAYER_MODE_HARDLIGHT_LEGACY => '18',
PIKA_LAYER_MODE_SOFTLIGHT_LEGACY => '19',
PIKA_LAYER_MODE_GRAIN_EXTRACT_LEGACY => '20',
PIKA_LAYER_MODE_GRAIN_MERGE_LEGACY => '21',
PIKA_LAYER_MODE_COLOR_ERASE_LEGACY => '22',
PIKA_LAYER_MODE_OVERLAY => '23',
PIKA_LAYER_MODE_LCH_HUE => '24',
PIKA_LAYER_MODE_LCH_CHROMA => '25',
PIKA_LAYER_MODE_LCH_COLOR => '26',
PIKA_LAYER_MODE_LCH_LIGHTNESS => '27',
PIKA_LAYER_MODE_NORMAL => '28',
PIKA_LAYER_MODE_BEHIND => '29',
PIKA_LAYER_MODE_MULTIPLY => '30',
PIKA_LAYER_MODE_SCREEN => '31',
PIKA_LAYER_MODE_DIFFERENCE => '32',
PIKA_LAYER_MODE_ADDITION => '33',
PIKA_LAYER_MODE_SUBTRACT => '34',
PIKA_LAYER_MODE_DARKEN_ONLY => '35',
PIKA_LAYER_MODE_LIGHTEN_ONLY => '36',
PIKA_LAYER_MODE_HSV_HUE => '37',
PIKA_LAYER_MODE_HSV_SATURATION => '38',
PIKA_LAYER_MODE_HSL_COLOR => '39',
PIKA_LAYER_MODE_HSV_VALUE => '40',
PIKA_LAYER_MODE_DIVIDE => '41',
PIKA_LAYER_MODE_DODGE => '42',
PIKA_LAYER_MODE_BURN => '43',
PIKA_LAYER_MODE_HARDLIGHT => '44',
PIKA_LAYER_MODE_SOFTLIGHT => '45',
PIKA_LAYER_MODE_GRAIN_EXTRACT => '46',
PIKA_LAYER_MODE_GRAIN_MERGE => '47',
PIKA_LAYER_MODE_VIVID_LIGHT => '48',
PIKA_LAYER_MODE_PIN_LIGHT => '49',
PIKA_LAYER_MODE_LINEAR_LIGHT => '50',
PIKA_LAYER_MODE_HARD_MIX => '51',
PIKA_LAYER_MODE_EXCLUSION => '52',
PIKA_LAYER_MODE_LINEAR_BURN => '53',
PIKA_LAYER_MODE_LUMA_DARKEN_ONLY => '54',
PIKA_LAYER_MODE_LUMA_LIGHTEN_ONLY => '55',
PIKA_LAYER_MODE_LUMINANCE => '56',
PIKA_LAYER_MODE_COLOR_ERASE => '57',
PIKA_LAYER_MODE_ERASE => '58',
PIKA_LAYER_MODE_MERGE => '59',
PIKA_LAYER_MODE_SPLIT => '60',
PIKA_LAYER_MODE_PASS_THROUGH => '61' }
},
PikaConvertDitherType =>
{ contig => 1,
header => 'core/core-enums.h',
symbols => [ qw(PIKA_CONVERT_DITHER_NONE PIKA_CONVERT_DITHER_FS
PIKA_CONVERT_DITHER_FS_LOWBLEED
PIKA_CONVERT_DITHER_FIXED) ],
mapping => { PIKA_CONVERT_DITHER_NONE => '0',
PIKA_CONVERT_DITHER_FS => '1',
PIKA_CONVERT_DITHER_FS_LOWBLEED => '2',
PIKA_CONVERT_DITHER_FIXED => '3' }
},
PikaHistogramChannel =>
{ contig => 1,
header => 'core/core-enums.h',
symbols => [ qw(PIKA_HISTOGRAM_VALUE PIKA_HISTOGRAM_RED
PIKA_HISTOGRAM_GREEN PIKA_HISTOGRAM_BLUE
PIKA_HISTOGRAM_ALPHA PIKA_HISTOGRAM_LUMINANCE) ],
mapping => { PIKA_HISTOGRAM_VALUE => '0',
PIKA_HISTOGRAM_RED => '1',
PIKA_HISTOGRAM_GREEN => '2',
PIKA_HISTOGRAM_BLUE => '3',
PIKA_HISTOGRAM_ALPHA => '4',
PIKA_HISTOGRAM_LUMINANCE => '5' }
},
PikaBrushApplicationMode =>
{ contig => 1,
header => 'paint/paint-enums.h',
symbols => [ qw(PIKA_BRUSH_HARD PIKA_BRUSH_SOFT) ],
mapping => { PIKA_BRUSH_HARD => '0',
PIKA_BRUSH_SOFT => '1' }
}
);
foreach $e (values %enums) {
$e->{info} = "";
foreach (@{$e->{symbols}}) {
$e->{info} .= "$_ ($e->{mapping}->{$_}), "
}
$e->{info} =~ s/, $//;
}
1;

57
pdb/groups.pl Normal file
View File

@ -0,0 +1,57 @@
# This file is autogenerated
@groups = qw(
brush
brush_select
brushes
buffer
channel
context
debug
display
drawable
drawable_color
drawable_edit
dynamics
edit
file
floating_sel
font
font_select
fonts
pika
pikarc
gradient
gradient_select
gradients
help
image
image_color_profile
image_convert
image_grid
image_guides
image_sample_points
image_select
image_transform
image_undo
item
item_transform
layer
message
paint_tools
palette
palette_select
palettes
pattern
pattern_select
patterns
pdb
plug_in
plug_in_compat
progress
resource
selection
text_layer
text_tool
unit
vectors
);

783
pdb/groups/brush.pdb Normal file
View File

@ -0,0 +1,783 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
# The invoke code is compiled on the app side.
# The invoke code must assign to each result var
$brush_arg_spec = { name => 'brush', type => 'brush', non_empty => 1,
desc => 'The brush' };
sub brush_new {
$blurb = "Create a new generated brush having default parameters.";
$help = "Creates a new, parametric brush.";
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The requested name of the new brush' }
);
@outargs = (
${brush_arg_spec}
);
%invoke = (
code => <<'CODE'
{
brush = (PikaBrush *) pika_data_factory_data_new (pika->brush_factory,
context, name);
if (! brush)
success = FALSE;
}
CODE
);
}
sub brush_get_by_name {
$blurb = "Returns the brush with the given name.";
$help = <<'HELP';
Search and return an existing brush with the name in argument, or nothing if no
brush has this name.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The name of the brush' }
);
@outargs = (
${brush_arg_spec}
);
%invoke = (
code => <<'CODE'
{
brush = PIKA_BRUSH (pika_pdb_get_resource (pika, PIKA_TYPE_BRUSH, name,
PIKA_PDB_DATA_ACCESS_READ, error));
if (! brush)
success = FALSE;
}
CODE
);
}
sub brush_is_generated {
$blurb = "Whether the brush is generated (parametric versus raster).";
$help = "Returns TRUE when brush is parametric.";
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec}
);
@outargs = (
{ name => 'generated', type => 'boolean',
desc => 'TRUE if the brush is generated' }
);
%invoke = (
code => <<'CODE'
{
generated = PIKA_IS_BRUSH_GENERATED (brush);
}
CODE
);
}
sub brush_get_info {
$blurb = "Gets information about the brush.";
$help = <<'HELP';
Gets information about the brush:
brush extents (width and height), color depth and mask depth (bpp).
The color bpp is zero when the brush is parametric versus raster.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${brush_arg_spec}
);
@outargs = (
{ name => 'width', type => 'int32', void_ret => 1,
desc => 'The brush width' },
{ name => 'height', type => 'int32',
desc => 'The brush height' },
{ name => 'mask_bpp', type => 'int32',
desc => 'The brush mask bpp' },
{ name => 'color_bpp', type => 'int32',
desc => 'The brush color bpp' }
);
%invoke = (
code => <<'CODE'
{
PikaTempBuf *mask = pika_brush_get_mask (brush);
PikaTempBuf *pixmap = pika_brush_get_pixmap (brush);
const Babl *format;
format = pika_babl_compat_u8_mask_format (
pika_temp_buf_get_format (mask));
width = pika_brush_get_width (brush);
height = pika_brush_get_height (brush);
mask_bpp = babl_format_get_bytes_per_pixel (format);
if (pixmap)
{
format = pika_babl_compat_u8_format (
pika_temp_buf_get_format (pixmap));
color_bpp = babl_format_get_bytes_per_pixel (format);
}
}
CODE
);
}
sub brush_get_pixels {
$blurb = 'Gets information about the brush.';
$help = <<'HELP';
Gets information about the brush:
the brush extents (width and height) and its pixels data.
The color bpp is zero and pixels empty when the brush is parametric versus raster.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${brush_arg_spec}
);
@outargs = (
{ name => 'width', type => 'int32', void_ret => 1,
desc => 'The brush width' },
{ name => 'height', type => 'int32',
desc => 'The brush height' },
{ name => 'mask_bpp', type => 'int32',
desc => 'The brush mask bpp' },
{ name => 'mask_bytes', type => 'bytes',
desc => 'The brush mask data' },
{ name => 'color_bpp', type => 'int32',
desc => 'The brush color bpp' },
{ name => 'color_bytes', type => 'bytes',
desc => 'The brush color data' }
);
%invoke = (
code => <<'CODE'
{
PikaTempBuf *mask = pika_brush_get_mask (brush);
PikaTempBuf *pixmap = pika_brush_get_pixmap (brush);
const Babl *format;
gpointer data;
gsize num_mask_bytes;
gsize num_color_bytes;
format = pika_babl_compat_u8_mask_format (
pika_temp_buf_get_format (mask));
data = pika_temp_buf_lock (mask, format, GEGL_ACCESS_READ);
width = pika_temp_buf_get_width (mask);
height = pika_temp_buf_get_height (mask);
mask_bpp = babl_format_get_bytes_per_pixel (format);
num_mask_bytes = (gsize) pika_temp_buf_get_height (mask) *
pika_temp_buf_get_width (mask) * mask_bpp;
mask_bytes = g_bytes_new (data, num_mask_bytes);
pika_temp_buf_unlock (mask, data);
if (pixmap)
{
format = pika_babl_compat_u8_format (
pika_temp_buf_get_format (pixmap));
data = pika_temp_buf_lock (pixmap, format, GEGL_ACCESS_READ);
color_bpp = babl_format_get_bytes_per_pixel (format);
num_color_bytes = (gsize) pika_temp_buf_get_height (pixmap) *
pika_temp_buf_get_width (pixmap) *
color_bpp;
color_bytes = g_bytes_new (data, num_color_bytes);
pika_temp_buf_unlock (pixmap, data);
}
}
CODE
);
}
sub brush_get_spacing {
$blurb = 'Gets the brush spacing, the stamping frequency.';
$help = <<'HELP';
Returns the spacing setting for the brush.
Spacing is an integer between 0 and 1000 which represents a
percentage of the maximum of the width and height of the mask.
Both parametric and raster brushes have a spacing.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${brush_arg_spec}
);
# Always just a value, not "void_ret => 1,"
@outargs = (
{ name => 'spacing', type => '0 <= int32 <= 1000',
desc => 'The brush spacing' }
);
%invoke = (
code => <<'CODE'
{
spacing = pika_brush_get_spacing (brush);
}
CODE
);
}
sub brush_get_shape {
$blurb = 'Gets the shape of a generated brush.';
$help = <<'HELP';
Gets the shape of a generated brush.
Returns an error when called for a non-parametric brush.
The choices for shape are Circle (PIKA_BRUSH_GENERATED_CIRCLE),
Square (PIKA_BRUSH_GENERATED_SQUARE), and Diamond
(PIKA_BRUSH_GENERATED_DIAMOND). Other shapes might be
added in the future.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec}
);
@outargs = (
{ name => 'shape', type => 'enum PikaBrushGeneratedShape',
void_ret => 1,
desc => 'The brush shape' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush))
shape = PIKA_BRUSH_GENERATED (brush)->shape;
else
success = FALSE;
}
CODE
);
}
sub brush_get_radius {
$blurb = 'Gets the radius of a generated brush.';
$help = <<'HELP';
Gets the radius of a generated brush.
Returns an error when called for a non-parametric brush.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec}
);
@outargs = (
{ name => 'radius', type => 'float',
void_ret => 1,
desc => 'The radius of the brush in pixels' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush))
radius = PIKA_BRUSH_GENERATED (brush)->radius;
else
success = FALSE;
}
CODE
);
}
sub brush_get_spikes {
$blurb = 'Gets the number of spikes for a generated brush.';
$help = <<'HELP';
Gets the number of spikes for a generated brush.
Returns an error when called for a non-parametric brush.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec}
);
@outargs = (
{ name => 'spikes', type => 'int32',
void_ret => 1,
desc => 'The number of spikes on the brush.' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush))
spikes = PIKA_BRUSH_GENERATED (brush)->spikes;
else
success = FALSE;
}
CODE
);
}
sub brush_get_hardness {
$blurb = 'Gets the hardness of a generated brush.';
$help = <<'HELP';
Gets the hardness of a generated brush.
The hardness of a brush is the amount its intensity fades at the
outside edge, as a float between 0.0 and 1.0.
Returns an error when called for a non-parametric brush.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec}
);
@outargs = (
{ name => 'hardness', type => 'float',
void_ret => 1,
desc => 'The hardness of the brush.' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush))
hardness = PIKA_BRUSH_GENERATED (brush)->hardness;
else
success = FALSE;
}
CODE
);
}
sub brush_get_aspect_ratio {
$blurb = 'Gets the aspect ratio of a generated brush.';
$help = <<'HELP';
Gets the aspect ratio of a generated brush.
Returns an error when called for a non-parametric brush.
The aspect ratio is a float between 0.0 and 1000.0.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec}
);
@outargs = (
{ name => 'aspect_ratio', type => 'float',
void_ret => 1,
desc => 'The aspect ratio of the brush.' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush))
aspect_ratio = PIKA_BRUSH_GENERATED (brush)->aspect_ratio;
else
success = FALSE;
}
CODE
);
}
sub brush_get_angle {
$blurb = 'Gets the rotation angle of a generated brush.';
$help = <<'HELP';
Gets the angle of rotation for a generated brush.
Returns an error when called for a non-parametric brush.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec}
);
@outargs = (
{ name => 'angle', type => 'float',
void_ret => 1,
desc => 'The rotation angle of the brush in degree.' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush))
angle = PIKA_BRUSH_GENERATED (brush)->angle;
else
success = FALSE;
}
CODE
);
}
sub brush_set_spacing {
$blurb = 'Sets the brush spacing.';
$help = <<'HELP';
Set the spacing for the brush.
The spacing must be an integer between 0 and 1000.
Both parametric and raster brushes have a spacing.
Returns an error when the brush is not editable.
Create a new or copied brush or to get an editable brush.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec},
{ name => 'spacing', type => '0 <= int32 <= 1000',
desc => 'The brush spacing' }
);
%invoke = (
code => <<'CODE'
{
if (pika_data_is_writable (PIKA_DATA (brush)))
pika_brush_set_spacing (brush, spacing);
else
success = FALSE;
}
CODE
);
}
sub brush_set_shape {
$blurb = 'Sets the shape of a generated brush.';
$help = <<'HELP';
Sets the shape of a generated brush.
Returns an error when brush is non-parametric or not editable.
The choices for shape are Circle (PIKA_BRUSH_GENERATED_CIRCLE),
Square (PIKA_BRUSH_GENERATED_SQUARE), and Diamond
(PIKA_BRUSH_GENERATED_DIAMOND).
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec},
{ name => 'shape_in', type => 'enum PikaBrushGeneratedShape',
desc => 'The brush shape' }
);
@outargs = (
{ name => 'shape_out', type => 'enum PikaBrushGeneratedShape',
void_ret => 1,
desc => 'The brush shape actually assigned' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush) &&
pika_data_is_writable (PIKA_DATA (brush)))
{
pika_brush_generated_set_shape (PIKA_BRUSH_GENERATED (brush),
shape_in);
shape_out = PIKA_BRUSH_GENERATED (brush)->shape;
}
else
{
success = FALSE;
}
}
CODE
);
}
sub brush_set_radius {
$blurb = 'Sets the radius of a generated brush.';
$help = <<'HELP';
Sets the radius for a generated brush.
Clamps radius to [0.0, 32767.0].
Returns the clamped value.
Returns an error when brush is non-parametric or not editable.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec},
{ name => 'radius_in', type => 'float',
desc => 'The desired brush radius in pixel' }
);
@outargs = (
{ name => 'radius_out', type => 'float',
void_ret => 1,
desc => 'The brush radius actually assigned' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush) &&
pika_data_is_writable (PIKA_DATA (brush)))
{
pika_brush_generated_set_radius (PIKA_BRUSH_GENERATED (brush),
radius_in);
radius_out = PIKA_BRUSH_GENERATED (brush)->radius;
}
else
{
success = FALSE;
}
}
CODE
);
}
sub brush_set_spikes {
$blurb = 'Sets the number of spikes for a generated brush.';
$help = <<'HELP';
Sets the number of spikes for a generated brush.
Clamps spikes to [2,20].
Returns the clamped value.
Returns an error when brush is non-parametric or not editable.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec},
{ name => 'spikes_in', type => 'int32',
desc => 'The desired number of spikes' }
);
@outargs = (
{ name => 'spikes_out', type => 'int32',
void_ret => 1,
desc => 'The number of spikes actually assigned' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush) &&
pika_data_is_writable (PIKA_DATA (brush)))
{
pika_brush_generated_set_spikes (PIKA_BRUSH_GENERATED (brush),
spikes_in);
spikes_out = PIKA_BRUSH_GENERATED (brush)->spikes;
}
else
{
success = FALSE;
}
}
CODE
);
}
sub brush_set_hardness {
$blurb = 'Sets the hardness of a generated brush.';
$help = <<'HELP';
Sets the hardness for a generated brush.
Clamps hardness to [0.0, 1.0].
Returns the clamped value.
Returns an error when brush is non-parametric or not editable.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec},
{ name => 'hardness_in', type => 'float',
desc => 'The desired brush hardness' }
);
@outargs = (
{ name => 'hardness_out', type => 'float',
void_ret => 1,
desc => 'The brush hardness actually assigned' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush) &&
pika_data_is_writable (PIKA_DATA (brush)))
{
pika_brush_generated_set_hardness (PIKA_BRUSH_GENERATED (brush),
hardness_in);
hardness_out = PIKA_BRUSH_GENERATED (brush)->hardness;
}
else
{
success = FALSE;
}
}
CODE
);
}
sub brush_set_aspect_ratio {
$blurb = 'Sets the aspect ratio of a generated brush.';
$help = <<'HELP';
Sets the aspect ratio for a generated brush.
Clamps aspect ratio to [0.0, 1000.0].
Returns the clamped value.
Returns an error when brush is non-parametric or not editable.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec},
{ name => 'aspect_ratio_in', type => 'float',
desc => 'The desired brush aspect ratio' }
);
@outargs = (
{ name => 'aspect_ratio_out', type => 'float',
void_ret => 1,
desc => 'The brush aspect ratio actually assigned' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush) &&
pika_data_is_writable (PIKA_DATA (brush)))
{
pika_brush_generated_set_aspect_ratio (PIKA_BRUSH_GENERATED (brush),
aspect_ratio_in);
aspect_ratio_out = PIKA_BRUSH_GENERATED (brush)->aspect_ratio;
}
else
{
success = FALSE;
}
}
CODE
);
}
sub brush_set_angle {
$blurb = 'Sets the rotation angle of a generated brush.';
$help = <<'HELP';
Sets the rotation angle for a generated brush.
Sets the angle modulo 180, in the range [-180.0, 180.0].
Returns the clamped value.
Returns an error when brush is non-parametric or not editable.
HELP
&bill_pdb_misc('2004', '2.4');
@inargs = (
${brush_arg_spec},
{ name => 'angle_in', type => 'float',
desc => 'The desired brush rotation angle in degrees' }
);
@outargs = (
{ name => 'angle_out', type => 'float',
void_ret => 1,
desc => 'The brush rotation angle actually assigned' }
);
%invoke = (
code => <<'CODE'
{
if (PIKA_IS_BRUSH_GENERATED (brush) &&
pika_data_is_writable (PIKA_DATA (brush)))
{
pika_brush_generated_set_angle (PIKA_BRUSH_GENERATED (brush),
angle_in);
angle_out = PIKA_BRUSH_GENERATED (brush)->angle;
}
else
{
success = FALSE;
}
}
CODE
);
}
@headers = qw(<string.h>
"gegl/pika-babl-compat.h"
"core/pika.h"
"core/pikabrush.h"
"core/pikabrushgenerated.h"
"core/pikacontext.h"
"core/pikadatafactory.h"
"core/pikatempbuf.h"
"pikapdb-utils.h");
@procs = qw(brush_new
brush_get_by_name
brush_is_generated
brush_get_info
brush_get_pixels
brush_get_spacing brush_set_spacing
brush_get_shape brush_set_shape
brush_get_radius brush_set_radius
brush_get_spikes brush_set_spikes
brush_get_hardness brush_set_hardness
brush_get_aspect_ratio brush_set_aspect_ratio
brush_get_angle brush_set_angle);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Brush';
$doc_title = 'pikabrush';
$doc_short_desc = 'Installable object used by painting and stroking tools.';
$doc_long_desc = 'Installable object used by painting and stroking tools.';
1;

115
pdb/groups/brush_select.pdb Normal file
View File

@ -0,0 +1,115 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub brushes_popup {
$blurb = 'Invokes the PIKA brush selection dialog.';
$help = 'Opens a dialog letting a user choose a brush.';
&andy_pdb_misc('1998');
@inargs = (
{ name => 'brush_callback', type => 'string', non_empty => 1,
desc => 'The callback PDB proc to call when user chooses a brush' },
{ name => 'popup_title', type => 'string',
desc => 'Title of the brush selection dialog' },
{ name => 'initial_brush_name', type => 'string', null_ok => 1,
desc => 'The name of the brush to set as the initial choice' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, brush_callback) ||
! pika_pdb_dialog_new (pika, context, progress,
pika_data_factory_get_container (pika->brush_factory),
popup_title, brush_callback, initial_brush_name,
NULL))
success = FALSE;
}
CODE
);
}
sub brushes_close_popup {
$blurb = 'Close the brush selection dialog.';
$help = 'Closes an open brush selection dialog.';
&andy_pdb_misc('1998');
@inargs = (
{ name => 'brush_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this pop-up' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, brush_callback) ||
! pika_pdb_dialog_close (pika, pika_data_factory_get_container (pika->brush_factory),
brush_callback))
success = FALSE;
}
CODE
);
}
sub brushes_set_popup {
$blurb = 'Sets the selected brush in a brush selection dialog.';
$help = $blurb;
&andy_pdb_misc('1998');
@inargs = (
{ name => 'brush_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this pop-up' },
{ name => 'brush_name', type => 'string',
desc => 'The name of the brush to set as selected' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, brush_callback) ||
! pika_pdb_dialog_set (pika, pika_data_factory_get_container (pika->brush_factory),
brush_callback, brush_name,
NULL))
success = FALSE;
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pikadatafactory.h");
@procs = qw(brushes_popup
brushes_close_popup
brushes_set_popup);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Brush UI';
$doc_title = 'pikabrushselect';
$doc_short_desc = 'Methods of a font chooser dialog';
$doc_long_desc = 'A dialog letting a user choose a brush. Read more at pikafontselect.';
1;

88
pdb/groups/brushes.pdb Normal file
View File

@ -0,0 +1,88 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub brushes_refresh {
$blurb = 'Refresh current brushes. This function always succeeds.';
$help = <<'HELP';
This procedure retrieves all brushes currently in the user's brush path
and updates the brush dialogs accordingly.
HELP
&seth_pdb_misc('1997');
%invoke = (
code => <<'CODE'
{
pika_data_factory_data_refresh (pika->brush_factory, context);
}
CODE
);
}
sub brushes_get_list {
$blurb = 'Retrieve a complete listing of the available brushes.';
$help = <<'HELP';
This procedure returns a complete listing of available PIKA
brushes. Each name returned can be used as input to the
pika_context_set_brush() procedure.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'filter', type => 'string', null_ok => 1,
desc => 'An optional regular expression used to filter the list' }
);
@outargs = (
{ name => 'brush_list', type => 'strv',
desc => 'The list of brush names' }
);
%invoke = (
headers => [ qw("core/pikacontainer-filter.h") ],
code => <<'CODE'
{
brush_list = pika_container_get_filtered_name_array (pika_data_factory_get_container (pika->brush_factory),
filter);
}
CODE
);
}
@headers = qw(<string.h>
"core/pika.h"
"core/pikabrush.h"
"core/pikacontext.h"
"core/pikadatafactory.h"
"core/pikatempbuf.h"
"pikapdb-utils.h");
@procs = qw(brushes_refresh
brushes_get_list);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Brushes';
$doc_title = 'pikabrushes';
$doc_short_desc = 'Functions for manipulating brushes.';
$doc_long_desc = 'Functions related to getting and setting brushes.';
1;

258
pdb/groups/buffer.pdb Normal file
View File

@ -0,0 +1,258 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub buffers_get_list {
$blurb = 'Retrieve a complete listing of the available buffers.';
$help = <<'HELP';
This procedure returns a complete listing of available named buffers.
HELP
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'filter', type => 'string', null_ok => 1,
desc => 'An optional regular expression used to filter the list' }
);
@outargs = (
{ name => 'buffer_list', type => 'strv',
desc => 'The list of buffer names' }
);
%invoke = (
code => <<'CODE'
{
buffer_list = pika_container_get_filtered_name_array (pika->named_buffers,
filter);
}
CODE
);
}
sub buffer_rename {
$blurb = 'Renames a named buffer.';
$help = 'This procedure renames a named buffer.';
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The buffer name' },
{ name => 'new_name', type => 'string', non_empty => 1,
desc => 'The buffer\'s new name' }
);
@outargs = (
{ name => 'real_name', type => 'string',
desc => 'The real name given to the buffer' }
);
%invoke = (
code => <<'CODE'
{
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
if (buffer)
{
pika_object_set_name (PIKA_OBJECT (buffer), new_name);
real_name = g_strdup (pika_object_get_name (buffer));
}
else
success = FALSE;
}
CODE
);
}
sub buffer_delete {
$blurb = 'Deletes a named buffer.';
$help = 'This procedure deletes a named buffer.';
$author = $copyright = 'David Gowers <neota@softhome.net>';
$date = '2005';
$since = '2.4';
@inargs = (
{ name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The buffer name' }
);
%invoke = (
code => <<'CODE'
{
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
if (buffer)
success = pika_container_remove (pika->named_buffers, PIKA_OBJECT (buffer));
else
success = FALSE;
}
CODE
);
}
sub buffer_get_width {
$blurb = "Retrieves the specified buffer's width.";
$help = "This procedure retrieves the specified named buffer's width.";
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The buffer name' }
);
@outargs = (
{ name => 'width', type => 'int32',
desc => "The buffer width" }
);
%invoke = (
code => <<'CODE'
{
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
if (buffer)
width = pika_buffer_get_width (buffer);
else
success = FALSE;
}
CODE
);
}
sub buffer_get_height {
$blurb = "Retrieves the specified buffer's height.";
$help = "This procedure retrieves the specified named buffer's height.";
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The buffer name' }
);
@outargs = (
{ name => 'height', type => 'int32',
desc => "The buffer height" }
);
%invoke = (
code => <<'CODE'
{
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
if (buffer)
height = pika_buffer_get_height (buffer);
else
success = FALSE;
}
CODE
);
}
sub buffer_get_bytes {
$blurb = "Retrieves the specified buffer's bytes.";
$help = "This procedure retrieves the specified named buffer's bytes.";
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The buffer name' }
);
@outargs = (
{ name => 'bytes', type => 'int32',
desc => "The buffer bpp" }
);
%invoke = (
code => <<'CODE'
{
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
if (buffer)
{
const Babl *format = pika_buffer_get_format (buffer);
bytes = babl_format_get_bytes_per_pixel (format);
}
else
success = FALSE;
}
CODE
);
}
sub buffer_get_image_type {
$blurb = "Retrieves the specified buffer's image type.";
$help = "This procedure retrieves the specified named buffer's image type.";
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The buffer name' }
);
@outargs = (
{ name => 'image_type', type => 'enum PikaImageBaseType',
desc => "The buffer image type" }
);
%invoke = (
code => <<'CODE'
{
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
if (buffer)
image_type = pika_babl_format_get_image_type (pika_buffer_get_format (buffer));
else
success = FALSE;
}
CODE
);
}
@headers = qw(<string.h>
"gegl/pika-babl-compat.h"
"core/pika.h"
"core/pikabuffer.h"
"core/pikacontainer.h"
"core/pikacontainer-filter.h"
"pikapdb-utils.h");
@procs = qw(buffers_get_list
buffer_rename
buffer_delete
buffer_get_width
buffer_get_height
buffer_get_bytes
buffer_get_image_type);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Buffer procedures';
$doc_title = 'pikabuffer';
$doc_short_desc = 'Functions for manipulating cut buffers.';
$doc_long_desc = 'Functions related to named cut buffers.';
1;

386
pdb/groups/channel.pdb Normal file
View File

@ -0,0 +1,386 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub channel_new {
$blurb = 'Create a new channel.';
$help = <<'HELP';
This procedure creates a new channel with the specified width, height,
name, opacity and color.
The new channel still needs to be added to the image, as this is not
automatic. Add the new channel with pika_image_insert_channel(). Other
attributes, such as channel visibility, should be set with explicit
procedure calls.
The channel's contents are undefined initially.
HELP
&std_pdb_misc;
$lib_private = 1;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image to which to add the channel' },
{ name => 'width', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
desc => 'The channel width' },
{ name => 'height', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
desc => 'The channel height' },
{ name => 'name', type => 'string',
desc => 'The channel name' },
{ name => 'opacity', type => '0 <= float <= 100',
desc => 'The channel opacity' },
{ name => 'color', type => 'color',
desc => 'The channel compositing color'
}
);
@outargs = (
{ name => 'channel', type => 'channel',
desc => 'The newly created channel' }
);
%invoke = (
code => <<'CODE'
{
PikaRGB rgb_color = color;
rgb_color.a = opacity / 100.0;
channel = pika_channel_new (image, width, height, name, &rgb_color);
if (! channel)
success = FALSE;
}
CODE
);
}
sub channel_copy {
$blurb = 'Copy a channel.';
$help = <<'HELP';
This procedure copies the specified channel and returns the copy.
The new channel still needs to be added to the image, as this is not
automatic. Add the new channel with pika_image_insert_channel().
HELP
&std_pdb_misc;
@inargs = (
{ name => 'channel', type => 'channel',
desc => 'The channel to copy' }
);
@outargs = (
{ name => 'channel_copy', type => 'channel',
desc => 'The newly copied channel' }
);
%invoke = (
code => <<'CODE'
{
PikaImage *image = pika_item_get_image (PIKA_ITEM (channel));
gint width = pika_image_get_width (image);
gint height = pika_image_get_height (image);
if (pika_item_get_width (PIKA_ITEM (channel)) == width &&
pika_item_get_height (PIKA_ITEM (channel)) == height)
{
channel_copy = PIKA_CHANNEL (pika_item_duplicate (PIKA_ITEM (channel),
PIKA_TYPE_CHANNEL));
if (! channel_copy)
success = FALSE;
}
else
success = FALSE;
}
CODE
);
}
sub channel_combine_masks {
$blurb = 'Combine two channel masks.';
$help = <<'HELP';
This procedure combines two channel masks. The result is stored
in the first channel.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'channel1', type => 'channel',
desc => 'The channel1' },
{ name => 'channel2', type => 'channel',
desc => 'The channel2' },
{ name => 'operation', type => 'enum PikaChannelOps',
desc => 'The selection operation' },
{ name => 'offx', type => 'int32',
desc => 'x offset between upper left corner of
channels: (second - first)' },
{ name => 'offy', type => 'int32',
desc => 'y offset between upper left corner of
channels: (second - first)' }
);
%invoke = (
headers => [ qw("core/pikachannel-combine.h" "pika-intl.h") ],
code => <<'CODE'
{
if (pika_item_is_attached (PIKA_ITEM (channel1)))
pika_channel_push_undo (channel1, _("Combine Masks"));
pika_channel_combine_mask (channel1, channel2, operation, offx, offy);
}
CODE
);
}
sub channel_new_from_component {
$blurb = 'Create a new channel from a color component';
$help = <<'HELP';
This procedure creates a new channel from a color component.
The new channel still needs to be added to the image, as this is not
automatic. Add the new channel with pika_image_insert_channel(). Other
attributes, such as channel visibility, should be set with explicit
procedure calls.
HELP
&shlomi_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image to which to add the channel' },
{ name => 'component', type => 'enum PikaChannelType',
desc => 'The image component' },
{ name => 'name', type => 'string',
desc => 'The channel name' },
);
@outargs = (
{ name => 'channel', type => 'channel',
desc => 'The newly created channel' }
);
%invoke = (
code => <<'CODE'
{
if (pika_image_get_component_format (image, component) != NULL)
channel = pika_channel_new_from_component (image,
component, name, NULL);
if (channel)
pika_item_set_visible (PIKA_ITEM (channel), FALSE, FALSE);
else
success = FALSE;
}
CODE
);
}
sub channel_get_show_masked {
$blurb = "Get the composite method of the specified channel.";
$help = <<'HELP';
This procedure returns the specified channel's composite method. If
it is TRUE, then the channel is composited with the image so that
masked regions are shown. Otherwise, selected regions are shown.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'channel', type => 'channel',
desc => 'The channel' }
);
@outargs = (
{ name => 'show_masked', type => 'boolean',
desc => 'The channel composite method' }
);
%invoke = (
code => <<'CODE'
{
show_masked = pika_channel_get_show_masked (channel);
}
CODE
);
}
sub channel_set_show_masked {
$blurb = "Set the composite method of the specified channel.";
$help = <<'HELP';
This procedure sets the specified channel's composite method. If
it is TRUE, then the channel is composited with the image so that
masked regions are shown. Otherwise, selected regions are shown.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'channel', type => 'channel',
desc => 'The channel' },
{ name => 'show_masked', type => 'boolean',
desc => 'The new channel composite method' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_set_show_masked (channel, show_masked);
}
CODE
);
}
sub channel_get_opacity {
$blurb = "Get the opacity of the specified channel.";
$help = <<'HELP';
This procedure returns the specified channel's opacity.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'channel', type => 'channel',
desc => 'The channel' }
);
@outargs = (
{ name => 'opacity', type => '0 <= float <= 100',
desc => 'The channel opacity' }
);
%invoke = (
code => <<'CODE'
{
opacity = pika_channel_get_opacity (channel) * 100;
}
CODE
);
}
sub channel_set_opacity {
$blurb = "Set the opacity of the specified channel.";
$help = <<'HELP';
This procedure sets the specified channel's opacity.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'channel', type => 'channel',
desc => 'The channel' },
{ name => 'opacity', type => '0 <= float <= 100',
desc => 'The new channel opacity' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_set_opacity (channel, opacity / 100.0, TRUE);
}
CODE
);
}
sub channel_get_color {
$blurb = "Get the compositing color of the specified channel.";
$help = <<'HELP';
This procedure returns the specified channel's compositing color.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'channel', type => 'channel',
desc => 'The channel' }
);
@outargs = (
{ name => 'color', type => 'color', void_ret => 1,
desc => 'The channel compositing color' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_get_color (channel, &color);
pika_rgb_set_alpha (&color, 1.0);
}
CODE
);
}
sub channel_set_color {
$blurb = "Set the compositing color of the specified channel.";
$help = <<'HELP';
This procedure sets the specified channel's compositing color.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'channel', type => 'channel',
desc => 'The channel' },
{ name => 'color', type => 'color',
desc => 'The new channel compositing color' }
);
%invoke = (
code => <<'CODE'
{
PikaRGB rgb_color = color;
rgb_color.a = channel->color.a;
pika_channel_set_color (channel, &rgb_color, TRUE);
}
CODE
);
}
@headers = qw("libpikabase/pikabase.h");
@procs = qw(channel_new
channel_new_from_component
channel_copy
channel_combine_masks
channel_get_show_masked channel_set_show_masked
channel_get_opacity channel_set_opacity
channel_get_color channel_set_color);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Channel';
$doc_title = 'pikachannel';
$doc_short_desc = 'Functions for manipulating channels.';
$doc_long_desc = 'Functions for manipulating channels.';
1;

3501
pdb/groups/context.pdb Normal file

File diff suppressed because it is too large Load Diff

104
pdb/groups/debug.pdb Normal file
View File

@ -0,0 +1,104 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub debug_timer_start {
$blurb = 'Starts measuring elapsed time.';
$help = <<'HELP';
This procedure starts a timer, measuring the elapsed time since the call.
Each call to this procedure should be matched by a call to
pika_debug_timer_end(), which returns the elapsed time.
If there is already an active timer, it is not affected by the call, however, a
matching pika_debug_timer_end() call is still required.
HELP
&ell_pdb_misc('2017');
&std_pdb_debug();
%invoke = (
code => <<'CODE'
{
if (pika_debug_timer_counter++ == 0)
pika_debug_timer = g_timer_new ();
}
CODE
);
}
sub debug_timer_end {
$blurb = 'Finishes measuring elapsed time.';
$help = <<'HELP';
This procedure stops the timer started by a previous pika_debug_timer_start()
call, and prints and returns the elapsed time.
If there was already an active timer at the time of corresponding call to
pika_debug_timer_start(), a dummy value is returned.
HELP
&ell_pdb_misc('2017');
&std_pdb_debug();
@outargs = (
{ name => 'elapsed', type => 'float',
desc => 'The elapsed time, in seconds' }
);
%invoke = (
code => <<'CODE'
{
elapsed = 0.0;
if (pika_debug_timer_counter == 0)
success = FALSE;
else if (--pika_debug_timer_counter == 0)
{
elapsed = g_timer_elapsed (pika_debug_timer, NULL);
g_printerr ("PIKA debug timer: %g seconds\n", elapsed);
g_timer_destroy (pika_debug_timer);
pika_debug_timer = NULL;
}
}
CODE
);
}
$extra{app}->{code} = <<'CODE';
static GTimer *pika_debug_timer = NULL;
static gint pika_debug_timer_counter = 0;
CODE
@procs = qw(debug_timer_start debug_timer_end);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Debug';
$doc_title = 'pikadebug';
$doc_short_desc = 'Debug utility functions';
$doc_long_desc = 'Miscellaneous debug utility functions. Not part of the stable library interface.';
1;

254
pdb/groups/display.pdb Normal file
View File

@ -0,0 +1,254 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub display_id_is_valid {
$blurb = 'Returns TRUE if the display ID is valid.';
$help = <<'HELP';
This procedure checks if the given display ID is valid and refers to an
existing display.
HELP
&neo_pdb_misc('2007', '3.0');
@inargs = (
{ name => 'display_id', type => 'int32',
desc => 'The display ID to check' }
);
@outargs = (
{ name => 'valid', type => 'boolean',
desc => 'Whether the display ID is valid' }
);
%invoke = (
code => <<'CODE'
{
valid = (pika_display_get_by_id (pika, display_id) != NULL);
}
CODE
);
}
sub display_new {
$blurb = 'Create a new display for the specified image.';
$help = <<'HELP';
Creates a new display for the specified image. If the image already has a
display, another is added. Multiple displays are handled transparently by
PIKA. The newly created display is returned and can be subsequently destroyed
with a call to pika_display_delete(). This procedure only makes sense for use
with the PIKA UI, and will result in an execution error if called when
PIKA has no UI.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'display', type => 'display',
desc => 'The new display' }
);
%invoke = (
code => <<'CODE'
{
pika_image_flush (image);
display = pika_create_display (pika, image, PIKA_UNIT_PIXEL, 1.0, NULL);
if (display)
{
/* the first display takes ownership of the image */
if (pika_image_get_display_count (image) == 1)
g_object_unref (image);
}
else
{
success = FALSE;
}
}
CODE
);
}
sub display_delete {
$blurb = 'Delete the specified display.';
$help = <<'HELP';
This procedure removes the specified display. If this is the last remaining
display for the underlying image, then the image is deleted also. Note that
the display is closed no matter if the image is dirty or not. Better save
the image before calling this procedure.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'display', type => 'display',
desc => 'The display to delete' }
);
%invoke = (
code => <<'CODE'
{
pika_delete_display (pika, display);
}
CODE
);
}
sub display_present {
$blurb = 'Present the specified display.';
$help = <<'HELP';
This procedure presents the specified display at the top of the display stack.
HELP
&jehan_pdb_misc('2021', '3.0');
@inargs = (
{ name => 'display', type => 'display',
desc => 'The display to present' }
);
%invoke = (
code => <<'CODE'
{
pika_display_present (display);
}
CODE
);
}
sub display_get_window_handle {
$blurb = 'Get a handle to the native window for an image display.';
$help = <<'HELP';
This procedure returns a handle to the native window for a given image
display. For example in the X backend of GDK, a native window handle is
an Xlib XID. A value of 0 is returned for an invalid display or if this
function is unimplemented for the windowing system that is being used.
HELP
&neo_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'display', type => 'display',
desc => 'The display to get the window handle from' }
);
@outargs = (
{ name => 'window', type => 'int32',
desc => 'The native window handle or 0' }
);
%invoke = (
code => <<'CODE'
{
window = (gint32) pika_get_display_window_id (pika, display);
}
CODE
);
}
sub displays_flush {
$blurb = 'Flush all internal changes to the user interface';
$help = <<'HELP';
This procedure takes no arguments and returns nothing except a success status.
Its purpose is to flush all pending updates of image manipulations to the user
interface. It should be called whenever appropriate.
HELP
&std_pdb_misc;
%invoke = (
headers => [ qw("core/pikacontainer.h") ],
code => <<'CODE'
{
pika_container_foreach (pika->images, (GFunc) pika_image_flush, NULL);
}
CODE
);
}
sub displays_reconnect {
$blurb = 'Reconnect displays from one image to another image.';
$help = <<'HELP';
This procedure connects all displays of the old_image to the
new_image. If the old_image has no display or new_image already has a
display the reconnect is not performed and the procedure returns
without success. You should rarely need to use this function.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'old_image', type => 'image',
desc => 'The old image (must have at least one display)' },
{ name => 'new_image', type => 'image',
desc => 'The new image (must not have a display)' }
);
%invoke = (
code => <<'CODE'
{
success = (old_image != new_image &&
pika_image_get_display_count (old_image) > 0 &&
pika_image_get_display_count (new_image) == 0);
if (success)
{
pika_reconnect_displays (pika, old_image, new_image);
/* take ownership of the image */
if (pika_image_get_display_count (new_image) > 0)
g_object_unref (new_image);
}
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pikadisplay.h");
@procs = qw(display_id_is_valid
display_new
display_delete
display_get_window_handle
display_present
displays_flush
displays_reconnect);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Display procedures';
$doc_title = 'pikadisplay';
$doc_short_desc = 'Functions to create, delete and flush displays (views) on an image.';
$doc_long_desc = 'Functions to create, delete and flush displays (views) on an image.';
1;

939
pdb/groups/drawable.pdb Normal file
View File

@ -0,0 +1,939 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub drawable_merge_shadow {
$blurb = 'Merge the shadow buffer with the specified drawable.';
$help = <<'HELP';
This procedure combines the contents of the drawable's shadow buffer
(for temporary processing) with the specified drawable. The 'undo'
parameter specifies whether to add an undo step for the operation.
Requesting no undo is useful for such applications as 'auto-apply'.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'undo', type => 'boolean',
desc => 'Push merge to undo stack?' }
);
%invoke = (
headers => [ qw("core/pikadrawable-shadow.h"
"plug-in/pikaplugin.h"
"plug-in/pikapluginmanager.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
const gchar *undo_desc = _("Plug-in");
if (pika->plug_in_manager->current_plug_in)
undo_desc = pika_plug_in_get_undo_desc (pika->plug_in_manager->current_plug_in);
pika_drawable_merge_shadow_buffer (drawable, undo, undo_desc);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_free_shadow {
$blurb = "Free the specified drawable's shadow data (if it exists).";
$help = <<'HELP';
This procedure is intended as a memory saving device. If any shadow
memory has been allocated, it will be freed automatically when the
drawable is removed from the image, or when the plug-in procedure
which allocated it returns.
HELP
&mitch_pdb_misc('2008', '2.6');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
%invoke = (
headers => [ qw("plug-in/pikaplugin-cleanup.h") ],
code => <<'CODE'
{
if (pika->plug_in_manager->current_plug_in)
pika_plug_in_cleanup_remove_shadow (pika->plug_in_manager->current_plug_in,
drawable);
pika_drawable_free_shadow_buffer (drawable);
}
CODE
);
}
sub drawable_fill {
$blurb = 'Fill the drawable with the specified fill mode.';
$help = <<'HELP';
This procedure fills the drawable. If the fill mode is foreground the
current foreground color is used. If the fill mode is background, the
current background color is used. If the fill type is white, then
white is used. Transparent fill only affects layers with an alpha
channel, in which case the alpha channel is set to transparent. If the
drawable has no alpha channel, it is filled to white. No fill leaves
the drawable's contents undefined.
This procedure is unlike pika_drawable_edit_fill() or the bucket fill
tool because it fills regardless of a selection. Its main purpose is to
fill a newly created drawable before adding it to the image. This
operation cannot be undone.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'fill_type', type => 'enum PikaFillType',
desc => 'The type of fill' }
);
%invoke = (
headers => [ qw("core/pikadrawable-fill.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_modifiable (PIKA_ITEM (drawable),
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
pika_drawable_fill (drawable, context, (PikaFillType) fill_type);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_update {
$blurb = 'Update the specified region of the drawable.';
$help = <<'HELP';
This procedure updates the specified region of the drawable. The (x, y)
coordinate pair is relative to the drawable's origin, not to the image origin.
Therefore, the entire drawable can be updated using (0, 0, width, height).
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'x', type => 'int32',
desc => 'x coordinate of upper left corner of update region' },
{ name => 'y', type => 'int32',
desc => 'y coordinate of upper left corner of update region' },
{ name => 'width', type => 'int32',
desc => 'Width of update region' },
{ name => 'height', type => 'int32',
desc => 'Height of update region' }
);
%invoke = (
code => <<'CODE'
{
pika_drawable_update (drawable, x, y, width, height);
}
CODE
);
}
sub drawable_mask_bounds {
$blurb = <<'BLURB';
Find the bounding box of the current selection in relation to the specified
drawable.
BLURB
$help = <<'HELP';
This procedure returns whether there is a selection. If there is one, the
upper left and lower right-hand corners of its bounding box are returned. These
coordinates are specified relative to the drawable's origin, and bounded by
the drawable's extents. Please note that the pixel specified by the lower
right-hand coordinate of the bounding box is not part of the selection. The
selection ends at the upper left corner of this pixel. This means the width
of the selection can be calculated as (x2 - x1), its height as (y2 - y1).
Note that the returned boolean does NOT correspond with the returned
region being empty or not, it always returns whether the selection
is non_empty. See pika_drawable_mask_intersect() for a boolean
return value which is more useful in most cases.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'non_empty', type => 'boolean',
desc => 'TRUE if there is a selection' },
{ name => 'x1', type => 'int32',
desc => "x coordinate of the upper left corner of selection bounds" },
{ name => 'y1', type => 'int32',
desc => "y coordinate of the upper left corner of selection bounds" },
{ name => 'x2', type => 'int32',
desc => "x coordinate of the lower right corner of selection bounds" },
{ name => 'y2', type => 'int32',
desc => "y coordinate of the lower right corner of selection bounds" }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL, 0, error))
non_empty = pika_item_mask_bounds (PIKA_ITEM (drawable), &x1, &y1, &x2, &y2);
else
success = FALSE;
}
CODE
);
}
sub drawable_mask_intersect {
$blurb = <<'BLURB';
Find the bounding box of the current selection in relation to the specified
drawable.
BLURB
$help = <<'HELP';
This procedure returns whether there is an intersection between the
drawable and the selection. Unlike pika_drawable_mask_bounds(), the
intersection's bounds are returned as x, y, width, height.
If there is no selection this function returns TRUE and the returned
bounds are the extents of the whole drawable.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'non_empty', type => 'boolean',
desc => 'TRUE if the returned area is not empty' },
{ name => 'x', type => 'int32',
desc => 'x coordinate of the upper left corner of the intersection' },
{ name => 'y', type => 'int32',
desc => 'y coordinate of the upper left corner of the intersection' },
{ name => 'width', type => 'int32',
desc => 'width of the intersection' },
{ name => 'height', type => 'int32',
desc => 'height of the intersection' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL, 0, error))
non_empty = pika_item_mask_intersect (PIKA_ITEM (drawable),
&x, &y, &width, &height);
else
success = FALSE;
}
CODE
);
}
sub drawable_get_format {
$blurb = "Returns the drawable's Babl format";
$help = <<'HELP';
This procedure returns the drawable's Babl format.
Note that the actual PDB procedure only transfers the format's
encoding. In order to get to the real format, the libbpika C wrapper
must be used.
HELP
&mitch_pdb_misc('2012', '2.10');
$lib_private = 1;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'format', type => 'string',
desc => "The drawable's Babl format" }
);
%invoke = (
code => <<'CODE'
{
/* this only transfers the encoding, losing the space, see the
* code in libpika/pikadrawable.c which reconstructs the actual
* format in the plug-in process
*/
format = g_strdup (babl_format_get_encoding (pika_drawable_get_format (drawable)));
}
CODE
);
}
sub drawable_get_thumbnail_format {
$blurb = "Returns the drawable's thumbnail Babl format";
$help = <<'HELP';
This procedure returns the drawable's thumbnail Babl format.
Thumbnails are always 8-bit images, see pika_drawable_thumbnail() and
pika_drawable_sub_thmbnail().
HELP
&mitch_pdb_misc('2019', '2.10.14');
$lib_private = 1;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'format', type => 'string',
desc => "The drawable's thumbnail Babl format" }
);
%invoke = (
code => <<'CODE'
{
format = g_strdup (babl_format_get_encoding (pika_drawable_get_preview_format (drawable)));
}
CODE
);
}
sub drawable_type {
$blurb = "Returns the drawable's type.";
$help = "This procedure returns the drawable's type.";
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'type', type => 'enum PikaImageType',
desc => "The drawable's type" }
);
%invoke = (
code => <<'CODE'
{
type = pika_babl_format_get_image_type (pika_drawable_get_format (drawable));
}
CODE
);
}
sub drawable_has_alpha {
$blurb = 'Returns TRUE if the drawable has an alpha channel.';
$help = <<'HELP';
This procedure returns whether the specified drawable has an alpha channel.
This can only be true for layers, and the associated type will be one of:
{ RGBA , GRAYA, INDEXEDA }.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'has_alpha', type => 'boolean',
desc => 'Does the drawable have an alpha channel?' }
);
%invoke = (
code => <<'CODE'
{
has_alpha = pika_drawable_has_alpha (drawable);
}
CODE
);
}
sub drawable_type_with_alpha {
$blurb = "Returns the drawable's type with alpha.";
$help = <<'HELP';
This procedure returns the drawable's type as if had an alpha
channel. If the type is currently Gray, for instance, the returned
type would be GrayA. If the drawable already has an alpha channel, the
drawable's type is simply returned.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'type_with_alpha', type => 'enum PikaImageType
(no PIKA_RGB_IMAGE,
PIKA_GRAY_IMAGE,
PIKA_INDEXED_IMAGE)',
desc => "The drawable's type with alpha" }
);
%invoke = (
code => <<'CODE'
{
const Babl *format = pika_drawable_get_format_with_alpha (drawable);
type_with_alpha = pika_babl_format_get_image_type (format);
}
CODE
);
}
sub drawable_is_rgb {
$blurb = 'Returns whether the drawable is an RGB type.';
$help = <<HELP;
This procedure returns TRUE if the specified drawable
is of type { RGB, RGBA }.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'is_rgb', type => 'boolean',
desc => 'TRUE if the drawable is an RGB type' }
);
%invoke = (
code => <<'CODE'
{
is_rgb = pika_drawable_is_rgb (drawable);
}
CODE
);
}
sub drawable_is_gray {
$blurb = 'Returns whether the drawable is a grayscale type.';
$help = <<HELP;
This procedure returns TRUE if the specified drawable
is of type { Gray, GrayA }.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'is_gray', type => 'boolean',
desc => 'TRUE if the drawable is a grayscale type' }
);
%invoke = (
code => <<'CODE'
{
is_gray = pika_drawable_is_gray (drawable);
}
CODE
);
}
sub drawable_is_indexed {
$blurb = 'Returns whether the drawable is an indexed type.';
$help = <<HELP;
This procedure returns TRUE if the specified drawable
is of type { Indexed, IndexedA }.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'is_indexed', type => 'boolean',
desc => 'TRUE if the drawable is an indexed type' }
);
%invoke = (
code => <<'CODE'
{
is_indexed = pika_drawable_is_indexed (drawable);
}
CODE
);
}
sub drawable_get_bpp {
$blurb = 'Returns the bytes per pixel.';
$help = <<'HELP';
This procedure returns the number of bytes per pixel.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'bpp', type => 'int32',
desc => 'Bytes per pixel' }
);
%invoke = (
code => <<'CODE'
{
const Babl *format = pika_drawable_get_format (drawable);
bpp = babl_format_get_bytes_per_pixel (format);
}
CODE
);
}
sub drawable_get_width {
$blurb = 'Returns the width of the drawable.';
$help = "This procedure returns the specified drawable's width in pixels.";
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'width', type => 'int32',
desc => 'Width of drawable' }
);
%invoke = (
code => <<'CODE'
{
width = pika_item_get_width (PIKA_ITEM (drawable));
}
CODE
);
}
sub drawable_get_height {
$blurb = 'Returns the height of the drawable.';
$help = "This procedure returns the specified drawable's height in pixels.";
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'height', type => 'int32',
desc => 'Height of drawable' }
);
%invoke = (
code => <<'CODE'
{
height = pika_item_get_height (PIKA_ITEM (drawable));
}
CODE
);
}
sub drawable_get_offsets {
$blurb = 'Returns the offsets for the drawable.';
$help = <<'HELP';
This procedure returns the specified drawable's offsets. This only makes sense
if the drawable is a layer since channels are anchored. The offsets of a
channel will be returned as 0.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
@outargs = (
{ name => 'offset_x', type => 'int32', void_ret => 1,
desc => "x offset of drawable" },
{ name => 'offset_y', type => 'int32',
desc => "y offset of drawable" }
);
%invoke = (
code => <<'CODE'
{
pika_item_get_offset (PIKA_ITEM (drawable), &offset_x, &offset_y);
}
CODE
);
}
sub drawable_thumbnail {
$blurb = 'Get a thumbnail of a drawable.';
$help = <<'HELP';
This function gets data from which a thumbnail of a drawable preview
can be created. Maximum x or y dimension is 1024 pixels. The pixels are
returned in RGB[A] or GRAY[A] format. The bpp return value gives the
number of bytes in the image.
HELP
&andy_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'width', type => '1 <= int32 <= 1024',
desc => 'The requested thumbnail width' },
{ name => 'height', type => '1 <= int32 <= 1024',
desc => 'The requested thumbnail height' }
);
@outargs = (
{ name => 'actual_width', type => 'int32', void_ret => 1,
desc => 'The previews width' },
{ name => 'actual_height', type => 'int32',
desc => 'The previews height' },
{ name => 'bpp', type => 'int32',
desc => 'The previews bpp' },
{ name => 'thumbnail_data', type => 'bytes',
desc => 'The thumbnail data', }
);
%invoke = (
code => <<'CODE'
{
PikaImage *image = pika_item_get_image (PIKA_ITEM (drawable));
PikaTempBuf *buf;
gint dwidth, dheight;
pika_assert (PIKA_VIEWABLE_MAX_PREVIEW_SIZE >= 1024);
/* Adjust the width/height ratio */
dwidth = pika_item_get_width (PIKA_ITEM (drawable));
dheight = pika_item_get_height (PIKA_ITEM (drawable));
if (dwidth > dheight)
height = MAX (1, (width * dheight) / dwidth);
else
width = MAX (1, (height * dwidth) / dheight);
if (image->pika->config->layer_previews)
buf = pika_viewable_get_new_preview (PIKA_VIEWABLE (drawable), context,
width, height);
else
buf = pika_viewable_get_dummy_preview (PIKA_VIEWABLE (drawable),
width, height,
pika_drawable_get_preview_format (drawable));
if (buf)
{
actual_width = pika_temp_buf_get_width (buf);
actual_height = pika_temp_buf_get_height (buf);
bpp = babl_format_get_bytes_per_pixel (pika_temp_buf_get_format (buf));
thumbnail_data = g_bytes_new (pika_temp_buf_get_data (buf),
pika_temp_buf_get_data_size (buf));
pika_temp_buf_unref (buf);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_sub_thumbnail {
$blurb = 'Get a thumbnail of a sub-area of a drawable drawable.';
$help = <<'HELP';
This function gets data from which a thumbnail of a drawable preview
can be created. Maximum x or y dimension is 1024 pixels. The pixels are
returned in RGB[A] or GRAY[A] format. The bpp return value gives the
number of bytes in the image.
HELP
&mitch_pdb_misc('2004', '2.2');
$lib_private = 1;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'src_x', type => '0 <= int32',
desc => 'The x coordinate of the area' },
{ name => 'src_y', type => '0 <= int32',
desc => 'The y coordinate of the area' },
{ name => 'src_width', type => '1 <= int32',
desc => 'The width of the area' },
{ name => 'src_height', type => '1 <= int32',
desc => 'The height of the area' },
{ name => 'dest_width', type => '1 <= int32 <= 1024',
desc => 'The thumbnail width' },
{ name => 'dest_height', type => '1 <= int32 <= 1024',
desc => 'The thumbnail height' }
);
@outargs = (
{ name => 'width', type => 'int32', void_ret => 1,
desc => 'The previews width' },
{ name => 'height', type => 'int32',
desc => 'The previews height' },
{ name => 'bpp', type => 'int32',
desc => 'The previews bpp' },
{ name => 'thumbnail_data', type => 'bytes',
desc => 'The thumbnail data' }
);
%invoke = (
headers => [ qw("core/pikadrawable-preview.h") ],
code => <<'CODE'
{
if ((src_x + src_width) <= pika_item_get_width (PIKA_ITEM (drawable)) &&
(src_y + src_height) <= pika_item_get_height (PIKA_ITEM (drawable)))
{
PikaImage *image = pika_item_get_image (PIKA_ITEM (drawable));
PikaTempBuf *buf;
if (image->pika->config->layer_previews)
buf = pika_drawable_get_sub_preview (drawable,
src_x, src_y,
src_width, src_height,
dest_width, dest_height);
else
buf = pika_viewable_get_dummy_preview (PIKA_VIEWABLE (drawable),
dest_width, dest_height,
pika_drawable_get_preview_format (drawable));
if (buf)
{
width = pika_temp_buf_get_width (buf);
height = pika_temp_buf_get_height (buf);
bpp = babl_format_get_bytes_per_pixel (pika_temp_buf_get_format (buf));
thumbnail_data = g_bytes_new (pika_temp_buf_get_data (buf),
pika_temp_buf_get_data_size (buf));
pika_temp_buf_unref (buf);
}
else
success = FALSE;
}
else
success = FALSE;
}
CODE
);
}
sub drawable_offset {
$blurb = <<'BLURB';
Offset the drawable by the specified amounts in the X and Y directions
BLURB
$help = <<'HELP';
This procedure offsets the specified drawable by the amounts specified by
'offset_x' and 'offset_y'. If 'wrap_around' is set to TRUE, then portions of
the drawable which are offset out of bounds are wrapped around. Alternatively,
the undefined regions of the drawable can be filled with transparency or the
background color, as specified by the 'fill-type' parameter.
HELP
&std_pdb_misc;
$date = '1997';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable to offset' },
{ name => 'wrap_around', type => 'boolean',
desc => 'wrap image around or fill vacated regions' },
{ name => 'fill_type', type => 'enum PikaOffsetType',
desc => 'fill vacated regions of drawable with background or
transparent' },
{ name => 'offset_x', type => 'int32',
desc => 'offset by this amount in X direction' },
{ name => 'offset_y', type => 'int32',
desc => 'offset by this amount in Y direction' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
pika_drawable_offset (drawable, context, wrap_around, fill_type,
offset_x, offset_y);
else
success = FALSE;
}
CODE
);
}
sub drawable_foreground_extract {
$blurb = 'Extract the foreground of a drawable using a given trimap.';
$help = <<'HELP';
Image Segmentation by Uniform Color Clustering, see
https://www.inf.fu-berlin.de/inst/pubs/tr-b-05-07.pdf
HELP
$author = 'Gerald Friedland <fland@inf.fu-berlin.de>, Kristian Jantz <jantz@inf.fu-berlin.de>, Sven Neumann <sven@gimp.org>';
$copyright = 'Gerald Friedland';
$date = '2005';
$since = '2.4';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'mode', type => 'enum PikaForegroundExtractMode',
desc => 'The algorithm to use' },
{ name => 'mask', type => 'drawable', desc => 'Tri-Map' }
);
%invoke = (
headers => [ qw("core/pikadrawable-foreground-extract.h") ],
code => <<'CODE'
{
if (mode == PIKA_FOREGROUND_EXTRACT_MATTING &&
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL, 0, error))
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
PikaImage *image = pika_item_get_image (PIKA_ITEM (drawable));
GeglBuffer *buffer;
buffer = pika_drawable_foreground_extract (drawable,
PIKA_MATTING_ENGINE_GLOBAL,
2,
2,
2,
pika_drawable_get_buffer (mask),
progress);
pika_channel_select_buffer (pika_image_get_mask (image),
C_("command", "Foreground Select"),
buffer,
0, /* x offset */
0, /* y offset */
PIKA_CHANNEL_OP_REPLACE,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y);
g_object_unref (buffer);
}
else
success = FALSE;
}
CODE
);
}
@headers = qw("config/pikacoreconfig.h"
"gegl/pika-babl.h"
"gegl/pika-babl-compat.h"
"core/pika.h"
"core/pikachannel-select.h"
"core/pikadrawable-offset.h"
"core/pikaimage.h"
"core/pikatempbuf.h"
"pikapdb-utils.h"
"pikapdbcontext.h"
"pika-intl.h");
@procs = qw(drawable_get_format
drawable_get_thumbnail_format
drawable_type
drawable_type_with_alpha
drawable_has_alpha
drawable_is_rgb
drawable_is_gray
drawable_is_indexed
drawable_get_bpp
drawable_get_width
drawable_get_height
drawable_get_offsets
drawable_mask_bounds
drawable_mask_intersect
drawable_merge_shadow
drawable_free_shadow
drawable_update
drawable_fill
drawable_offset
drawable_thumbnail
drawable_sub_thumbnail
drawable_foreground_extract);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Drawable procedures';
$doc_title = 'pikadrawable';
$doc_short_desc = 'Functions to manipulate drawables.';
$doc_long_desc = 'Functions to manipulate drawables.';
1;

View File

@ -0,0 +1,949 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub drawable_brightness_contrast {
$blurb = 'Modify brightness/contrast in the specified drawable.';
$help = <<'HELP';
This procedures allows the brightness and contrast of the specified drawable to
be modified. Both 'brightness' and 'contrast' parameters are defined between
-1.0 and 1.0.
HELP
&std_pdb_misc;
$date = '1997';
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'brightness', type => '-1.0 <= float <= 1.0',
desc => 'Brightness adjustment' },
{ name => 'contrast', type => '-1.0 <= float <= 1.0',
desc => 'Contrast adjustment' }
);
%invoke = (
headers => [ qw("operations/pikabrightnesscontrastconfig.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
GObject *config = g_object_new (PIKA_TYPE_BRIGHTNESS_CONTRAST_CONFIG,
"brightness", brightness,
"contrast", contrast,
NULL);
pika_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Brightness-Contrast"),
"pika:brightness-contrast",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_color_balance {
$blurb = 'Modify the color balance of the specified drawable.';
$help = <<'HELP';
Modify the color balance of the specified drawable. There are three axis which
can be modified: cyan-red, magenta-green, and yellow-blue. Negative values
increase the amount of the former, positive values increase the amount of the
latter. Color balance can be controlled with the 'transfer_mode' setting, which
allows shadows, mid-tones, and highlights in an image to be affected
differently. The 'preserve-lum' parameter, if TRUE, ensures that the
luminosity of each pixel remains fixed.
HELP
&std_pdb_misc;
$date = '1997';
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'transfer_mode', type => 'enum PikaTransferMode',
desc => 'Transfer mode' },
{ name => 'preserve_lum', type => 'boolean',
desc => 'Preserve luminosity values at each pixel' },
{ name => 'cyan_red', type => '-100 <= float <= 100',
desc => 'Cyan-Red color balance' },
{ name => 'magenta_green', type => '-100 <= float <= 100',
desc => 'Magenta-Green color balance' },
{ name => 'yellow_blue', type => '-100 <= float <= 100',
desc => 'Yellow-Blue color balance' }
);
%invoke = (
headers => [ qw("operations/pikacolorbalanceconfig.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
GObject *config = g_object_new (PIKA_TYPE_COLOR_BALANCE_CONFIG,
"range", transfer_mode,
"preserve-luminosity", preserve_lum,
NULL);
g_object_set (config,
"cyan-red", cyan_red / 100.0,
"magenta-green", magenta_green / 100.0,
"yellow-blue", yellow_blue / 100.0,
NULL);
pika_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Color Balance"),
"pika:color-balance",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_colorize_hsl {
$blurb = 'Render the drawable as a grayscale image seen through a colored glass.';
$help = <<'HELP';
Desaturates the drawable, then tints it with the specified color. This tool is
only valid on RGB color images. It will not operate on grayscale drawables.
HELP
&neo_pdb_misc('2004', '2.10');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'hue', type => '0 <= float <= 360',
desc => 'Hue in degrees' },
{ name => 'saturation', type => '0 <= float <= 100',
desc => 'Saturation in percent' },
{ name => 'lightness', type => '-100 <= float <= 100',
desc => 'Lightness in percent' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error) &&
! pika_drawable_is_gray (drawable))
{
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "pika:colorize",
"hue", hue / 360.0,
"saturation", saturation / 100.0,
"lightness", lightness / 100.0,
NULL);
pika_drawable_apply_operation (drawable, progress,
C_("undo-type", "Colorize"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_curves_explicit {
$blurb = 'Modifies the intensity curve(s) for specified drawable.';
$help = <<'HELP';
Modifies the intensity mapping for one channel in the specified
drawable. The channel can be either an intensity component, or the
value. The 'values' parameter is an array of doubles which explicitly
defines how each pixel value in the drawable will be modified. Use
the pika_drawable_curves_spline() function to modify intensity levels
with Catmull Rom splines.
HELP
&std_pdb_misc;
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'channel', type => 'enum PikaHistogramChannel',
desc => 'The channel to modify' },
{ name => 'values', type => 'floatarray',
desc => 'The explicit curve',
array => { name => 'num_values', type => '256 <= int32 <= 2096',
desc => 'The number of values in the new curve' } }
);
%invoke = (
headers => [ qw("operations/pikacurvesconfig.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error) &&
(num_values >= 256) &&
(num_values <= 4096) &&
(pika_drawable_has_alpha (drawable) || channel != PIKA_HISTOGRAM_ALPHA) &&
(! pika_drawable_is_gray (drawable) ||
channel == PIKA_HISTOGRAM_VALUE || channel == PIKA_HISTOGRAM_ALPHA) &&
channel != PIKA_HISTOGRAM_LUMINANCE)
{
GObject *config = pika_curves_config_new_explicit (channel,
values,
num_values);
pika_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Curves"),
"pika:curves",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_curves_spline {
$blurb = 'Modifies the intensity curve(s) for specified drawable.';
$help = <<'HELP';
Modifies the intensity mapping for one channel in the specified
drawable. The channel can be either an intensity component, or the
value. The 'points' parameter is an array of doubles which define a
set of control points which describe a Catmull Rom spline which yields
the final intensity curve. Use the pika_drawable_curves_explicit()
function to explicitly modify intensity levels.
HELP
&std_pdb_misc;
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'channel', type => 'enum PikaHistogramChannel',
desc => 'The channel to modify' },
{ name => 'points', type => 'floatarray',
desc => 'The spline control points: { cp1.x, cp1.y, cp2.x, cp2.y,
... }',
array => { name => 'num_points', type => '4 <= int32 <= 2048',
desc => 'The number of values in the control point array' }
}
);
%invoke = (
headers => [ qw("operations/pikacurvesconfig.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error) &&
! (num_points & 1) &&
(pika_drawable_has_alpha (drawable) || channel != PIKA_HISTOGRAM_ALPHA) &&
(! pika_drawable_is_gray (drawable) ||
channel == PIKA_HISTOGRAM_VALUE || channel == PIKA_HISTOGRAM_ALPHA) &&
channel != PIKA_HISTOGRAM_LUMINANCE)
{
GObject *config = pika_curves_config_new_spline (channel,
points,
num_points / 2);
pika_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Curves"),
"pika:curves",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_extract_component {
$blurb = 'Extract a color model component.';
$help = 'Extract a color model component.';
&std_pdb_compat('gegl:component-extract');
$date = '2021';
$since = '2.10.34';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'component', type => '0 <= int32 <= 20',
desc => 'Component (RGB Red (0), RGB Green (1), RGB Blue (2), Hue (3), HSV Saturation (4), HSV Value (5),' .
' HSL Saturation (6), HSL Lightness (7), CMYK Cyan (8), CMYK Magenta (9), CMYK Yellow (10), CMYK Key (11),' .
' Y\'CbCr Y\' (12), Y\'CbCr Cb (13), Y\'CbCr Cr (14), LAB L (15), LAB A (16), LAB B (17), LCH C(ab) (18),' .
' LCH H(ab) (19), Alpha (20))' },
{ name => 'invert', type => 'boolean',
desc => 'Invert the extracted component' },
{ name => 'linear', type => 'boolean',
desc => 'Use linear output instead of gamma corrected' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error) &&
pika_drawable_is_rgb (drawable))
{
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "gegl:component-extract",
"component", component,
"invert", invert,
"linear", linear,
NULL);
pika_drawable_apply_operation (drawable, progress,
C_("undo-type", "Extract Component"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_desaturate {
$blurb = <<'BLURB';
Desaturate the contents of the specified drawable, with the specified formula.
BLURB
$help = <<'HELP';
This procedure desaturates the contents of the specified drawable,
with the specified formula. This procedure only works on drawables of
type RGB color.
HELP
$author = $copyright = 'Karine Delvare';
$date = '2005';
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'desaturate_mode', type => 'enum PikaDesaturateMode',
desc => 'The formula to use to desaturate' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error) &&
pika_drawable_is_rgb (drawable))
{
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "pika:desaturate",
"mode", desaturate_mode,
NULL);
pika_drawable_apply_operation (drawable, progress,
C_("undo-type", "Desaturate"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_equalize {
$blurb = 'Equalize the contents of the specified drawable.';
$help = <<'HELP';
This procedure equalizes the contents of the specified drawable. Each
intensity channel is equalized independently. The equalized intensity
is given as inten' = (255 - inten). The 'mask_only' option specifies
whether to adjust only the area of the image within the selection
bounds, or the entire image based on the histogram of the selected
area. If there is no selection, the entire image is adjusted based on
the histogram for the entire image.
HELP
&std_pdb_misc;
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'mask_only', type => 'boolean',
desc => 'Equalization option' }
);
%invoke = (
headers => [ qw("core/pikadrawable-equalize.h") ],
code => <<'CODE'
{
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) ||
! pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
success = FALSE;
if (success)
pika_drawable_equalize (drawable, mask_only);
}
CODE
);
}
sub drawable_histogram {
$blurb = <<'BLURB';
Returns information on the intensity histogram for the specified drawable.
BLURB
$help = <<'HELP';
This tool makes it possible to gather information about the intensity
histogram of a drawable. A channel to examine is first specified. This
can be either value, red, green, or blue, depending on whether the
drawable is of type color or grayscale. Second, a range of intensities
are specified. The pika_drawable_histogram() function returns
statistics based on the pixels in the drawable that fall under this
range of values. Mean, standard deviation, median, number of pixels,
and percentile are all returned. Additionally, the total count of
pixels in the image is returned. Counts of pixels are weighted by any
associated alpha values and by the current selection mask. That is,
pixels that lie outside an active selection mask will not be
counted. Similarly, pixels with transparent alpha values will not be
counted. The returned mean, std_dev and median are in the range
(0..255) for 8-bit images or if the plug-in is not precision-aware,
and in the range (0.0..1.0) otherwise.
HELP
&std_pdb_misc;
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'channel', type => 'enum PikaHistogramChannel',
desc => 'The channel to query' },
{ name => 'start_range', type => '0.0 <= float <= 1.0',
desc => 'Start of the intensity measurement range' },
{ name => 'end_range', type => '0.0 <= float <= 1.0',
desc => 'End of the intensity measurement range' }
);
@outargs = (
{ name => 'mean', type => 'float', void_ret => 1,
desc => 'Mean intensity value' },
{ name => 'std_dev', type => 'float',
desc => 'Standard deviation of intensity values' },
{ name => 'median', type => 'float',
desc => 'Median intensity value' },
{ name => 'pixels', type => 'float',
desc => 'Alpha-weighted pixel count for entire image' },
{ name => 'count', type => 'float',
desc => 'Alpha-weighted pixel count for range' },
{ name => 'percentile', type => 'float',
desc => 'Percentile that range falls under' }
);
%invoke = (
headers => [ qw("core/pikadrawable-histogram.h"
"core/pikahistogram.h") ],
code => <<'CODE'
{
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL, 0, error) ||
(! pika_drawable_has_alpha (drawable) &&
channel == PIKA_HISTOGRAM_ALPHA) ||
(pika_drawable_is_gray (drawable) &&
channel != PIKA_HISTOGRAM_VALUE && channel != PIKA_HISTOGRAM_ALPHA))
success = FALSE;
if (success)
{
PikaHistogram *histogram;
gint n_bins;
gint start;
PikaTRCType trc;
gint end;
trc = pika_drawable_get_trc (drawable);
histogram = pika_histogram_new (trc);
pika_drawable_calculate_histogram (drawable, histogram, FALSE);
n_bins = pika_histogram_n_bins (histogram);
start = ROUND (start_range * (n_bins - 1));
end = ROUND (end_range * (n_bins - 1));
mean = pika_histogram_get_mean (histogram, channel,
start, end);
std_dev = pika_histogram_get_std_dev (histogram, channel,
start, end);
median = pika_histogram_get_median (histogram, channel,
start, end);
pixels = pika_histogram_get_count (histogram, channel, 0, n_bins - 1);
count = pika_histogram_get_count (histogram, channel,
start, end);
percentile = count / pixels;
g_object_unref (histogram);
if (n_bins == 256)
{
mean *= 255;
std_dev *= 255;
median *= 255;
}
}
}
CODE
);
}
sub drawable_hue_saturation {
$blurb = <<'BLURB';
Modify hue, lightness, and saturation in the specified drawable.
BLURB
$help = <<'HELP';
This procedure allows the hue, lightness, and saturation in the specified
drawable to be modified. The 'hue-range' parameter provides the capability to
limit range of affected hues. The 'overlap' parameter provides blending into
neighboring hue channels when rendering.
HELP
&std_pdb_misc;
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'hue_range', type => 'enum PikaHueRange',
desc => 'Range of affected hues' },
{ name => 'hue_offset', type => '-180 <= float <= 180',
desc => 'Hue offset in degrees' },
{ name => 'lightness', type => '-100 <= float <= 100',
desc => 'Lightness modification' },
{ name => 'saturation', type => '-100 <= float <= 100',
desc => 'Saturation modification' },
{ name => 'overlap', type => '0 <= float <= 100',
desc => 'Overlap other hue channels' }
);
%invoke = (
headers => [ qw("operations/pikahuesaturationconfig.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
GObject *config = g_object_new (PIKA_TYPE_HUE_SATURATION_CONFIG,
"range", hue_range,
NULL);
g_object_set (config,
"hue", hue_offset / 180.0,
"saturation", saturation / 100.0,
"lightness", lightness / 100.0,
"overlap", overlap / 100.0,
NULL);
pika_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Hue-Saturation"),
"pika:hue-saturation",
config);
g_object_unref (config);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_invert {
$blurb = 'Invert the contents of the specified drawable.';
$help = <<'HELP';
This procedure inverts the contents of the specified drawable. Each
intensity channel is inverted independently. The inverted intensity is
given as inten' = (255 - inten). If 'linear' is TRUE, the drawable is
inverted in linear space.
HELP
&std_pdb_misc;
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'linear', type => 'boolean',
desc => 'Whether to invert in linear space' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
pika_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Invert"),
linear ?
"gegl:invert-linear" :
"gegl:invert-gamma",
NULL);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_levels {
$blurb = 'Modifies intensity levels in the specified drawable.';
$help = <<'HELP';
This tool allows intensity levels in the specified drawable to be remapped
according to a set of parameters. The low/high input levels specify an initial
mapping from the source intensities. The gamma value determines how intensities
between the low and high input intensities are interpolated. A gamma value of
1.0 results in a linear interpolation. Higher gamma values result in more
high-level intensities. Lower gamma values result in more low-level
intensities. The low/high output levels constrain the final intensity
mapping--that is, no final intensity will be lower than the low output level
and no final intensity will be higher than the high output level. This tool is
only valid on RGB color and grayscale images.
HELP
&std_pdb_misc;
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'channel', type => 'enum PikaHistogramChannel',
desc => 'The channel to modify' },
{ name => 'low_input', type => '0.0 <= float <= 1.0',
desc => "Intensity of lowest input" },
{ name => 'high_input', type => '0.0 <= float <= 1.0',
desc => "Intensity of highest input" },
{ name => 'clamp_input', type => 'boolean',
desc => 'Clamp input values before applying output levels' },
{ name => 'gamma', type => '0.1 <= float <= 10',
desc => 'Gamma adjustment factor' },
{ name => 'low_output', type => '0.0 <= float <= 1.0',
desc => "Intensity of lowest output" },
{ name => 'high_output', type => '0.0 <= float <= 1.0',
desc => "Intensity of highest output" },
{ name => 'clamp_output', type => 'boolean',
desc => 'Clamp final output values' },
);
%invoke = (
headers => [ qw("operations/pikalevelsconfig.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error) &&
(pika_drawable_has_alpha (drawable) || channel != PIKA_HISTOGRAM_ALPHA) &&
(! pika_drawable_is_gray (drawable) ||
channel == PIKA_HISTOGRAM_VALUE || channel == PIKA_HISTOGRAM_ALPHA) &&
channel != PIKA_HISTOGRAM_LUMINANCE)
{
GObject *config = g_object_new (PIKA_TYPE_LEVELS_CONFIG,
"channel", channel,
NULL);
g_object_set (config,
"low-input", low_input,
"high-input", high_input,
"clamp-input", clamp_input,
"gamma", gamma,
"low-output", low_output,
"high-output", high_output,
"clamp-output", clamp_output,
NULL);
pika_drawable_apply_operation_by_name (drawable, progress,
C_("undo-type", "Levels"),
"pika:levels",
config);
g_object_unref (config);
}
else
success = TRUE;
}
CODE
);
}
sub drawable_levels_stretch {
$blurb = 'Automatically modifies intensity levels in the specified drawable.';
$help = <<'HELP';
This procedure allows intensity levels in the specified drawable to be
remapped according to a set of guessed parameters. It is equivalent to
clicking the "Auto" button in the Levels tool.
HELP
$author = $copyright = 'Joao S.O. Bueno, Shawn Willden';
$date = '2003';
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' }
);
%invoke = (
headers => [ qw("core/pikadrawable-levels.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
pika_drawable_levels_stretch (drawable, progress);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_shadows_highlights {
$blurb = 'Perform shadows and highlights correction.';
$help = <<'HELP';
This filter allows adjusting shadows and highlights in the image
separately. The implementation closely follow its counterpart in the
Darktable photography software.
HELP
&std_pdb_compat('gegl:shadows-highlights');
$date = '2021';
$since = '2.10.34';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'shadows', type => '-100 <= float <= 100',
desc => 'Adjust exposure of shadows' },
{ name => 'highlights', type => '-100 <= float <= 100',
desc => 'Adjust exposure of highlights' },
{ name => 'whitepoint', type => '-10 <= float <= 10',
desc => 'Shift white point' },
{ name => 'radius', type => '0.1 <= float <= 1500',
desc => 'Spatial extent' },
{ name => 'compress', type => '0 <= float <= 100',
desc => 'Compress the effect on shadows/highlights and preserve midtones' },
{ name => 'shadows_ccorrect', type => '0 <= float <= 100',
desc => 'Adjust saturation of shadows' },
{ name => 'highlights_ccorrect', type => '0 <= float <= 100',
desc => 'Adjust saturation of highlights' },
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
GeglNode *node;
node = gegl_node_new_child (NULL,
"operation", "gegl:shadows-highlights",
"shadows", shadows,
"highlights", highlights,
"whitepoint", whitepoint,
"radius", radius,
"compress", compress,
"shadows-ccorrect", shadows_ccorrect,
"highlights-ccorrect", highlights_ccorrect,
NULL);
pika_drawable_apply_operation (drawable, progress,
C_("undo-type", "Shadows-Highlights"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_posterize {
$blurb = 'Posterize the specified drawable.';
$help = <<'HELP';
This procedures reduces the number of shades allows in each intensity channel
to the specified 'levels' parameter.
HELP
&std_pdb_misc;
$date = '1997';
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'levels', type => '2 <= int32 <= 255',
desc => 'Levels of posterization' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "pika:posterize",
"levels", levels,
NULL);
pika_drawable_apply_operation (drawable, progress,
C_("undo-type", "Posterize"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_threshold {
$blurb = 'Threshold the specified drawable.';
$help = <<'HELP';
This procedures generates a threshold map of the specified
drawable. All pixels between the values of 'low_threshold' and
'high_threshold', on the scale of 'channel' are replaced with white,
and all other pixels with black.
HELP
&std_pdb_misc;
$date = '1997';
$since = '2.10';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable' },
{ name => 'channel', type => 'enum PikaHistogramChannel',
desc => 'The channel to base the threshold on' },
{ name => 'low_threshold', type => '0.0 <= float <= 1.0',
desc => 'The low threshold value' },
{ name => 'high_threshold', type => '0.0 <= float <= 1.0',
desc => 'The high threshold value' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
GeglNode *node =
gegl_node_new_child (NULL,
"operation", "pika:threshold",
"channel", channel,
"low", low_threshold,
"high", high_threshold,
NULL);
pika_drawable_apply_operation (drawable, progress,
C_("undo-type", "Threshold"),
node);
g_object_unref (node);
}
else
success = FALSE;
}
CODE
);
}
@headers = qw("libpikamath/pikamath.h"
"core/pika.h"
"core/pikadrawable.h"
"core/pikadrawable-operation.h"
"pikapdb-utils.h"
"pika-intl.h");
@procs = qw(drawable_brightness_contrast
drawable_color_balance
drawable_colorize_hsl
drawable_curves_explicit
drawable_curves_spline
drawable_extract_component
drawable_desaturate
drawable_equalize
drawable_histogram
drawable_hue_saturation
drawable_invert
drawable_levels
drawable_levels_stretch
drawable_shadows_highlights
drawable_posterize
drawable_threshold);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Color';
$doc_title = 'pikadrawablecolor';
$doc_short_desc = "Functions for manipulating a drawable's color.";
$doc_long_desc = "Functions for manipulating a drawable's color, including curves and histograms.";
1;

View File

@ -0,0 +1,454 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub drawable_edit_clear {
$blurb = 'Clear selected area of drawable.';
$help = <<'HELP';
This procedure clears the specified drawable. If the drawable has an
alpha channel, the cleared pixels will become transparent. If the
drawable does not have an alpha channel, cleared pixels will be set to
the background color. This procedure only affects regions within a
selection if there is a selection active.
This procedure is affected by the following context setters:
pika_context_set_background().
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable to clear from' }
);
%invoke = (
code => <<CODE
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
pika_drawable_edit_clear (drawable, context);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_edit_fill {
$blurb = 'Fill selected area of drawable.';
$help = <<'HELP';
This procedure fills the specified drawable according to fill
mode. This procedure only affects regions within a selection if there
is a selection active. If you want to fill the whole drawable,
regardless of the selection, use pika_drawable_fill().
This procedure is affected by the following context setters:
pika_context_set_opacity(), pika_context_set_paint_mode(),
pika_context_set_foreground(), pika_context_set_background(),
pika_context_set_pattern().
HELP
&std_pdb_misc;
$author .= ' & Raphael Quinet';
$date = '1995-2000';
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => "The drawable to fill to" },
{ name => 'fill_type', type => 'enum PikaFillType',
desc => 'The type of fill' }
);
%invoke = (
code => <<CODE
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
PikaFillOptions *options = pika_fill_options_new (pika, NULL, FALSE);
pika_context_set_opacity (PIKA_CONTEXT (options),
pika_context_get_opacity (context));
pika_context_set_paint_mode (PIKA_CONTEXT (options),
pika_context_get_paint_mode (context));
if (pika_fill_options_set_by_fill_type (options, context,
fill_type, error))
{
pika_drawable_edit_fill (drawable, options, NULL);
}
else
success = FALSE;
g_object_unref (options);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_edit_bucket_fill {
$blurb = <<'BLURB';
Fill the area by a seed fill starting at the specified coordinates.
BLURB
$help = <<'HELP';
This procedure does a seed fill at the specified coordinates, using
various parameters from the current context.
In the case of merged sampling, the x and y coordinates are relative
to the image's origin; otherwise, they are relative to the drawable's
origin.
This procedure is affected by the following context setters:
pika_context_set_opacity(), pika_context_set_paint_mode(),
pika_context_set_foreground(), pika_context_set_background(),
pika_context_set_pattern(), pika_context_set_sample_threshold(),
pika_context_set_sample_merged(), pika_context_set_sample_criterion(),
pika_context_set_diagonal_neighbors(), pika_context_set_antialias().
HELP
&mitch_pdb_misc('2018', '2.10');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ name => 'fill_type', type => 'enum PikaFillType',
desc => 'The type of fill' },
{ name => 'x', type => 'float',
desc => "The x coordinate of this bucket fill's application." },
{ name => 'y', type => 'float',
desc => "The y coordinate of this bucket fill's application." }
);
%invoke = (
headers => [ qw ("core/pikadrawable-bucket-fill.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
PikaFillOptions *options = pika_fill_options_new (pika, NULL, FALSE);
pika_context_set_opacity (PIKA_CONTEXT (options),
pika_context_get_opacity (context));
pika_context_set_paint_mode (PIKA_CONTEXT (options),
pika_context_get_paint_mode (context));
pika_fill_options_set_antialias (options,
PIKA_PDB_CONTEXT (context)->antialias);
if (pika_fill_options_set_by_fill_type (options, context,
fill_type, error))
{
pika_drawable_bucket_fill (drawable, options,
PIKA_PDB_CONTEXT (context)->sample_transparent,
PIKA_PDB_CONTEXT (context)->sample_criterion,
PIKA_PDB_CONTEXT (context)->sample_threshold,
PIKA_PDB_CONTEXT (context)->sample_merged,
PIKA_PDB_CONTEXT (context)->diagonal_neighbors,
x, y);
}
else
success = FALSE;
g_object_unref (options);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_edit_gradient_fill {
$blurb = <<'BLURB';
Draw a gradient between the starting and ending coordinates with the
specified gradient type.
BLURB
$help = <<'HELP';
This tool requires information on the gradient type. It creates the
specified variety of gradient using the starting and ending
coordinates as defined for each gradient type. For shapeburst
gradient types, the context's distance metric is also relevant and can
be updated with pika_context_set_distance_metric().
This procedure is affected by the following context setters:
pika_context_set_opacity(), pika_context_set_paint_mode(),
pika_context_set_foreground(), pika_context_set_background(),
pika_context_set_gradient() and all gradient property settings,
pika_context_set_distance_metric().
HELP
&mitch_pdb_misc('2018', '2.10');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ name => 'gradient_type', type => 'enum PikaGradientType',
desc => 'The type of gradient' },
{ name => 'offset', type => '0 <= float',
desc => 'Offset relates to the starting and ending coordinates
specified for the blend. This parameter is mode dependent.' },
{ name => 'supersample', type => 'boolean',
desc => 'Do adaptive supersampling' },
{ name => 'supersample_max_depth', type => '1 <= int32 <= 9',
no_validate => 1,
desc => 'Maximum recursion levels for supersampling' },
{ name => 'supersample_threshold', type => '0 <= float <= 4',
no_validate => 1,
desc => 'Supersampling threshold' },
{ name => 'dither', type => 'boolean',
desc => 'Use dithering to reduce banding' },
{ name => 'x1', type => 'float',
desc => "The x coordinate of this gradient's starting point" },
{ name => 'y1', type => 'float',
desc => "The y coordinate of this gradient's starting point" },
{ name => 'x2', type => 'float',
desc => "The x coordinate of this gradient's ending point" },
{ name => 'y2', type => 'float',
desc => "The y coordinate of this gradient's ending point" }
);
%invoke = (
headers => [ qw("core/pika-gradients.h" "core/pikadrawable-gradient.h") ],
code => <<'CODE'
{
success = (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error));
if (success)
{
if (supersample)
{
if (supersample_max_depth < 1 || supersample_max_depth > 9)
success = FALSE;
if (supersample_threshold < 0.0 || supersample_threshold > 4.0)
success = FALSE;
}
else
{
supersample_max_depth = CLAMP (supersample_max_depth, 1, 9);
supersample_threshold = CLAMP (supersample_threshold, 0.0, 4.0);
}
}
if (success)
{
/* all options should have the same value, so pick a random one */
PikaPaintOptions *options =
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context),
"pika-paintbrush");
if (progress)
pika_progress_start (progress, FALSE, _("Gradient"));
pika_drawable_gradient (drawable,
context,
pika_context_get_gradient (context),
PIKA_PDB_CONTEXT (context)->distance_metric,
pika_context_get_paint_mode (context),
gradient_type,
pika_context_get_opacity (context),
offset,
options->gradient_options->gradient_repeat,
options->gradient_options->gradient_reverse,
options->gradient_options->gradient_blend_color_space,
supersample,
supersample_max_depth,
supersample_threshold,
dither,
x1, y1, x2, y2,
progress);
if (progress)
pika_progress_end (progress);
}
}
CODE
);
}
sub drawable_edit_stroke_selection {
$blurb = 'Stroke the current selection';
$help = <<'HELP';
This procedure strokes the current selection, painting along the
selection boundary with the active paint method and brush, or using a
plain line with configurable properties. The paint is applied to the
specified drawable regardless of the active selection.
This procedure is affected by the following context setters:
pika_context_set_opacity(), pika_context_set_paint_mode(),
pika_context_set_paint_method(), pika_context_set_stroke_method(),
pika_context_set_foreground(),
pika_context_set_brush() and all brush property settings,
pika_context_set_gradient() and all gradient property settings,
pika_context_set_line_width() and all line property settings,
pika_context_set_antialias().
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable to stroke to' }
);
%invoke = (
headers => [ qw("core/pikastrokeoptions.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
PikaImage *image = pika_item_get_image (PIKA_ITEM (drawable));
PikaStrokeOptions *options;
PikaPaintOptions *paint_options;
GList *drawables = g_list_prepend (NULL, drawable);
options = pika_pdb_context_get_stroke_options (PIKA_PDB_CONTEXT (context));
paint_options =
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context), NULL);
paint_options = pika_config_duplicate (PIKA_CONFIG (paint_options));
success = pika_item_stroke (PIKA_ITEM (pika_image_get_mask (image)),
drawables, context, options, paint_options,
TRUE, progress, error);
g_object_unref (paint_options);
g_list_free (drawables);
}
else
success = FALSE;
}
CODE
);
}
sub drawable_edit_stroke_item {
$blurb = 'Stroke the specified item';
$help = <<'HELP';
This procedure strokes the specified item, painting along its outline
(e.g. along a path, or along a channel's boundary), with the active
paint method and brush, or using a plain line with configurable
properties.
This procedure is affected by the following context setters:
pika_context_set_opacity(), pika_context_set_paint_mode(),
pika_context_set_paint_method(), pika_context_set_stroke_method(),
pika_context_set_foreground(),
pika_context_set_brush() and all brush property settings,
pika_context_set_gradient() and all gradient property settings,
pika_context_set_line_width() and all line property settings,
pika_context_set_antialias().
HELP
&mitch_pdb_misc('2018', '2.10');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable to stroke to' },
{ name => 'item', type => 'item',
desc => 'The item to stroke' }
);
%invoke = (
headers => [ qw("core/pikastrokeoptions.h") ],
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error) &&
pika_pdb_item_is_attached (item,
pika_item_get_image (PIKA_ITEM (drawable)),
0, error))
{
PikaStrokeOptions *options;
PikaPaintOptions *paint_options;
GList *drawables = g_list_prepend (NULL, drawable);
options = pika_pdb_context_get_stroke_options (PIKA_PDB_CONTEXT (context));
paint_options =
pika_pdb_context_get_paint_options (PIKA_PDB_CONTEXT (context), NULL);
paint_options = pika_config_duplicate (PIKA_CONFIG (paint_options));
success = pika_item_stroke (item, drawables,
context, options, paint_options,
TRUE, progress, error);
g_object_unref (paint_options);
g_list_free (drawables);
}
else
success = FALSE;
}
CODE
);
}
@headers = qw("libpikaconfig/pikaconfig.h"
"paint/pikapaintoptions.h"
"core/pika.h"
"core/pikadrawable-edit.h"
"core/pikabuffer.h"
"core/pikaimage.h"
"core/pikaprogress.h"
"pikapdb-utils.h"
"pikapdbcontext.h"
"pika-intl.h");
@procs = qw(drawable_edit_clear
drawable_edit_fill
drawable_edit_bucket_fill
drawable_edit_gradient_fill
drawable_edit_stroke_selection
drawable_edit_stroke_item);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Drawable edit procedures';
$doc_title = 'pikadrawableedit';
$doc_short_desc = 'Drawable edit functions (clear, fill, gradient, stroke etc.)';
$doc_long_desc = 'Drawable edit functions (clear, fill, gradient, stroke etc.)';
1;

85
pdb/groups/dynamics.pdb Normal file
View File

@ -0,0 +1,85 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub dynamics_refresh {
$blurb = 'Refresh current paint dynamics. This function always succeeds.';
$help = <<'HELP';
This procedure retrieves all paint dynamics currently in the user's
paint dynamics path and updates the paint dynamics dialogs
accordingly.
HELP
&mitch_pdb_misc('2011', '2.8');
%invoke = (
code => <<'CODE'
{
pika_data_factory_data_refresh (pika->dynamics_factory, context);
}
CODE
);
}
sub dynamics_get_list {
$blurb = 'Retrieve the list of loaded paint dynamics.';
$help = <<'HELP';
This procedure returns a list of the paint dynamics that are currently
available.
HELP
&mitch_pdb_misc('2011', '2.8');
@inargs = (
{ name => 'filter', type => 'string', null_ok => 1,
desc => 'An optional regular expression used to filter the list' }
);
@outargs = (
{ name => 'dynamics_list', type => 'strv',
desc => 'The list of paint dynamics names' }
);
%invoke = (
headers => [ qw("core/pikacontainer-filter.h") ],
code => <<'CODE'
{
dynamics_list = pika_container_get_filtered_name_array (pika_data_factory_get_container (pika->dynamics_factory),
filter);
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pikacontainer.h"
"core/pikadatafactory.h");
@procs = qw(dynamics_refresh
dynamics_get_list);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Paint Dynamics';
$doc_title = 'pikadynamics';
$doc_short_desc = 'Operations related to paint dynamics.';
$doc_long_desc = 'Operations related to paint dynamics.';
1;

705
pdb/groups/edit.pdb Normal file
View File

@ -0,0 +1,705 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub edit_cut {
$blurb = 'Cut from the specified drawables.';
$help = <<'HELP';
If there is a selection in the image, then the area specified by the
selection is cut from the specified drawables and placed in an internal
PIKA edit buffer. It can subsequently be retrieved using the
pika_edit_paste() command. If there is no selection and only one
specified drawable, then the specified drawable will be removed and its
contents stored in the internal PIKA edit buffer.
This procedure will fail if the selected area lies completely outside
the bounds of the current drawables and there is nothing to cut from.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawables', type => 'itemarray',
desc => 'The drawables to cut from',
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables" } }
);
@outargs = (
{ name => 'non_empty', type => 'boolean',
desc => 'TRUE if the cut was successful,
FALSE if there was nothing to copy from' }
);
%invoke = (
code => <<CODE
{
PikaImage *image = NULL;
GList *drawable_list = NULL;
gint i;
for (i = 0; i < num_drawables; i++)
{
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawables[i]), NULL,
PIKA_PDB_ITEM_CONTENT, error) ||
pika_pdb_item_is_group (PIKA_ITEM (drawables[i]), error))
{
success = FALSE;
break;
}
if (! image)
{
image = pika_item_get_image (PIKA_ITEM (drawables[i]));
}
else if (image != pika_item_get_image (PIKA_ITEM (drawables[i])))
{
success = FALSE;
pika_message_literal (pika,
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
_("All specified drawables must belong to the same image."));
break;
}
drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]);
}
if (success && image)
{
GError *my_error = NULL;
non_empty = pika_edit_cut (image, drawable_list, context, &my_error) != NULL;
if (! non_empty)
{
pika_message_literal (pika,
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
my_error->message);
g_clear_error (&my_error);
}
}
else
{
success = FALSE;
}
g_list_free (drawable_list);
}
CODE
);
}
sub edit_copy {
$blurb = 'Copy from the specified drawables.';
$help = <<'HELP';
If there is a selection in the image, then the area specified by the
selection is copied from the specified drawables and placed in an
internal PIKA edit buffer. It can subsequently be retrieved using the
pika_edit_paste() command. If there is no selection, then the
specified drawables' contents will be stored in the internal PIKA edit
buffer. This procedure will fail if the selected area lies completely
outside the bounds of the current drawables and there is nothing to
copy from.
All the drawables must belong to the same image.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawables', type => 'itemarray',
desc => 'Drawables to copy from',
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables to save" } },
);
@outargs = (
{ name => 'non_empty', type => 'boolean',
desc => 'TRUE if the cut was successful,
FALSE if there was nothing to copy from' }
);
%invoke = (
code => <<CODE
{
PikaImage *image = NULL;
GList *drawables_list = NULL;
gint i;
for (i = 0; i < num_drawables; i++)
{
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawables[i]), NULL, 0, error))
{
success = FALSE;
break;
}
if (image == NULL)
{
image = pika_item_get_image (PIKA_ITEM (drawables[i]));
}
else if (image != pika_item_get_image (PIKA_ITEM (drawables[i])))
{
success = FALSE;
break;
}
drawables_list = g_list_prepend (drawables_list, (gpointer) drawables[i]);
}
if (success && num_drawables > 0)
{
GError *my_error = NULL;
non_empty = pika_edit_copy (image, drawables_list, context, &my_error) != NULL;
if (! non_empty)
{
pika_message_literal (pika,
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
my_error->message);
g_clear_error (&my_error);
}
}
else
success = FALSE;
g_list_free (drawables_list);
}
CODE
);
}
sub edit_copy_visible {
$blurb = 'Copy from the projection.';
$help = <<'HELP';
If there is a selection in the image, then the area specified by the
selection is copied from the projection and placed in an internal PIKA
edit buffer. It can subsequently be retrieved using the
pika_edit_paste() command. If there is no selection, then the
projection's contents will be stored in the internal PIKA edit buffer.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'image', type => 'image',
desc => "The image to copy from" }
);
@outargs = (
{ name => 'non_empty', type => 'boolean',
desc => 'TRUE if the copy was successful' }
);
%invoke = (
code => <<CODE
{
GError *my_error = NULL;
non_empty = pika_edit_copy_visible (image, context, &my_error) != NULL;
if (! non_empty)
{
pika_message_literal (pika,
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
my_error->message);
g_clear_error (&my_error);
}
}
CODE
);
}
sub edit_paste {
$blurb = 'Paste buffer to the specified drawable.';
$help = <<'HELP';
This procedure pastes a copy of the internal PIKA edit buffer to the
specified drawable. The PIKA edit buffer will be empty unless a call
was previously made to either pika_edit_cut() or pika_edit_copy(). The
"paste_into" option specifies whether to clear the current image
selection, or to paste the buffer "behind" the selection. This allows
the selection to act as a mask for the pasted buffer. Anywhere that
the selection mask is non-zero, the pasted buffer will show
through.
The pasted data may be a floating selection when relevant, layers otherwise.
If the image has a floating selection at the time of pasting, the old
floating selection will be anchored to its drawable before the new
floating selection is added.
This procedure returns the new layers (floating or not). If the result
is a floating selection, it will already be attached to the specified
drawable, and a subsequent call to floating_sel_attach is not needed.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable to paste to' },
{ name => 'paste_into', type => 'boolean',
desc => 'Clear selection, or paste behind it?' }
);
@outargs = (
{ name => 'layers', type => 'layerarray',
desc => 'The list of pasted layers.',
array => { name => 'num_layers',
desc => 'The newly pasted layers' } }
);
%invoke = (
code => <<CODE
{
PikaObject *paste = pika_get_clipboard_object (pika);
if (paste &&
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
GList *drawables = NULL;
GList *list;
gint i;
if (drawable != NULL)
drawables = g_list_prepend (drawables, drawable);
list = pika_edit_paste (pika_item_get_image (PIKA_ITEM (drawable)),
drawables, paste,
paste_into ?
PIKA_PASTE_TYPE_FLOATING_INTO :
PIKA_PASTE_TYPE_FLOATING,
context, FALSE,
-1, -1, -1, -1);
g_list_free (drawables);
if (! list)
success = FALSE;
num_layers = g_list_length (list);
layers = g_new (PikaLayer *, num_layers);
for (i = 0; i < num_layers; i++, list = g_list_next (list))
layers[i] = g_object_ref (list->data);
g_list_free (list);
}
else
success = FALSE;
}
CODE
);
}
sub edit_paste_as_new_image {
$blurb = 'Paste buffer to a new image.';
$help = <<'HELP';
This procedure pastes a copy of the internal PIKA edit buffer to a new
image. The PIKA edit buffer will be empty unless a call was
previously made to either pika_edit_cut() or pika_edit_copy(). This
procedure returns the new image or -1 if the edit buffer was empty.
HELP
&mitch_pdb_misc('2005', '2.10');
@outargs = (
{ name => 'image', type => 'image',
desc => 'The new image' }
);
%invoke = (
code => <<CODE
{
PikaObject *paste = pika_get_clipboard_object (pika);
if (paste)
{
image = pika_edit_paste_as_new_image (pika, paste, context);
if (! image)
success = FALSE;
}
}
CODE
);
}
sub edit_named_cut {
$blurb = 'Cut into a named buffer.';
$help = <<'HELP';
This procedure works like pika_edit_cut(), but additionally stores the
cut buffer into a named buffer that will stay available for later
pasting, regardless of any intermediate copy or cut operations.
HELP
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'drawables', type => 'itemarray',
desc => 'The drawables to cut from',
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables" } },
{ name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The name of the buffer to create' }
);
@outargs = (
{ name => 'real_name', type => 'string',
desc => 'The real name given to the buffer, or NULL if the
cut failed' }
);
%invoke = (
code => <<CODE
{
PikaImage *image = NULL;
GList *drawable_list = NULL;
gint i;
for (i = 0; i < num_drawables; i++)
{
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawables[i]), NULL,
PIKA_PDB_ITEM_CONTENT, error) ||
pika_pdb_item_is_group (PIKA_ITEM (drawables[i]), error))
{
success = FALSE;
break;
}
if (! image)
{
image = pika_item_get_image (PIKA_ITEM (drawables[i]));
}
else if (image != pika_item_get_image (PIKA_ITEM (drawables[i])))
{
success = FALSE;
pika_message_literal (pika,
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
_("All specified drawables must belong to the same image."));
break;
}
drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]);
}
if (success && image)
{
GError *my_error = NULL;
real_name = (gchar *) pika_edit_named_cut (image, buffer_name,
drawable_list, context, &my_error);
if (real_name)
{
real_name = g_strdup (real_name);
}
else
{
pika_message_literal (pika,
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
my_error->message);
g_clear_error (&my_error);
}
}
else
{
success = FALSE;
}
g_list_free (drawable_list);
}
CODE
);
}
sub edit_named_copy {
$blurb = 'Copy into a named buffer.';
$help = <<'HELP';
This procedure works like pika_edit_copy(), but additionally stores the
copied buffer into a named buffer that will stay available for later
pasting, regardless of any intermediate copy or cut operations.
HELP
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'drawables', type => 'itemarray',
desc => 'The drawables to copy from',
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables" } },
{ name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The name of the buffer to create' }
);
@outargs = (
{ name => 'real_name', type => 'string',
desc => 'The real name given to the buffer, or NULL if the
copy failed' }
);
%invoke = (
code => <<CODE
{
PikaImage *image = NULL;
GList *drawable_list = NULL;
gint i;
for (i = 0; i < num_drawables; i++)
{
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawables[i]), NULL,
0, error))
{
success = FALSE;
break;
}
if (! image)
{
image = pika_item_get_image (PIKA_ITEM (drawables[i]));
}
else if (image != pika_item_get_image (PIKA_ITEM (drawables[i])))
{
success = FALSE;
pika_message_literal (pika,
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
_("All specified drawables must belong to the same image."));
break;
}
drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]);
}
if (success && image)
{
GError *my_error = NULL;
real_name = (gchar *) pika_edit_named_copy (image, buffer_name,
drawable_list, context, &my_error);
if (real_name)
{
real_name = g_strdup (real_name);
}
else
{
pika_message_literal (pika,
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
my_error->message);
g_clear_error (&my_error);
}
}
else
{
success = FALSE;
}
g_list_free (drawable_list);
}
CODE
);
}
sub edit_named_copy_visible {
$blurb = 'Copy from the projection into a named buffer.';
$help = <<'HELP';
This procedure works like pika_edit_copy_visible(), but additionally
stores the copied buffer into a named buffer that will stay available
for later pasting, regardless of any intermediate copy or cut
operations.
HELP
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => "The image to copy from" },
{ name => 'buffer_name', type => 'string', non_empty => 1,
desc => 'The name of the buffer to create' }
);
@outargs = (
{ name => 'real_name', type => 'string',
desc => 'The real name given to the buffer, or NULL if the
copy failed' }
);
%invoke = (
code => <<CODE
{
GError *my_error = NULL;
real_name = (gchar *) pika_edit_named_copy_visible (image, buffer_name,
context, &my_error);
if (real_name)
{
real_name = g_strdup (real_name);
}
else
{
pika_message_literal (pika,
G_OBJECT (progress), PIKA_MESSAGE_WARNING,
my_error->message);
g_clear_error (&my_error);
}
}
CODE
);
}
sub edit_named_paste {
$blurb = 'Paste named buffer to the specified drawable.';
$help = <<'HELP';
This procedure works like pika_edit_paste() but pastes a named buffer
instead of the global buffer.
HELP
&mitch_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The drawable to paste to' },
{ name => 'buffer_name', type => 'string',
desc => 'The name of the buffer to paste' },
{ name => 'paste_into', type => 'boolean',
desc => 'Clear selection, or paste behind it?' }
);
@outargs = (
{ name => 'floating_sel', type => 'layer',
desc => 'The new floating selection' }
);
%invoke = (
code => <<CODE
{
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
if (buffer &&
pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
GList *drawables = NULL;
GList *layers;
if (drawable != NULL)
drawables = g_list_prepend (drawables, drawable);
layers = pika_edit_paste (pika_item_get_image (PIKA_ITEM (drawable)),
drawables, PIKA_OBJECT (buffer),
paste_into ?
PIKA_PASTE_TYPE_FLOATING_INTO :
PIKA_PASTE_TYPE_FLOATING,
context, FALSE,
-1, -1, -1, -1);
g_list_free (drawables);
if (! layers)
success = FALSE;
else
floating_sel = layers->data;
g_list_free (layers);
}
else
success = FALSE;
}
CODE
)
}
sub edit_named_paste_as_new_image {
$blurb = 'Paste named buffer to a new image.';
$help = <<'HELP';
This procedure works like pika_edit_paste_as_new_image() but pastes a
named buffer instead of the global buffer.
HELP
&mitch_pdb_misc('2005', '2.10');
@inargs = (
{ name => 'buffer_name', type => 'string',
desc => 'The name of the buffer to paste' }
);
@outargs = (
{ name => 'image', type => 'image',
desc => 'The new image' }
);
%invoke = (
code => <<CODE
{
PikaBuffer *buffer = pika_pdb_get_buffer (pika, buffer_name, error);
if (buffer)
{
image = pika_edit_paste_as_new_image (pika, PIKA_OBJECT (buffer), context);
if (! image)
success = FALSE;
}
else
success = FALSE;
}
CODE
);
}
@headers = qw("libpikaconfig/pikaconfig.h"
"core/pika.h"
"core/pika-edit.h"
"core/pikadrawable-edit.h"
"core/pikabuffer.h"
"core/pikaimage.h"
"core/pikaprogress.h"
"pikapdb-utils.h"
"pikapdbcontext.h"
"pika-intl.h");
@procs = qw(edit_cut
edit_copy
edit_copy_visible
edit_paste
edit_paste_as_new_image
edit_named_cut
edit_named_copy
edit_named_copy_visible
edit_named_paste
edit_named_paste_as_new_image);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Edit procedures';
$doc_title = 'pikaedit';
$doc_short_desc = 'Edit menu functions (cut, copy, paste, clear, etc.)';
$doc_long_desc = 'Edit menu functions (cut, copy, paste, clear, etc.)';
1;

404
pdb/groups/file.pdb Normal file
View File

@ -0,0 +1,404 @@
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1995, 1996, 1997 Spencer Kimball and Peter Mattis
# Copyright (C) 1997 Josh MacDonald
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub file_load {
$blurb = 'Loads an image file by invoking the right load handler.';
$help = <<'HELP';
This procedure invokes the correct file load handler using magic if
possible, and falling back on the file's extension and/or prefix if
not.
HELP
&josh_pdb_misc('1997');
@inargs = (
{ name => 'run_mode',
type => 'enum PikaRunMode (no PIKA_RUN_WITH_LAST_VALS)',
desc => 'The run mode' },
{ name => 'file', type => 'file',
desc => 'The file to load' }
);
@outargs = (
{ name => 'image', type => 'image',
desc => 'The output image' }
);
%invoke = (
no_marshalling => 1,
code => <<'CODE'
{
PikaValueArray *new_args;
PikaValueArray *return_vals;
PikaPlugInProcedure *file_proc;
PikaProcedure *proc;
GFile *file;
gint i;
file = g_value_get_object (pika_value_array_index (args, 1));
if (! file)
return pika_procedure_get_return_values (procedure, FALSE,
error ? *error : NULL);
file_proc = pika_plug_in_manager_file_procedure_find (pika->plug_in_manager,
PIKA_FILE_PROCEDURE_GROUP_OPEN,
file, error);
if (! file_proc)
return pika_procedure_get_return_values (procedure, FALSE,
error ? *error : NULL);
proc = PIKA_PROCEDURE (file_proc);
new_args = pika_procedure_get_arguments (proc);
g_value_transform (pika_value_array_index (args, 0),
pika_value_array_index (new_args, 0));
g_value_transform (pika_value_array_index (args, 1),
pika_value_array_index (new_args, 1));
for (i = 2; i < proc->num_args; i++)
if (G_IS_PARAM_SPEC_STRING (proc->args[i]))
g_value_set_static_string (pika_value_array_index (new_args, i), "");
return_vals =
pika_pdb_execute_procedure_by_name_args (pika->pdb,
context, progress, error,
pika_object_get_name (proc),
new_args);
pika_value_array_unref (new_args);
if (g_value_get_enum (pika_value_array_index (return_vals, 0)) ==
PIKA_PDB_SUCCESS)
{
if (pika_value_array_length (return_vals) > 1 &&
PIKA_VALUE_HOLDS_IMAGE (pika_value_array_index (return_vals, 1)))
{
PikaImage *image =
g_value_get_object (pika_value_array_index (return_vals, 1));
pika_image_set_load_proc (image, file_proc);
}
}
return return_vals;
}
CODE
);
}
sub file_load_layer {
$blurb = 'Loads an image file as a layer for an existing image.';
$help = <<'HELP';
This procedure behaves like the file-load procedure but opens the specified
image as a layer for an existing image. The returned layer needs to be
added to the existing image with pika_image_insert_layer().
HELP
&neo_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'run_mode',
type => 'enum PikaRunMode (no PIKA_RUN_WITH_LAST_VALS)',
desc => 'The run mode' },
{ name => 'image', type => 'image',
desc => 'Destination image' },
{ name => 'file', type => 'file',
desc => 'The file to load' }
);
@outargs = (
{ name => 'layer', type => 'layer',
desc => 'The layer created when loading the image file' }
);
%invoke = (
code => <<'CODE'
{
GList *layers;
PikaPDBStatusType status;
layers = file_open_layers (pika, context, progress,
image, FALSE,
file, run_mode, NULL, &status, error);
if (layers)
{
layer = layers->data;
g_list_free (layers);
}
else
success = FALSE;
}
CODE
);
}
sub file_load_layers {
$blurb = 'Loads an image file as layers for an existing image.';
$help = <<'HELP';
This procedure behaves like the file-load procedure but opens the specified
image as layers for an existing image. The returned layers needs to be
added to the existing image with pika_image_insert_layer().
HELP
&mitch_pdb_misc('2006', '2.4');
@inargs = (
{ name => 'run_mode',
type => 'enum PikaRunMode (no PIKA_RUN_WITH_LAST_VALS)',
desc => 'The run mode' },
{ name => 'image', type => 'image',
desc => 'Destination image' },
{ name => 'file', type => 'file',
desc => 'The file to load' }
);
@outargs = (
{ name => 'layers', type => 'layerarray',
desc => 'The list of loaded layers',
array => { name => 'num_layers',
desc => 'The number of loaded layers' } }
);
%invoke = (
code => <<'CODE'
{
GList *layer_list;
PikaPDBStatusType status;
layer_list = file_open_layers (pika, context, progress,
image, FALSE,
file, run_mode, NULL, &status, error);
if (layer_list)
{
GList *list;
gint i;
num_layers = g_list_length (layer_list);
layers = g_new (PikaLayer *, num_layers);
for (i = 0, list = layer_list;
i < num_layers;
i++, list = g_list_next (list))
{
layers[i] = g_object_ref (list->data);
}
g_list_free (layer_list);
}
else
success = FALSE;
}
CODE
);
}
sub file_save {
$blurb = 'Saves a file by extension.';
$help = <<'HELP';
This procedure invokes the correct file save handler according to the
file's extension and/or prefix.
HELP
&josh_pdb_misc('1997');
@inargs = (
{ name => 'run_mode', type => 'enum PikaRunMode',
desc => 'The run mode' },
{ name => 'image', type => 'image',
desc => 'Input image' },
{ name => 'drawables', type => 'itemarray',
desc => 'Drawables to save',
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables to save" } },
{ name => 'file', type => 'file',
desc => 'The file to save the image in' }
);
%invoke = (
headers => [ qw(<string.h>) ],
no_marshalling => 1,
code => <<'CODE'
{
PikaValueArray *new_args;
PikaValueArray *return_vals;
PikaPlugInProcedure *file_proc;
GFile *file;
PikaProcedure *proc;
gint i;
file = g_value_get_object (pika_value_array_index (args, 4));
file_proc = pika_plug_in_manager_file_procedure_find (pika->plug_in_manager,
PIKA_FILE_PROCEDURE_GROUP_SAVE,
file, NULL);
if (! file_proc)
file_proc = pika_plug_in_manager_file_procedure_find (pika->plug_in_manager,
PIKA_FILE_PROCEDURE_GROUP_EXPORT,
file, error);
if (! file_proc)
return pika_procedure_get_return_values (procedure, FALSE,
error ? *error : NULL);
proc = PIKA_PROCEDURE (file_proc);
new_args = pika_procedure_get_arguments (proc);
g_value_transform (pika_value_array_index (args, 0),
pika_value_array_index (new_args, 0));
g_value_transform (pika_value_array_index (args, 1),
pika_value_array_index (new_args, 1));
g_value_transform (pika_value_array_index (args, 2),
pika_value_array_index (new_args, 2));
g_value_transform (pika_value_array_index (args, 3),
pika_value_array_index (new_args, 3));
g_value_transform (pika_value_array_index (args, 4),
pika_value_array_index (new_args, 4));
for (i = 5; i < proc->num_args; i++)
if (G_IS_PARAM_SPEC_STRING (proc->args[i]))
g_value_set_static_string (pika_value_array_index (new_args, i), "");
return_vals =
pika_pdb_execute_procedure_by_name_args (pika->pdb,
context, progress, error,
pika_object_get_name (proc),
new_args);
pika_value_array_unref (new_args);
return return_vals;
}
CODE
);
}
sub file_load_thumbnail {
$blurb = 'Loads the thumbnail for a file.';
$help = <<'HELP';
This procedure tries to load a thumbnail that belongs to the given file.
The returned data is an array of colordepth 3 (RGB), regardless of the
image type. Width and height of the thumbnail are also returned. Don't
use this function if you need a thumbnail of an already opened image,
use pika_image_thumbnail() instead.
HELP
$author = $copyright = 'Adam D. Moss, Sven Neumann';
$date = '1999-2003';
@inargs = (
{ name => 'file', type => 'file',
desc => 'The file that owns the thumbnail to load' }
);
@outargs = (
{ name => 'width', type => 'int32',
desc => 'The width of the thumbnail' },
{ name => 'height', type => 'int32',
desc => 'The height of the thumbnail' },
{ name => 'thumb_data', type => 'bytes',
desc => 'The thumbnail data' }
);
%invoke = (
code => <<'CODE'
{
GdkPixbuf *pixbuf = file_utils_load_thumbnail (file);
if (pixbuf)
{
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
thumb_data = g_bytes_new (gdk_pixbuf_get_pixels (pixbuf),
3 * width * height);
g_object_unref (pixbuf);
}
else
success = FALSE;
}
CODE
);
}
sub file_save_thumbnail {
$blurb = 'Saves a thumbnail for the given image';
$help = <<'HELP';
This procedure saves a thumbnail for the given image according to the
Free Desktop Thumbnail Managing Standard. The thumbnail is saved so
that it belongs to the given file. This means you have to save the image
under this name first, otherwise this procedure will fail. This
procedure may become useful if you want to explicitly save a thumbnail
with a file.
HELP
&josh_pdb_misc('1997');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'file', type => 'file',
desc => 'The file the thumbnail belongs to' },
);
%invoke = (
code => <<'CODE'
{
success = file_utils_save_thumbnail (image, file);
}
CODE
);
}
@headers = qw("core/pika.h"
"plug-in/pikapluginmanager-file.h"
"file/file-open.h"
"file/file-save.h"
"file/file-utils.h");
@procs = qw(file_load
file_load_layer
file_load_layers
file_save
file_load_thumbnail
file_save_thumbnail);
%exports = (app => [@procs], lib => [@procs[0..3,5]]);
$desc = 'File Operations';
$doc_title = 'pikafile';
$doc_short_desc = 'Image file operations (load, save, etc.)';
$doc_long_desc = 'Image file operations (load, save, etc.)';
1;

193
pdb/groups/floating_sel.pdb Normal file
View File

@ -0,0 +1,193 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub floating_sel_remove {
$blurb = <<'BLURB';
Remove the specified floating selection from its associated drawable.
BLURB
$help = <<'HELP';
This procedure removes the floating selection completely, without any side
effects. The associated drawable is then set to active.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'floating_sel', type => 'layer',
desc => 'The floating selection' }
);
%invoke = (
code => <<'CODE'
{
if (pika_layer_is_floating_sel (floating_sel))
{
pika_image_remove_layer (pika_item_get_image (PIKA_ITEM (floating_sel)),
floating_sel, TRUE, NULL);
}
else
{
g_set_error_literal (error, PIKA_PDB_ERROR,
PIKA_PDB_ERROR_INVALID_ARGUMENT,
_("Cannot remove this layer because "
"it is not a floating selection."));
success = FALSE;
}
}
CODE
);
}
sub floating_sel_anchor {
$blurb = <<'BLURB';
Anchor the specified floating selection to its associated drawable.
BLURB
$help = <<'HELP';
This procedure anchors the floating selection to its associated drawable. This
is similar to merging with a merge type of ClipToBottomLayer. The floating
selection layer is no longer valid after this operation.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'floating_sel', type => 'layer',
desc => 'The floating selection' }
);
%invoke = (
code => <<'CODE'
{
if (pika_layer_is_floating_sel (floating_sel))
{
floating_sel_anchor (floating_sel);
}
else
{
g_set_error_literal (error, PIKA_PDB_ERROR,
PIKA_PDB_ERROR_INVALID_ARGUMENT,
_("Cannot anchor this layer because "
"it is not a floating selection."));
success = FALSE;
}
}
CODE
);
}
sub floating_sel_to_layer {
$blurb = 'Transforms the specified floating selection into a layer.';
$help = <<'HELP';
This procedure transforms the specified floating selection into a layer with
the same offsets and extents. The composited image will look precisely the
same, but the floating selection layer will no longer be clipped to the extents
of the drawable it was attached to. The floating selection will become the
active layer. This procedure will not work if the floating selection has a
different base type from the underlying image. This might be the case if the
floating selection is above an auxiliary channel or a layer mask.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'floating_sel', type => 'layer',
desc => 'The floating selection' }
);
%invoke = (
code => <<'CODE'
{
if (pika_layer_is_floating_sel (floating_sel))
{
success = floating_sel_to_layer (floating_sel, error);
}
else
{
g_set_error_literal (error, PIKA_PDB_ERROR,
PIKA_PDB_ERROR_INVALID_ARGUMENT,
_("Cannot convert this layer to a normal layer "
"because it is not a floating selection."));
success = FALSE;
}
}
CODE
);
}
sub floating_sel_attach {
$blurb = <<'BLURB';
Attach the specified layer as floating to the specified drawable.
BLURB
$help = <<'HELP';
This procedure attaches the layer as floating selection to the drawable.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'layer', type => 'layer',
desc => 'The layer (is attached as floating selection)' },
{ name => 'drawable', type => 'drawable',
desc => 'The drawable (where to attach the floating selection)' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (PIKA_ITEM (drawable), NULL,
PIKA_PDB_ITEM_CONTENT, error) &&
pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error))
{
/* see layer-new */
if (pika_drawable_is_gray (PIKA_DRAWABLE (layer)) &&
PIKA_IS_LAYER (drawable))
pika_layer_fix_format_space (layer, TRUE, FALSE);
floating_sel_attach (layer, drawable);
}
else
success = FALSE;
}
CODE
);
}
@headers = qw("core/pikaimage.h"
"core/pikalayer-floating-selection.h"
"pikapdberror.h"
"pikapdb-utils.h"
"pika-intl.h");
@procs = qw(floating_sel_remove
floating_sel_anchor
floating_sel_to_layer
floating_sel_attach);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Floating selections';
$doc_title = 'pikafloatingsel';
$doc_short_desc = 'Functions for removing or attaching floating selections.';
$doc_long_desc = 'Functions for removing or attaching floating selections.';
1;

62
pdb/groups/font.pdb Normal file
View File

@ -0,0 +1,62 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
# The invoke code is compiled on the app side.
# The invoke code must assign to each result var
sub font_get_by_name {
$blurb = "Returns the font with the given name.";
$help = "Returns the font with the given name.";
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The name of the font' }
);
@outargs = (
{ name => 'font', type => 'font', non_empty => 1,
desc => 'The font' }
);
%invoke = (
code => <<'CODE'
{
font = PIKA_FONT (pika_pdb_get_resource (pika, PIKA_TYPE_FONT, name, PIKA_PDB_DATA_ACCESS_READ, error));
if (! font)
success = FALSE;
}
CODE
);
}
@headers = qw("core/pika.h"
"pikapdb-utils.h");
@procs = qw(font_get_by_name);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Font';
$doc_title = 'pikafont';
$doc_short_desc = 'Installable object used by text tools.';
$doc_long_desc = 'Installable object used by text tools.';
1;

131
pdb/groups/font_select.pdb Normal file
View File

@ -0,0 +1,131 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub fonts_popup {
$blurb = 'Invokes the Pika font selection dialog.';
$help = 'Opens a dialog letting a user choose a font.';
&neo_pdb_misc('2003');
@inargs = (
{ name => 'font_callback', type => 'string', non_empty => 1,
desc => 'The callback PDB proc to call when user chooses a font' },
{ name => 'popup_title', type => 'string',
desc => 'Title of the font selection dialog' },
{ name => 'initial_font_name', type => 'string', null_ok => 1,
desc => 'The name of the initial font choice.' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, font_callback) ||
! pika_data_factory_data_wait (pika->font_factory) ||
! pika_pdb_dialog_new (pika, context, progress,
pika_data_factory_get_container (pika->font_factory),
popup_title, font_callback, initial_font_name,
NULL))
success = FALSE;
}
CODE
);
}
sub fonts_close_popup {
$blurb = 'Close the font selection dialog.';
$help = 'Closes an open font selection dialog.';
&neo_pdb_misc('2003');
@inargs = (
{ name => 'font_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered in the PDB for this dialog' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, font_callback) ||
! pika_pdb_dialog_close (pika,
pika_data_factory_get_container (pika->font_factory),
font_callback))
success = FALSE;
}
CODE
);
}
sub fonts_set_popup {
$blurb = 'Sets the current font in a font selection dialog.';
$help = $blurb;
&neo_pdb_misc('2003');
@inargs = (
{ name => 'font_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered in the PDB for the dialog.' },
{ name => 'font_name', type => 'string',
desc => 'The name of the font to set as selected' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, font_callback) ||
! pika_data_factory_data_wait (pika->font_factory) ||
! pika_pdb_dialog_set (pika,
pika_data_factory_get_container (pika->font_factory),
font_callback, font_name,
NULL))
success = FALSE;
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pikadatafactory.h");
@procs = qw(fonts_popup
fonts_close_popup
fonts_set_popup);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Font UI';
$doc_title = 'pikafontselect';
$doc_short_desc = 'Methods of a font chooser dialog.';
$doc_long_desc = <<'LONG_DESC';
A font chooser dialog shows installed fonts.
The dialog is non-modal with its owning dialog,
which is usually a plugin procedure's dialog.
When a user selects a font,
the dialog calls back but the dialog remains open.
The chosen font is only a choice for the owning widget
and does not select the font for the context.
The user can close but not cancel the dialog.
The owning dialog can close the font chooser dialog
when the user closes or cancels the owning dialog.
LONG_DESC
1;

91
pdb/groups/fonts.pdb Normal file
View File

@ -0,0 +1,91 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub fonts_refresh {
$blurb = 'Refresh current fonts. This function always succeeds.';
$help = <<'HELP';
This procedure retrieves all fonts currently in the user's font path
and updates the font dialogs accordingly. Depending on the amount
of fonts on the system, this can take considerable time.
HELP
&neo_pdb_misc('2003');
%invoke = (
code => <<'CODE'
{
pika_data_factory_data_refresh (pika->font_factory, context);
pika_data_factory_data_wait (pika->font_factory);
}
CODE
);
}
sub fonts_get_list {
$blurb = 'Retrieve the list of loaded fonts.';
$help = <<'HELP';
This procedure returns a list of the fonts that are currently available.
HELP
&neo_pdb_misc('2003');
@inargs = (
{ name => 'filter', type => 'string', null_ok => 1,
desc => 'An optional regular expression used to filter the list' }
);
@outargs = (
{ name => 'font_list', type => 'strv',
desc => 'The list of font names' }
);
%invoke = (
headers => [ qw("core/pikacontainer-filter.h") ],
code => <<'CODE'
{
if (! pika_data_factory_data_wait (pika->font_factory))
success = FALSE;
if (success)
{
font_list = pika_container_get_filtered_name_array (pika_data_factory_get_container (pika->font_factory),
filter);
}
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pikacontainer.h"
"core/pikadatafactory.h");
@procs = qw(fonts_refresh
fonts_get_list);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Fonts';
$doc_title = 'pikafonts';
$doc_short_desc = 'Operations related to fonts.';
$doc_long_desc = 'Operations related to fonts.';
1;

1291
pdb/groups/gradient.pdb Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,123 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub gradients_popup {
$blurb = 'Invokes the Pika gradients selection dialog.';
$help = 'Opens a dialog letting a user choose a gradient.';
&andy_pdb_misc('1998');
@inargs = (
{ name => 'gradient_callback', type => 'string', non_empty => 1,
desc => 'The callback PDB proc to call when user chooses a gradient' },
{ name => 'popup_title', type => 'string',
desc => 'Title of the gradient selection dialog' },
{ name => 'initial_gradient_name', type => 'string', null_ok => 1,
desc => 'The name of the initial gradient choice' }
);
%invoke = (
code => <<'CODE'
{
/* Formerly, this procedure had another parameter:
* the sample size of the gradient's data passed in the changed callback.
* Now the sample size is determined by core, and in the future,
* the callback won't return a sample of the data at all.
*/
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, gradient_callback) ||
! pika_pdb_dialog_new (pika, context, progress,
pika_data_factory_get_container (pika->gradient_factory),
popup_title, gradient_callback, initial_gradient_name,
NULL))
success = FALSE;
}
CODE
);
}
sub gradients_close_popup {
$blurb = 'Close the gradient selection dialog.';
$help = 'Closes an open gradient selection dialog.';
&andy_pdb_misc('1998');
@inargs = (
{ name => 'gradient_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this pop-up' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, gradient_callback) ||
! pika_pdb_dialog_close (pika, pika_data_factory_get_container (pika->gradient_factory),
gradient_callback))
success = FALSE;
}
CODE
);
}
sub gradients_set_popup {
$blurb = 'Sets the current gradient in a gradient selection dialog.';
$help = $blurb;
&andy_pdb_misc('1998');
@inargs = (
{ name => 'gradient_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this pop-up' },
{ name => 'gradient_name', type => 'string',
desc => 'The name of the gradient to set as selected' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, gradient_callback) ||
! pika_pdb_dialog_set (pika, pika_data_factory_get_container (pika->gradient_factory),
gradient_callback, gradient_name,
NULL))
success = FALSE;
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pikadatafactory.h"
"core/pikagradient.h");
@procs = qw(gradients_popup
gradients_close_popup
gradients_set_popup);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Gradient UI';
$doc_title = 'pikagradientselect';
$doc_short_desc = 'Methods of a gradient chooser dialog';
$doc_long_desc = 'A dialog letting a user choose a gradient. Read more at pikafontselect.';
1;

88
pdb/groups/gradients.pdb Normal file
View File

@ -0,0 +1,88 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub gradients_refresh {
$blurb = 'Refresh current gradients. This function always succeeds.';
$help = <<'HELP';
This procedure retrieves all gradients currently in the user's gradient path
and updates the gradient dialogs accordingly.
HELP
&mitch_pdb_misc('2002');
%invoke = (
code => <<'CODE'
{
pika_data_factory_data_refresh (pika->gradient_factory, context);
}
CODE
);
}
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.
You can later use the pika_context_set_gradient() function to
set the active gradient.
HELP
&federico_pdb_misc('1997');
@inargs = (
{ name => 'filter', type => 'string', null_ok => 1,
desc => 'An optional regular expression used to filter the list' }
);
@outargs = (
{ name => 'gradient_list', type => 'strv',
desc => 'The list of gradient names' }
);
%invoke = (
headers => [ qw("core/pikacontainer-filter.h") ],
code => <<'CODE'
{
gradient_list = pika_container_get_filtered_name_array (pika_data_factory_get_container (pika->gradient_factory),
filter);
}
CODE
);
}
@headers = qw(<string.h>
"core/pika.h"
"core/pikacontext.h"
"core/pikadatafactory.h"
"core/pikagradient.h"
"pikapdb-utils.h");
@procs = qw(gradients_refresh
gradients_get_list);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Gradients';
$doc_title = 'pikagradients';
$doc_short_desc = 'Operations related to gradients.';
$doc_long_desc = 'Operations related to gradients.';
1;

72
pdb/groups/help.pdb Normal file
View File

@ -0,0 +1,72 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Sven Neumann <sven@gimp.org>
sub help {
$blurb = "Load a help page.";
$help = <<HELP;
This procedure loads the specified help page into the helpbrowser or
what ever is configured as help viewer. The help page is identified by
its domain and ID: if help_domain is NULL, we use the help_domain
which was registered using the pika_plugin_help_register() procedure. If
help_domain is NULL and no help domain was registered, the help domain
of the main PIKA installation is used.
HELP
&mitch_pdb_misc('2000');
@inargs = (
{ name => 'help_domain', type => 'string', null_ok => 1,
desc => "The help domain in which help_id is registered" },
{ name => 'help_id', type => 'string',
desc => "The help page's ID" }
);
%invoke = (
code => <<'CODE'
{
PikaPlugInManager *manager = pika->plug_in_manager;
if (! help_domain && manager->current_plug_in)
help_domain = (gchar *)
pika_plug_in_manager_get_help_domain (manager,
manager->current_plug_in->file,
NULL);
pika_help (pika, progress, help_domain, help_id);
}
CODE
);
}
@headers = qw("core/pika.h"
"plug-in/pikaplugin.h"
"plug-in/pikapluginmanager.h"
"plug-in/pikapluginmanager-help-domain.h");
@procs = qw(help);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Help procedures';
$doc_title = 'pikahelp';
$doc_short_desc = 'Loading help pages using pika_help.';
$doc_long_desc = 'Loading help pages using pika_help.';
1;

3248
pdb/groups/image.pdb Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,580 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub image_get_color_profile {
$blurb = "Returns the image's color profile";
$help = <<'HELP';
This procedure returns the image's color profile, or NULL if the image
has no color profile assigned.
HELP
&mitch_pdb_misc('2015', '2.10');
$lib_private = 1;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'profile_data', type => 'bytes',
desc => "The image's serialized color profile." }
);
%invoke = (
code => <<'CODE'
{
PikaColorProfile *profile;
profile = pika_image_get_color_profile (image);
if (profile)
{
const guint8 *data;
gsize length;
data = pika_color_profile_get_icc_profile (profile, &length);
profile_data = g_bytes_new (data, length);
}
}
CODE
);
}
sub image_get_effective_color_profile {
$blurb = "Returns the color profile that is used for the image";
$help = <<'HELP';
This procedure returns the color profile that is actually used for
this image, which is the profile returned by
pika_image_get_color_profile() if the image has a profile assigned, or
a generated default RGB or grayscale profile, according to the image's type.
HELP
&mitch_pdb_misc('2015', '2.10');
$lib_private = 1;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'profile_data', type => 'bytes',
desc => "The image's serialized color profile." }
);
%invoke = (
code => <<'CODE'
{
PikaColorProfile *profile;
profile = pika_color_managed_get_color_profile (PIKA_COLOR_MANAGED (image));
if (profile)
{
const guint8 *data;
gsize length;
data = pika_color_profile_get_icc_profile (profile, &length);
profile_data = g_bytes_new (data, length);
}
}
CODE
);
}
sub image_set_color_profile {
$blurb = "Sets the image's color profile";
$help = <<'HELP';
This procedure sets the image's color profile, or unsets it if NULL is
passed as 'color_profile'. This procedure does no color conversion.
However, it will change the pixel format of all layers to contain the
babl space matching the profile. You must call this procedure before
adding layers to the image.
HELP
&mitch_pdb_misc('2015', '2.10');
$lib_private = 1;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'color_profile', type => 'bytes',
desc => 'The new serialized color profile' }
);
%invoke = (
code => <<'CODE'
{
if (color_profile)
{
PikaColorProfile *profile;
profile = pika_color_profile_new_from_icc_profile (g_bytes_get_data (color_profile, NULL),
g_bytes_get_size (color_profile),
error);
if (profile)
{
success = pika_image_assign_color_profile (image, profile,
progress, error);
g_object_unref (profile);
}
else
success = FALSE;
}
else
{
success = pika_image_assign_color_profile (image, NULL,
progress, error);
}
}
CODE
);
}
sub image_set_color_profile_from_file {
$blurb = "Sets the image's color profile from an ICC file";
$help = <<'HELP';
This procedure sets the image's color profile from a file containing
an ICC profile, or unsets it if NULL is passed as 'file'. This
procedure does no color conversion. However, it will change the pixel
format of all layers to contain the babl space matching the
profile. You must call this procedure before adding layers to the
image.
HELP
&mitch_pdb_misc('2015', '2.10');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'file', type => 'file',
desc => 'The file containing the new color profile' }
);
%invoke = (
code => <<'CODE'
{
if (file)
{
PikaColorProfile *profile;
profile = pika_color_profile_new_from_file (file, error);
if (profile)
{
success = pika_image_assign_color_profile (image, profile,
progress, error);
g_object_unref (profile);
}
else
success = FALSE;
}
else
{
success = pika_image_assign_color_profile (image, NULL,
progress, error);
}
}
CODE
);
}
sub image_get_simulation_profile {
$blurb = "Returns the image's simulation color profile";
$help = <<'HELP';
This procedure returns the image's simulation color profile, or NULL if the image
has no simulation color profile assigned.
HELP
&alxsa_pdb_misc('2022', '3.0');
$lib_private = 1;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'profile_data', type => 'bytes',
desc => "The image's serialized simulation color profile." }
);
%invoke = (
code => <<'CODE'
{
PikaColorProfile *profile;
profile = pika_image_get_simulation_profile (image);
if (profile)
{
const guint8 *data;
gsize length;
data = pika_color_profile_get_icc_profile (profile, &length);
profile_data = g_bytes_new (data, length);
}
}
CODE
);
}
sub image_set_simulation_profile {
$blurb = "Sets the image's simulation color profile";
$help = <<'HELP';
This procedure sets the image's simulation color profile, or unsets it if NULL is
passed as 'color_profile'. This procedure does no color conversion.
HELP
&alxsa_pdb_misc('2022', '3.0');
$lib_private = 1;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'color_profile', type => 'bytes',
desc => 'The new serialized simulation color profile'}
);
%invoke = (
code => <<'CODE'
{
if (color_profile)
{
PikaColorProfile *profile;
profile = pika_color_profile_new_from_icc_profile (g_bytes_get_data (color_profile, NULL),
g_bytes_get_size (color_profile),
error);
if (profile)
{
pika_image_set_simulation_profile (image, profile);
g_object_unref (profile);
}
else
{
success = FALSE;
}
}
else
{
pika_image_set_simulation_profile (image, NULL);
}
}
CODE
);
}
sub image_set_simulation_profile_from_file {
$blurb = "Sets the image's simulation color profile from an ICC file";
$help = <<'HELP';
This procedure sets the image's simulation color profile from a file containing
an ICC profile, or unsets it if NULL is passed as 'file'. This
procedure does no color conversion.
HELP
&alxsa_pdb_misc('2022', '3.0');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'file', type => 'file',
desc => 'The file containing the new simulation color profile' }
);
%invoke = (
code => <<'CODE'
{
if (file)
{
PikaColorProfile *profile;
profile = pika_color_profile_new_from_file (file, error);
if (profile)
{
pika_image_set_simulation_profile (image, profile);
g_object_unref (profile);
}
else
{
success = FALSE;
}
}
else
{
pika_image_set_simulation_profile (image, NULL);
}
}
CODE
);
}
sub image_get_simulation_intent {
$blurb = "Returns the image's simulation rendering intent";
$help = <<'HELP';
This procedure returns the image's simulation rendering intent.
HELP
&alxsa_pdb_misc('2022', '3.0');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'intent', type => 'enum PikaColorRenderingIntent',
desc => "The image's simulation rendering intent." }
);
%invoke = (
code => <<'CODE'
{
intent = pika_image_get_simulation_intent (image);
}
CODE
);
}
sub image_set_simulation_intent {
$blurb = "Sets the image's simulation rendering intent";
$help = <<'HELP';
This procedure sets the image's simulation rendering intent.
HELP
&alxsa_pdb_misc('2022', '3.0');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'intent', type => 'enum PikaColorRenderingIntent',
desc => 'A PikaColorRenderingIntent' }
);
%invoke = (
code => <<'CODE'
{
pika_image_set_simulation_intent (image, intent);
}
CODE
);
}
sub image_get_simulation_bpc {
$blurb = "Returns whether the image has Black Point Compensation enabled for its simulation";
$help = <<'HELP';
This procedure returns whether the image has Black Point Compensation enabled for its simulation
HELP
&alxsa_pdb_misc('2022', '3.0');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'bpc', type => 'boolean',
desc => "The Black Point Compensation status." }
);
%invoke = (
code => <<'CODE'
{
bpc = pika_image_get_simulation_bpc (image);
}
CODE
);
}
sub image_set_simulation_bpc {
$blurb = "Sets whether the image has Black Point Compensation enabled for its simulation";
$help = <<'HELP';
This procedure whether the image has Black Point Compensation enabled for its simulation
HELP
&alxsa_pdb_misc('2022', '3.0');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'bpc', type => 'boolean',
desc => 'The Black Point Compensation status.' }
);
%invoke = (
code => <<'CODE'
{
pika_image_set_simulation_bpc (image, bpc);
}
CODE
);
}
sub image_convert_color_profile {
$blurb = "Convert the image's layers to a color profile";
$help = <<'HELP';
This procedure converts from the image's color profile (or the default
RGB or grayscale profile if none is set) to the given color profile. Only
RGB and grayscale color profiles are accepted, according to the image's
type.
HELP
&mitch_pdb_misc('2015', '2.10');
$lib_private = 1;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'color_profile', type => 'bytes',
desc => 'The serialized color profile' },
{ name => 'intent', type => 'enum PikaColorRenderingIntent',
desc => 'Rendering intent' },
{ name => 'bpc', type => 'boolean',
desc => 'Black point compensation' }
);
%invoke = (
code => <<'CODE'
{
if (color_profile)
{
PikaColorProfile *profile;
profile = pika_color_profile_new_from_icc_profile (g_bytes_get_data (color_profile, NULL),
g_bytes_get_size (color_profile),
error);
if (profile)
{
success = pika_image_convert_color_profile (image, profile,
intent, bpc,
progress, error);
g_object_unref (profile);
}
else
success = FALSE;
}
else
success = FALSE;
}
CODE
);
}
sub image_convert_color_profile_from_file {
$blurb = "Convert the image's layers to a color profile";
$help = <<'HELP';
This procedure converts from the image's color profile (or the default
RGB or grayscale profile if none is set) to an ICC profile specified by
'file'. Only RGB and grayscale color profiles are accepted, according to
the image's type.
HELP
&mitch_pdb_misc('2015', '2.10');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'file', type => 'file',
desc => 'The file containing the new color profile' },
{ name => 'intent', type => 'enum PikaColorRenderingIntent',
desc => 'Rendering intent' },
{ name => 'bpc', type => 'boolean',
desc => 'Black point compensation' }
);
%invoke = (
code => <<'CODE'
{
if (file)
{
PikaColorProfile *profile;
profile = pika_color_profile_new_from_file (file, error);
if (profile)
{
success = pika_image_convert_color_profile (image, profile,
intent, bpc,
progress, error);
g_object_unref (profile);
}
else
success = FALSE;
}
else
success = FALSE;
}
CODE
);
}
@headers = qw(<cairo.h>
"libpikacolor/pikacolor.h"
"core/pikaimage-color-profile.h"
"pika-intl.h");
@procs = qw(image_get_color_profile
image_get_effective_color_profile
image_set_color_profile
image_set_color_profile_from_file
image_get_simulation_profile
image_set_simulation_profile
image_set_simulation_profile_from_file
image_get_simulation_intent
image_set_simulation_intent
image_get_simulation_bpc
image_set_simulation_bpc
image_convert_color_profile
image_convert_color_profile_from_file);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Image Color Profile';
$doc_title = 'pikaimagecolorprofile';
$doc_short_desc = 'Operations on an image\'s color profile.';
$doc_long_desc = 'Operations on an image\'s color profile.';
1;

View File

@ -0,0 +1,285 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub image_convert_rgb {
$blurb = 'Convert specified image to RGB color';
$help = <<'HELP';
This procedure converts the specified image to RGB color. This process
requires an image in Grayscale or Indexed color mode. No image content is
lost in this process aside from the colormap for an indexed image.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_image_is_not_base_type (image, PIKA_RGB, error) &&
pika_babl_is_valid (PIKA_RGB, pika_image_get_precision (image)))
{
success = pika_image_convert_type (image, PIKA_RGB, NULL, NULL, error);
}
else
{
success = FALSE;
}
}
CODE
);
}
sub image_convert_grayscale {
$blurb = 'Convert specified image to grayscale';
$help = <<'HELP';
This procedure converts the specified image to grayscale. This process
requires an image in RGB or Indexed color mode.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_image_is_not_base_type (image, PIKA_GRAY, error) &&
pika_babl_is_valid (PIKA_GRAY, pika_image_get_precision (image)))
{
success = pika_image_convert_type (image, PIKA_GRAY, NULL, NULL, error);
}
else
{
success = FALSE;
}
}
CODE
);
}
sub image_convert_indexed {
$blurb = 'Convert specified image to and Indexed image';
$help = <<'HELP';
This procedure converts the specified image to 'indexed' color. This
process requires an image in RGB or Grayscale mode. The 'palette_type'
specifies what kind of palette to use, A type of '0' means to use an
optimal palette of 'num_cols' generated from the colors in the
image. A type of '1' means to re-use the previous palette (not
currently implemented). A type of '2' means to use the so-called
WWW-optimized palette. Type '3' means to use only black and white
colors. A type of '4' means to use a palette from the pika palettes
directories. The 'dither type' specifies what kind of dithering to
use. '0' means no dithering, '1' means standard Floyd-Steinberg error
diffusion, '2' means Floyd-Steinberg error diffusion with reduced
bleeding, '3' means dithering based on pixel location ('Fixed'
dithering).
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'dither_type', type => 'enum PikaConvertDitherType',
desc => 'The dither type to use' },
{ name => 'palette_type', type => 'enum PikaConvertPaletteType',
desc => 'The type of palette to use' },
{ name => 'num_cols', type => 'int32',
desc => 'The number of colors to quantize to, ignored unless
(palette_type == PIKA_CONVERT_PALETTE_GENERATE)' },
{ name => 'alpha_dither', type => 'boolean',
desc => 'Dither transparency to fake partial opacity' },
{ name => 'remove_unused', type => 'boolean',
desc => 'Remove unused or duplicate color entries from final
palette, ignored if (palette_type ==
PIKA_CONVERT_PALETTE_GENERATE)' },
{ name => 'palette', type => 'string',
desc => 'The name of the custom palette to use, ignored unless
(palette_type == PIKA_CONVERT_PALETTE_CUSTOM)' }
);
%invoke = (
code => <<'CODE'
{
PikaPalette *pal = NULL;
if (pika_pdb_image_is_not_base_type (image, PIKA_INDEXED, error) &&
pika_pdb_image_is_precision (image, PIKA_PRECISION_U8_NON_LINEAR, error) &&
pika_babl_is_valid (PIKA_INDEXED, pika_image_get_precision (image)) &&
pika_item_stack_is_flat (PIKA_ITEM_STACK (pika_image_get_layers (image))))
{
switch (palette_type)
{
case PIKA_CONVERT_PALETTE_GENERATE:
if (num_cols < 1 || num_cols > MAXNUMCOLORS)
success = FALSE;
break;
case PIKA_CONVERT_PALETTE_CUSTOM:
pal = PIKA_PALETTE (pika_pdb_get_resource (pika, PIKA_TYPE_PALETTE, palette,
PIKA_PDB_DATA_ACCESS_READ, error));
if (! pal)
{
success = FALSE;
}
else if (pal->n_colors > MAXNUMCOLORS)
{
g_set_error_literal (error,
PIKA_PDB_ERROR,
PIKA_PDB_ERROR_INVALID_ARGUMENT,
_("Cannot convert to a palette "
"with more than 256 colors."));
success = FALSE;
}
break;
default:
break;
}
}
else
{
success = FALSE;
}
if (success)
success = pika_image_convert_indexed (image,
palette_type, num_cols, remove_unused,
dither_type, alpha_dither, FALSE,
pal,
NULL, error);
}
CODE
);
}
sub image_convert_set_dither_matrix {
$blurb = 'Set dither matrix for conversion to indexed';
$help = <<'HELP';
This procedure sets the dither matrix used when converting images to INDEXED mode with
positional dithering.
HELP
&david_pdb_misc('2006', '2.4');
@inargs = (
{ name => 'width', type => 'int32',
desc => 'Width of the matrix (0 to reset to default matrix)' },
{ name => 'height', type => 'int32',
desc => 'Height of the matrix (0 to reset to default matrix)' },
{ name => 'matrix', type => 'bytes',
desc => 'The matrix -- all values must be >= 1' },
);
%invoke = (
code => <<'CODE'
{
if (width == 0 || height == 0 || g_bytes_get_size (matrix) == width * height)
{
pika_image_convert_indexed_set_dither_matrix (g_bytes_get_data (matrix, NULL),
width, height);
}
else
{
g_set_error_literal (error, PIKA_PDB_ERROR,
PIKA_PDB_ERROR_INVALID_ARGUMENT,
"Dither matrix length must be width * height");
success = FALSE;
}
}
CODE
);
}
sub image_convert_precision {
$blurb = 'Convert the image to the specified precision';
$help = <<'HELP';
This procedure converts the image to the specified precision. Note
that indexed images cannot be converted and are always in
PIKA_PRECISION_U8.
HELP
&mitch_pdb_misc('2012', '2.10');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'precision', type => 'enum PikaPrecision',
desc => 'The new precision' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_image_is_not_base_type (image, PIKA_INDEXED, error) &&
pika_pdb_image_is_not_precision (image, precision, error) &&
pika_babl_is_valid (pika_image_get_base_type (image), precision))
{
pika_image_convert_precision (image, precision,
GEGL_DITHER_NONE,
GEGL_DITHER_NONE,
GEGL_DITHER_NONE,
progress);
}
else
{
success = FALSE;
}
}
CODE
);
}
@headers = qw("gegl/pika-babl.h"
"core/pika.h"
"core/pikaimage.h"
"core/pikaimage-convert-indexed.h"
"core/pikaimage-convert-precision.h"
"core/pikaimage-convert-type.h"
"core/pikaitemstack.h"
"core/pikapalette.h"
"pikapdberror.h"
"pikapdb-utils.h"
"pika-intl.h");
@procs = qw(image_convert_rgb
image_convert_grayscale
image_convert_indexed
image_convert_set_dither_matrix
image_convert_precision);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Image Convert';
$doc_title = 'pikaimageconvert';
$doc_short_desc = 'Conversions between RGB, indexed, and grayscale modes.';
$doc_long_desc = 'Conversions between RGB, indexed, and grayscale modes.';
1;

372
pdb/groups/image_grid.pdb Normal file
View File

@ -0,0 +1,372 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
sub image_grid_get_spacing {
$blurb = "Gets the spacing of an image's grid.";
$help = <<HELP;
This procedure retrieves the horizontal and vertical spacing of an image's grid.
It takes the image as parameter.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'xspacing', type => 'float', void_ret => 1,
desc => "The image's grid horizontal spacing" },
{ name => 'yspacing', type => 'float', void_ret => 1,
desc => "The image's grid vertical spacing" }
);
%invoke = (
code => <<'CODE'
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
g_object_get (grid,
"xspacing", &xspacing,
"yspacing", &yspacing,
NULL);
else
success = FALSE;
}
CODE
);
}
sub image_grid_set_spacing {
$blurb = "Sets the spacing of an image's grid.";
$help = <<HELP;
This procedure sets the horizontal and vertical spacing of an image's grid.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'xspacing', type => 'float',
desc => "The image's grid horizontal spacing" },
{ name => 'yspacing', type => 'float',
desc => "The image's grid vertical spacing" }
);
%invoke = (
code => <<CODE
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
g_object_set (grid,
"xspacing", xspacing,
"yspacing", yspacing,
NULL);
else
success = FALSE;
}
CODE
);
}
sub image_grid_get_offset {
$blurb = "Gets the offset of an image's grid.";
$help = <<HELP;
This procedure retrieves the horizontal and vertical offset of an image's grid.
It takes the image as parameter.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'xoffset', type => 'float', void_ret => 1,
desc => "The image's grid horizontal offset" },
{ name => 'yoffset', type => 'float', void_ret => 1,
desc => "The image's grid vertical offset" }
);
%invoke = (
code => <<'CODE'
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
g_object_get (grid,
"xoffset", &xoffset,
"yoffset", &yoffset,
NULL);
else
success = FALSE;
}
CODE
);
}
sub image_grid_set_offset {
$blurb = "Sets the offset of an image's grid.";
$help = <<HELP;
This procedure sets the horizontal and vertical offset of an image's grid.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'xoffset', type => 'float',
desc => "The image's grid horizontal offset" },
{ name => 'yoffset', type => 'float',
desc => "The image's grid vertical offset" }
);
%invoke = (
code => <<CODE
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
g_object_set (grid,
"xoffset", xoffset,
"yoffset", yoffset,
NULL);
else
success = FALSE;
}
CODE
);
}
sub image_grid_get_foreground_color {
$blurb = "Sets the foreground color of an image's grid.";
$help = <<HELP;
This procedure gets the foreground color of an image's grid.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'fgcolor', type => 'color', has_alpha => 1, void_ret => 1,
desc => "The image's grid foreground color" }
);
%invoke = (
code => <<'CODE'
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
fgcolor = grid->fgcolor;
else
success = FALSE;
}
CODE
);
}
sub image_grid_set_foreground_color {
$blurb = "Gets the foreground color of an image's grid.";
$help = <<HELP;
This procedure sets the foreground color of an image's grid.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'fgcolor', type => 'color', has_alpha => 1,
desc => "The new foreground color" }
);
%invoke = (
code => <<'CODE'
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
g_object_set (grid, "fgcolor", &fgcolor, NULL);
else
success = FALSE;
}
CODE
);
}
sub image_grid_get_background_color {
$blurb = "Sets the background color of an image's grid.";
$help = <<HELP;
This procedure gets the background color of an image's grid.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'bgcolor', type => 'color', has_alpha => 1, void_ret => 1,
desc => "The image's grid background color" }
);
%invoke = (
code => <<'CODE'
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
bgcolor = grid->bgcolor;
else
success = FALSE;
}
CODE
);
}
sub image_grid_set_background_color {
$blurb = "Gets the background color of an image's grid.";
$help = <<HELP;
This procedure sets the background color of an image's grid.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'bgcolor', type => 'color', has_alpha => 1,
desc => "The new background color" }
);
%invoke = (
code => <<'CODE'
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
g_object_set (grid, "bgcolor", &bgcolor, NULL);
else
success = FALSE;
}
CODE
);
}
sub image_grid_get_style {
$blurb = "Gets the style of an image's grid.";
$help = <<HELP;
This procedure retrieves the style of an image's grid.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'style', type => 'enum PikaGridStyle',
desc => "The image's grid style" }
);
%invoke = (
code => <<CODE
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
g_object_get (grid, "style", &style, NULL);
else
success = FALSE;
}
CODE
);
}
sub image_grid_set_style {
$blurb = "Sets the style unit of an image's grid.";
$help = <<HELP;
This procedure sets the style of an image's grid.
It takes the image and the new style as parameters.
HELP
&sylvain_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'style', type => 'enum PikaGridStyle',
desc => "The image's grid style" }
);
%invoke = (
code => <<CODE
{
PikaGrid *grid = pika_image_get_grid (image);
if (grid)
g_object_set (grid, "style", style, NULL);
else
success = FALSE;
}
CODE
);
}
@headers = qw("core/pikaimage-grid.h" "core/pikagrid.h"
"libpikabase/pikabaseenums.h");
@procs = qw(image_grid_get_spacing image_grid_set_spacing
image_grid_get_offset image_grid_set_offset
image_grid_get_foreground_color image_grid_set_foreground_color
image_grid_get_background_color image_grid_set_background_color
image_grid_get_style image_grid_set_style);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Image grid procedures';
$doc_title = 'pikaimagegrid';
$doc_short_desc = "Functions manuipulating an image's grid.";
$doc_long_desc = "Functions manuipulating an image's grid.";
1;

270
pdb/groups/image_guides.pdb Normal file
View File

@ -0,0 +1,270 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub image_add_hguide {
$blurb = 'Add a horizontal guide to an image.';
$help = <<HELP;
This procedure adds a horizontal guide to an image. It takes the input
image and the y-position of the new guide as parameters. It returns
the guide ID of the new guide.
HELP
&adam_pdb_misc('1998');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'yposition', type => '0 <= int32',
desc => "The guide's y-offset from top of image" }
);
@outargs = (
{ name => 'guide', type => 'guide',
desc => 'The new guide' }
);
%invoke = (
code => <<'CODE'
{
if (yposition <= pika_image_get_height (image))
{
PikaGuide *g;
g = pika_image_add_hguide (image, yposition, TRUE);
guide = pika_aux_item_get_id (PIKA_AUX_ITEM (g));
}
else
success = FALSE;
}
CODE
);
}
sub image_add_vguide {
$blurb = 'Add a vertical guide to an image.';
$help = <<HELP;
This procedure adds a vertical guide to an image. It takes the input
image and the x-position of the new guide as parameters. It returns
the guide ID of the new guide.
HELP
&adam_pdb_misc('1998');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'xposition', type => '0 <= int32',
desc => "The guide's x-offset from left of image" }
);
@outargs = (
{ name => 'guide', type => 'guide',
desc => 'The new guide' }
);
%invoke = (
code => <<'CODE'
{
if (xposition <= pika_image_get_width (image))
{
PikaGuide *g;
g = pika_image_add_vguide (image, xposition, TRUE);
guide = pika_aux_item_get_id (PIKA_AUX_ITEM (g));
}
else
success = FALSE;
}
CODE
);
}
sub image_delete_guide {
$blurb = 'Deletes a guide from an image.';
$help = <<'HELP';
This procedure takes an image and a guide ID as input and removes the specified
guide from the specified image.
HELP
&adam_pdb_misc('1998');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'guide', type => 'guide',
desc => 'The ID of the guide to be removed' }
);
%invoke = (
code => <<'CODE'
{
PikaGuide *g = pika_pdb_image_get_guide (image, guide, error);
if (g)
pika_image_remove_guide (image, g, TRUE);
else
success = FALSE;
}
CODE
);
}
sub image_find_next_guide {
$blurb = 'Find next guide on an image.';
$help = <<'HELP';
This procedure takes an image and a guide ID as input and finds the guide ID of
the successor of the given guide ID in the image's guide list. If the supplied
guide ID is 0, the procedure will return the first Guide. The procedure will
return 0 if given the final guide ID as an argument or the image has no guides.
HELP
&adam_pdb_misc('1998');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'guide', type => 'guide', no_validate => 1,
desc => 'The ID of the current guide (0 if first invocation)' }
);
@outargs = (
{ name => 'next_guide', type => 'guide',
desc => "The next guide's ID" }
);
%invoke = (
code => <<'CODE'
{
PikaGuide *g = pika_image_get_next_guide (image, guide, &success);
if (g)
next_guide = pika_aux_item_get_id (PIKA_AUX_ITEM (g));
if (! success)
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_INVALID_ARGUMENT,
_("Image '%s' (%d) does not contain guide with ID %d"),
pika_image_get_display_name (image),
pika_image_get_id (image),
guide);
}
CODE
);
}
sub image_get_guide_orientation {
$blurb = 'Get orientation of a guide on an image.';
$help = <<'HELP';
This procedure takes an image and a guide ID as input and returns the
orientations of the guide.
HELP
&adam_pdb_misc('1998');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'guide', type => 'guide',
desc => 'The guide' }
);
@outargs = (
{ name => 'orientation',
type => 'enum PikaOrientationType (no PIKA_ORIENTATION_UNKNOWN)',
desc => "The guide's orientation",
libdef => 'PIKA_ORIENTATION_UNKNOWN' }
);
%invoke = (
code => <<'CODE'
{
PikaGuide *g = pika_pdb_image_get_guide (image, guide, error);
if (g)
orientation = pika_guide_get_orientation (g);
else
success = FALSE;
}
CODE
);
}
sub image_get_guide_position {
$blurb = 'Get position of a guide on an image.';
$help = <<'HELP';
This procedure takes an image and a guide ID as input and returns the position
of the guide relative to the top or left of the image.
HELP
&adam_pdb_misc('1998');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'guide', type => 'guide',
desc => 'The guide' }
);
@outargs = (
{ name => 'position', type => 'int32',
libdef => 'G_MININT /* PIKA_GUIDE_POSITION_UNDEFINED */',
desc => "The guide's position relative to top or left of image" }
);
%invoke = (
code => <<'CODE'
{
PikaGuide *g = pika_pdb_image_get_guide (image, guide, error);
if (g)
position = pika_guide_get_position (g);
else
success = FALSE;
}
CODE
);
}
@headers = qw("cairo.h"
"core/pikaguide.h"
"core/pikaimage-guides.h"
"core/pikaimage-undo-push.h"
"pikapdb-utils.h"
"pikapdberror.h"
"pika-intl.h");
@procs = qw(image_add_hguide image_add_vguide
image_delete_guide
image_find_next_guide
image_get_guide_orientation
image_get_guide_position);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Image Guide procedures';
$doc_title = 'pikaimageguides';
$doc_short_desc = 'Functions for manipulating an image\'s guides.';
$doc_long_desc = 'Functions for manipulating an image\'s guides.';
1;

View File

@ -0,0 +1,202 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub image_add_sample_point {
$blurb = 'Add a sample point to an image.';
$help = <<HELP;
This procedure adds a sample point to an image. It takes the input
image and the position of the new sample points as parameters. It
returns the sample point ID of the new sample point.
HELP
&mitch_pdb_misc('2016', '2.10');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'position_x', type => '0 <= int32',
desc => "The sample point's x-offset from left of image" },
{ name => 'position_y', type => '0 <= int32',
desc => "The sample point's y-offset from top of image" }
);
@outargs = (
{ name => 'sample_point', type => 'sample_point',
desc => 'The new sample point' }
);
%invoke = (
code => <<'CODE'
{
if (position_x <= pika_image_get_width (image) &&
position_y <= pika_image_get_height (image))
{
PikaSamplePoint *sp;
sp = pika_image_add_sample_point_at_pos (image, position_x, position_y,
TRUE);
sample_point = pika_aux_item_get_id (PIKA_AUX_ITEM (sp));
}
else
success = FALSE;
}
CODE
);
}
sub image_delete_sample_point {
$blurb = 'Deletes a sample point from an image.';
$help = <<'HELP';
This procedure takes an image and a sample point ID as input and
removes the specified sample point from the specified image.
HELP
&mitch_pdb_misc('2016', '2.10');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'sample_point', type => 'sample_point',
desc => 'The ID of the sample point to be removed' }
);
%invoke = (
code => <<'CODE'
{
PikaSamplePoint *sp = pika_pdb_image_get_sample_point (image, sample_point,
error);
if (sp)
pika_image_remove_sample_point (image, sp, TRUE);
else
success = FALSE;
}
CODE
);
}
sub image_find_next_sample_point {
$blurb = 'Find next sample point on an image.';
$help = <<'HELP';
This procedure takes an image and a sample point ID as input and finds
the sample point ID of the successor of the given sample point ID in
the image's sample point list. If the supplied sample point ID is 0,
the procedure will return the first sample point. The procedure will
return 0 if given the final sample point ID as an argument or the
image has no sample points.
HELP
&mitch_pdb_misc('2016', '2.10');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'sample_point', type => 'sample_point', no_validate => 1,
desc => 'The ID of the current sample point (0 if first invocation)' }
);
@outargs = (
{ name => 'next_sample_point', type => 'sample_point',
desc => "The next sample point's ID" }
);
%invoke = (
code => <<'CODE'
{
PikaSamplePoint *sp = pika_image_get_next_sample_point (image, sample_point,
&success);
if (sp)
next_sample_point = pika_aux_item_get_id (PIKA_AUX_ITEM (sp));
if (! success)
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_INVALID_ARGUMENT,
_("Image '%s' (%d) does not contain sample point with ID %d"),
pika_image_get_display_name (image),
pika_image_get_id (image),
sample_point);
}
CODE
);
}
sub image_get_sample_point_position {
$blurb = 'Get position of a sample point on an image.';
$help = <<'HELP';
This procedure takes an image and a sample point ID as input and
returns the position of the sample point relative to the top and left
of the image.
HELP
&mitch_pdb_misc('2016', '2.10');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'sample_point', type => 'sample_point',
desc => 'The guide' }
);
@outargs = (
{ name => 'position_x', type => 'int32',
libdef => 'G_MININT',
desc => "The sample point's x-offset relative to left of image" },
{ name => 'position_y', type => 'int32',
libdef => 'G_MININT',
desc => "The sample point's y-offset relative to top of image" }
);
%invoke = (
code => <<'CODE'
{
PikaSamplePoint *sp = pika_pdb_image_get_sample_point (image, sample_point,
error);
if (sp)
pika_sample_point_get_position (sp, &position_x, &position_y);
else
success = FALSE;
}
CODE
);
}
@headers = qw("core/pikasamplepoint.h"
"core/pikaimage-sample-points.h"
"pikapdb-utils.h"
"pikapdberror.h"
"pika-intl.h");
@procs = qw(image_add_sample_point
image_delete_sample_point
image_find_next_sample_point
image_get_sample_point_position);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Image Sample Point procedures';
$doc_title = 'pikaimagesamplepoints';
$doc_short_desc = 'Functions for manipulating an image\'s sample points.';
$doc_long_desc = 'Functions for manipulating an image\'s sample points.';
1;

449
pdb/groups/image_select.pdb Normal file
View File

@ -0,0 +1,449 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub image_select_color {
$blurb = <<'BLURB';
Create a selection by selecting all pixels (in the specified drawable)
with the same (or similar) color to that specified.
BLURB
$help = <<'HELP';
This tool creates a selection over the specified image. A by-color
selection is determined by the supplied color under the constraints of
the current context settings. Essentially, all pixels (in the drawable)
that have color sufficiently close to the specified color (as
determined by the threshold and criterion context values) are included
in the selection. To select transparent regions, the color specified
must also have minimum alpha.
This procedure is affected by the following context setters:
pika_context_set_antialias(), pika_context_set_feather(),
pika_context_set_feather_radius(), pika_context_set_sample_merged(),
pika_context_set_sample_criterion(), pika_context_set_sample_threshold(),
pika_context_set_sample_transparent().
In the case of a merged sampling, the supplied drawable is ignored.
HELP
&david_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The affected image' },
{ name => 'operation', type => 'enum PikaChannelOps',
desc => 'The selection operation' },
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ name => 'color', type => 'color',
desc => 'The color to select' }
);
%invoke = (
code => <<'CODE'
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
if (pdb_context->sample_merged ||
pika_pdb_item_is_attached (PIKA_ITEM (drawable), image, 0, error))
{
GList *drawables = g_list_prepend (NULL, drawable);
pika_channel_select_by_color (pika_image_get_mask (image), drawables,
pdb_context->sample_merged,
&color,
pdb_context->sample_threshold,
pdb_context->sample_transparent,
pdb_context->sample_criterion,
operation,
pdb_context->antialias,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y);
g_list_free (drawables);
}
else
success = FALSE;
}
CODE
);
}
sub image_select_contiguous_color {
$blurb = <<'BLURB';
Create a selection by selecting all pixels around specified coordinates
with the same (or similar) color to that at the coordinates.
BLURB
$help = <<'HELP';
This tool creates a contiguous selection over the specified image. A
contiguous color selection is determined by a seed fill under the
constraints of the current context settings. Essentially, the color
at the specified coordinates (in the drawable) is measured and the
selection expands outwards from that point to any adjacent pixels
which are not significantly different (as determined by the threshold
and criterion context settings). This process continues until no more
expansion is possible. If antialiasing is turned on, the final
selection mask will contain intermediate values based on close misses
to the threshold bar at pixels along the seed fill boundary.
This procedure is affected by the following context setters:
pika_context_set_antialias(), pika_context_set_feather(),
pika_context_set_feather_radius(), pika_context_set_sample_merged(),
pika_context_set_sample_criterion(), pika_context_set_sample_threshold(),
pika_context_set_sample_transparent(), pika_context_set_diagonal_neighbors().
In the case of a merged sampling, the supplied drawable is ignored.
If the sample is merged, the specified coordinates are relative to the
image origin; otherwise, they are relative to the drawable's origin.
HELP
&david_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The affected image' },
{ name => 'operation', type => 'enum PikaChannelOps',
desc => 'The selection operation' },
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ name => 'x', type => 'float',
desc => 'x coordinate of initial seed fill point: (image
coordinates)' },
{ name => 'y', type => 'float',
desc => 'y coordinate of initial seed fill point: (image
coordinates)' }
);
%invoke = (
code => <<'CODE'
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
if (pdb_context->sample_merged ||
pika_pdb_item_is_attached (PIKA_ITEM (drawable), image, 0, error))
{
pika_channel_select_fuzzy (pika_image_get_mask (image),
drawable,
pdb_context->sample_merged,
x, y,
pdb_context->sample_threshold,
pdb_context->sample_transparent,
pdb_context->sample_criterion,
pdb_context->diagonal_neighbors,
operation,
pdb_context->antialias,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y);
}
else
success = FALSE;
}
CODE
);
}
sub image_select_rectangle {
$blurb = 'Create a rectangular selection over the specified image;';
$help = <<'HELP';
This tool creates a rectangular selection over the specified
image. The rectangular region can be either added to, subtracted from,
or replace the contents of the previous selection mask.
This procedure is affected by the following context setters:
pika_context_set_feather(), pika_context_set_feather_radius().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'operation', type => 'enum PikaChannelOps',
desc => 'The selection operation' },
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of rectangle' },
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of rectangle' },
{ name => 'width', type => '0 < float',
desc => 'The width of the rectangle' },
{ name => 'height', type => '0 < float',
desc => 'The height of the rectangle' }
);
%invoke = (
code => <<'CODE'
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
pika_channel_select_rectangle (pika_image_get_mask (image),
(gint) x, (gint) y,
(gint) width, (gint) height,
operation,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y,
TRUE);
}
CODE
);
}
sub image_select_round_rectangle {
$blurb = 'Create a rectangular selection with round corners over the specified image;';
$help = <<'HELP';
This tool creates a rectangular selection with round corners over the
specified image. The rectangular region can be either added to,
subtracted from, or replace the contents of the previous selection
mask.
This procedure is affected by the following context setters:
pika_context_set_antialias(), pika_context_set_feather(),
pika_context_set_feather_radius().
HELP
&martin_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'operation', type => 'enum PikaChannelOps',
desc => 'The selection operation' },
{ name => 'x', type => 'float',
desc => 'x coordinate of upper-left corner of rectangle' },
{ name => 'y', type => 'float',
desc => 'y coordinate of upper-left corner of rectangle' },
{ name => 'width', type => '0 < float',
desc => 'The width of the rectangle' },
{ name => 'height', type => '0 < float',
desc => 'The height of the rectangle' },
{ name => 'corner_radius_x', type => '0 < float < PIKA_MAX_IMAGE_SIZE',
desc => 'The corner radius in X direction' },
{ name => 'corner_radius_y', type => '0 < float < PIKA_MAX_IMAGE_SIZE',
desc => 'The corner radius in Y direction' }
);
%invoke = (
code => <<'CODE'
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
pika_channel_select_round_rect (pika_image_get_mask (image),
(gint) x, (gint) y,
(gint) width, (gint) height,
corner_radius_x,
corner_radius_y,
operation,
pdb_context->antialias,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y,
TRUE);
}
CODE
);
}
sub image_select_ellipse {
$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.
This procedure is affected by the following context setters:
pika_context_set_antialias(), pika_context_set_feather(),
pika_context_set_feather_radius().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'operation', type => 'enum PikaChannelOps',
desc => 'The selection operation' },
{ 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' },
{ name => 'height', type => '0 < float',
desc => 'The height of the ellipse' }
);
%invoke = (
code => <<'CODE'
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
pika_channel_select_ellipse (pika_image_get_mask (image),
(gint) x, (gint) y,
(gint) width, (gint) height,
operation,
pdb_context->antialias,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y,
TRUE);
}
CODE
);
}
sub image_select_polygon {
$blurb = 'Create a polygonal selection over the specified image.';
$help = <<'HELP';
This tool creates a polygonal selection over the specified image. The
polygonal region can be either added to, subtracted from, or replace
the contents of the previous selection mask. The polygon is specified
through an array of floating point numbers and its length. The length
of array must be 2n, where n is the number of points. Each point is
defined by 2 floating point values which correspond to the x and y
coordinates. If the final point does not connect to the starting
point, a connecting segment is automatically added.
This procedure is affected by the following context setters:
pika_context_set_antialias(), pika_context_set_feather(),
pika_context_set_feather_radius().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'operation', type => 'enum PikaChannelOps',
desc => 'The selection operation' },
{ name => 'segs', type => 'floatarray',
desc => 'Array of points: { p1.x, p1.y, p2.x, p2.y, ...,
pn.x, pn.y}',
array => { type => '2 <= int32',
desc => 'Number of points (count 1 coordinate as two
points)' } }
);
%invoke = (
code => <<'CODE'
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
pika_channel_select_polygon (pika_image_get_mask (image),
_("Free Select"),
num_segs / 2,
(PikaVector2 *) segs,
operation,
pdb_context->antialias,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y,
TRUE);
}
CODE
);
}
sub image_select_item {
$blurb = 'Transforms the specified item into a selection';
$help = <<'HELP';
This procedure renders the item's outline into the current selection
of the image the item belongs to. What exactly the item's outline is
depends on the item type: for layers, it's the layer's alpha channel,
for vectors the vector's shape.
This procedure is affected by the following context setters:
pika_context_set_antialias(), pika_context_set_feather(),
pika_context_set_feather_radius().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'operation', type => 'enum PikaChannelOps',
desc => 'The desired operation with current selection' },
{ name => 'item', type => 'item',
desc => 'The item to render to the selection' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_attached (item, image, 0, error))
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
pika_item_to_selection (item, operation,
pdb_context->antialias,
pdb_context->feather,
pdb_context->feather_radius_x,
pdb_context->feather_radius_y);
}
else
success = FALSE;
}
CODE
);
}
@headers = qw("libpikabase/pikabase.h"
"core/pikachannel-select.h"
"pikapdb-utils.h"
"pikapdbcontext.h"
"pika-intl.h");
@procs = qw(image_select_color
image_select_contiguous_color
image_select_rectangle
image_select_round_rectangle
image_select_ellipse
image_select_polygon
image_select_item);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Selection procedures';
$doc_title = 'pikaimageselect';
$doc_short_desc = "Modify the image's selection.";
$doc_long_desc = "Functions to modify the image's selection.";
1;

View File

@ -0,0 +1,245 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub image_resize {
$blurb = 'Resize the image to the specified extents.';
$help = <<'HELP';
This procedure resizes 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
within the image are resized according to the specified parameters;
this includes the image selection mask. All layers within the image
are repositioned according to the specified offsets.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'new_width', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
desc => 'New image width' },
{ name => 'new_height', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
desc => 'New image height' },
{ name => 'offx', type => 'int32',
desc => 'x offset between upper left corner of old and
new images: (new - old)' },
{ name => 'offy', type => 'int32',
desc => 'y offset between upper left corner of old and
new images: (new - old)' }
);
%invoke = (
headers => [ qw("core/pikaimage-resize.h") ],
code => <<'CODE'
{
pika_image_resize (image, context,
new_width, new_height, offx, offy, NULL);
}
CODE
);
}
sub image_resize_to_layers {
$blurb = 'Resize the image to fit all layers.';
$help = <<'HELP';
This procedure resizes the image to the bounding box of all layers of
the image. All channels within the image are resized to the new size;
this includes the image selection mask. All layers within the image
are repositioned to the new image area.
HELP
&simon_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
%invoke = (
headers => [ qw("core/pikaimage-resize.h") ],
code => <<'CODE'
{
pika_image_resize_to_layers (image, context, NULL, NULL, NULL, NULL, NULL);
}
CODE
);
}
sub image_scale {
$blurb = 'Scale the image using the default interpolation method.';
$help = <<'HELP';
This procedure scales the image so that its new width and height are
equal to the supplied parameters. All layers and channels within the
image are scaled according to the specified parameters; this includes
the image selection mask. The interpolation method used can be set
with pika_context_set_interpolation().
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'new_width', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
desc => 'New image width' },
{ name => 'new_height', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
desc => 'New image height' }
);
%invoke = (
headers => [ qw("core/pikaimage-scale.h") ],
code => <<'CODE'
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
if (progress)
pika_progress_start (progress, FALSE, _("Scaling"));
pika_image_scale (image, new_width, new_height,
pdb_context->interpolation,
progress);
if (progress)
pika_progress_end (progress);
}
CODE
);
}
sub image_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 = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'new_width', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
desc => 'New image width: (0 < new_width <= width)' },
{ name => 'new_height', type => '1 <= int32 <= PIKA_MAX_IMAGE_SIZE',
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("core/pikaimage-crop.h") ],
code => <<'CODE'
{
if (new_width > pika_image_get_width (image) ||
new_height > pika_image_get_height (image) ||
offx > (pika_image_get_width (image) - new_width) ||
offy > (pika_image_get_height (image) - new_height))
success = FALSE;
else
pika_image_crop (image, context, PIKA_FILL_TRANSPARENT,
offx, offy, new_width, new_height,
TRUE);
}
CODE
);
}
sub image_flip {
$blurb = 'Flips the image horizontally or vertically.';
$help = <<'HELP';
This procedure flips (mirrors) the image.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'flip_type',
type => 'enum PikaOrientationType (no PIKA_ORIENTATION_UNKNOWN)',
desc => 'Type of flip' }
);
%invoke = (
headers => [ qw("core/pikaimage-flip.h") ],
code => <<'CODE'
{
pika_image_flip (image, context, flip_type, NULL);
}
CODE
);
}
sub image_rotate {
$blurb = 'Rotates the image by the specified degrees.';
$help = 'This procedure rotates the image.';
&mitch_pdb_misc('2003');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'rotate_type', type => 'enum PikaRotationType',
desc => 'Angle of rotation' }
);
%invoke = (
headers => [ qw("core/pikaimage-rotate.h") ],
code => <<'CODE'
{
if (progress)
pika_progress_start (progress, FALSE, _("Rotating"));
pika_image_rotate (image, context, rotate_type, progress);
if (progress)
pika_progress_end (progress);
}
CODE
);
}
@headers = qw("core/pikaprogress.h"
"pikapdbcontext.h"
"pika-intl.h");
@procs = qw(image_resize image_resize_to_layers
image_scale
image_crop image_flip image_rotate);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Image Transform';
$doc_title = 'pikaimagetransform';
$doc_short_desc = 'Transformations on images.';
$doc_long_desc = 'Operations to scale, resize, crop, flip and rotate images.';
1;

306
pdb/groups/image_undo.pdb Normal file
View File

@ -0,0 +1,306 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub image_undo_group_start {
$blurb = 'Starts a group undo.';
$help = <<'HELP';
This function is used to start a group undo--necessary for logically combining
two or more undo operations into a single operation. This call must be used in
conjunction with a pika_image_undo_group_end() call.
HELP
&std_pdb_misc;
$date = '1997';
@inargs = (
{ name => 'image', type => 'image',
desc => 'The ID of the image in which to open an undo group' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
const gchar *undo_desc = NULL;
if (plug_in)
{
success = pika_plug_in_cleanup_undo_group_start (plug_in, image);
if (success)
undo_desc = pika_plug_in_get_undo_desc (plug_in);
}
if (success)
pika_image_undo_group_start (image, PIKA_UNDO_GROUP_MISC, undo_desc);
}
CODE
);
}
sub image_undo_group_end {
$blurb = 'Finish a group undo.';
$help = <<'HELP';
This function must be called once for each pika_image_undo_group_start() call
that is made.
HELP
&std_pdb_misc;
$date = '1997';
@inargs = (
{ name => 'image', type => 'image',
desc => 'The ID of the image in which to close an undo group' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in)
success = pika_plug_in_cleanup_undo_group_end (plug_in, image);
if (success)
pika_image_undo_group_end (image);
}
CODE
);
}
sub image_undo_is_enabled {
$blurb = "Check if the image's undo stack is enabled.";
$help = <<'HELP';
This procedure checks if the image's undo stack is currently enabled or
disabled. This is useful when several plug-ins or scripts call each other
and want to check if their caller has already used pika_image_undo_disable()
or pika_image_undo_freeze().
HELP
&raphael_pdb_misc('1999');
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'enabled', type => 'boolean',
desc => 'TRUE if undo is enabled for this image' }
);
%invoke = (
code => <<'CODE'
{
enabled = pika_image_undo_is_enabled (image);
}
CODE
);
}
sub image_undo_disable {
$blurb = "Disable the image's undo stack.";
$help = <<'HELP';
This procedure disables the image's undo stack, allowing subsequent operations
to ignore their undo steps. This is generally called in conjunction with
pika_image_undo_enable() to temporarily disable an image undo stack. This is
advantageous because saving undo steps can be time and memory intensive.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'disabled', type => 'boolean',
desc => 'TRUE if the image undo has been disabled' }
);
%invoke = (
code => <<'CODE'
{
#if 0
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in)
success = pika_plug_in_cleanup_undo_disable (plug_in, image);
#endif
if (success)
disabled = pika_image_undo_disable (image);
}
CODE
);
}
sub image_undo_enable {
$blurb = "Enable the image's undo stack.";
$help = <<'HELP';
This procedure enables the image's undo stack, allowing subsequent operations
to store their undo steps. This is generally called in conjunction with
pika_image_undo_disable() to temporarily disable an image undo stack.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'enabled', type => 'boolean',
desc => 'TRUE if the image undo has been enabled' }
);
%invoke = (
code => <<'CODE'
{
#if 0
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in)
success = pika_plug_in_cleanup_undo_enable (plug_in, image);
#endif
if (success)
enabled = pika_image_undo_enable (image);
}
CODE
);
}
sub image_undo_freeze {
$blurb = "Freeze the image's undo stack.";
&adam_pdb_misc('1999');
$help = <<'HELP';
This procedure freezes the image's undo stack, allowing subsequent
operations to ignore their undo steps. This is generally called in
conjunction with pika_image_undo_thaw() to temporarily disable an
image undo stack. This is advantageous because saving undo steps can
be time and memory intensive. pika_image_undo_freeze() /
pika_image_undo_thaw() and pika_image_undo_disable() /
pika_image_undo_enable() differ in that the former does not free up
all undo steps when undo is thawed, so is more suited to interactive
in-situ previews. It is important in this case that the image is back
to the same state it was frozen in before thawing, else 'undo'
behavior is undefined.
HELP
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'frozen', type => 'boolean',
desc => 'TRUE if the image undo has been frozen' }
);
%invoke = (
code => <<'CODE'
{
#if 0
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in)
success = pika_plug_in_cleanup_undo_freeze (plug_in, image);
#endif
if (success)
frozen = pika_image_undo_freeze (image);
}
CODE
);
}
sub image_undo_thaw {
$blurb = "Thaw the image's undo stack.";
&adam_pdb_misc('1999');
$help = <<'HELP';
This procedure thaws the image's undo stack, allowing subsequent
operations to store their undo steps. This is generally called in
conjunction with pika_image_undo_freeze() to temporarily freeze an
image undo stack. pika_image_undo_thaw() does NOT free the undo stack
as pika_image_undo_enable() does, so is suited for situations where
one wishes to leave the undo stack in the same state in which one
found it despite non-destructively playing with the image in the
meantime. An example would be in-situ plug-in previews. Balancing
freezes and thaws and ensuring image consistency is the responsibility
of the caller.
HELP
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'thawed', type => 'boolean',
desc => 'TRUE if the image undo has been thawed' }
);
%invoke = (
code => <<'CODE'
{
#if 0
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in)
success = pika_plug_in_cleanup_undo_thaw (plug_in, image);
#endif
if (success)
thawed = pika_image_undo_thaw (image);
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pikaimage-undo.h"
"plug-in/pikaplugin.h"
"plug-in/pikaplugin-cleanup.h"
"plug-in/pikapluginmanager.h");
@procs = qw(image_undo_group_start image_undo_group_end
image_undo_is_enabled
image_undo_disable image_undo_enable
image_undo_freeze image_undo_thaw);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Image Undo';
$doc_title = 'pikaimageundo';
$doc_short_desc = 'Control of image undo/redo.';
$doc_long_desc = 'Control of image undo/redo.';
1;

1020
pdb/groups/item.pdb Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,833 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
# Item Transformations
# shortcuts
sub transform_invoke {
my ($progress_text, $assemble_matrix, $check) = @_;
my $success_check = <<"CODE";
success = pika_pdb_item_is_attached (item, NULL,
PIKA_PDB_ITEM_CONTENT |
PIKA_PDB_ITEM_POSITION, error);
CODE
if ($check) {
$success_check = <<"CODE"
success = (pika_pdb_item_is_attached (item, NULL,
PIKA_PDB_ITEM_CONTENT |
PIKA_PDB_ITEM_POSITION, error) &&
$check);
CODE
}
%invoke = (
code => <<"CODE"
{
gint x, y, width, height;
$success_check
if (success &&
pika_item_mask_intersect (item, &x, &y, &width, &height))
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
PikaImage *image = pika_item_get_image (item);
PikaChannel *mask = pika_image_get_mask (image);
PikaMatrix3 matrix;
gint off_x, off_y;
pika_item_get_offset (item, &off_x, &off_y);
x += off_x;
y += off_y;
/* Assemble the transformation matrix */
$assemble_matrix
if (progress)
pika_progress_start (progress, FALSE, _(\"$progress_text\"));
if (PIKA_IS_DRAWABLE (item) &&
item != PIKA_ITEM (mask) &&
! pika_viewable_get_children (PIKA_VIEWABLE (item)) &&
! pika_channel_is_empty (mask))
{
PikaDrawable *drawable;
drawable = pika_drawable_transform_affine (PIKA_DRAWABLE (item),
context, &matrix,
pdb_context->transform_direction,
pdb_context->interpolation,
pdb_context->transform_resize,
progress);
if (drawable)
item = PIKA_ITEM (drawable);
else
success = FALSE;
}
else
{
pika_item_transform (item, context, &matrix,
pdb_context->transform_direction,
pdb_context->interpolation,
pika_item_get_clip (
item, pdb_context->transform_resize),
progress);
}
if (progress)
pika_progress_end (progress);
}
}
CODE
)
}
# The defs
sub item_transform_translate {
$blurb = 'Translate the item by the specified offsets.';
$help = <<'HELP';
This procedure translates the item by the amounts specified in the
off_x and off_y arguments. These can be negative, and are considered
offsets from the current position. The offsets will be rounded to the
nearest pixel unless the item is a path.
HELP
&mitch_pdb_misc('2018', '2.10');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The item' },
{ name => 'off_x', type => 'float',
desc => "Offset in x direction" },
{ name => 'off_y', type => 'float',
desc => "Offset in y direction" }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The translated item' }
);
%invoke = (
code => <<'CODE'
{
if (pika_pdb_item_is_modifiable (item,
PIKA_PDB_ITEM_POSITION, error))
pika_item_translate (item, off_x, off_y, TRUE);
else
success = FALSE;
}
CODE
);
}
sub item_transform_flip_simple {
$blurb = <<'BLURB';
Flip the specified item either vertically or horizontally.
BLURB
$help = <<'HELP';
This procedure flips the specified item.
If a selection exists and the item is a drawable, the portion of the
drawable which lies under the selection is cut from the drawable and
made into a floating selection which is then flipped. If auto_center
is set to TRUE, the flip is around the selection's center. Otherwise,
the coordinate of the axis needs to be specified. The return value is
the ID of the flipped floating selection.
If there is no selection or the item is not a drawable, the entire
item will be flipped around its center if auto_center is set to TRUE,
otherwise the coordinate of the axis needs to be specified.
The return value will be equal to the item ID supplied as input.
This procedure is affected by the following context setters:
pika_context_set_transform_resize().
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The affected item' },
{ name => 'flip_type',
type => 'enum PikaOrientationType (no PIKA_ORIENTATION_UNKNOWN)',
desc => 'Type of flip' },
{ name => 'auto_center', type => 'boolean',
desc => 'Whether to automatically position the axis in the selection center' },
{ name => 'axis', type => 'float',
desc => 'coord. of flip axis' }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The flipped item' }
);
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = pika_pdb_item_is_attached (item, NULL,
PIKA_PDB_ITEM_CONTENT |
PIKA_PDB_ITEM_POSITION, error);
if (success &&
pika_item_mask_intersect (item, &x, &y, &width, &height))
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
PikaImage *image = pika_item_get_image (item);
PikaChannel *mask = pika_image_get_mask (image);
gint off_x, off_y;
pika_item_get_offset (item, &off_x, &off_y);
x += off_x;
y += off_y;
pika_transform_get_flip_axis (x, y, width, height,
flip_type, auto_center, &axis);
if (PIKA_IS_DRAWABLE (item) &&
item != PIKA_ITEM (mask) &&
! pika_viewable_get_children (PIKA_VIEWABLE (item)) &&
! pika_channel_is_empty (mask))
{
PikaDrawable *drawable;
drawable = pika_drawable_transform_flip (PIKA_DRAWABLE (item), context,
flip_type, axis,
pdb_context->transform_resize);
if (drawable)
item = PIKA_ITEM (drawable);
else
success = FALSE;
}
else
{
pika_item_flip (item, context,
flip_type, axis,
pika_item_get_clip (
item, pdb_context->transform_resize));
}
}
}
CODE
);
}
sub item_transform_flip {
$blurb = <<'BLURB';
Flip the specified item around a given line.
BLURB
$help = <<'HELP';
This procedure flips the specified item.
If a selection exists and the item is a drawable, the portion of the
drawable which lies under the selection is cut from the drawable and
made into a floating selection which is then flipped. The axis to flip
around is specified by specifying two points from that line. The
return value is the ID of the flipped floating selection.
If there is no selection or the item is not a drawable, the entire
item will be flipped around the specified axis.
The return value will be equal to the item ID supplied as input.
This procedure is affected by the following context setters:
pika_context_set_interpolation(), pika_context_set_transform_direction(),
pika_context_set_transform_resize().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The affected item' },
{ name => 'x0', type => 'float',
desc => 'horz. coord. of one end of axis' },
{ name => 'y0', type => 'float',
desc => 'vert. coord. of one end of axis' },
{ name => 'x1', type => 'float',
desc => 'horz. coord. of other end of axis' },
{ name => 'y1', type => 'float',
desc => 'vert. coord. of other end of axis' }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The flipped item' }
);
transform_invoke ("Flipping", <<CODE);
pika_matrix3_identity (&matrix);
pika_transform_matrix_flip_free (&matrix, x0, y0, x1, y1);
CODE
}
sub item_transform_perspective {
$blurb = <<'BLURB';
Perform a possibly non-affine transformation on the specified item.
BLURB
$help = <<'HELP';
This procedure performs a possibly non-affine transformation on the
specified item by allowing the corners of the original bounding box to
be arbitrarily remapped to any values.
The 4 coordinates specify the new locations of each corner of the
original bounding box. By specifying these values, any affine
transformation (rotation, scaling, translation) can be affected.
Additionally, these values can be specified such that the resulting
transformed item will appear to have been projected via a perspective
transform.
If a selection exists and the item is a drawable, the portion of the
drawable which lies under the selection is cut from the drawable and
made into a floating selection which is then transformed as specified.
The return value is the ID of the transformed floating selection.
If there is no selection or the item is not a drawable, the entire
item will be transformed according to the specified mapping.
The return value will be equal to the item ID supplied as input.
This procedure is affected by the following context setters:
pika_context_set_interpolation(), pika_context_set_transform_direction(),
pika_context_set_transform_resize().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The affected item' },
{ name => 'x0', type => 'float',
desc => 'The new x coordinate of upper-left corner of original
bounding box' },
{ name => 'y0', type => 'float',
desc => 'The new y coordinate of upper-left corner of original
bounding box' },
{ name => 'x1', type => 'float',
desc => 'The new x coordinate of upper-right corner of original
bounding box' },
{ name => 'y1', type => 'float',
desc => 'The new y coordinate of upper-right corner of original
bounding box' },
{ name => 'x2', type => 'float',
desc => 'The new x coordinate of lower-left corner of original
bounding box' },
{ name => 'y2', type => 'float',
desc => 'The new y coordinate of lower-left corner of original
bounding box' },
{ name => 'x3', type => 'float',
desc => 'The new x coordinate of lower-right corner of original
bounding box' },
{ name => 'y3', type => 'float',
desc => 'The new y coordinate of lower-right corner of original
bounding box' }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The transformed item' }
);
transform_invoke ("Perspective", <<CODE);
pika_matrix3_identity (&matrix);
pika_transform_matrix_perspective (&matrix,
x, y, width, height,
x0, y0, x1, y1,
x2, y2, x3, y3);
CODE
}
sub item_transform_rotate_simple {
$blurb = <<'BLURB';
Rotate the specified item about given coordinates through the specified angle.
BLURB
$help = <<'HELP';
This function rotates the specified item.
If a selection exists and the item is a drawable, the portion of the
drawable which lies under the selection is cut from the drawable and
made into a floating selection which is then rotated by the specified
amount. If auto_center is set to TRUE, the rotation is around the
selection's center. Otherwise, the coordinate of the center point
needs to be specified. The return value is the ID of the rotated
floating selection.
If there is no selection or the item is not a drawable, the entire
item will be rotated around its center if auto_center is set to TRUE,
otherwise the coordinate of the center point needs to be specified.
The return value will be equal to the item ID supplied as input.
This procedure is affected by the following context setters:
pika_context_set_transform_resize().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The affected item' },
{ name => 'rotate_type', type => 'enum PikaRotationType',
desc => 'Type of rotation' },
{ name => 'auto_center', type => 'boolean',
desc => 'Whether to automatically rotate around the selection center' },
{ name => 'center_x', type => 'float',
desc => 'The hor. coordinate of the center of rotation' },
{ name => 'center_y', type => 'float',
desc => 'The vert. coordinate of the center of rotation' }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The rotated item' }
);
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = pika_pdb_item_is_attached (item, NULL,
PIKA_PDB_ITEM_CONTENT |
PIKA_PDB_ITEM_POSITION, error);
if (success &&
pika_item_mask_intersect (item, &x, &y, &width, &height))
{
PikaPDBContext *pdb_context = PIKA_PDB_CONTEXT (context);
PikaImage *image = pika_item_get_image (item);
PikaChannel *mask = pika_image_get_mask (image);
gint off_x, off_y;
pika_item_get_offset (item, &off_x, &off_y);
x += off_x;
y += off_y;
pika_transform_get_rotate_center (x, y, width, height,
auto_center, &center_x, &center_y);
if (PIKA_IS_DRAWABLE (item) &&
item != PIKA_ITEM (mask) &&
! pika_viewable_get_children (PIKA_VIEWABLE (item)) &&
! pika_channel_is_empty (mask))
{
PikaDrawable *drawable;
drawable = pika_drawable_transform_rotate (PIKA_DRAWABLE (item),
context,
rotate_type,
center_x, center_y,
pdb_context->transform_resize);
if (drawable)
item = PIKA_ITEM (drawable);
else
success = FALSE;
}
else
{
pika_item_rotate (item, context,
rotate_type,
center_x, center_y,
pika_item_get_clip (
item, pdb_context->transform_resize));
}
}
}
CODE
);
}
sub item_transform_rotate {
$blurb = <<'BLURB';
Rotate the specified item about given coordinates through the
specified angle.
BLURB
$help = <<'HELP';
This function rotates the specified item.
If a selection exists and the item is a drawable, the portion of the
drawable which lies under the selection is cut from the drawable and
made into a floating selection which is then rotated by the specified
amount. If auto_center is set to TRUE, the rotation is around the
selection's center. Otherwise, the coordinate of the center point
needs to be specified. The return value is the ID of the rotated
floating selection.
If there is no selection or the item is not a drawable, the entire
item will be rotated around its center if auto_center is set to TRUE,
otherwise the coordinate of the center point needs to be specified.
The return value will be equal to the item ID supplied as input.
This procedure is affected by the following context setters:
pika_context_set_interpolation(), pika_context_set_transform_direction(),
pika_context_set_transform_resize().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The affected item' },
{ name => 'angle', type => 'float',
desc => 'The angle of rotation (radians)' },
{ name => 'auto_center', type => 'boolean',
desc => 'Whether to automatically rotate around the selection center' },
{ name => 'center_x', type => 'float',
desc => 'The hor. coordinate of the center of rotation' },
{ name => 'center_y', type => 'float',
desc => 'The vert. coordinate of the center of rotation' }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The rotated item' }
);
transform_invoke ("Rotating", <<CODE);
pika_matrix3_identity (&matrix);
if (auto_center)
pika_transform_matrix_rotate_rect (&matrix,
x, y, width, height, angle);
else
pika_transform_matrix_rotate_center (&matrix,
center_x, center_y, angle);
CODE
}
sub item_transform_scale {
$blurb = 'Scale the specified item.';
$help = <<'HELP';
This procedure scales the specified item.
The 2 coordinates specify the new locations of the top-left and
bottom-roght corners of the original bounding box.
If a selection exists and the item is a drawable, the portion of the
drawable which lies under the selection is cut from the drawable and
made into a floating selection which is then scaled as specified. The
return value is the ID of the scaled floating selection.
If there is no selection or the item is not a drawable, the entire
item will be scaled according to the specified coordinates.
The return value will be equal to the item ID supplied as input.
This procedure is affected by the following context setters:
pika_context_set_interpolation(), pika_context_set_transform_direction(),
pika_context_set_transform_resize().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The affected item' },
{ name => 'x0', type => 'float',
desc => 'The new x coordinate of the upper-left corner of the
scaled region' },
{ name => 'y0', type => 'float',
desc => 'The new y coordinate of the upper-left corner of the
scaled region' },
{ name => 'x1', type => 'float',
desc => 'The new x coordinate of the lower-right corner of the
scaled region' },
{ name => 'y1', type => 'float',
desc => 'The new y coordinate of the lower-right corner of the
scaled region' }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The scaled item' }
);
transform_invoke ("Scaling", <<CODE, 'x0 < x1 && y0 < y1');
pika_matrix3_identity (&matrix);
pika_transform_matrix_scale (&matrix,
x, y, width, height,
x0, y0, x1 - x0, y1 - y0);
CODE
}
sub item_transform_shear {
$blurb = <<'BLURB';
Shear the specified item about its center by the specified magnitude.
BLURB
$help = <<'HELP';
This procedure shears the specified item.
The shear type parameter indicates whether the shear will be applied
horizontally or vertically. The magnitude can be either positive or
negative and indicates the extent (in pixels) to shear by.
If a selection exists and the item is a drawable, the portion of the
drawable which lies under the selection is cut from the drawable and
made into a floating selection which is then sheared as specified.
The return value is the ID of the sheared floating selection.
If there is no selection or the item is not a drawable, the entire
item will be sheared according to the specified parameters.
The return value will be equal to the item ID supplied as input.
This procedure is affected by the following context setters:
pika_context_set_interpolation(), pika_context_set_transform_direction(),
pika_context_set_transform_resize().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The affected item' },
{ name => 'shear_type',
type => 'enum PikaOrientationType (no PIKA_ORIENTATION_UNKNOWN)',
desc => 'Type of shear' },
{ name => 'magnitude', type => 'float',
desc => 'The magnitude of the shear' }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The sheared item' }
);
transform_invoke ("Shearing", <<CODE);
pika_matrix3_identity (&matrix);
pika_transform_matrix_shear (&matrix,
x, y, width, height,
shear_type, magnitude);
CODE
}
sub item_transform_2d {
$blurb = 'Transform the specified item in 2d.';
$help = <<'HELP';
This procedure transforms the specified item.
The transformation is done by scaling by the x and y scale factors
about the point (source_x, source_y), then rotating around the same
point, then translating that point to the new position (dest_x,
dest_y).
If a selection exists and the item is a drawable, the portion of the
drawable which lies under the selection is cut from the drawable and
made into a floating selection which is then transformed as specified.
The return value is the ID of the transformed floating selection.
If there is no selection or the item is not a drawable, the entire
item will be transformed according to the specified parameters.
The return value will be equal to the item ID supplied as input.
This procedure is affected by the following context setters:
pika_context_set_interpolation(), pika_context_set_transform_direction(),
pika_context_set_transform_resize().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The affected item' },
{ name => 'source_x', type => 'float',
desc => 'X coordinate of the transformation center' },
{ name => 'source_y', type => 'float',
desc => 'Y coordinate of the transformation center' },
{ name => 'scale_x', type => 'float',
desc => 'Amount to scale in x direction' },
{ name => 'scale_y', type => 'float',
desc => 'Amount to scale in y direction' },
{ name => 'angle', type => 'float',
desc => 'The angle of rotation (radians)' },
{ name => 'dest_x', type => 'float',
desc => 'X coordinate of where the center goes' },
{ name => 'dest_y', type => 'float',
desc => 'Y coordinate of where the center goes' }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The transformed item' }
);
transform_invoke ("2D Transform", <<CODE);
pika_matrix3_identity (&matrix);
pika_matrix3_translate (&matrix, -source_x, -source_y);
pika_matrix3_scale (&matrix, scale_x, scale_y);
pika_matrix3_rotate (&matrix, angle);
pika_matrix3_translate (&matrix, dest_x, dest_y);
CODE
}
sub item_transform_matrix {
$blurb = 'Transform the specified item in 2d.';
$help = <<'HELP';
This procedure transforms the specified item.
The transformation is done by assembling a 3x3 matrix from the
coefficients passed.
If a selection exists and the item is a drawable, the portion of the
drawable which lies under the selection is cut from the drawable and
made into a floating selection which is then transformed as specified.
The return value is the ID of the transformed floating selection.
If there is no selection or the item is not a drawable, the entire
item will be transformed according to the specified matrix.
The return value will be equal to the item ID supplied as input.
This procedure is affected by the following context setters:
pika_context_set_interpolation(), pika_context_set_transform_direction(),
pika_context_set_transform_resize().
HELP
&mitch_pdb_misc('2010', '2.8');
@inargs = (
{ name => 'item', type => 'item',
desc => 'The affected item' },
{ name => 'coeff_0_0', type => 'float',
desc => 'coefficient (0,0) of the transformation matrix' },
{ name => 'coeff_0_1', type => 'float',
desc => 'coefficient (0,1) of the transformation matrix' },
{ name => 'coeff_0_2', type => 'float',
desc => 'coefficient (0,2) of the transformation matrix' },
{ name => 'coeff_1_0', type => 'float',
desc => 'coefficient (1,0) of the transformation matrix' },
{ name => 'coeff_1_1', type => 'float',
desc => 'coefficient (1,1) of the transformation matrix' },
{ name => 'coeff_1_2', type => 'float',
desc => 'coefficient (1,2) of the transformation matrix' },
{ name => 'coeff_2_0', type => 'float',
desc => 'coefficient (2,0) of the transformation matrix' },
{ name => 'coeff_2_1', type => 'float',
desc => 'coefficient (2,1) of the transformation matrix' },
{ name => 'coeff_2_2', type => 'float',
desc => 'coefficient (2,2) of the transformation matrix' }
);
@outargs = (
{ name => 'item', type => 'item', no_declare => 1,
desc => 'The transformed item' }
);
transform_invoke ("2D Transforming", <<CODE);
matrix.coeff[0][0] = coeff_0_0;
matrix.coeff[0][1] = coeff_0_1;
matrix.coeff[0][2] = coeff_0_2;
matrix.coeff[1][0] = coeff_1_0;
matrix.coeff[1][1] = coeff_1_1;
matrix.coeff[1][2] = coeff_1_2;
matrix.coeff[2][0] = coeff_2_0;
matrix.coeff[2][1] = coeff_2_1;
matrix.coeff[2][2] = coeff_2_2;
CODE
}
@headers = qw("libpikamath/pikamath.h"
"core/pika-transform-utils.h"
"core/pikachannel.h"
"core/pikadrawable.h"
"core/pikadrawable-transform.h"
"core/pikaimage.h"
"core/pikaprogress.h"
"pikapdb-utils.h"
"pikapdbcontext.h"
"pika-intl.h");
@procs = qw(item_transform_translate
item_transform_flip_simple
item_transform_flip
item_transform_perspective
item_transform_rotate_simple
item_transform_rotate
item_transform_scale
item_transform_shear
item_transform_2d
item_transform_matrix);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Transformation procedures';
$doc_title = 'pikaitemtransform';
$doc_short_desc = 'Functions to perform transformations on items.';
$doc_long_desc = 'Functions to perform transformations on items.';
1;

1328
pdb/groups/layer.pdb Normal file

File diff suppressed because it is too large Load Diff

116
pdb/groups/message.pdb Normal file
View File

@ -0,0 +1,116 @@
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1998-1999 Manish Singh
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub message {
$blurb = 'Displays a dialog box with a message.';
$help = <<'HELP';
Displays a dialog box with a message. Useful for status or error reporting.
The message must be in UTF-8 encoding.
HELP
&yosh_pdb_misc('1998');
@inargs = (
{ name => 'message', type => 'string',
desc => 'Message to display in the dialog' }
);
%invoke = (
code => <<'CODE'
{
const gchar *domain = NULL;
if (pika->plug_in_manager->current_plug_in)
domain = pika_plug_in_get_undo_desc (pika->plug_in_manager->current_plug_in);
pika_show_message (pika, G_OBJECT (progress), PIKA_MESSAGE_WARNING,
domain, message);
}
CODE
);
}
sub message_get_handler {
$blurb = <<'BLURB';
Returns the current state of where warning messages are displayed.
BLURB
$help = <<'HELP';
This procedure returns the way g_message warnings are displayed. They can be
shown in a dialog box or printed on the console where pika was started.
HELP
&yosh_pdb_misc('1998');
@outargs = (
{ name => 'handler', type => 'enum PikaMessageHandlerType',
desc => 'The current handler type' }
);
%invoke = (
code => <<'CODE'
{
handler = pika->message_handler;
}
CODE
);
}
sub message_set_handler {
$blurb = 'Controls where warning messages are displayed.';
$help = <<'HELP';
This procedure controls how g_message warnings are displayed. They can be shown
in a dialog box or printed on the console where pika was started.
HELP
&yosh_pdb_misc('1998');
@inargs = (
{ name => 'handler', type => 'enum PikaMessageHandlerType',
desc => 'The new handler type' }
);
%invoke = (
code => <<'CODE'
{
pika->message_handler = handler;
}
CODE
);
}
@headers = qw(<string.h>
"core/pika.h"
"plug-in/pikaplugin.h"
"plug-in/pikapluginmanager.h"
"pika-intl.h");
@procs = qw(message
message_get_handler
message_set_handler);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Message procedures';
$doc_title = 'pikamessage';
$doc_short_desc = 'Display a dialog box with a message.';
$doc_long_desc = 'Display a dialog box with a message.';
1;

1082
pdb/groups/paint_tools.pdb Normal file

File diff suppressed because it is too large Load Diff

442
pdb/groups/palette.pdb Normal file
View File

@ -0,0 +1,442 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
# The invoke code is compiled on the app side.
# The invoke code must assign to each result var
$palette_arg_spec = { name => 'palette', type => 'palette', non_empty => 1,
desc => 'The palette' };
sub palette_new {
$blurb = "Creates a new palette";
$help = <<'HELP';
Creates a new palette.
The new palette has no color entries.
You must add color entries for a user to choose.
The actual name might be different than the requested name,
when the requested name is already in use.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The requested name of the new palette' }
);
@outargs = (
${palette_arg_spec}
);
%invoke = (
code => <<'CODE'
{
palette = (PikaPalette*) pika_data_factory_data_new (pika->palette_factory,
context, name);
}
CODE
);
}
sub palette_get_by_name {
$blurb = "Returns the palette with the given name.";
$help = "Returns the palette with the given name.";
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The name of the palette' }
);
@outargs = (
{ name => 'palette', type => 'palette', non_empty => 1,
desc => 'The palette' }
);
%invoke = (
code => <<'CODE'
{
palette = PIKA_PALETTE (pika_pdb_get_resource (pika, PIKA_TYPE_PALETTE, name,
PIKA_PDB_DATA_ACCESS_READ, error));
if (! palette)
success = FALSE;
}
CODE
);
}
sub palette_get_color_count {
$blurb = 'Get the count of colors in the palette.';
$help = 'Returns the number of colors in the palette.';
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${palette_arg_spec}
);
@outargs = (
{ name => 'num_colors', type => 'int32',
desc => 'The number of colors in the palette' }
);
%invoke = (
code => <<'CODE'
{
num_colors = pika_palette_get_n_colors (palette);
}
CODE
);
}
sub palette_get_colors {
$blurb = 'Gets colors in the palette.';
$help = "Returns an array of colors in the palette.";
&neo_pdb_misc('2006', '2.6');
@inargs = (
${palette_arg_spec}
);
@outargs = (
{ name => 'colors', type => 'colorarray',
desc => 'The colors in the palette',
array => { name => 'num_colors',
desc => 'Length of the colors array' } }
);
%invoke = (
code => <<'CODE'
{
GList *list = pika_palette_get_colors (palette);
gint i;
num_colors = pika_palette_get_n_colors (palette);
colors = g_new (PikaRGB, num_colors);
for (i = 0; i < num_colors; i++, list = g_list_next (list))
{
PikaPaletteEntry *entry = list->data;
colors[i] = entry->color;
}
}
CODE
);
}
sub palette_get_columns {
$blurb = "Gets the number of columns used to display the palette";
$help = "Gets the preferred number of columns to display the palette.";
&neo_pdb_misc('2005', '2.4');
@inargs = (
${palette_arg_spec}
);
@outargs = (
{ name => 'num_columns', type => 'int32',
desc => "The number of columns used to display this palette" }
);
%invoke = (
code => <<'CODE'
{
num_columns = pika_palette_get_columns (palette);
}
CODE
);
}
sub palette_set_columns {
$blurb = "Sets the number of columns used to display the palette";
$help = <<'HELP';
Set the number of colors shown per row when the palette is displayed.
Returns an error when the palette is not editable.
The maximum allowed value is 64.
HELP
&neo_pdb_misc('2005', '2.4');
@inargs = (
${palette_arg_spec},
{ name => 'columns', type => '0 <= int32 <= 64',
desc => "The new number of columns" }
);
%invoke = (
code => <<'CODE'
{
if (pika_data_is_writable (PIKA_DATA (palette)))
pika_palette_set_columns (palette, columns);
else
success = FALSE;
}
CODE
);
}
# FIXME null_ok should allow None in Python for name, but fails.
sub palette_add_entry {
$blurb = 'Appends an entry to the palette.';
$help = <<'HELP';
Appends an entry to the palette.
Neither color nor name must be unique within the palette.
When name is the empty string, this sets the entry name to "Untitled".
Returns the index of the entry.
Returns an error when palette is not editable.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${palette_arg_spec},
{ name => 'entry_name', type => 'string', null_ok => 1,
desc => 'A name for the entry' },
{ name => 'color', type => 'color',
desc => 'The color for the added entry.' }
);
@outargs = (
{ name => 'entry_num', type => 'int32', void_ret => 1,
desc => 'The index of the added entry' }
);
%invoke = (
code => <<'CODE'
{
/* Must check writeable here, because add_entry does not fail when not writeable. */
if (pika_data_is_writable (PIKA_DATA (palette)))
{
/* -1 for the index means append. */
PikaPaletteEntry *entry = pika_palette_add_entry (palette, -1, entry_name, &color);
entry_num = pika_palette_get_entry_position (palette, entry);
}
else
{
success = FALSE;
}
}
CODE
);
}
sub palette_delete_entry {
$blurb = 'Deletes an entry from the palette.';
$help = <<'HELP';
Deletes an entry from the palette.
Returns an error if the index is out or range.
Returns an error if the palette is not editable.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The index of the entry to delete' }
);
%invoke = (
code => <<'CODE'
{
if (pika_data_is_writable (PIKA_DATA (palette)))
{
PikaPaletteEntry *entry = pika_palette_get_entry (palette, entry_num);
if (entry)
pika_palette_delete_entry (palette, entry);
else
success = FALSE;
}
else
success = FALSE;
}
CODE
);
}
sub palette_entry_get_color {
$blurb = 'Gets the color of an entry in the palette.';
$help = <<'HELP';
Returns the color of the entry at the given zero-based index into the palette.
Returns an error when the index is out of range.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The index of the entry to get the color of.' }
);
@outargs = (
{ name => 'color', type => 'color', void_ret => 1,
desc => 'The color at the index.' }
);
%invoke = (
code => <<'CODE'
{
PikaPaletteEntry *entry = pika_palette_get_entry (palette, entry_num);
if (entry)
color = entry->color;
else
success = FALSE;
}
CODE
);
}
sub palette_entry_set_color {
$blurb = 'Sets the color of an entry in the palette.';
$help = <<'HELP';
Sets the color of the entry at the zero-based index into the palette.
Returns an error when the index is out of range.
Returns an error when the palette is not editable.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The entry to get' },
{ name => 'color', type => 'color',
desc => 'The new color' }
);
%invoke = (
code => <<'CODE'
{
if (pika_data_is_writable (PIKA_DATA (palette)))
success = pika_palette_set_entry_color (palette, entry_num, &color);
else
success = FALSE;
}
CODE
);
}
sub palette_entry_get_name {
$blurb = 'Gets the name of an entry in the palette.';
$help = <<'HELP';
Gets the name of the entry at the zero-based index into the palette.
Returns an error when the index is out of range.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The entry to get' }
);
@outargs = (
{ name => 'entry_name', type => 'string', void_ret => 1,
desc => 'The name of the entry.' }
);
%invoke = (
code => <<'CODE'
{
PikaPaletteEntry *entry = pika_palette_get_entry (palette, entry_num);
if (entry)
entry_name = g_strdup (entry->name);
else
success = FALSE;
}
CODE
);
}
sub palette_entry_set_name {
$blurb = 'Sets the name of an entry in the palette.';
$help = <<'HELP';
Sets the name of the entry at the zero-based index into the palette.
Returns an error if the index is out or range.
Returns an error if the palette is not editable.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The entry to get' },
{ name => 'entry_name', type => 'string', null_ok => 1,
desc => 'The new name' }
);
%invoke = (
code => <<'CODE'
{
if (pika_data_is_writable (PIKA_DATA (palette)))
success = pika_palette_set_entry_name (palette, entry_num, entry_name);
else
success = FALSE;
}
CODE
);
}
@headers = qw(<string.h>
"core/pika.h"
"core/pikacontext.h"
"core/pikadatafactory.h"
"core/pikapalette.h"
"pikapdb-utils.h");
@procs = qw(palette_new
palette_get_by_name
palette_get_color_count
palette_get_colors
palette_get_columns palette_set_columns
palette_add_entry palette_delete_entry
palette_entry_get_color palette_entry_set_color
palette_entry_get_name palette_entry_set_name);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Palette';
$doc_title = 'pikapalette';
$doc_short_desc = 'Installable object, a small set of colors a user can choose from.';
$doc_long_desc = 'Installable object, a small set of colors a user can choose from.';
1;

View File

@ -0,0 +1,115 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub palettes_popup {
$blurb = 'Invokes the Pika palette selection dialog.';
$help = 'Opens a dialog letting a user choose a palette.';
&mitch_pdb_misc('2002');
@inargs = (
{ name => 'palette_callback', type => 'string', non_empty => 1,
desc => 'The callback PDB proc to call when user chooses a palette' },
{ name => 'popup_title', type => 'string',
desc => 'Title of the palette selection dialog' },
{ name => 'initial_palette_name', type => 'string', null_ok => 1,
desc => 'The name of the palette to set as the initial choice.' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, palette_callback) ||
! pika_pdb_dialog_new (pika, context, progress,
pika_data_factory_get_container (pika->palette_factory),
popup_title, palette_callback, initial_palette_name,
NULL))
success = FALSE;
}
CODE
);
}
sub palettes_close_popup {
$blurb = 'Close the palette selection dialog.';
$help = 'Closes an open palette selection dialog.';
&mitch_pdb_misc('2002');
@inargs = (
{ name => 'palette_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this pop-up' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, palette_callback) ||
! pika_pdb_dialog_close (pika, pika_data_factory_get_container (pika->palette_factory),
palette_callback))
success = FALSE;
}
CODE
);
}
sub palettes_set_popup {
$blurb = 'Sets the current palette in a palette selection dialog.';
$help = $blurb;
&mitch_pdb_misc('2002');
@inargs = (
{ name => 'palette_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this pop-up' },
{ name => 'palette_name', type => 'string',
desc => 'The name of the palette to set as selected' },
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, palette_callback) ||
! pika_pdb_dialog_set (pika, pika_data_factory_get_container (pika->palette_factory),
palette_callback, palette_name,
NULL))
success = FALSE;
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pikadatafactory.h");
@procs = qw(palettes_popup
palettes_close_popup
palettes_set_popup);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Palette UI';
$doc_title = 'pikapaletteselect';
$doc_short_desc = 'Methods of a palette chooser dialog';
$doc_long_desc = 'A dialog letting a user choose a palette. Read more at pikafontselect.';
1;

87
pdb/groups/palettes.pdb Normal file
View File

@ -0,0 +1,87 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub palettes_refresh {
$blurb = 'Refreshes current palettes. This function always succeeds.';
$help = <<'HELP';
This procedure retrieves all palettes currently in the user's palette path
and updates the palette dialogs accordingly.
HELP
&adrian_pdb_misc('1998');
%invoke = (
code => <<'CODE'
{
pika_data_factory_data_refresh (pika->palette_factory, context);
}
CODE
);
}
sub palettes_get_list {
$blurb = 'Retrieves a list of all of the available palettes';
$help = <<'HELP';
This procedure returns a complete listing of available palettes. Each name
returned can be used as input to the command pika_context_set_palette().
HELP
&rock_pdb_misc('2001');
@inargs = (
{ name => 'filter', type => 'string', null_ok => 1,
desc => 'An optional regular expression used to filter the list' }
);
@outargs = (
{ name => 'palette_list', type => 'strv',
desc => 'The list of palette names' }
);
%invoke = (
headers => [ qw("core/pikacontainer-filter.h") ],
code => <<'CODE'
{
palette_list = pika_container_get_filtered_name_array (pika_data_factory_get_container (pika->palette_factory),
filter);
}
CODE
);
}
@headers = qw(<string.h>
"core/pika.h"
"core/pikacontext.h"
"core/pikadatafactory.h"
"core/pikapalette.h"
"pikapdb-utils.h");
@procs = qw(palettes_refresh
palettes_get_list);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Palettes';
$doc_title = 'pikapalettes';
$doc_short_desc = 'Operations related to palettes.';
$doc_long_desc = 'Operations related to palettes.';
1;

164
pdb/groups/pattern.pdb Normal file
View File

@ -0,0 +1,164 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
# The invoke code is compiled on the app side.
# The invoke code must assign to each result var
$pattern_arg_spec = { name => 'pattern', type => 'pattern', non_empty => 1,
desc => 'The pattern' };
sub pattern_get_by_name {
$blurb = "Returns the pattern with the given name.";
$help = "Returns the pattern with the given name.";
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The name of the pattern' }
);
@outargs = (
{ name => 'pattern', type => 'pattern', non_empty => 1,
desc => 'The pattern' }
);
%invoke = (
code => <<'CODE'
{
pattern = PIKA_PATTERN (pika_pdb_get_resource (pika, PIKA_TYPE_PATTERN, name, PIKA_PDB_DATA_ACCESS_READ, error));
if (! pattern)
success = FALSE;
}
CODE
);
}
sub pattern_get_info {
$blurb = 'Gets information about the pattern.';
$help = <<'HELP';
Gets information about the pattern:
the pattern extents (width and height) and bytes per pixel.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${pattern_arg_spec}
);
@outargs = (
{ name => 'width', type => 'int32', void_ret => 1,
desc => "The pattern width" },
{ name => 'height', type => 'int32',
desc => "The pattern height" },
{ name => 'bpp', type => 'int32',
desc => "The pattern bpp" }
);
%invoke = (
code => <<'CODE'
{
const Babl *format;
format = pika_babl_compat_u8_format (
pika_temp_buf_get_format (pattern->mask));
width = pika_temp_buf_get_width (pattern->mask);
height = pika_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
}
CODE
);
}
sub pattern_get_pixels {
$blurb = <<'BLURB';
Gets information about the pattern (including pixels).
BLURB
$help = <<'HELP';
Gets information about the pattern:
the pattern extents (width and height), its bpp, and its pixel data.
The pixel data is an array in C or a list in some languages.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
${pattern_arg_spec}
);
@outargs = (
{ name => 'width', type => 'int32', void_ret => 1,
desc => "The pattern width" },
{ name => 'height', type => 'int32',
desc => "The pattern height" },
{ name => 'bpp', type => 'int32',
desc => "The pattern bpp" },
{ name => 'color_bytes', type => 'bytes',
desc => 'The pattern data.' }
);
%invoke = (
code => <<'CODE'
{
const Babl *format;
gpointer data;
format = pika_babl_compat_u8_format (
pika_temp_buf_get_format (pattern->mask));
data = pika_temp_buf_lock (pattern->mask, format, GEGL_ACCESS_READ);
width = pika_temp_buf_get_width (pattern->mask);
height = pika_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
color_bytes = g_bytes_new (data, pika_temp_buf_get_data_size (pattern->mask));
pika_temp_buf_unlock (pattern->mask, data);
}
CODE
);
}
@headers = qw(<string.h>
"gegl/pika-babl-compat.h"
"core/pikacontext.h"
"core/pikadatafactory.h"
"core/pikapattern.h"
"core/pikatempbuf.h"
"pikapdb-utils.h");
@procs = qw(pattern_get_by_name
pattern_get_info
pattern_get_pixels);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Pattern';
$doc_title = 'pikapattern';
$doc_short_desc = 'Installable object used by fill and clone tools.';
$doc_long_desc = 'Installable object used by fill and clone tools.';
1;

View File

@ -0,0 +1,115 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub patterns_popup {
$blurb = 'Invokes the Pika pattern selection.';
$help = 'Opens the pattern selection dialog.';
&andy_pdb_misc('1998');
@inargs = (
{ name => 'pattern_callback', type => 'string', non_empty => 1,
desc => 'The callback PDB proc to call when the user chooses a pattern' },
{ name => 'popup_title', type => 'string',
desc => 'Title of the pattern selection dialog' },
{ name => 'initial_pattern_name', type => 'string', null_ok => 1,
desc => 'The name of the pattern to set as the initial choice' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, pattern_callback) ||
! pika_pdb_dialog_new (pika, context, progress,
pika_data_factory_get_container (pika->pattern_factory),
popup_title, pattern_callback, initial_pattern_name,
NULL))
success = FALSE;
}
CODE
);
}
sub patterns_close_popup {
$blurb = 'Close the pattern selection dialog.';
$help = 'Closes an open pattern selection dialog.';
&andy_pdb_misc('1998');
@inargs = (
{ name => 'pattern_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this pop-up' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, pattern_callback) ||
! pika_pdb_dialog_close (pika, pika_data_factory_get_container (pika->pattern_factory),
pattern_callback))
success = FALSE;
}
CODE
);
}
sub patterns_set_popup {
$blurb = 'Sets the current pattern in a pattern selection dialog.';
$help = $blurb;
&andy_pdb_misc('1998');
@inargs = (
{ name => 'pattern_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this pop-up' },
{ name => 'pattern_name', type => 'string',
desc => 'The name of the pattern to set as selected' }
);
%invoke = (
code => <<'CODE'
{
if (pika->no_interface ||
! pika_pdb_lookup_procedure (pika->pdb, pattern_callback) ||
! pika_pdb_dialog_set (pika, pika_data_factory_get_container (pika->pattern_factory),
pattern_callback, pattern_name,
NULL))
success = FALSE;
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pikadatafactory.h");
@procs = qw(patterns_popup
patterns_close_popup
patterns_set_popup);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Pattern UI';
$doc_title = 'pikapatternselect';
$doc_short_desc = 'Methods of a pattern chooser dialog';
$doc_long_desc = 'A dialog letting a user choose a pattern. Read more at pikafontselect.';
1;

88
pdb/groups/patterns.pdb Normal file
View File

@ -0,0 +1,88 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub patterns_refresh {
$blurb = 'Refresh current patterns. This function always succeeds.';
$help = <<'HELP';
This procedure retrieves all patterns currently in the user's pattern path
and updates all pattern dialogs accordingly.
HELP
&mitch_pdb_misc('2002');
%invoke = (
code => <<'CODE'
{
pika_data_factory_data_refresh (pika->pattern_factory, context);
}
CODE
);
}
sub patterns_get_list {
$blurb = 'Retrieve a complete listing of the available patterns.';
$help = <<'HELP';
This procedure returns a complete listing of available PIKA patterns. Each name
returned can be used as input to the pika_context_set_pattern().
HELP
&std_pdb_misc;
@inargs = (
{ name => 'filter', type => 'string', null_ok => 1,
desc => 'An optional regular expression used to filter the list' }
);
@outargs = (
{ name => 'pattern_list', type => 'strv',
desc => 'The list of pattern names' }
);
%invoke = (
headers => [ qw("core/pikacontainer-filter.h") ],
code => <<'CODE'
{
pattern_list = pika_container_get_filtered_name_array (pika_data_factory_get_container (pika->pattern_factory),
filter);
}
CODE
);
}
@headers = qw(<string.h>
"core/pika.h"
"core/pikacontext.h"
"core/pikadatafactory.h"
"core/pikapattern.h"
"core/pikatempbuf.h"
"pikapdb-utils.h");
@procs = qw(patterns_refresh
patterns_get_list);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Patterns';
$doc_title = 'pikapatterns';
$doc_short_desc = 'Functions relating to patterns.';
$doc_long_desc = 'Functions relating to patterns.';
1;

1410
pdb/groups/pdb.pdb Normal file

File diff suppressed because it is too large Load Diff

247
pdb/groups/pika.pdb Normal file
View File

@ -0,0 +1,247 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub version {
$blurb = 'Returns the host PIKA version.';
$help = <<'HELP';
This procedure returns the version number of the currently running PIKA.
HELP
&yosh_pdb_misc('1999');
@outargs = (
{ name => 'version', type => 'string',
desc => 'PIKA version number' }
);
%invoke = (
headers => [ qw("libpikabase/pikabase.h") ],
code => <<'CODE'
{
version = g_strdup (PIKA_VERSION);
}
CODE
);
}
sub getpid {
$blurb = 'Returns the PID of the host PIKA process.';
$help = <<'HELP';
This procedure returns the process ID of the currently running PIKA.
HELP
&mitch_pdb_misc('2005', '2.4');
@outargs = (
{ name => 'pid', type => 'int32',
desc => 'The PID' }
);
%invoke = (
headers => [ qw("core/pika-utils.h") ],
code => <<'CODE'
{
pid = pika_get_pid ();
}
CODE
);
}
sub quit {
$blurb = 'Causes PIKA to exit gracefully.';
$help = <<'HELP';
If there are unsaved images in an interactive PIKA session, the user
will be asked for confirmation. If force is TRUE, the application is
quit without querying the user to save any dirty images.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'force', type => 'boolean',
desc => 'Force PIKA to quit without asking' }
);
%invoke = (
code => <<'CODE'
{
pika_exit (pika, force);
}
CODE
);
}
sub attach_parasite {
$blurb = 'Add a global parasite.';
$help = <<'HELP';
This procedure attaches a global parasite. It has no return values.
HELP
&jay_pdb_misc('1998', '2.8');
@inargs = (
{ name => 'parasite', type => 'parasite',
desc => 'The parasite to attach' }
);
%invoke = (
code => <<'CODE'
{
if (pika_parasite_validate (pika, parasite, error))
pika_parasite_attach (pika, parasite);
else
success = FALSE;
}
CODE
);
}
sub detach_parasite {
$blurb = 'Removes a global parasite.';
$help = <<'HELP';
This procedure detaches a global parasite from. It has no return values.
HELP
&jay_pdb_misc('1998', '2.8');
@inargs = (
{ name => 'name', type => 'string',
desc => 'The name of the parasite to detach.' }
);
%invoke = (
code => <<'CODE'
{
pika_parasite_detach (pika, name);
}
CODE
);
}
sub get_parasite {
$blurb = 'Look up a global parasite.';
$help = <<'HELP';
Finds and returns the global parasite that was previously attached.
HELP
&jay_pdb_misc('1998', '2.8');
@inargs = (
{ name => 'name', type => 'string',
desc => 'The name of the parasite to find' }
);
@outargs = (
{ name => 'parasite', type => 'parasite',
desc => 'The found parasite' }
);
%invoke = (
code => <<'CODE'
{
parasite = pika_parasite_copy (pika_parasite_find (pika, name));
if (! parasite)
success = FALSE;
}
CODE
);
}
sub get_parasite_list {
$blurb = 'List all parasites.';
$help = 'Returns a list of all currently attached global parasites.';
&marc_pdb_misc('1999', '2.8');
@outargs = (
{ name => 'parasites', type => 'strv',
desc => 'The names of currently attached parasites' }
);
%invoke = (
code => <<'CODE'
{
parasites = pika_parasite_list (pika);
}
CODE
);
}
sub temp_file {
$blurb = 'Generates a unique temporary file.';
$help = <<'HELP';
Generates a unique file using the temp path supplied in the user's pikarc.
HELP
&josh_pdb_misc('1997');
@inargs = (
{ name => 'extension', type => 'string',
allow_non_utf8 => 1, null_ok => 1,
desc => 'The extension the file will have' }
);
@outargs = (
{ name => 'file', type => 'file',
desc => 'The new temp file' }
);
%invoke = (
code => <<'CODE'
{
file = pika_get_temp_file (pika, extension);
}
CODE
);
}
@headers = qw("core/pika.h"
"core/pika-parasites.h");
@procs = qw(version
getpid
quit
attach_parasite
detach_parasite
get_parasite
get_parasite_list
temp_file);
%exports = (app => [@procs], lib => [@procs[0..1,3..7]]);
$desc = 'Pika';
$doc_title = 'pika';
$doc_short_desc = 'Main functions needed for building a PIKA plug-in.';
$doc_long_desc = <<'DESC';
Main functions needed for building a PIKA plug-in.
This header includes all other PIKA Library headers.
Also contains some miscellaneous procedures that don't fit in any
other category.
DESC
1;

237
pdb/groups/pikarc.pdb Normal file
View File

@ -0,0 +1,237 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub pikarc_query {
$blurb = <<'BLURB';
Queries the pikarc file parser for information on a specified token.
BLURB
$help = <<'HELP';
This procedure is used to locate additional information contained in the pikarc
file considered extraneous to the operation of PIKA. Plug-ins that need
configuration information can expect it will be stored in the user pikarc
file and can use this procedure to retrieve it. This query procedure will
return the value associated with the specified token. This corresponds _only_
to entries with the format: (<token> <value>). The value must be a string.
Entries not corresponding to this format will cause warnings to be issued on
pikarc parsing and will not be queryable.
HELP
&std_pdb_misc;
$date = '1997';
@inargs = (
{ name => 'token', type => 'string',
desc => 'The token to query for' }
);
@outargs = (
{ name => 'value', type => 'string',
desc => 'The value associated with the queried token' }
);
%invoke = (
code => <<'CODE'
{
if (strlen (token))
{
/* use edit_config because unknown tokens are set there */
value = pika_rc_query (PIKA_RC (pika->edit_config), token);
if (! value)
success = FALSE;
}
else
success = FALSE;
}
CODE
);
}
sub pikarc_set {
$blurb = 'Sets a pikarc token to a value and saves it in the pikarc.';
$help = <<'HELP';
This procedure is used to add or change additional information in the pikarc
file that is considered extraneous to the operation of PIKA. Plug-ins that
need configuration information can use this function to store it, and
pika_pikarc_query() to retrieve it. This will accept _only_ string values in
UTF-8 encoding.
HELP
&seth_pdb_misc('1999');
@inargs = (
{ name => 'token', type => 'string',
desc => 'The token to add or modify' },
{ name => 'value', type => 'string',
desc => 'The value to set the token to' }
);
%invoke = (
code => <<'CODE'
{
if (strlen (token))
{
/* use edit_config because that's the one that gets saved */
pika_rc_set_unknown_token (PIKA_RC (pika->edit_config), token, value);
}
else
success = FALSE;
}
CODE
);
}
sub get_monitor_resolution {
$blurb = 'Get the monitor resolution as specified in the Preferences.';
$help = <<'HELP';
Returns the resolution of the monitor in pixels/inch. This value
is taken from the Preferences (or the windowing system if this is set in
the Preferences) and there's no guarantee for the value to be reasonable.
HELP
&std_pdb_misc;
@outargs = (
{ name => 'xres', type => 'float', void_ret => 1,
desc => 'X resolution' },
{ name => 'yres', type => 'float',
desc => 'Y resolution' },
);
%invoke = (
code => <<'CODE'
{
xres = PIKA_DISPLAY_CONFIG (pika->config)->monitor_xres;
yres = PIKA_DISPLAY_CONFIG (pika->config)->monitor_yres;
}
CODE
);
}
sub get_default_comment {
$blurb = 'Get the default image comment as specified in the Preferences.';
$help = 'Returns a copy of the default image comment.';
&std_pdb_misc;
@outargs = (
{ name => 'comment', type => 'string',
desc => 'Default image comment' }
);
%invoke = (
headers => [ qw("core/pikatemplate.h") ],
code => <<'CODE'
{
comment = g_strdup (pika_template_get_comment (pika->config->default_image));
}
CODE
);
}
sub get_default_unit {
$blurb = 'Get the default unit (taken from the user\'s locale).';
$help = 'Returns the default unit\'s integer ID.';
&std_pdb_misc;
$since = '2.4';
@outargs = (
{ name => 'unit_id', type => 'unit',
desc => 'Default unit' }
);
%invoke = (
headers => [ qw("libpikabase/pikabase.h"
"core/pika-utils.h") ],
code => <<'CODE'
{
unit_id = pika_get_default_unit ();
}
CODE
);
}
sub get_color_configuration {
$blurb = 'Get a serialized version of the color management configuration.';
$help = 'Returns a string that can be deserialized into a PikaColorConfig object representing the current color management configuration.';
&neo_pdb_misc('2005', '2.4');
$lib_private = 1;
@outargs = (
{ name => 'config', type => 'string',
desc => 'Serialized color management configuration' }
);
%invoke = (
headers => [ qw("libpikaconfig/pikaconfig.h") ],
code => <<'CODE'
{
config = pika_config_serialize_to_string (PIKA_CONFIG (pika->config->color_management), NULL);
}
CODE
);
}
sub get_module_load_inhibit {
$blurb = 'Get the list of modules which should not be loaded.';
$help = 'Returns a copy of the list of modules which should not be loaded.';
&std_pdb_misc;
@outargs = (
{ name => 'load_inhibit', type => 'string',
desc => 'The list of modules' }
);
%invoke = (
headers => [ qw("libpikamodule/pikamodule.h") ],
code => <<'CODE'
{
load_inhibit = g_strdup (pika_module_db_get_load_inhibit (pika->module_db));
}
CODE
);
}
@headers = qw(<string.h>
"config/pikarc.h"
"core/pika.h");
@procs = qw(pikarc_query
pikarc_set
get_default_comment
get_default_unit
get_monitor_resolution
get_color_configuration
get_module_load_inhibit);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Pikarc procedures';
$doc_title = 'pikapikarc';
$doc_short_desc = 'Interactions with settings from pikarc.';
$doc_long_desc = 'Interactions with settings from pikarc.';
1;

238
pdb/groups/plug_in.pdb Normal file
View File

@ -0,0 +1,238 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub plug_ins_query {
$blurb = 'Queries the plug-in database for its contents.';
$help = 'This procedure queries the contents of the plug-in database.';
&andy_pdb_misc('1998');
$lib_private = 1;
@inargs = (
{ name => 'search_string', type => 'string', no_validate => 1,
desc => 'If not an empty string then use this as a search pattern' }
);
@outargs = (
{ name => 'procedures', type => 'strv',
desc => 'The plug-in procedure name' },
{ name => 'accelerators', type => 'strv',
desc => 'String representing keyboard accelerator (could be empty
string)', },
{ name => 'locations', type => 'strv',
desc => 'Location of the plug-in program' },
{ name => 'install_times', type => 'int32array',
desc => 'Time that the plug-in was installed',
array => { name => 'num_install_times',
desc => 'The number of matching procedures' } }
);
%invoke = (
code => <<'CODE'
{
num_install_times = pika_plug_in_manager_query (pika->plug_in_manager,
search_string,
&procedures,
&accelerators,
&locations,
&install_times);
}
CODE
);
}
sub plug_in_help_register {
$blurb = "Register a help path for a plug-in.";
$help = <<HELP;
This procedure registers user documentation for the calling plug-in
with the PIKA help system. The domain_uri parameter points to the root
directory where the plug-in help is installed. For each supported
language there should be a file called 'pika-help.xml' that maps the
help IDs to the actual help files.
HELP
&mitch_pdb_misc('2000');
$lib_private = 1;
@inargs = (
{ name => 'domain_name', type => 'string',
desc => "The XML namespace of the plug-in's help pages" },
{ name => 'domain_file', type => 'file',
desc => "The root URI of the plug-in's help pages" }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->call_mode == PIKA_PLUG_IN_CALL_QUERY)
{
gchar *domain_uri = domain_file ? g_file_get_uri (domain_file) : NULL;
pika_plug_in_def_set_help_domain (plug_in->plug_in_def,
domain_name, domain_uri);
g_free (domain_uri);
}
else
success = FALSE;
}
CODE
);
}
sub plug_in_menu_branch_register {
$blurb = "Register a sub-menu.";
$help = <<HELP;
This procedure installs a sub-menu which does not belong to any procedure.
The menu-name should be the untranslated menu label. PIKA will look up the
translation in the textdomain registered for the plug-in.
HELP
&mitch_pdb_misc('2005', '2.4');
$lib_private = 1;
@inargs = (
{ name => 'menu_path', type => 'string',
desc => "The sub-menu's menu path" },
{ name => 'menu_name', type => 'string',
desc => 'The name of the sub-menu' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in)
{
pika_plug_in_manager_add_menu_branch (pika->plug_in_manager,
plug_in->file, menu_path, menu_name);
}
else
success = FALSE;
}
CODE
);
}
sub plug_in_set_pdb_error_handler {
$blurb = "Sets an error handler for procedure calls.";
$help = <<HELP;
This procedure changes the way that errors in procedure calls are
handled. By default PIKA will raise an error dialog if a procedure
call made by a plug-in fails. Using this procedure the plug-in can
change this behavior. If the error handler is set to
%PIKA_PDB_ERROR_HANDLER_PLUGIN, then the plug-in is responsible for
calling pika_get_pdb_error() and handling the error whenever one if
its procedure calls fails. It can do this by displaying the error
message or by forwarding it in its own return values.
HELP
&neo_pdb_misc('2008', '2.6');
$lib_private = 1;
@inargs = (
{ name => 'handler', type => 'enum PikaPDBErrorHandler',
desc => "Who is responsible for handling procedure call errors" }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in)
{
pika_plug_in_set_error_handler (plug_in, handler);
}
else
success = FALSE;
}
CODE
);
}
sub plug_in_get_pdb_error_handler {
$blurb = "Retrieves the active error handler for procedure calls.";
$help = <<HELP;
This procedure retrieves the currently active error handler for
procedure calls made by the calling plug-in. See
pika_plugin_set_pdb_error_handler() for details.
HELP
&neo_pdb_misc('2008', '2.6');
$lib_private = 1;
@outargs = (
{ name => 'handler', type => 'enum PikaPDBErrorHandler',
desc => "Who is responsible for handling procedure call errors" }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in)
{
handler = pika_plug_in_get_error_handler (plug_in);
}
else
success = FALSE;
}
CODE
);
}
@headers = qw(<string.h>
<stdlib.h>
"libpikabase/pikabase.h"
"core/pika.h"
"plug-in/pikaplugin.h"
"plug-in/pikaplugindef.h"
"plug-in/pikapluginmanager.h"
"plug-in/pikapluginmanager-menu-branch.h"
"plug-in/pikapluginmanager-query.h"
"plug-in/pikapluginprocedure.h"
"pikapdb-utils.h");
@procs = qw(plug_ins_query
plug_in_help_register
plug_in_menu_branch_register
plug_in_set_pdb_error_handler
plug_in_get_pdb_error_handler);
%exports = (app => [@procs], lib => [@procs[1,2,3,4]]);
$desc = 'Plug-in';
$lib_private = 1;
1;

File diff suppressed because it is too large Load Diff

327
pdb/groups/progress.pdb Normal file
View File

@ -0,0 +1,327 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub progress_init {
$blurb = 'Initializes the progress bar for the current plug-in.';
$help = <<'HELP';
Initializes the progress bar for the current plug-in. It is only valid to call
this procedure from a plug-in.
HELP
&std_pdb_misc;
$lib_private = 1;
@inargs = (
{ name => 'message', type => 'string', null_ok => 1,
desc => 'Message to use in the progress dialog' },
{ name => 'gdisplay', type => 'display', none_ok => 1,
desc => 'PikaDisplay to update progressbar in, or %NULL for a separate
window' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->open)
{
if (! pika->no_interface)
pika_plug_in_progress_start (plug_in, message, gdisplay);
}
else
success = FALSE;
}
CODE
);
}
sub progress_update {
$blurb = 'Updates the progress bar for the current plug-in.';
$help = <<'HELP';
Updates the progress bar for the current plug-in. It is only valid to call this
procedure from a plug-in.
HELP
&std_pdb_misc;
$lib_private = 1;
@inargs = (
{ name => 'percentage', type => 'float',
desc => 'Percentage of progress completed which must
be between 0.0 and 1.0' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->open)
{
if (! pika->no_interface)
pika_plug_in_progress_set_value (plug_in, percentage);
}
else
success = FALSE;
}
CODE
);
}
sub progress_pulse {
$blurb = 'Pulses the progress bar for the current plug-in.';
$help = <<'HELP';
Updates the progress bar for the current plug-in. It is only valid to
call this procedure from a plug-in. Use this function instead of
pika_progress_update() if you cannot tell how much progress has been
made. This usually causes the the progress bar to enter "activity
mode", where a block bounces back and forth.
HELP
&neo_pdb_misc('2005', '2.4');
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->open)
{
if (! pika->no_interface)
pika_plug_in_progress_pulse (plug_in);
}
else
success = FALSE;
}
CODE
);
}
sub progress_set_text {
$blurb = 'Changes the text in the progress bar for the current plug-in.';
$help = <<'HELP';
This function changes the text in the progress bar for the current
plug-in. Unlike pika_progress_init() it does not change the displayed
value.
HELP
&neo_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'message', type => 'string', null_ok => 1,
desc => 'Message to use in the progress dialog' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->open)
{
if (! pika->no_interface)
pika_plug_in_progress_set_text (plug_in, message);
}
else
success = FALSE;
}
CODE
);
}
sub progress_end {
$blurb = 'Ends the progress bar for the current plug-in.';
$help = <<'HELP';
Ends the progress display for the current plug-in. Most plug-ins don't need to call this, they just exit when the work is done. It is only valid to call this
procedure from a plug-in.
HELP
&neo_pdb_misc('2007', '2.4');
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->open)
{
PikaPlugInProcFrame *proc_frame = pika_plug_in_get_proc_frame (plug_in);
pika_plug_in_progress_end (plug_in, proc_frame);
}
else
success = FALSE;
}
CODE
);
}
sub progress_get_window_handle {
$blurb = 'Returns the native window ID of the toplevel window this plug-in\'s progress is displayed in.';
$help = <<'HELP';
This function returns the native window ID of the toplevel window this plug-in\'s progress is displayed in.
HELP
&mitch_pdb_misc('2004', '2.2');
@outargs = (
{ name => 'window', type => 'int32',
desc => 'The progress bar\'s toplevel window' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->open)
{
if (! pika->no_interface)
window = pika_plug_in_progress_get_window_id (plug_in);
}
else
success = FALSE;
}
CODE
);
}
sub progress_install {
$blurb = 'Installs a progress callback for the current plug-in.';
$help = <<'HELP';
This function installs a temporary PDB procedure which will handle all
progress calls made by this plug-in and any procedure it calls. Calling
this function multiple times simply replaces the old progress callbacks.
HELP
&mitch_pdb_misc('2004', '2.2');
$lib_private = 1;
@inargs = (
{ name => 'progress_callback', type => 'string', non_empty => 1,
desc => 'The callback PDB proc to call' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->open)
success = pika_plug_in_progress_install (plug_in, progress_callback);
else
success = FALSE;
}
CODE
);
}
sub progress_uninstall {
$blurb = 'Uninstalls the progress callback for the current plug-in.';
$help = <<'HELP';
This function uninstalls any progress callback installed with
pika_progress_install() before.
HELP
&mitch_pdb_misc('2004', '2.2');
$lib_private = 1;
@inargs = (
{ name => 'progress_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this progress' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->open)
success = pika_plug_in_progress_uninstall (plug_in, progress_callback);
else
success = FALSE;
}
CODE
);
}
sub progress_cancel {
$blurb = 'Cancels a running progress.';
$help = <<'HELP';
This function cancels the currently running progress.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'progress_callback', type => 'string', non_empty => 1,
desc => 'The name of the callback registered for this progress' }
);
%invoke = (
code => <<'CODE'
{
PikaPlugIn *plug_in = pika->plug_in_manager->current_plug_in;
if (plug_in && plug_in->open)
success = pika_plug_in_progress_cancel (plug_in, progress_callback);
else
success = FALSE;
}
CODE
);
}
@headers = qw("core/pika.h"
"plug-in/pikaplugin.h"
"plug-in/pikaplugin-progress.h"
"plug-in/pikapluginmanager.h");
@procs = qw(progress_init
progress_update
progress_pulse
progress_set_text
progress_end
progress_get_window_handle
progress_install
progress_uninstall
progress_cancel);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Progress';
$doc_title = 'pikaprogress';
$doc_short_desc = "Functions for embedding the progress bar into a plug-in's GUI.";
$doc_long_desc = "Functions for embedding the progress bar into a plug-in's GUI.";
1;

506
pdb/groups/resource.pdb Normal file
View File

@ -0,0 +1,506 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub resource_get_by_name {
$blurb = "Returns a resource with the given name.";
$help = "Returns a resource with the given name.";
&jehan_pdb_misc('2023', '3.0');
$lib_private = 1;
@inargs = (
{ name => 'type_name', type => 'string', non_empty => 1,
desc => 'The name of the resource type' },
{ name => 'resource_name', type => 'string', non_empty => 1,
desc => 'The name of the resource' }
);
@outargs = (
{ name => 'resource',
type => 'resource',
desc => "The resource" }
);
%invoke = (
code => <<'CODE'
{
resource = pika_pdb_get_resource (pika, g_type_from_name (type_name), resource_name,
PIKA_PDB_DATA_ACCESS_READ, error);
if (! resource)
success = FALSE;
}
CODE
);
}
sub resource_get_by_identifiers {
$blurb = "Returns the resource contained in a given file with a given name.";
$help = <<'HELP';
Returns a resource specifically stored in a given file path, under a given name
(a single path may be a collection containing several resources).
HELP
&jehan_pdb_misc('2023', '3.0');
$lib_private = 1;
@inargs = (
{ name => 'type_name', type => 'string', non_empty => 1,
desc => 'The name of the resource type' },
{ name => 'resource_name', type => 'string', non_empty => 1,
desc => 'The name of the resource' },
{ name => 'collection', type => 'string', non_empty => 1,
desc => 'The collection identifier' },
{ name => 'is_internal', type => 'boolean',
desc => 'Whether this is the identifier for internal data'}
);
@outargs = (
{ name => 'resource',
type => 'resource',
desc => "The resource" }
);
%invoke = (
code => <<'CODE'
{
resource = pika_pdb_get_resource_by_id (pika, g_type_from_name (type_name),
resource_name, collection, is_internal,
PIKA_PDB_DATA_ACCESS_READ, error);
if (! resource)
success = FALSE;
}
CODE
);
}
sub resource_id_is_valid {
$blurb = 'Returns TRUE if the resource ID is valid.';
$help = <<'HELP';
This procedure checks if the given resource ID is valid and refers to an
existing resource.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource_id', type => 'int32',
desc => 'The resource ID to check' }
);
@outargs = (
{ name => 'valid', type => 'boolean',
desc => 'Whether the resource ID is valid' }
);
%invoke = (
code => <<'CODE'
{
PikaData *data = pika_data_get_by_id (resource_id);
valid = PIKA_IS_DATA (data);
}
CODE
);
}
sub resource_id_is_brush {
$blurb = 'Returns whether the resource ID is a brush.';
$help = <<HELP;
This procedure returns TRUE if the specified resource ID is a brush.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource_id', type => 'int32',
desc => 'The resource ID' }
);
@outargs = (
{ name => 'brush', type => 'boolean',
desc => 'TRUE if the resource ID is a brush, FALSE otherwise' }
);
%invoke = (
code => <<'CODE'
{
PikaData *data = pika_data_get_by_id (resource_id);
brush = PIKA_IS_BRUSH (data);
}
CODE
);
}
sub resource_id_is_pattern {
$blurb = 'Returns whether the resource ID is a pattern.';
$help = <<HELP;
This procedure returns TRUE if the specified resource ID is a pattern.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource_id', type => 'int32',
desc => 'The resource ID' }
);
@outargs = (
{ name => 'pattern', type => 'boolean',
desc => 'TRUE if the resource ID is a pattern, FALSE otherwise' }
);
%invoke = (
code => <<'CODE'
{
PikaData *data = pika_data_get_by_id (resource_id);
pattern = PIKA_IS_PATTERN (data);
}
CODE
);
}
sub resource_id_is_gradient {
$blurb = 'Returns whether the resource ID is a gradient.';
$help = <<HELP;
This procedure returns TRUE if the specified resource ID is a gradient.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource_id', type => 'int32',
desc => 'The resource ID' }
);
@outargs = (
{ name => 'gradient', type => 'boolean',
desc => 'TRUE if the resource ID is a gradient, FALSE otherwise' }
);
%invoke = (
code => <<'CODE'
{
PikaData *data = pika_data_get_by_id (resource_id);
gradient = PIKA_IS_GRADIENT (data);
}
CODE
);
}
sub resource_id_is_palette {
$blurb = 'Returns whether the resource ID is a palette.';
$help = <<HELP;
This procedure returns TRUE if the specified resource ID is a palette.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource_id', type => 'int32',
desc => 'The resource ID' }
);
@outargs = (
{ name => 'palette', type => 'boolean',
desc => 'TRUE if the resource ID is a palette, FALSE otherwise' }
);
%invoke = (
code => <<'CODE'
{
PikaData *data = pika_data_get_by_id (resource_id);
palette = PIKA_IS_PALETTE (data);
}
CODE
);
}
sub resource_id_is_font {
$blurb = 'Returns whether the resource ID is a font.';
$help = <<HELP;
This procedure returns TRUE if the specified resource ID is a font.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource_id', type => 'int32',
desc => 'The resource ID' }
);
@outargs = (
{ name => 'font', type => 'boolean',
desc => 'TRUE if the resource ID is a font, FALSE otherwise' }
);
%invoke = (
code => <<'CODE'
{
PikaData *data = pika_data_get_by_id (resource_id);
font = PIKA_IS_FONT (data);
}
CODE
);
}
sub resource_get_name {
$blurb = "Returns the resource's name.";
$help = <<HELP;
This procedure returns the resource's name.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource', type => 'resource',
desc => 'The resource' }
);
@outargs = (
{ name => 'name', type => 'string',
desc => "The resource's name" }
);
%invoke = (
code => <<'CODE'
{
name = g_strdup (pika_object_get_name (PIKA_OBJECT (resource)));
}
CODE
);
}
sub resource_get_identifiers {
$blurb = "Returns a triplet identifying the resource.";
$help = <<HELP;
This procedure returns 2 strings and a boolean. The first string is the resource
name, similar to what you would obtain calling pika_resource_get_name(). The
second is an opaque identifier for the collection this resource belongs to.
Note: as far as PIKA is concerned, a collection of resource usually corresponds
to a single file on disk (which may or may not contain several resources).
Therefore the identifier may be derived from the local file path. Nevertheless
you should not use this string as such as this is not guaranteed to be always
the case. You should consider it as an opaque identifier only to be used again
through _pika_resource_get_by_identifier().
HELP
&jehan_pdb_misc('2023', '3.0');
$lib_private = 1;
@inargs = (
{ name => 'resource', type => 'resource',
desc => 'The resource' }
);
@outargs = (
{ name => 'is_internal', type => 'boolean',
desc => 'Whether this is the identifier for internal data'},
{ name => 'name', type => 'string',
desc => "The resource's name" },
{ name => 'collection_id', type => 'string',
desc => "The resource's collection identifier" }
);
%invoke = (
code => <<'CODE'
{
pika_data_get_identifiers (PIKA_DATA (resource), &name, &collection_id, &is_internal);
}
CODE
);
}
sub resource_is_editable {
$blurb = "Whether the resource can be edited.";
$help = "Returns TRUE if you have permission to change the resource.";
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource', type => 'resource',
desc => 'The resource' }
);
@outargs = (
{ name => 'editable', type => 'boolean',
desc => 'TRUE if the resource can be edited' }
);
%invoke = (
code => <<'CODE'
{
editable = pika_data_is_writable (PIKA_DATA (resource));
}
CODE
);
}
sub resource_duplicate {
$blurb = "Duplicates a resource.";
$help = "Returns a copy having a different, unique ID.";
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource', type => 'resource',
desc => 'The resource' }
);
@outargs = (
{ name => 'resource_copy',
type => 'resource',
desc => "A copy of the resource." }
);
%invoke = (
code => <<'CODE'
{
PikaDataFactory *factory;
factory = pika_pdb_get_data_factory (pika, G_TYPE_FROM_INSTANCE (resource));
resource_copy = (PikaResource *)
pika_data_factory_data_duplicate (factory, PIKA_DATA (resource));
if (! resource_copy)
success = FALSE;
}
CODE
);
}
sub resource_rename {
$blurb = "Renames a resource. When the name is in use, renames to a unique name.";
$help = <<'HELP';
Renames a resource. When the proposed name is already used, PIKA
generates a unique name.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource', type => 'resource',
desc => 'The resource' },
{ name => 'new_name', type => 'string', non_empty => 1,
desc => 'The proposed new name of the resource' }
);
%invoke = (
code => <<'CODE'
{
if (pika_viewable_is_name_editable (PIKA_VIEWABLE (resource)))
{
pika_object_set_name (PIKA_OBJECT (resource), new_name);
}
else
{
g_set_error (error, PIKA_PDB_ERROR, PIKA_PDB_ERROR_INVALID_ARGUMENT,
_("Resource '%s' is not renamable"),
pika_object_get_name (PIKA_OBJECT (resource)));
success = FALSE;
}
}
CODE
);
}
sub resource_delete {
$blurb = "Deletes a resource.";
$help = <<'HELP';
Deletes a resource. Returns an error if the resource is not deletable.
Deletes the resource's data. You should not use the resource afterwards.
HELP
&mitch_pdb_misc('2023', '3.0');
@inargs = (
{ name => 'resource', type => 'resource',
desc => 'The resource' }
);
%invoke = (
code => <<'CODE'
{
PikaDataFactory *factory;
factory = pika_pdb_get_data_factory (pika, G_TYPE_FROM_INSTANCE (resource));
if (pika_data_is_deletable (PIKA_DATA (resource)))
success = pika_data_factory_data_delete (factory, PIKA_DATA (resource),
TRUE, error);
else
success = FALSE;
}
CODE
);
}
@headers = qw("core/pikabrush.h"
"core/pikadatafactory.h"
"core/pikagradient.h"
"core/pikapalette.h"
"core/pikapattern.h"
"text/pikafont.h"
"pikapdb-utils.h"
"pikapdberror.h"
"pika-intl.h");
@procs = qw(resource_get_by_name
resource_get_by_identifiers
resource_id_is_valid
resource_id_is_brush
resource_id_is_pattern
resource_id_is_gradient
resource_id_is_palette
resource_id_is_font
resource_get_name
resource_get_identifiers
resource_is_editable
resource_duplicate
resource_rename
resource_delete);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Resource procedures';
$doc_title = 'pikaresource';
$doc_short_desc = 'Functions to manipulate resources.';
$doc_long_desc = 'Functions to manipulate resources.';
1;

552
pdb/groups/selection.pdb Normal file
View File

@ -0,0 +1,552 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub selection_bounds {
$blurb = 'Find the bounding box of the current selection.';
$help = <<'HELP';
This procedure returns whether there is a selection for the specified image. If
there is one, the upper left and lower right corners of the bounding box are
returned. These coordinates are relative to the image. Please note that the
pixel specified by the lower right coordinate of the bounding box is not
part of the selection. The selection ends at the upper left corner of this
pixel. This means the width of the selection can be calculated as (x2 - x1),
its height as (y2 - y1).
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'non_empty', type => 'boolean', void_ret => 1,
desc => 'TRUE if there is a selection' },
{ name => 'x1', type => 'int32',
desc => 'x coordinate of upper left corner of selection bounds' },
{ name => 'y1', type => 'int32',
desc => 'y coordinate of upper left corner of selection bounds' },
{ name => 'x2', type => 'int32',
desc => 'x coordinate of lower right corner of selection bounds' },
{ name => 'y2', type => 'int32',
desc => 'y coordinate of lower right corner of selection bounds' }
);
%invoke = (
code => <<'CODE'
{
gint x, y, w, h;
non_empty = pika_item_bounds (PIKA_ITEM (pika_image_get_mask (image)),
&x, &y, &w, &h);
x1 = x;
y1 = y;
x2 = x + w;
y2 = y + h;
}
CODE
);
}
sub selection_value {
$blurb = 'Find the value of the selection at the specified coordinates.';
$help = <<'HELP';
This procedure returns the value of the selection at the specified coordinates.
If the coordinates lie out of bounds, 0 is returned.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'x', type => 'int32',
desc => 'x coordinate of value' },
{ name => 'y', type => 'int32',
desc => 'y coordinate of value' }
);
@outargs = (
{ name => 'value', type => '0 <= int32 <= 255',
desc => 'Value of the selection' }
);
%invoke = (
code => <<'CODE'
{
gdouble val;
val= pika_pickable_get_opacity_at (PIKA_PICKABLE (pika_image_get_mask (image)),
x, y);
value = ROUND (CLAMP (val, 0.0, 1.0) * 255.0);
}
CODE
);
}
sub selection_is_empty {
$blurb = 'Determine whether the selection is empty.';
$help = <<'HELP';
This procedure returns TRUE if the selection for the specified image is empty.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'is_empty', type => 'boolean',
desc => 'Is the selection empty?' }
);
%invoke = (
code => <<'CODE'
{
is_empty = pika_channel_is_empty (pika_image_get_mask (image));
}
CODE
);
}
sub selection_translate {
$blurb = 'Translate the selection by the specified offsets.';
$help = <<'HELP';
This procedure actually translates the selection for the specified image by the
specified offsets. Regions that are translated from beyond the bounds of the
image are set to empty. Valid regions of the selection which are translated
beyond the bounds of the image because of this call are lost.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'offx', type => 'int32',
desc => 'x offset for translation' },
{ name => 'offy', type => 'int32',
desc => 'y offset for translation' }
);
%invoke = (
code => <<'CODE'
{
pika_item_translate (PIKA_ITEM (pika_image_get_mask (image)),
offx, offy, TRUE);
}
CODE
);
}
sub selection_float {
$blurb = <<'BLURB';
Float the selection from the specified drawable with initial offsets as
specified.
BLURB
$help = <<'HELP';
This procedure determines the region of the specified drawable that lies
beneath the current selection. The region is then cut from the drawable and the
resulting data is made into a new layer which is instantiated as a floating
selection. The offsets allow initial positioning of the new floating selection.
HELP
&std_pdb_misc;
$lib_private = 1;
@inargs = (
{ name => 'drawables', type => 'itemarray',
desc => 'The drawables from which to float selection',
no_validate => 1,
array => { name => 'num_drawables',
type => '1 <= int32',
desc => "The number of drawables" } },
{ name => 'offx', type => 'int32',
desc => 'x offset for translation' },
{ name => 'offy', type => 'int32',
desc => 'y offset for translation' }
);
@outargs = (
{ name => 'layer', type => 'layer',
desc => 'The floated layer' }
);
%invoke = (
code => <<'CODE'
{
PikaImage *image = NULL;
gint i;
if (num_drawables < 1)
{
success = FALSE;
}
else
{
for (i = 0; i < num_drawables; i++)
{
if (! pika_pdb_item_is_attached (PIKA_ITEM (drawables[i]), NULL,
PIKA_PDB_ITEM_CONTENT, error) ||
pika_pdb_item_is_group (PIKA_ITEM (drawables[i]), error) ||
(image && image != pika_item_get_image (PIKA_ITEM (drawables[i]))))
{
success = FALSE;
break;
}
else
{
image = pika_item_get_image (PIKA_ITEM (drawables[i]));
}
}
}
if (success)
{
GList *drawable_list = NULL;
for (i = 0; i < num_drawables; i++)
drawable_list = g_list_prepend (drawable_list, (gpointer) drawables[i]);
layer = pika_selection_float (PIKA_SELECTION (pika_image_get_mask (image)),
drawable_list, context, TRUE, offx, offy,
error);
g_list_free (drawable_list);
if (! layer)
success = FALSE;
}
}
CODE
);
}
sub selection_invert {
$blurb = 'Invert the selection mask.';
$help = <<'HELP';
This procedure inverts the selection mask. For every pixel in the selection
channel, its new value is calculated as (255 - old-value).
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_invert (pika_image_get_mask (image), TRUE);
}
CODE
);
}
sub selection_sharpen {
$blurb = 'Sharpen the selection mask.';
$help = <<'HELP';
This procedure sharpens the selection mask. For every pixel in the selection
channel, if the value is > 127, the new pixel is assigned a value of 255.
This removes any "anti-aliasing" that might exist in the selection mask's
boundary.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_sharpen (pika_image_get_mask (image), TRUE);
}
CODE
);
}
sub selection_all {
$blurb = 'Select all of the image.';
$help = <<'HELP';
This procedure sets the selection mask to completely encompass the image.
Every pixel in the selection channel is set to 255.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_all (pika_image_get_mask (image), TRUE);
}
CODE
);
}
sub selection_none {
$blurb = 'Deselect the entire image.';
$help = <<'HELP';
This procedure deselects the entire image. Every pixel in the selection channel
is set to 0.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_clear (pika_image_get_mask (image), NULL, TRUE);
}
CODE
);
}
sub selection_feather {
$blurb = "Feather the image's selection";
$help = <<'HELP';
This procedure feathers the selection. Feathering is implemented
using a gaussian blur.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'radius', type => '0 <= float',
desc => 'Radius of feather (in pixels)' }
);
%invoke = (
code => <<'CODE'
{
/* FIXME: "edge-lock" hardcoded to TRUE */
pika_channel_feather (pika_image_get_mask (image),
radius, radius, TRUE, TRUE);
}
CODE
);
}
sub selection_border {
$blurb = "Border the image's selection";
$help .= <<'HELP';
This procedure borders the selection. Bordering creates a new
selection which is defined along the boundary of the previous
selection at every point within the specified radius.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'radius', type => '0 <= int32',
desc => 'Radius of border (in pixels)' }
);
%invoke = (
code => <<'CODE'
{
/* FIXME: "style" and "edge-lock" hardcoded to SMOOTH and TRUE, respectively. */
pika_channel_border (pika_image_get_mask (image),
radius, radius,
PIKA_CHANNEL_BORDER_STYLE_SMOOTH,
TRUE, TRUE);
}
CODE
);
}
sub selection_grow {
$blurb = "Grow the image's selection";
$help .= <<'HELP';
This procedure grows the selection. Growing involves expanding the
boundary in all directions by the specified pixel amount.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'steps', type => '0 <= int32',
desc => 'Steps of grow (in pixels)' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_grow (pika_image_get_mask (image),
steps, steps, TRUE);
}
CODE
);
}
sub selection_shrink {
$blurb = "Shrink the image's selection";
$help .= <<'HELP';
This procedure shrinks the selection. Shrinking involves trimming the
existing selection boundary on all sides by the specified number of
pixels.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'steps', type => '0 <= int32',
desc => 'Steps of shrink (in pixels)' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_shrink (pika_image_get_mask (image),
steps, steps, FALSE, TRUE);
}
CODE
);
}
sub selection_flood {
$blurb = "Remove holes from the image's selection";
$help .= <<'HELP';
This procedure removes holes from the selection, that can come from
selecting a patchy area with the Fuzzy Select Tool.
In technical terms this procedure floods the selection.
See the Algorithms page in the developer wiki for details.
HELP
$author = 'Ell';
$copyright = 'Ell';
$date = '2016';
$since = '2.10';
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
%invoke = (
code => <<'CODE'
{
pika_channel_flood (pika_image_get_mask (image), TRUE);
}
CODE
);
}
sub selection_save {
$blurb = 'Copy the selection mask to a new channel.';
$help = <<'HELP';
This procedure copies the selection mask and stores the content in a new
channel. The new channel is automatically inserted into the image's list of
channels.
HELP
&std_pdb_misc;
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' }
);
@outargs = (
{ name => 'channel', type => 'channel',
desc => 'The new channel' }
);
%invoke = (
headers => [qw("core/pikaselection.h") ],
code => <<'CODE'
{
channel = PIKA_CHANNEL (pika_item_duplicate (PIKA_ITEM (pika_image_get_mask (image)),
PIKA_TYPE_CHANNEL));
if (channel)
{
/* saved selections are not visible by default */
pika_item_set_visible (PIKA_ITEM (channel), FALSE, FALSE);
pika_image_add_channel (image, channel,
PIKA_IMAGE_ACTIVE_PARENT, -1, TRUE);
}
else
success = FALSE;
}
CODE
);
}
@headers = qw("libpikamath/pikamath.h"
"core/pikapickable.h"
"pikapdb-utils.h"
"pika-intl.h");
@procs = qw(selection_bounds selection_value selection_is_empty
selection_translate selection_float
selection_invert selection_sharpen selection_all selection_none
selection_feather selection_border selection_grow selection_shrink
selection_flood
selection_save);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Image mask';
$doc_title = 'pikaselection';
$doc_short_desc = 'Functions for manipulating selections.';
$doc_long_desc = 'Functions for manipulating selections.';
1;

1042
pdb/groups/text_layer.pdb Normal file

File diff suppressed because it is too large Load Diff

165
pdb/groups/text_tool.pdb Normal file
View File

@ -0,0 +1,165 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub text_fontname {
$blurb = <<'BLURB';
Add text at the specified location as a floating selection or a new layer.
BLURB
$help = <<'HELP';
This tool requires a fontname matching an installed PangoFT2 font.
You can specify the fontsize in units of pixels
or points, and the appropriate metric is specified using the size_type
argument. The x and y parameters together control the placement of the new
text by specifying the upper left corner of the text bounding box. If the
specified drawable parameter is valid, the text will be created as a floating
selection attached to the drawable. If the drawable parameter is not valid
(%NULL), the text will appear as a new layer. Finally, a border can be specified
around the final rendered text. The border is measured in pixels. Parameter
size-type is not used and is currently ignored. If you need to display a font
in points, divide the size in points by 72.0 and multiply it by the image's
vertical resolution.
HELP
&std_pdb_misc;
$author = 'Martin Edlman & Sven Neumann';
$date = '1998- 2001';
@inargs = (
{ name => 'image', type => 'image',
desc => 'The image' },
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable: (%NULL for a new text layer)',
none_ok => 1 },
{ name => 'x', type => 'float',
desc => 'The x coordinate for the left of the text bounding box' },
{ name => 'y', type => 'float',
desc => 'The y coordinate for the top of the text bounding box' },
{ name => 'text', type => 'string',
desc => 'The text to generate (in UTF-8 encoding)' },
{ name => 'border', type => '-1 <= int32',
desc => 'The size of the border' },
{ name => 'antialias', type => 'boolean',
desc => 'Antialiasing' },
{ name => 'size', type => '0 < float',
desc => 'The size of text in either pixels or points' },
{ name => 'size_type', type => 'enum PikaSizeType', dead => 1,
desc => 'The units of specified size' },
{ name => 'fontname', type => 'string',
desc => 'The name of the font' }
);
@outargs = (
{ name => 'text_layer', type => 'layer', none_ok => 1,
desc => 'The new text layer or %NULL if no layer was created.' }
);
%invoke = (
code => <<'CODE'
{
if (drawable &&
(! pika_pdb_item_is_attached (PIKA_ITEM (drawable), image,
PIKA_PDB_ITEM_CONTENT, error) ||
! pika_pdb_item_is_not_group (PIKA_ITEM (drawable), error)))
success = FALSE;
if (success)
{
gchar *real_fontname = g_strdup_printf ("%s %d", fontname, (gint) size);
text_layer = text_render (image, drawable, context,
x, y, real_fontname, text,
border, antialias);
g_free (real_fontname);
}
}
CODE
);
}
sub text_get_extents_fontname {
$blurb = 'Get extents of the bounding box for the specified text.';
$help = <<'HELP';
This tool returns the width and height of a bounding box for the specified text
string with the specified font information. Ascent and descent for the
specified font are returned as well. Parameter size-type is not used and is
currently ignored. If you need to display a font in points, divide the
size in points by 72.0 and multiply it by the vertical resolution of the
image you are taking into account.
HELP
&std_pdb_misc;
$author = 'Martin Edlman & Sven Neumann';
$date = '1998- 2001';
@inargs = (
{ name => 'text', type => 'string',
desc => 'The text to generate (in UTF-8 encoding)' },
{ name => 'size', type => '0 < float',
desc => 'The size of text in either pixels or points' },
{ name => 'size_type', type => 'enum PikaSizeType', dead => 1,
desc => 'The units of specified size' },
{ name => 'fontname', type => 'string',
desc => 'The name of the font' }
);
@outargs = (
{ name => 'width', type => 'int32', void_ret => 1,
desc => 'The width of the specified font' },
{ name => 'height', type => 'int32',
desc => 'The height of the specified font' },
{ name => 'ascent', type => 'int32',
desc => 'The ascent of the specified font' },
{ name => 'descent', type => 'int32',
desc => 'The descent of the specified font' }
);
%invoke = (
code => <<'CODE'
{
gchar *real_fontname = g_strdup_printf ("%s %d", fontname, (gint) size);
success = text_get_extents (pika,
real_fontname, text,
&width, &height,
&ascent, &descent);
g_free (real_fontname);
}
CODE
);
}
@headers = qw("libpikabase/pikabase.h"
"text/pikatext-compat.h"
"pikapdb-utils.h");
@procs = qw(text_fontname
text_get_extents_fontname);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Text procedures';
$doc_title = 'pikatexttool';
$doc_short_desc = 'Functions for controlling the text tool.';
$doc_long_desc = 'Functions for controlling the text tool.';
1;

405
pdb/groups/unit.pdb Normal file
View File

@ -0,0 +1,405 @@
# PIKA - Photo and Image Kooker Application
# 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 3 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, see <https://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub unit_get_number_of_units {
$blurb = 'Returns the number of units.';
$help = 'This procedure returns the number of defined units.';
&mitch_pdb_misc('1999');
$lib_private = 1;
@outargs = (
{ name => 'num_units', type => 'int32', libdef => 'PIKA_UNIT_END',
desc => 'The number of units' }
);
%invoke = (
code => <<'CODE'
{
num_units = _pika_unit_get_number_of_units (pika);
}
CODE
);
}
sub unit_get_number_of_built_in_units {
$blurb = 'Returns the number of built-in units.';
$help = <<'HELP';
This procedure returns the number of defined units built-in to PIKA.
HELP
&mitch_pdb_misc('1999');
$lib_private = 1;
@outargs = (
{ name => 'num_units', type => 'int32', libdef => 'PIKA_UNIT_END',
desc => 'The number of built-in units' }
);
%invoke = (
code => <<'CODE'
{
num_units = _pika_unit_get_number_of_built_in_units (pika);
}
CODE
);
}
sub unit_new {
$blurb = "Creates a new unit and returns it's integer ID.";
$help = <<'HELP';
This procedure creates a new unit and returns it's integer ID. Note that the
new unit will have it's deletion flag set to TRUE, so you will have to set it
to FALSE with pika_unit_set_deletion_flag() to make it persistent.
HELP
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'identifier', type => 'string', non_empty => 1,
desc => "The new unit's identifier" },
{ name => 'factor', type => 'float',
desc => "The new unit's factor" },
{ name => 'digits', type => 'int32',
desc => "The new unit's digits" },
{ name => 'symbol', type => 'string', non_empty => 1,
desc => "The new unit's symbol" },
{ name => 'abbreviation', type => 'string', non_empty => 1,
desc => "The new unit's abbreviation" },
{ name => 'singular', type => 'string', non_empty => 1,
desc => "The new unit's singular form" },
{ name => 'plural', type => 'string', non_empty => 1,
desc => "The new unit's plural form" }
);
@outargs = (
{ name => 'unit_id', type => 'unit',
desc => "The new unit's ID",
libdef => 'PIKA_UNIT_INCH' }
);
%invoke = (
code => <<'CODE'
{
unit_id = _pika_unit_new (pika, identifier, factor, digits,
symbol, abbreviation, singular, plural);
}
CODE
);
}
sub unit_get_deletion_flag {
$blurb = "Returns the deletion flag of the unit.";
$help = <<'HELP';
This procedure returns the deletion flag of the unit. If this value is TRUE the
unit's definition will not be saved in the user's unitrc file on pika exit.
HELP
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'unit_id', type => 'unit',
desc => "The unit's integer ID" }
);
@outargs = (
{ name => 'deletion_flag', type => 'boolean',
desc => "The unit's deletion flag" }
);
%invoke = (
code => <<'CODE'
{
deletion_flag = _pika_unit_get_deletion_flag (pika, unit_id);
}
CODE
);
}
sub unit_set_deletion_flag {
$blurb = 'Sets the deletion flag of a unit.';
$help = <<'HELP';
This procedure sets the unit's deletion flag. If the deletion flag of a unit is
TRUE on pika exit, this unit's definition will not be saved in the user's
unitrc.
HELP
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'unit_id', type => 'unit',
desc => "The unit's integer ID" },
{ name => 'deletion_flag', type => 'boolean',
desc => 'The new deletion flag of the unit' }
);
%invoke = (
code => <<'CODE'
{
_pika_unit_set_deletion_flag (pika, unit_id, deletion_flag);
}
CODE
);
}
sub unit_get_identifier {
$blurb = "Returns the textual identifier of the unit.";
$help = <<'HELP';
This procedure returns the textual identifier of the unit. For built-in units
it will be the english singular form of the unit's name. For user-defined units
this should equal to the singular form.
HELP
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'unit_id', type => 'unit',
desc => "The unit's integer ID" }
);
@outargs = (
{ name => 'identifier', type => 'string',
desc => "The unit's textual identifier" }
);
%invoke = (
code => <<'CODE'
{
identifier = g_strdup (_pika_unit_get_identifier (pika, unit_id));
}
CODE
);
}
sub unit_get_factor {
$blurb = "Returns the factor of the unit.";
$help = <<'HELP';
This procedure returns the unit's factor which indicates how many units make up
an inch. Note that asking for the factor of "pixels" will produce an error.
HELP
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'unit_id', type => 'unit',
desc => "The unit's integer ID" }
);
@outargs = (
{ name => 'factor', type => 'float',
desc => "The unit's factor" }
);
%invoke = (
code => <<'CODE'
{
factor = _pika_unit_get_factor (pika, unit_id);
}
CODE
);
}
sub unit_get_digits {
$blurb = "Returns the number of digits of the unit.";
$help = <<'HELP';
This procedure returns the number of digits you should provide in input or
output functions to get approximately the same accuracy as with two digits and
inches. Note that asking for the digits of "pixels" will produce an error.
HELP
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'unit_id', type => 'unit',
desc => "The unit's integer ID" }
);
@outargs = (
{ name => 'digits', type => 'int32',
desc => "The unit's number of digits" }
);
%invoke = (
code => <<'CODE'
{
digits = _pika_unit_get_digits (pika, unit_id);
}
CODE
);
}
sub unit_get_symbol {
$blurb = "Returns the symbol of the unit.";
$help = <<'HELP';
This procedure returns the symbol of the unit ("''" for inches).
HELP
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'unit_id', type => 'unit',
desc => "The unit's integer ID" }
);
@outargs = (
{ name => 'symbol', type => 'string',
desc => "The unit's symbol" }
);
%invoke = (
code => <<'CODE'
{
symbol = g_strdup (_pika_unit_get_symbol (pika, unit_id));
}
CODE
);
}
sub unit_get_abbreviation {
$blurb = "Returns the abbreviation of the unit.";
$help = <<'HELP';
This procedure returns the abbreviation of the unit ("in" for inches).
HELP
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'unit_id', type => 'unit',
desc => "The unit's integer ID" }
);
@outargs = (
{ name => 'abbreviation', type => 'string',
desc => "The unit's abbreviation" }
);
%invoke = (
code => <<'CODE'
{
abbreviation = g_strdup (_pika_unit_get_abbreviation (pika, unit_id));
}
CODE
);
}
sub unit_get_singular {
$blurb = "Returns the singular form of the unit.";
$help = 'This procedure returns the singular form of the unit.';
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'unit_id', type => 'unit',
desc => "The unit's integer ID" }
);
@outargs = (
{ name => 'singular', type => 'string',
desc => "The unit's singular form" }
);
%invoke = (
code => <<'CODE'
{
singular = g_strdup (_pika_unit_get_singular (pika, unit_id));
}
CODE
);
}
sub unit_get_plural {
$blurb = "Returns the plural form of the unit.";
$help = 'This procedure returns the plural form of the unit.';
&mitch_pdb_misc('1999');
$lib_private = 1;
@inargs = (
{ name => 'unit_id', type => 'unit',
desc => "The unit's integer ID" }
);
@outargs = (
{ name => 'plural', type => 'string',
desc => "The unit's plural form" }
);
%invoke = (
code => <<'CODE'
{
plural = g_strdup (_pika_unit_get_plural (pika, unit_id));
}
CODE
);
}
@headers = qw("libpikabase/pikabase.h"
"core/pikaunit.h");
@procs = qw(unit_get_number_of_units
unit_get_number_of_built_in_units
unit_new
unit_get_deletion_flag
unit_set_deletion_flag
unit_get_identifier
unit_get_factor
unit_get_digits
unit_get_symbol
unit_get_abbreviation
unit_get_singular
unit_get_plural);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Units';
$lib_private = 1;
1;

1374
pdb/groups/vectors.pdb Normal file

File diff suppressed because it is too large Load Diff

817
pdb/lib.pl Normal file
View File

@ -0,0 +1,817 @@
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1998-2003 Manish Singh <yosh@gimp.org>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 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, see <https://www.gnu.org/licenses/>.
package Pika::CodeGen::lib;
# Generates all the libpika C wrappers (used by plugins)
$destdir = "$main::destdir/libpika";
$builddir = "$main::builddir/libpika";
*arg_types = \%Pika::CodeGen::pdb::arg_types;
*arg_parse = \&Pika::CodeGen::pdb::arg_parse;
*enums = \%Pika::CodeGen::enums::enums;
*write_file = \&Pika::CodeGen::util::write_file;
*FILE_EXT = \$Pika::CodeGen::util::FILE_EXT;
use Text::Wrap qw(wrap);
sub desc_wrap {
my ($str) = @_;
my $leading = ' * ';
my $wrapped;
$str =~ s/\s+$//; # trim trailing whitespace
$str =~ s/&/&amp\;/g;
$str =~ s/\</&lt\;/g;
$str =~ s/\>/&gt\;/g;
$Text::Wrap::columns = 72;
$wrapped = wrap($leading, $leading, $str);
$wrapped =~ s/[ \t]+\n/\n/g;
return $wrapped;
}
sub generate_fun {
my ($proc, $out) = @_;
my @inargs = @{$proc->{inargs}} if (defined $proc->{inargs});
my @outargs = @{$proc->{outargs}} if (defined $proc->{outargs});
sub libtype {
my $arg = shift;
my $outarg = shift;
my ($type, $name) = &arg_parse($arg->{type});
my $argtype = $arg_types{$type};
my $rettype = '';
if ($type eq 'enum') {
return "$name ";
}
if ($outarg) {
$rettype .= $argtype->{type};
}
else {
if (exists $argtype->{struct}) {
$rettype .= 'const ';
}
$rettype .= $argtype->{const_type};
}
$rettype =~ s/int32/int/ unless exists $arg->{keep_size};
$rettype .= '*' if exists $argtype->{struct};
return $rettype;
}
my $funcname = "pika_$name";
my $wrapped = "";
my $new_funcname = $funcname;
my %usednames;
my $retdesc = " * Returns:";
my $func_annotations = "";
if ($proc->{lib_private}) {
$wrapped = '_';
}
$skip_gi = '';
if ($proc->{skip_gi}) {
$skip_gi = ' (skip)';
}
if ($proc->{deprecated}) {
if ($proc->{deprecated} eq 'NONE') {
push @{$out->{protos}}, "PIKA_DEPRECATED\n";
}
else {
my $underscores = $proc->{deprecated};
$underscores =~ s/-/_/g;
push @{$out->{protos}}, "PIKA_DEPRECATED_FOR($underscores)\n";
}
}
# Find the return argument (defaults to the first arg if not
# explicitly set
my $retarg = undef;
$retvoid = 0;
foreach (@outargs) {
$retarg = $_, last if exists $_->{retval};
}
unless ($retarg) {
if (scalar @outargs) {
if (exists $outargs[0]->{void_ret}) {
$retvoid = 1;
}
else {
$retarg = exists $outargs[0]->{num} ? $outargs[1]
: $outargs[0];
}
}
}
my $rettype;
if ($retarg) {
my ($type) = &arg_parse($retarg->{type});
my $argtype = $arg_types{$type};
my $annotate = "";
$rettype = &libtype($retarg, 1);
chop $rettype unless $rettype =~ /\*$/;
$retarg->{retval} = 1;
if (exists $argtype->{array}) {
$annotate = " (array length=$retarg->{array}->{name})";
}
if (exists $retarg->{none_ok}) {
$annotate .= " (nullable)";
}
if (exists $argtype->{out_annotate}) {
$annotate .= " $argtype->{out_annotate}";
}
if ($annotate eq "") {
$retdesc .= " $retarg->{desc}";
}
else {
if (exists $retarg->{desc}) {
if ((length ($annotate) +
length ($retarg->{desc})) > 65) {
$retdesc .= $annotate . ":\n * " . $retarg->{desc};
}
else {
$retdesc .= $annotate . ": " . $retarg->{desc};
}
}
}
unless ($retdesc =~ /[\.\!\?]$/) { $retdesc .= '.' }
if ($retarg->{type} eq 'string') {
$retdesc .= "\n * The returned value must be freed with g_free().";
}
elsif ($retarg->{type} eq 'strv') {
$retdesc .= "\n * The returned value must be freed with g_strfreev().";
}
elsif ($retarg->{type} eq 'param') {
$retdesc .= "\n * The returned value must be freed with g_param_spec_unref().";
}
elsif (exists $argtype->{array}) {
$retdesc .= "\n * The returned value must be freed with g_free().";
}
}
else {
# No return values
$rettype = 'void';
}
# The parameters to the function
my $arglist = "";
my $argdesc = "";
my $sincedesc = "";
my $value_array = "";
my $arg_array = "";
my $argc = 0;
foreach (@inargs) {
my ($type, @typeinfo) = &arg_parse($_->{type});
my $arg = $arg_types{$type};
my $var = $_->{name};
my $desc = exists $_->{desc} ? $_->{desc} : "";
my $var_len;
my $value;
# This gets passed to pika_value_array_new_with_types()
if ($type eq 'enum') {
$enum_type = $typeinfo[0];
$enum_type =~ s/([a-z])([A-Z])/$1_$2/g;
$enum_type =~ s/([A-Z]+)([A-Z])/$1_$2/g;
$enum_type =~ tr/[a-z]/[A-Z]/;
$enum_type =~ s/^PIKA/PIKA_TYPE/;
$enum_type =~ s/^GEGL/GEGL_TYPE/;
$value_array .= "$enum_type, ";
}
else {
$value_array .= "$arg->{gtype}, ";
}
if (exists $_->{array}) {
$value_array .= "NULL";
}
else {
$value_array .= "$var";
}
$value_array .= ",\n" . " " x 42;
if (exists $_->{array}) {
my $arrayarg = $_->{array};
$value = "pika_value_array_index (args, $argc)";
if (exists $arrayarg->{name}) {
$var_len = $arrayarg->{name};
}
else {
$var_len = 'num_' . $_->{name};
}
# This is the list of g_value_set_foo_array
$arg_array .= eval qq/" $arg->{set_value_func};\n"/;
}
$usednames{$_->{name}}++;
$arglist .= &libtype($_, 0);
$arglist .= $_->{name};
$arglist .= ', ';
$argdesc .= " * \@$_->{name}";
$argdesc .= ":";
if (exists $arg->{array}) {
$argdesc .= " (array length=@inargs[$argc - 1]->{name})";
}
if (exists $arg->{in_annotate}) {
$argdesc .= " $arg->{in_annotate}";
}
if (exists $_->{none_ok}) {
$argdesc .= " (nullable)";
}
if (exists $arg->{array} || exists $_->{none_ok} || exists $arg->{in_annotate}) {
$argdesc .= ":";
}
$argdesc .= " $desc";
unless ($argdesc =~ /[\.\!\?]$/) { $argdesc .= '.' }
$argdesc .= "\n";
$argc++;
}
# This marshals the return value(s)
my $return_args = "";
my $return_marshal = "pika_value_array_unref (return_vals);";
# return success/failure boolean if we don't have anything else
if ($rettype eq 'void') {
$return_args .= "\n" . ' ' x 2 . "gboolean success = TRUE;";
$retdesc .= " TRUE on success.";
}
# We only need to bother with this if we have to return a value
if ($rettype ne 'void' || $retvoid) {
my $once = 0;
my $firstvar;
my @initnums;
foreach (@outargs) {
my ($type) = &arg_parse($_->{type});
my $arg = $arg_types{$type};
my $var;
$return_marshal = "" unless $once++;
$_->{libname} = exists $usednames{$_->{name}} ? "ret_$_->{name}"
: $_->{name};
if (exists $_->{num}) {
if (!exists $_->{no_lib}) {
push @initnums, $_;
}
}
elsif (exists $_->{retval}) {
$return_args .= "\n" . ' ' x 2;
$return_args .= &libtype($_, 1);
# The return value variable
$var = $_->{libname};
$return_args .= $var;
# Save the first var to "return" it
$firstvar = $var unless defined $firstvar;
if ($_->{libdef}) {
$return_args .= " = $_->{libdef}";
}
else {
$return_args .= " = $arg->{init_value}";
}
$return_args .= ";";
if (exists $_->{array} && exists $_->{array}->{no_lib}) {
$return_args .= "\n" . ' ' x 2 . "gint num_$var;";
}
}
elsif ($retvoid) {
push @initnums, $_ unless exists $arg->{struct};
}
}
if (scalar(@initnums)) {
foreach (@initnums) {
$return_marshal .= "\*$_->{libname} = ";
my ($type) = &arg_parse($_->{type});
for ($arg_types{$type}->{type}) {
/\*$/ && do { $return_marshal .= "NULL"; last };
/boolean/ && do { $return_marshal .= "FALSE"; last };
/double/ && do { $return_marshal .= "0.0"; last };
$return_marshal .= "0";
}
$return_marshal .= ";\n ";
}
$return_marshal =~ s/\n $/\n\n /s;
}
if ($rettype eq 'void') {
$return_marshal .= <<CODE;
success = PIKA_VALUES_GET_ENUM (return_vals, 0) == PIKA_PDB_SUCCESS;
if (success)
CODE
}
else {
$return_marshal .= <<CODE;
if (PIKA_VALUES_GET_ENUM (return_vals, 0) == PIKA_PDB_SUCCESS)
CODE
}
$return_marshal .= ' ' x 4 . "{\n" if $#outargs;
my $argc = 1; my ($numpos, $numtype);
foreach (@outargs) {
my ($type) = &arg_parse($_->{type});
my $desc = exists $_->{desc} ? $_->{desc} : "";
my $arg = $arg_types{$type};
my $var;
# The return value variable
$var = "";
unless (exists $_->{retval}) {
$var .= '*';
$arglist .= &libtype($_, 1);
$arglist .= '*' unless exists $arg->{struct};
$arglist .= "$_->{libname}";
$arglist .= ', ';
$argdesc .= " * \@$_->{libname}";
if ($arg->{name} eq 'COLOR') {
$argdesc .= ": (out caller-allocates)";
}
else {
$argdesc .= ": (out)";
}
if (exists $arg->{array}) {
$argdesc .= " (array length=@outargs[$argc - 2]->{name})";
}
if (exists $arg->{out_annotate}) {
$argdesc .= " $arg->{out_annotate}";
}
$argdesc .= ": $desc";
}
$var = exists $_->{retval} ? "" : '*';
$var .= $_->{libname};
$value = "return_vals, $argc";
$return_marshal .= ' ' x 2 if $#outargs;
$return_marshal .= eval qq/" $arg->{dup_value_func};\n"/;
if ($argdesc) {
unless ($argdesc =~ /[\.\!\?]$/) { $argdesc .= '.' }
unless ($argdesc =~ /\n$/) { $argdesc .= "\n" }
}
$argc++;
}
$return_marshal .= ' ' x 4 . "}\n" if $#outargs;
$return_marshal .= <<'CODE';
pika_value_array_unref (return_vals);
CODE
unless ($retvoid) {
$return_marshal .= ' ' x 2 . "return $firstvar;";
}
else {
$return_marshal .= ' ' x 2 . "return success;";
}
}
else {
$return_marshal = <<CODE;
success = PIKA_VALUES_GET_ENUM (return_vals, 0) == PIKA_PDB_SUCCESS;
$return_marshal
return success;
CODE
chop $return_marshal;
}
if ($arglist) {
my @arglist = split(/, /, $arglist);
my $longest = 0; my $seen = 0;
foreach (@arglist) {
/(const \w+) \S+/ || /(\w+) \S+/;
my $len = length($1);
my $num = scalar @{[ /\*/g ]};
$seen = $num if $seen < $num;
$longest = $len if $longest < $len;
}
$longest += $seen;
my $once = 0; $arglist = "";
foreach (@arglist) {
my $space = rindex($_, ' ');
my $len = $longest - $space + 1;
$len -= scalar @{[ /\*/g ]};
substr($_, $space, 1) = ' ' x $len if $space != -1 && $len > 1;
$arglist .= "\t" if $once;
$arglist .= $_;
$arglist .= ",\n";
$once++;
}
$arglist =~ s/,\n$//;
}
else {
$arglist = "void";
}
$rettype = 'gboolean' if $rettype eq 'void';
# Our function prototype for the headers
(my $hrettype = $rettype) =~ s/ //g;
my $proto = "$hrettype $wrapped$funcname ($arglist);\n";
$proto =~ s/ +/ /g;
push @{$out->{protos}}, $proto;
my $clist = $arglist;
my $padlen = length($wrapped) + length($funcname) + 2;
my $padding = ' ' x $padlen;
$clist =~ s/\t/$padding/eg;
if ($proc->{since}) {
$sincedesc = "\n *\n * Since: $proc->{since}";
}
my $procdesc = '';
if ($proc->{deprecated}) {
if ($proc->{deprecated} eq 'NONE') {
if ($proc->{blurb}) {
$procdesc = &desc_wrap($proc->{blurb}) . "\n *\n";
}
if ($proc->{help}) {
$procdesc .= &desc_wrap($proc->{help}) . "\n *\n";
}
$procdesc .= &desc_wrap("Deprecated: There is no replacement " .
"for this procedure.");
}
else {
my $underscores = $proc->{deprecated};
$underscores =~ s/-/_/g;
if ($proc->{blurb}) {
$procdesc = &desc_wrap($proc->{blurb}) . "\n *\n";
}
if ($proc->{help}) {
$procdesc .= &desc_wrap($proc->{help}) . "\n *\n";
}
$procdesc .= &desc_wrap("Deprecated: " .
"Use $underscores() instead.");
}
}
else {
$procdesc = &desc_wrap($proc->{blurb}) . "\n *\n" .
&desc_wrap($proc->{help});
}
return <<CODE;
/**
* $wrapped$funcname:$func_annotations$skip_gi
$argdesc *
$procdesc
*
$retdesc$sincedesc
**/
$rettype
$wrapped$funcname ($clist)
{
PikaValueArray *args;
PikaValueArray *return_vals;$return_args
args = pika_value_array_new_from_types (NULL,
${value_array}G_TYPE_NONE);
$arg_array
return_vals = pika_pdb_run_procedure_array (pika_get_pdb (),
"pika-$proc->{canonical_name}",
args);
pika_value_array_unref (args);
$return_marshal
}
CODE
}
sub generate_hbody {
my ($out, $extra) = @_;
if (exists $extra->{protos}) {
my $proto = "";
foreach (split(/\n/, $extra->{protos})) {
next if /^\s*$/;
if (/^\t/ && length($proto)) {
s/\s+/ /g; s/ $//; s/^ /\t/;
$proto .= $_ . "\n";
}
else {
push @{$out->{protos}}, $proto if length($proto);
s/\s+/ /g; s/^ //; s/ $//;
$proto = $_ . "\n";
}
}
}
my @longest = (0, 0, 0); my @arglist = (); my $seen = 0;
foreach (@{$out->{protos}}) {
my $arglist;
if (!/^PIKA_DEPRECATED/) {
my $len;
$arglist = [ split(' ', $_, 3) ];
if ($arglist->[1] =~ /^_/) {
$arglist->[0] = "G_GNUC_INTERNAL ".$arglist->[0];
}
for (0..1) {
$len = length($arglist->[$_]);
$longest[$_] = $len if $longest[$_] < $len;
}
foreach (split(/,/, $arglist->[2])) {
next unless /(const \w+) \S+/ || /(\w+) \S+/;
$len = length($1) + 1;
my $num = scalar @{[ /\*/g ]};
$seen = $num if $seen < $num;
$longest[2] = $len if $longest[2] < $len;
}
}
else {
$arglist = $_;
}
push @arglist, $arglist;
}
$longest[2] += $seen;
@{$out->{protos}} = ();
foreach (@arglist) {
my $arg;
if (ref) {
my ($type, $func, $arglist) = @$_;
my @args = split(/,/, $arglist); $arglist = "";
foreach (@args) {
$space = rindex($_, ' ');
if ($space > 0 && substr($_, $space - 1, 1) eq ')') {
$space = rindex($_, ' ', $space - 1)
}
my $len = $longest[2] - $space + 1;
$len -= scalar @{[ /\*/g ]};
$len++ if /\t/;
if ($space != -1 && $len > 1) {
substr($_, $space, 1) = ' ' x $len;
}
$arglist .= $_;
$arglist .= "," if !/;\n$/;
}
$arg = $type;
$arg .= ' ' x ($longest[0] - length($type) + 1) . $func;
$arg .= ' ' x ($longest[1] - length($func) + 1) . $arglist;
$arg =~ s/\t/' ' x ($longest[0] + $longest[1] + 3)/eg;
}
else {
$arg = $_;
}
push @{$out->{protos}}, $arg;
}
my $body = '';
$body = $extra->{decls} if exists $extra->{decls};
foreach (@{$out->{protos}}) { $body .= $_ }
if ($out->{deprecated}) {
$body .= "#endif /* PIKA_DISABLE_DEPRECATED */\n";
}
chomp $body;
return $body;
}
sub generate {
my @procs = @{(shift)};
my %out;
foreach $name (@procs) {
my $proc = $main::pdb{$name};
my $out = \%{$out{$proc->{group}}};
my @inargs = @{$proc->{inargs}} if (defined $proc->{inargs});
my @outargs = @{$proc->{outargs}} if (defined $proc->{outargs});
$out->{code} .= generate_fun($proc, $out);
}
my $lgpl_top = <<'LGPL';
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
*
LGPL
my $lgpl_bottom = <<'LGPL';
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
/* NOTE: This file is auto-generated by pdbgen.pl */
LGPL
# We generate two files, a _pdb.h file with prototypes for all
# the functions we make, and a _pdb.c file for the actual implementation
while (my($group, $out) = each %out) {
my $hname = "${group}pdb.h";
my $cname = "${group}pdb.c";
if ($group ne 'pika') {
$hname = "pika${hname}";
$cname = "pika${cname}";
}
$hname =~ s/_//g; $hname =~ s/pdb\./_pdb./;
$cname =~ s/_//g; $cname =~ s/pdb\./_pdb./;
my $hfile = "$builddir/$hname$FILE_EXT";
my $cfile = "$builddir/$cname$FILE_EXT";
my $body;
my $extra = {};
if (exists $main::grp{$group}->{extra}->{lib}) {
$extra = $main::grp{$group}->{extra}->{lib}
}
$body = generate_hbody($out, $extra, "protos");
open HFILE, "> $hfile" or die "Can't open $hfile: $!\n";
print HFILE $lgpl_top;
print HFILE " * $hname\n";
print HFILE $lgpl_bottom;
my $guard = "__PIKA_\U$group\E_PDB_H__";
print HFILE <<HEADER;
#if !defined (__PIKA_H_INSIDE__) && !defined (PIKA_COMPILATION)
#error "Only <libpika/pika.h> can be included directly."
#endif
#ifndef $guard
#define $guard
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
$body
G_END_DECLS
#endif /* $guard */
HEADER
close HFILE;
&write_file($hfile, $destdir);
open CFILE, "> $cfile" or die "Can't open $cfile: $!\n";
print CFILE $lgpl_top;
print CFILE " * $cname\n";
print CFILE $lgpl_bottom;
print CFILE qq/#include "config.h"\n\n/;
print CFILE qq/#include "stamp-pdbgen.h"\n\n/;
print CFILE $out->{headers}, "\n" if exists $out->{headers};
print CFILE qq/#include "pika.h"\n/;
if (exists $main::grp{$group}->{lib_private}) {
print CFILE qq/#include "$hname"\n/;
}
if (exists $main::grp{$group}->{doc_title}) {
$long_desc = &desc_wrap($main::grp{$group}->{doc_long_desc});
print CFILE <<SECTION_DOCS;
/**
* SECTION: $main::grp{$group}->{doc_title}
* \@title: $main::grp{$group}->{doc_title}
* \@short_description: $main::grp{$group}->{doc_short_desc}
*
${long_desc}
**/
SECTION_DOCS
}
print CFILE "\n", $extra->{code} if exists $extra->{code};
print CFILE $out->{code};
close CFILE;
&write_file($cfile, $destdir);
}
if (! $ENV{PDBGEN_GROUPS}) {
my $pika_pdb_headers = "$builddir/pika_pdb_headers.h$FILE_EXT";
open PFILE, "> $pika_pdb_headers" or die "Can't open $pika_pdb_headers: $!\n";
print PFILE $lgpl_top;
print PFILE " * pika_pdb_headers.h\n";
print PFILE $lgpl_bottom;
my $guard = "__PIKA_PDB_HEADERS_H__";
print PFILE <<HEADER;
#if !defined (__PIKA_H_INSIDE__) && !defined (PIKA_COMPILATION)
#error "Only <libpika/pika.h> can be included directly."
#endif
#ifndef $guard
#define $guard
HEADER
my @groups;
foreach $group (keys %out) {
my $hname = "${group}pdb.h";
if ($group ne 'pika') {
$hname = "pika${hname}";
}
$hname =~ s/_//g; $hname =~ s/pdb\./_pdb./;
if (! exists $main::grp{$group}->{lib_private}) {
push @groups, $hname;
}
}
foreach $group (sort @groups) {
print PFILE "#include <libpika/$group>\n";
}
print PFILE <<HEADER;
#endif /* $guard */
HEADER
close PFILE;
&write_file($pika_pdb_headers, $destdir);
}
}

19
pdb/meson-pdbgen.sh Normal file
View File

@ -0,0 +1,19 @@
#!/bin/sh
PERL="$1"
top_srcdir="$2"
top_builddir="$3"
# Environment for the pdbgen.pl file.
destdir=`cd "$top_srcdir" && pwd`
export destdir
builddir=`cd "$top_builddir" && pwd`
export BUILD builddir
cd "$top_srcdir"/pdb
$PERL pdbgen.pl app lib
RET=$?
if [ $RET -eq 0 ]; then
echo "/* Generated on `date`. */" > $top_builddir/pdb/stamp-pdbgen.h
fi
exit $RET

200
pdb/meson.build Normal file
View File

@ -0,0 +1,200 @@
pdbgen_backup = false
pdbgen_groups = false
pdb_names = [
'brush_select',
'brush',
'brushes',
'buffer',
'channel',
'context',
'debug',
'display',
'drawable_color',
'drawable_edit',
'drawable',
'dynamics',
'edit',
'file',
'floating_sel',
'font',
'font_select',
'fonts',
'pika',
'pikarc',
'gradient_select',
'gradient',
'gradients',
'help',
'image_color_profile',
'image_convert',
'image_grid',
'image_guides',
'image_sample_points',
'image_select',
'image_transform',
'image_undo',
'image',
'item_transform',
'item',
'layer',
'message',
'paint_tools',
'palette_select',
'palette',
'palettes',
'pattern_select',
'pattern',
'patterns',
'pdb',
'plug_in_compat',
'plug_in',
'progress',
'resource',
'selection',
'text_layer',
'text_tool',
'unit',
'vectors',
]
pdb_sources = []
foreach name : pdb_names
pdb_sources += files('groups' / name + '.pdb')
endforeach
enum_headers = [
meson.project_source_root() + '/libpikabase/pikabaseenums.h',
meson.project_source_root() + '/libpikaconfig/pikaconfigenums.h',
meson.project_source_root() + '/app/operations/operations-enums.h',
meson.project_source_root() + '/app/core/core-enums.h',
meson.project_source_root() + '/app/paint/paint-enums.h'
]
# Perl environment
perlsrcdir = meson.current_source_dir()
perlbindir = meson.current_build_dir()
perl_env = [
'PDBGEN_BACKUP=' + (pdbgen_backup ? '1' : '0'),
'PDBGEN_GROUPS=' + (pdbgen_groups ? '1' : '0'),
'rootme=' + perlbindir,
'srcdir=' + perlsrcdir,
'destdir=' + meson.project_build_root(),
'builddir=' + meson.project_build_root(),
]
perl_opts = [
perl,
'-I', perlbindir,
'-I', perlsrcdir,
]
groups_pl_content = '# This file is autogenerated\n'
groups_pl_content += '@groups = qw(\n'
foreach source : pdb_names
groups_pl_content += ' '+ source +'\n'
endforeach
groups_pl_content += ');\n'
# All perl files
groups_pl = custom_target('groups.pl',
input : [ ],
output: [ 'groups.pl', ],
command: [ 'echo', groups_pl_content, ],
capture: true,
)
pdbgen_run = find_program('meson-pdbgen.sh')
if meson.version().version_compare('>=0.57.0')
enums_pl = custom_target('enums.pl',
input : [ 'enumgen.pl', 'enums-external.pl', enum_headers, ],
output: [ 'enums.pl', ],
env: perl_env,
command: [
perl, '@INPUT0@',
enum_headers,
],
)
pdbgen = custom_target('stamp-pdbgen.h',
input : [
files(
'meson-pdbgen.sh',
'pdbgen.pl',
'app.pl',
'lib.pl',
'pdb.pl',
'stddefs.pdb',
'util.pl',
),
enums_pl,
groups_pl,
pdb_sources,
],
output: [ 'stamp-pdbgen.h', ],
env: perl_env,
command: [
pdbgen_run, perl, meson.project_source_root(), meson.project_build_root()
],
)
stamp_enumcode = custom_target('stamp-enum-code',
input : [ 'enumcode.pl', ],
output: [ 'stamp-enum-code', ],
env: perl_env,
command: [
perl_opts, '@INPUT0@',
],
)
else
# TODO: remove this workaround when we bump meson requirement to >= 0.57.0
# See MR !506.
# In the meantime, make sure the 2 if/else blocks are well synced.
env = find_program('env')
enums_pl = custom_target('enums.pl',
input : [ 'enumgen.pl', 'enums-external.pl', enum_headers, ],
output: [ 'enums.pl', ],
command: [
env, perl_env, perl_opts, '@INPUT0@',
enum_headers,
],
)
pdbgen = custom_target('stamp-pdbgen.h',
input : [
files(
'meson-pdbgen.sh',
'pdbgen.pl',
'app.pl',
'lib.pl',
'pdb.pl',
'stddefs.pdb',
'util.pl',
),
enums_pl,
groups_pl,
pdb_sources,
],
output: [ 'stamp-pdbgen.h', ],
command: [
env, perl_env, pdbgen_run, perl, meson.project_source_root(), meson.project_build_root()
],
)
stamp_enumcode = custom_target('stamp-enum-code',
input : [ 'enumcode.pl', ],
output: [ 'stamp-enum-code', ],
command: [
env, perl_env, perl_opts, '@INPUT0@',
],
)
endif

519
pdb/pdb.pl Normal file
View File

@ -0,0 +1,519 @@
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1998-2003 Manish Singh <yosh@gimp.org>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 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, see <https://www.gnu.org/licenses/>.
package Pika::CodeGen::pdb;
%arg_types = (
int32 => { name => 'INT32',
gtype => 'G_TYPE_INT',
type => 'gint ',
const_type => 'gint ',
init_value => '0',
get_value_func => '$var = g_value_get_int ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_INT ($value)',
set_value_func => 'g_value_set_int ($value, $var)',
take_value_func => 'g_value_set_int ($value, $var)' },
uchar => { name => 'UCHAR',
gtype => 'G_TYPE_UCHAR',
type => 'guchar ',
const_type => 'guchar ',
init_value => '0',
get_value_func => '$var = g_value_get_uchar ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_UCHAR ($value)',
set_value_func => 'g_value_set_uchar ($value, $var)',
take_value_func => 'g_value_set_uchar ($value, $var)' },
float => { name => 'FLOAT',
gtype => 'G_TYPE_DOUBLE',
type => 'gdouble ',
const_type => 'gdouble ',
init_value => '0.0',
get_value_func => '$var = g_value_get_double ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_DOUBLE ($value)',
set_value_func => 'g_value_set_double ($value, $var)',
take_value_func => 'g_value_set_double ($value, $var)' },
string => { name => 'STRING',
gtype => 'G_TYPE_STRING',
type => 'gchar *',
const_type => 'const gchar *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_string ($value)',
dup_value_func => '$var = PIKA_VALUES_DUP_STRING ($value)',
set_value_func => 'g_value_set_string ($value, $var)',
take_value_func => 'g_value_take_string ($value, $var)' },
strv => { name => 'STRV',
gtype => 'G_TYPE_STRV',
type => 'gchar **',
const_type => 'const gchar **',
init_value => 'NULL',
in_annotate => '(array zero-terminated=1)',
out_annotate => '(array zero-terminated=1) (transfer full)',
get_value_func => '$var = g_value_get_boxed ($value)',
dup_value_func => '$var = PIKA_VALUES_DUP_STRV ($value)',
set_value_func => 'g_value_set_boxed ($value, $var)',
take_value_func => 'g_value_take_boxed ($value, $var)' },
bytes => { name => 'BYTES',
gtype => 'G_TYPE_BYTES',
type => 'GBytes *',
const_type => 'GBytes *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_boxed ($value)',
dup_value_func => '$var = PIKA_VALUES_DUP_BYTES ($value)',
set_value_func => 'g_value_set_boxed ($value, $var)',
take_value_func => 'g_value_take_boxed ($value, $var)' },
int32array => { name => 'INT32ARRAY',
gtype => 'PIKA_TYPE_INT32_ARRAY',
type => 'gint32 *',
const_type => 'const gint32 *',
array => 1,
init_value => 'NULL',
in_annotate => '(element-type gint32)',
out_annotate => '(element-type gint32) (transfer full)',
get_value_func => '$var = pika_value_get_int32_array ($value)',
dup_value_func => '$var = PIKA_VALUES_DUP_INT32_ARRAY ($value)',
set_value_func => 'pika_value_set_int32_array ($value, $var, $var_len)',
take_value_func => 'pika_value_take_int32_array ($value, $var, $var_len)' },
floatarray => { name => 'FLOATARRAY',
gtype => 'PIKA_TYPE_FLOAT_ARRAY',
type => 'gdouble *',
const_type => 'const gdouble *',
array => 1,
init_value => 'NULL',
in_annotate => '(element-type gdouble)',
out_annotate => '(element-type gdouble) (transfer full)',
get_value_func => '$var = pika_value_get_float_array ($value)',
dup_value_func => '$var = PIKA_VALUES_DUP_FLOAT_ARRAY ($value)',
set_value_func => 'pika_value_set_float_array ($value, $var, $var_len)',
take_value_func => 'pika_value_take_float_array ($value, $var, $var_len)' },
colorarray => { name => 'COLORARRAY',
gtype => 'PIKA_TYPE_RGB_ARRAY',
type => 'PikaRGB *',
const_type => 'const PikaRGB *',
array => 1,
init_value => 'NULL',
in_annotate => '(element-type PikaRGB)',
out_annotate => '(element-type PikaRGB) (transfer full)',
get_value_func => '$var = pika_value_get_rgb_array ($value)',
dup_value_func => '$var = PIKA_VALUES_DUP_RGB_ARRAY ($value)',
set_value_func => 'pika_value_set_rgb_array ($value, $var, $var_len)',
take_value_func => 'pika_value_take_rgb_array ($value, $var, $var_len)' },
imagearray => { name => 'IMAGEARRAY',
gtype => 'PIKA_TYPE_OBJECT_ARRAY',
type => 'PikaImage **',
const_type => 'const PikaImage **',
array => 1,
init_value => 'NULL',
in_annotate => '(element-type PikaImage)',
out_annotate => '(element-type PikaImage) (transfer container)',
get_value_func => '$var = (const PikaImage **) pika_value_get_object_array ($value)',
dup_value_func => '{ PikaObjectArray *a = g_value_get_boxed (pika_value_array_index ($value)); if (a) $var = g_memdup2 (a->data, a->length * sizeof (gpointer)); }',
set_value_func => 'pika_value_set_object_array ($value, PIKA_TYPE_IMAGE, (GObject **) $var, $var_len)',
take_value_func => 'pika_value_take_object_array ($value, PIKA_TYPE_IMAGE, (GObject **) $var, $var_len)' },
itemarray => { name => 'ITEMARRAY',
gtype => 'PIKA_TYPE_OBJECT_ARRAY',
type => 'PikaItem **',
const_type => 'const PikaItem **',
array => 1,
init_value => 'NULL',
in_annotate => '(element-type PikaItem)',
out_annotate => '(element-type PikaItem) (transfer container)',
get_value_func => '$var = (const PikaItem **) pika_value_get_object_array ($value)',
dup_value_func => '{ PikaObjectArray *a = g_value_get_boxed (pika_value_array_index ($value)); if (a) $var = g_memdup2 (a->data, a->length * sizeof (gpointer)); }',
set_value_func => 'pika_value_set_object_array ($value, PIKA_TYPE_ITEM, (GObject **) $var, $var_len)',
take_value_func => 'pika_value_take_object_array ($value, PIKA_TYPE_ITEM, (GObject **) $var, $var_len)' },
layerarray => { name => 'LAYERARRAY',
gtype => 'PIKA_TYPE_OBJECT_ARRAY',
type => 'PikaLayer **',
const_type => 'const PikaLayer **',
array => 1,
init_value => 'NULL',
in_annotate => '(element-type PikaLayer)',
out_annotate => '(element-type PikaLayer) (transfer container)',
get_value_func => '$var = (const PikaLayer **) pika_value_get_object_array ($value)',
dup_value_func => '{ PikaObjectArray *a = g_value_get_boxed (pika_value_array_index ($value)); if (a) $var = g_memdup2 (a->data, a->length * sizeof (gpointer)); }',
set_value_func => 'pika_value_set_object_array ($value, PIKA_TYPE_LAYER, (GObject **) $var, $var_len)',
take_value_func => 'pika_value_take_object_array ($value, PIKA_TYPE_LAYER, (GObject **) $var, $var_len)' },
channelarray => { name => 'CHANNELARRAY',
gtype => 'PIKA_TYPE_OBJECT_ARRAY',
type => 'PikaChannel **',
const_type => 'const PikaChannel **',
array => 1,
init_value => 'NULL',
in_annotate => '(element-type PikaChannel)',
out_annotate => '(element-type PikaChannel) (transfer container)',
get_value_func => '$var = (const PikaChannel **) pika_value_get_object_array ($value)',
dup_value_func => '{ PikaObjectArray *a = g_value_get_boxed (pika_value_array_index ($value)); if (a) $var = g_memdup2 (a->data, a->length * sizeof (gpointer)); }',
set_value_func => 'pika_value_set_object_array ($value, PIKA_TYPE_CHANNEL, (GObject **) $var, $var_len)',
take_value_func => 'pika_value_take_object_array ($value, PIKA_TYPE_CHANNEL, (GObject **) $var, $var_len)' },
vectorarray => { name => 'VECTORSARRAY',
gtype => 'PIKA_TYPE_OBJECT_ARRAY',
type => 'PikaVectors **',
const_type => 'const PikaVectors **',
array => 1,
init_value => 'NULL',
in_annotate => '(element-type PikaVectors)',
out_annotate => '(element-type PikaVectors) (transfer container)',
get_value_func => '$var = (const PikaVectors **) pika_value_get_object_array ($value)',
dup_value_func => '{ PikaObjectArray *a = g_value_get_boxed (pika_value_array_index ($value)); if (a) $var = g_memdup2 (a->data, a->length * sizeof (gpointer)); }',
set_value_func => 'pika_value_set_object_array ($value, PIKA_TYPE_VECTORS, (GObject **) $var, $var_len)',
take_value_func => 'pika_value_take_object_array ($value, PIKA_TYPE_VECTORS, (GObject **) $var, $var_len)' },
color => { name => 'COLOR',
gtype => 'PIKA_TYPE_RGB',
type => 'PikaRGB ',
const_type => 'PikaRGB ',
struct => 1,
init_value => '{ 0.0, 0.0, 0.0, 1.0 }',
get_value_func => 'pika_value_get_rgb ($value, &$var)',
dup_value_func => 'PIKA_VALUES_GET_RGB ($value, &$var)',
set_value_func => 'pika_value_set_rgb ($value, $var)',
take_value_func => 'pika_value_set_rgb ($value, &$var)',
headers => [ qw(<cairo.h> "libpikacolor/pikacolor.h") ] },
display => { name => 'DISPLAY',
gtype => 'PIKA_TYPE_DISPLAY',
type => 'PikaDisplay *',
const_type => 'PikaDisplay *',
app_type => 'PikaDisplay *',
app_const_type => 'PikaDisplay *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_DISPLAY ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)' },
image => { name => 'IMAGE',
gtype => 'PIKA_TYPE_IMAGE',
type => 'PikaImage *',
const_type => 'PikaImage *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_IMAGE ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikaimage.h") ] },
item => { name => 'ITEM',
gtype => 'PIKA_TYPE_ITEM',
type => 'PikaItem *',
const_type => 'PikaItem *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_ITEM ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikaitem.h") ] },
layer => { name => 'LAYER',
gtype => 'PIKA_TYPE_LAYER',
type => 'PikaLayer *',
const_type => 'PikaLayer *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_LAYER ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikalayer.h") ] },
text_layer => { name => 'TEXT_LAYER',
gtype => 'PIKA_TYPE_TEXT_LAYER',
type => 'PikaTextLayer *',
const_type => 'PikaTextLayer *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_TEXT_LAYER ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("text/pikatextlayer.h") ] },
channel => { name => 'CHANNEL',
gtype => 'PIKA_TYPE_CHANNEL',
type => 'PikaChannel *',
const_type => 'PikaChannel *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_CHANNEL ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikachannel.h") ] },
drawable => { name => 'DRAWABLE',
gtype => 'PIKA_TYPE_DRAWABLE',
type => 'PikaDrawable *',
const_type => 'PikaDrawable *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_DRAWABLE ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikadrawable.h") ] },
selection => { name => 'SELECTION',
gtype => 'PIKA_TYPE_SELECTION',
type => 'PikaSelection *',
const_type => 'PikaSelection *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_SELECTION ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikaselection.h") ] },
layer_mask => { name => 'CHANNEL',
gtype => 'PIKA_TYPE_LAYER_MASK',
type => 'PikaLayerMask *',
const_type => 'PikaLayerMask *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_LAYER_MASK ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikalayermask.h") ] },
vectors => { name => 'VECTORS',
gtype => 'PIKA_TYPE_VECTORS',
type => 'PikaVectors *',
const_type => 'PikaVectors *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_VECTORS ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("vectors/pikavectors.h") ] },
file => { name => 'FILE',
gtype => 'G_TYPE_FILE',
type => 'GFile *',
const_type => 'GFile *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_DUP_FILE ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)' },
parasite => { name => 'PARASITE',
gtype => 'PIKA_TYPE_PARASITE',
type => 'PikaParasite *',
const_type => 'const PikaParasite *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_boxed ($value)',
dup_value_func => '$var = PIKA_VALUES_DUP_PARASITE ($value)',
set_value_func => 'g_value_set_boxed ($value, $var)',
take_value_func => 'g_value_take_boxed ($value, $var)',
headers => [ qw("libpikabase/pikabase.h") ] },
param => { name => 'PARAM',
gtype => 'G_TYPE_PARAM_SPEC',
type => 'GParamSpec *',
const_type => 'GParamSpec *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_param ($value)',
dup_value_func => '$var = PIKA_VALUES_DUP_PARAM ($value)',
set_value_func => 'g_value_set_param ($value, $var)',
take_value_func => 'g_value_take_param ($value, $var)' },
# Special cases
enum => { name => 'ENUM',
gtype => 'G_TYPE_ENUM',
type => 'gint ',
const_type => 'gint ',
init_value => '0',
get_value_func => '$var = g_value_get_enum ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_ENUM ($value)',
set_value_func => 'g_value_set_enum ($value, $var)',
take_value_func => 'g_value_set_enum ($value, $var)' },
boolean => { name => 'BOOLEAN',
gtype => 'G_TYPE_BOOLEAN',
type => 'gboolean ',
const_type => 'gboolean ',
init_value => 'FALSE',
get_value_func => '$var = g_value_get_boolean ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_BOOLEAN ($value)',
set_value_func => 'g_value_set_boolean ($value, $var)',
take_value_func => 'g_value_set_boolean ($value, $var)' },
tattoo => { name => 'TATTOO',
gtype => 'G_TYPE_UINT',
type => 'guint ',
const_type => 'guint ',
init_value => '0',
get_value_func => '$var = g_value_get_uint ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_UINT ($value)',
set_value_func => 'g_value_set_uint ($value, $var)',
take_value_func => 'g_value_set_uint ($value, $var)' },
guide => { name => 'GUIDE',
gtype => 'G_TYPE_UINT',
type => 'guint ',
const_type => 'guint ',
init_value => '0',
get_value_func => '$var = g_value_get_uint ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_UINT ($value)',
set_value_func => 'g_value_set_uint ($value, $var)',
take_value_func => 'g_value_set_uint ($value, $var)' },
sample_point => { name => 'SAMPLE_POINT',
gtype => 'G_TYPE_UINT',
type => 'guint ',
const_type => 'guint ',
init_value => '0',
get_value_func => '$var = g_value_get_uint ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_UINT ($value)',
set_value_func => 'g_value_set_uint ($value, $var)',
take_value_func => 'g_value_set_uint ($value, $var)' },
unit => { name => 'UNIT',
gtype => 'PIKA_TYPE_UNIT',
type => 'PikaUnit ',
const_type => 'PikaUnit ',
init_value => 'PIKA_UNIT_PIXEL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_int ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_INT ($value)',
set_value_func => 'g_value_set_int ($value, $var)',
take_value_func => 'g_value_set_int ($value, $var)' },
resource => { name => 'RESOURCE',
gtype => 'PIKA_TYPE_RESOURCE',
type => 'PikaResource *',
const_type => 'PikaResource *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_RESOURCE ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikaresource.h") ] },
brush => { name => 'BRUSH',
gtype => 'PIKA_TYPE_BRUSH',
type => 'PikaBrush *',
const_type => 'PikaBrush *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_BRUSH ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikabrush.h") ] },
pattern => { name => 'PATTERN',
gtype => 'PIKA_TYPE_PATTERN',
type => 'PikaPattern *',
const_type => 'PikaPattern *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_PATTERN ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikapattern.h") ] },
gradient => { name => 'GRADIENT',
gtype => 'PIKA_TYPE_GRADIENT',
type => 'PikaGradient *',
const_type => 'PikaGradient *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_GRADIENT ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikagradient.h") ] },
palette => { name => 'PALETTE',
gtype => 'PIKA_TYPE_PALETTE',
type => 'PikaPalette *',
const_type => 'PikaPalette *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_PALETTE ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/pikapalette.h") ] },
font => { name => 'FONT',
gtype => 'PIKA_TYPE_FONT',
type => 'PikaFont *',
const_type => 'PikaFont *',
init_value => 'NULL',
out_annotate => '(transfer none)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = PIKA_VALUES_GET_FONT ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("text/pikafont.h") ] }
);
# Split out the parts of an arg constraint
sub arg_parse {
my $arg = shift;
if ($arg =~ /^enum (\w+)(.*)/) {
my ($name, $remove) = ($1, $2);
my @retvals = ('enum', $name);
if ($remove && $remove =~ m@ \(no @) {
chop $remove; ($remove = substr($remove, 5)) =~ s/ $//;
push @retvals, split(/,\s*/, $remove);
}
return @retvals;
}
elsif ($arg =~ /^unit(?: \(min (.*?)\))?/) {
my @retvals = ('unit');
push @retvals, $1 if $1;
return @retvals;
}
elsif ($arg =~ /^(?:([+-.\dA-Z_][^\s]*) \s* (<=|<))?
\s* (\w+) \s*
(?:(<=|<) \s* ([+-.\dA-Z_][^\s]*))?
/x) {
return ($3, $1, $2, $5, $4);
}
}
1;

242
pdb/pdbgen.pl Normal file
View File

@ -0,0 +1,242 @@
#!/usr/bin/perl -w
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1998-2003 Manish Singh <yosh@gimp.org>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 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, see <https://www.gnu.org/licenses/>.
require 5.004;
BEGIN {
$srcdir = $ENV{srcdir} || '.';
$destdir = $ENV{destdir} || '.';
$builddir = $ENV{builddir} || '.';
}
use lib $srcdir;
BEGIN {
# Some important stuff
require 'pdb.pl';
require 'enums.pl';
require 'util.pl';
# What to do?
require 'groups.pl';
if ($ENV{PDBGEN_GROUPS}) {
@groups = split(/:/, $ENV{PDBGEN_GROUPS});
}
}
# Stifle "used only once" warnings
$destdir = $destdir;
$builddir = $builddir;
%pdb = ();
# The actual parser (in a string so we can eval it in another namespace)
$evalcode = <<'CODE';
{
my $file = $main::file;
my $srcdir = $main::srcdir;
my $copyvars = sub {
my $dest = shift;
foreach (@_) {
if (eval "defined scalar $_") {
(my $var = $_) =~ s/^(\W)//;
for ($1) {
/\$/ && do { $$dest->{$var} = $$var ; last; };
/\@/ && do { $$dest->{$var} = [ @$var ]; last; };
/\%/ && do { $$dest->{$var} = { %$var }; last; };
}
}
}
};
# Variables to evaluate and insert into the PDB structure
my @procvars = qw($name $group $blurb $help $author $copyright $date $since
$deprecated @inargs @outargs %invoke $canonical_name
$lib_private $skip_gi);
# These are attached to the group structure
my @groupvars = qw($desc $doc_title $doc_short_desc $doc_long_desc
$lib_private $skip_gi
@headers %extra);
# Hook some variables into the top-level namespace
*pdb = \%main::pdb;
*gen = \%main::gen;
*grp = \%main::grp;
# Hide our globals
my $safeeval = sub { local(%pdb, %gen, %grp); eval $_[0]; die $@ if $@ };
# Some standard shortcuts used by all def files
&$safeeval("do '$main::srcdir/stddefs.pdb'");
# Group properties
foreach (@groupvars) { eval "undef $_" }
# Load the file in and get the group info
&$safeeval("require '$main::srcdir/groups/$file.pdb'");
# Save these for later
&$copyvars(\$grp{$file}, @groupvars);
foreach $proc (@procs) {
# Reset all our PDB vars so previous defs don't interfere
foreach (@procvars) { eval "undef $_" }
# Get the info
&$safeeval("&$proc");
# Some derived fields
$name = $proc;
$group = $file;
($canonical_name = $name) =~ s/_/-/g;
# Load the info into %pdb, making copies of the data instead of refs
my $entry = {};
&$copyvars(\$entry, @procvars);
$pdb{$proc} = $entry;
}
# Find out what to do with these entries
while (my ($dest, $procs) = each %exports) { push @{$gen{$dest}}, @$procs }
}
CODE
# Slurp in the PDB defs
foreach $file (@groups) {
print "Processing $srcdir/groups/$file.pdb...\n";
eval "package Pika::CodeGen::Safe::$file; $evalcode;";
die $@ if $@;
}
# Squash whitespace into just single spaces between words.
# Single new lines are considered as normal spaces, but n > 1 newlines are considered (n - 1) newlines.
# The slightly complicated suite of regexp is so that \n\s+\n is still considered a double newline.
sub trimspace { for (${$_[0]}) { s/(\S)[\ \t\r\f]*\n[\ \t\r\f]*(\S)/$1 $2/g; s/[\ \t\r\f]+/ /gs;
s/\n(([\ \t\r\f]*\n)+)/$1/g; s/[\ \t\r\f]*\n[\ \t\r\f]/\n/g ; s/^\s+//; s/\s+$//; } }
# Trim spaces and escape quotes C-style
sub nicetext {
my $val = shift;
if (defined $$val) {
&trimspace($val);
$$val =~ s/"/\\"/g;
}
}
# Do the same for all the strings in the args, plus expand constraint text
sub niceargs {
my $args = shift;
foreach $arg (@$args) {
foreach (keys %$arg) {
&nicetext(\$arg->{$_});
}
}
}
# Trim spaces from all the elements in a list
sub nicelist {
my $list = shift;
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->{void_ret} = 1 if exists $_->{void_ret};
$arg->{num} = 1;
push @$newargs, $arg;
}
push @$newargs, $_;
}
$$args = $newargs;
}
sub canonicalargs {
my $args = shift;
foreach $arg (@$args) {
($arg->{canonical_name} = $arg->{name}) =~ s/_/-/g;
}
}
# Post-process each pdb entry
while ((undef, $entry) = each %pdb) {
&nicetext(\$entry->{blurb});
&nicetext(\$entry->{help});
&nicetext(\$entry->{author});
&nicetext(\$entry->{copyright});
&nicetext(\$entry->{date});
foreach (qw(in out)) {
my $args = $_ . 'args';
if (exists $entry->{$args}) {
&arrayexpand(\$entry->{$args});
&niceargs($entry->{$args});
&canonicalargs($entry->{$args});
}
}
&nicelist($entry->{invoke}{headers}) if exists $entry->{invoke}{headers};
&nicelist($entry->{globals}) if exists $entry->{globals};
$entry->{invoke}{success} = 'TRUE' unless exists $entry->{invoke}{success};
}
# Generate code from the modules
my $didstuff;
while (@ARGV) {
my $type = shift @ARGV;
print "\nProcessing $type...\n";
if (exists $gen{$type}) {
require "$type.pl";
&{"Pika::CodeGen::${type}::generate"}($gen{$type});
print "done.\n";
$didstuff = 1;
}
else {
print "nothing to do.\n";
}
}
print "\nNothing done at all.\n" unless $didstuff;

201
pdb/stddefs.pdb Normal file
View File

@ -0,0 +1,201 @@
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1998-2003 Manish Singh <yosh@gimp.org>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 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, see <https://www.gnu.org/licenses/>.
# Boilerplate PDB stuff
sub std_pdb_misc {
$author = $copyright = 'Spencer Kimball & Peter Mattis';
$date = '1995-1996';
}
sub contrib_pdb_misc {
my $a = shift;
my $e = shift;
my $d = shift;
my $s = shift;
if ($e eq '') {
$author = "$a";
} else {
$author = "$a <$e>";
}
$copyright = "$a";
$date = "$d";
if ($s) {
$since = "$s";
}
}
sub adam_pdb_misc {
contrib_pdb_misc('Adam D. Moss', '', @_);
}
sub adrian_pdb_misc {
contrib_pdb_misc('Adrian Likins', 'adrian@gimp.org', @_);
}
sub adeath_pdb_misc {
contrib_pdb_misc('Alexia Death', '', @_);
}
sub andy_pdb_misc {
contrib_pdb_misc('Andy Thomas', '', @_);
}
sub austin_pdb_misc {
contrib_pdb_misc('Austin Donnelly', '', @_);
}
sub barak_pdb_misc {
contrib_pdb_misc('Barak Itkin', 'lightningismyname@gmail.com', @_);
}
sub bill_pdb_misc {
contrib_pdb_misc('Bill Skaggs', 'weskaggs@primate.ucdavis.edu', @_);
}
sub bootchk_pdb_misc {
contrib_pdb_misc('Lloyd Konneker', '', @_);
}
sub david_pdb_misc {
contrib_pdb_misc('David Gowers', '', @_);
}
sub ejs_pdb_misc {
contrib_pdb_misc('Ed Swartz', '', @_);
}
sub ell_pdb_misc {
contrib_pdb_misc('Ell', '', @_);
}
sub federico_pdb_misc {
contrib_pdb_misc('Federico Mena Quintero', '', @_);
}
sub jay_pdb_misc {
contrib_pdb_misc('Jay Cox', '', @_);
}
sub jehan_pdb_misc {
contrib_pdb_misc('Jehan', '', @_);
}
sub joao_pdb_misc {
contrib_pdb_misc('Jo\xc3\xa3o S. O. Bueno', '', @_);
}
sub josh_pdb_misc {
contrib_pdb_misc('Josh MacDonald', '', @_);
}
sub kevins_pdb_misc {
contrib_pdb_misc('Kevin Sookocheff', '', @_);
}
sub larry_pdb_misc {
contrib_pdb_misc('Larry Ewing', '', @_);
}
sub marc_pdb_misc {
contrib_pdb_misc('Marc Lehmann', '', @_);
}
sub marcus_pdb_misc {
contrib_pdb_misc('Marcus Heese', 'heese@cip.ifi.lmu.de', @_);
}
sub martin_pdb_misc {
contrib_pdb_misc('Martin Nordholts', '', @_);
}
sub mitch_pdb_misc {
contrib_pdb_misc('Michael Natterer', 'mitch@gimp.org', @_);
}
sub neo_pdb_misc {
contrib_pdb_misc('Sven Neumann', 'sven@gimp.org', @_);
}
sub nick_pdb_misc {
contrib_pdb_misc('Nick Lamb', '', @_);
}
sub raphael_pdb_misc {
contrib_pdb_misc('Rapha\xc3\xabl Quinet', 'raphael@gimp.org', @_);
}
sub rock_pdb_misc {
contrib_pdb_misc('Nathan Summers', 'rock@gimp.org', @_);
}
sub seth_pdb_misc {
contrib_pdb_misc('Seth Burgess', '', @_);
}
sub shlomi_pdb_misc {
contrib_pdb_misc('Shlomi Fish', 'shlomif@iglu.org.il', @_);
}
sub simon_pdb_misc {
contrib_pdb_misc('Simon Budig', '', @_);
}
sub sylvain_pdb_misc {
contrib_pdb_misc('Sylvain Foret', '', @_);
}
sub wolfgang_pdb_misc {
contrib_pdb_misc('Wolfgang Hofer', '', @_);
}
sub yosh_pdb_misc {
contrib_pdb_misc('Manish Singh', '', @_);
}
sub alxsa_pdb_misc {
contrib_pdb_misc('Alex S.', '', @_);
}
sub std_pdb_deprecated {
if (@_) {
$blurb = $help = '';
$deprecated = "@_";
} else {
$blurb = $help = '';
$deprecated = "NONE";
}
$author = $copyright = $date = '';
}
sub std_pdb_compat {
$author = $copyright = "Compatibility procedure. Please see '@_' for credits.";
}
sub std_pdb_debug {
$help .= <<'HELP';
This is a debug utility procedure. It is subject to change at any point,
and should not be used in production.
HELP
}
1;

52
pdb/util.pl Normal file
View File

@ -0,0 +1,52 @@
# PIKA - Photo and Image Kooker Application
# Copyright (C) 1998-2003 Manish Singh <yosh@gimp.org>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 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, see <https://www.gnu.org/licenses/>.
package Pika::CodeGen::util;
use File::Basename 'basename';
use File::Copy 'cp';
use File::Compare 'cmp';
$DEBUG_OUTPUT = exists $ENV{PDBGEN_BACKUP} ? $ENV{PDBGEN_BACKUP} : 1;
$FILE_EXT = ".tmp.$$";
sub write_file {
my $file = shift;
my $destdir = shift;
my $realfile = basename($file);
$realfile =~ s/$FILE_EXT$//;
$realfile = "$destdir/$realfile";
if (-e $realfile) {
if (cmp($realfile, $file)) {
cp($realfile, "$realfile~") if $DEBUG_OUTPUT;
cp($file, $realfile);
print "Wrote $realfile\n";
}
else {
print "No changes to $realfile\n";
}
unlink $file;
}
else {
rename $file, $realfile;
print "Wrote $realfile\n";
}
}
1;