Adapting scripts to PDB version 3
This describes some changes needed to port a Scriptfu script to GIMP 3.
This discusses changes required due to changes to the PDB API:
It also discusses a few changes to ScriptFu itself:
It does not document:
- PDB procedures whose names have changed (see PDB equivalence)
- PDB procedures that have been removed (see Removed Functions)
- PDB procedures that have been added
- changes in signature, where arguments are reordered or changed in number
Notation
Where we say “returns a vector”, in the v2 dialect, the returned value is actually a vector wrapped in a list, and you must use the car function to unwrap it. In the v3 dialect, the returned value is just a vector, not wrapped in a list.
Whether a called PDB procedure wraps its returned values in a list depends on the arity of the return values, that is, whether the PDB procedure returns a single result.
Passing containers as objects and generalized re passing of selected layers
The API of the PDB has become more object oriented.
Formerly, the PDB passed C arrays as an integer length and the data of the array.
Now an array is passed as an object, which has a method for getting its length. (Both in C, and in Scheme.)
So, for example, now a plugin receives a container of drawables. A user can select many drawables to be passed to plugins. More details below.
Changes in types of PDB signatures
As you know, calls from a script to GIMP are calls to PDB procedures. PDB procedures are documented in terms of C, GLib, and GIMP types.
Formerly, the declared types of some arguments were primitives such as string names, or lists of numbers. Some of those arguments have changed to object types.
This table summarizes changes in the PDB API from v2 to v3. It gives the corresponding Scheme types. Each row is explained below, in the context of a Scheme plugin.
| Purpose | Old C type | New C type | Old Scheme type | New Scheme type |
|---|---|---|---|---|
| Pass file name | gchar*, gchar* | GFile | string string | string |
| Recv file name (not affected) | gchar* | GFile | string | string |
| Pass selected drawable | GimpDrawable | GimpCoreObjectArray | int (an ID) | vector |
| Pass obj array | gint, GimpInt32Array | GimpCoreObjectArray | int vector | vector |
| Recv obj array (not affected) | gint, GimpInt32Array | GimpCoreObjectArray | int vector | vector |
| Pass set of str | gint, GimpStringArray | GStrv | int list-of-string | list-of-string |
| Recv set of str | gint, GimpStringArray | GStrv | int list-of-string | list-of-string |
| Pass or Recv a color | GimpRGB | GeglColor | int triplet, or string name | same, or quadruplet |
| Pass or Recv a resource | gchar* | GimpFont, etc. | string | int (an ID) |
| Recv array of color | gint, GimpInt8Array | GimpColorArray | int vector | vector |
Where “obj” means an object of a GIMP type such as GimpDrawable or similar.
In the explanations below, we use integer literals for the ID’s of images and drawables. Ordinarily, scripts don’t do that, but instead pass object ID’s opaquely. Remember that internally, ScriptFu represents GIMP object by numeric IDs.
1 Pass one string for a filename instead of two.
Formerly a PDB procedure taking a filename (usually a full path) required two strings (two gchar* .). In Scheme, formerly you passed two strings, being the second string for a URI, to specify a remote file, or, in most cases, an empty second string.
Now such PDB procedures require type GFile. And Scheme now pass one string.
The single string in a script can be either a local file path or a remote URI.
Example:
(gimp-file-load RUN-NONINTERACTIVE "/tmp/foo" "") ;before
=> (gimp-file-load RUN-NONINTERACTIVE "/tmp/foo") ;now2 PDB procedures still return a string to Scheme, for a filename
Formerly a PDB signature for a procedure returning a filename specifies a returned type gchar*, but now specifies a returned type GFile.
The returned string is either a local file path or a URI.
3,4 Use a vector of drawables for PDB procedures that now take an array of drawables
Formerly, some PDB procedures took a single GimpDrawable.
But now they take an array of GimpDrawable (type GimpCoreObjectArray). This affects:
- Many of the file load/save procedures.
- Most plugins that are filters
- gimp-color-picker
- gimp-edit-copy
- gimp-edit-cut
- gimp-edit-named-copy
- gimp-edit-named-cut
- gimp-file-save
- gimp-image-pick-color
- gimp-selection-float
- gimp-xcf-save
For PDB procedures that now take an array of drawables,
in Scheme pass a vector of numeric drawable ID’s.
Examples:
(gimp-edit-copy drawable) => (gimp-edit-copy (vector drawable))
(gimp-edit-copy 2) => (gimp-edit-copy '#(2))
(gimp-edit-copy 2) => (gimp-edit-copy (vector 2))
(plug-in-despeckle NON-INTERACTIVE 1 2) => (plug-in-despeckle NON-INTERACTIVE 1 (vector 2))5 Receiving an array of drawables or other objects
Formerly a PDB procedure returning an array of drawables (or other GIMP objects) had a signature specifying a returned gint and GimpInt32Array.
Now the signature specifies a returned GimpCoreObjectArray. A script receives a vector. The elements of the vector are numeric ID’s, but are opaque to scripts (a script can pass them around, but should not for example use arithmetic on them.)
For example: (gimp-image-get-layers image) will return a Scheme vector of numerics, for drawable ID’s.
6,7 Passing or receiving a set of strings
Formerly, you passed an integer count of strings, and a list of strings.
Now you only pass the list of strings.
ScriptFu converts to/from the C type GStrv
(which is an object knowing its own length.)
Formerly, you received an integer count of strings, and a list of strings.
Now you only receive the list
(and subsequently get its length using (length list)).
Remember that in the v2 dialect, the result of a call to the PDB can be wrapped in an extra list. In this case the result is a list containing a list of strings, and for example you get the list of strings like “(car (gimp-fonts-get-list “.*”))”
8 Passing or receiving colors
The C type in the PDB changes from GimpRGB to GeglColor.
Arguments of this type are the “colors”.
In version 2, gimp-drawable-get-pixel returned a count of components and a list of components e.g. (3 (255 255 255)).
Now it just returns a list of components,
and the length of the list correlates with format length.
You may also receive a quadruplet for a color from an image with transparency.
See: list representation
ScriptFu and the PDB, however, do not have all the object methods needed to manipulate colors as objects. For example in ScriptFu you can’t get the format of a GeglColor. You can get the length of the list representation to know the format. So, you should not use Scheme scripts to alter colors as objects. See: Color in Script-Fu
9 Passing or receiving resources e.g. fonts
A resource is a brush, font, gradient, palette or pattern.
Formerly, a script passed or received the name of a resource. A name is type string.
Now resources are passed as objects, identified by an opaque integer ID.
The PDB has methods on superclass Resource.
A script can get an object for a resource by name.
(gimp-context-set-font "Sans Serif") => (gimp-context-set-font (gimp-font-get-by-name "Sans Serif"))A script can get attributes of a resource object.
(gimp-resource-get-name (gimp-context-get-brush))10 Receiving an array of color
Formerly, a script received an integer length and a list of lists of numbers.
Now a script receives just a list of lists of numbers.
Where each list of numbers was a triplet, i.e. an RGB representation.
Changes in error detection for calls to the PDB
Formerly, ScriptFu would not accept a call construct, to a PDB procedure, where the argument count was wrong, except for the case when you provided one argument to a PDB procedure that took zero arguments, called a nullary function.
Now, ScriptFu is now more forgiving in calls to PDB procedures. When a script has the wrong count of arguments to a PDB procedure:
-
too many actual arguments: ScriptFu will give a warning to the console and call the PDB procedure with a prefix of the actual arguments. This is now true no matter how many arguments the PDB procedure takes. Extra arguments in the script are ignored by Scriptfu, not evaluated and not passed to the PDB.
-
too few actual arguments: ScriptFu will give a warning to the console and call the PDB procedure with the given actual arguments. The warning will say the expected Scheme formal type of the first missing actual argument. Usually the PDB procedure will fail and return its own error message.
New keyword arguments in calls to plugins in the PDB
As you know, certain procedures in the PDB are Plugins. Other procedures are Internal.
Now, you can use keyword syntax for calls to plugins. See: Keyword arguments in calls to plugins in the PDB
ScriptFu logging
ScriptFu now does some logging using GLib logging.
When you define in the environment G_MESSAGES_DEBUG=scriptfu
ScriptFu will print many messages to the console.
This is most useful for GIMP developers, but sometimes useful to debug a script plugin. See: View Logs