"Fossies" - the Fresh Open Source Software Archive

Member "gimp-2.10.28/pdb/README_NEW_PDB_PROC" (14 Sep 2021, 17624 Bytes) of package /linux/misc/gimp-2.10.28.tar.bz2:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 Creating new PDB procedures
    2 ===========================
    3 Barak Itkin <lightningismyname@gmail.com>
    4 version 1.0, August 2010
    5 
    6 ////
    7 This document is an asciidoc document. It can be read as is, or you can
    8 print it as a formatted HTML page by running
    9 
   10     asciidoc README_NEW_PDB_PROC
   11 
   12 This will generate the file README_NEW_PDB_PROC.html.
   13 
   14 Note that inline code parts are marked with + signs around them.
   15 ////
   16 
   17 This tutorial will show you the basics of creating a new procedure and
   18 adding it to GIMP's PDB.
   19 
   20 Introduction
   21 ------------
   22 
   23 What are PDB procedures?
   24 ~~~~~~~~~~~~~~~~~~~~~~~~
   25 
   26 A *PDB procedure* is a process which is registered in the Procedure
   27 Data-Base. Procedures registered in the database are available to all
   28 the GIMP plugins/scripts.
   29 
   30 What should I want to add to the PDB?
   31 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   32 
   33 Let's say a new feature was added to GIMP, and your plugin/script wants
   34 to use it. In order to do so, this function should be publicly available
   35 (most functions are only available to GIMP's core, and in order to
   36 expose them externally we have to add them to the PDB).
   37 
   38 
   39 Anything I should know before continuing this tutorial?
   40 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   41 
   42 Yes. You should know
   43 https://en.wikipedia.org/wiki/C_%28programming_language%29[C Programming]
   44 (C is the language in which GIMP is coded), know a bit of
   45 https://library.gnome.org/devel/glib/stable/[Glib] (the library which
   46 GIMP uses for many of it's data-structures). In addition, you should
   47 know enough about the GIMP core for implementing your function (this is
   48 not a programming tutorial, this is only a technical tutorial) or at
   49 least have the intuition to understand enough from the code you see, to
   50 copy paste and modify the parts you need (In fact, this is how I made my
   51 first addition to the PDB :D However in most cases it's better to know
   52 what you are doing).
   53 
   54 The basics of PDB procedures
   55 ----------------------------
   56 
   57 Since adding a function to the PDB can be tedious (you would need to
   58 modify 3 or more different source files), a scripting framework was
   59 developed to add functions to the PDB by writing them once. To see how
   60 function are implemented in the PDB, take a look in
   61 https://gitlab.gnome.org/GNOME/gimp/tree/master/pdb/groups[pdb/groups].
   62 
   63 You can see many files with the .pdb suffix - these are special template
   64 files which include the actual source of the PDB functions. Let's take a
   65 quick look at one of these - text_layer_get_text in
   66 https://gitlab.gnome.org/GNOME/gimp/tree/master/pdb/groups/text_layer.pdb[pdb/groups/text_layer.pdb].
   67 
   68 [source,perl]
   69 ----
   70 sub text_layer_get_text {
   71     $blurb = 'Get the text from a text layer as string.';
   72 
   73     $help = <<'HELP';
   74 This procedure returns the text from a text layer as a string.
   75 HELP
   76 
   77     &marcus_pdb_misc('2008', '2.6');
   78 
   79     @inargs = (
   80         { name => 'layer', type => 'layer',
   81           desc => 'The text layer' }
   82     );
   83 
   84     @outargs = (
   85         { name => 'text', type => 'string',
   86           desc => 'The text from the specified text layer.' }
   87     );
   88 
   89     %invoke = (
   90         code => <<'CODE'
   91 {
   92   if (gimp_pdb_layer_is_text_layer (layer, FALSE, error))
   93     {
   94       g_object_get (gimp_text_layer_get_text (GIMP_TEXT_LAYER (layer)),
   95                     "text", &text,
   96                     NULL);
   97     }
   98   else
   99     {
  100       success = FALSE;
  101     }
  102 }
  103 CODE
  104     );
  105 }
  106 ----
  107 
  108 As you can see, all the function is wrapped inside the following wrapper:
  109 
  110 [source,perl]
  111 ----
  112 sub text_layer_get_text {
  113   ...
  114 }
  115 ----
  116 
  117 That's the first line, declaring the name of the new PDB function (it
  118 will be renamed to +gimp_text_layer_get_text+ automatically), and
  119 opening the braces for it's content.
  120 
  121 Description of the procedure
  122 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  123 
  124 At the beginning of the PDB function, you'll find lines similar to these:
  125 
  126 [source,perl]
  127 ----
  128     $blurb = 'Get the text from a text layer as string.';
  129 
  130     $help = <<'HELP';
  131 This procedure returns the text from a text layer as a string.
  132 HELP
  133 ----
  134 
  135 Every procedure has a blurb string and a help string. A blurb is a short
  136 string summarizing what the function does, and the help is a longer
  137 string  in which you describe your function in more depth.
  138 
  139 A one line string can be specified by simply putting it between braces
  140 (like the blurb string). A longer string, which can possibly spread over
  141 several lines, must be written in a special way:
  142 
  143 [source,perl]
  144 ----
  145 <<'HELP';
  146 This procedure returns the text from a text layer as a string.
  147 HELP
  148 ----
  149 
  150 The +<<'*HELP*'+ practically mean that the content of the string will be
  151 specified in the next lines and it will continue until reaching a line
  152 which has the content +HELP+ in it (without any spaces before/after it,
  153 and without anything else in that line).
  154 
  155 Now, the next line is:
  156 
  157 [source,perl]
  158 ----
  159      &marcus_pdb_misc('2008', '2.6');
  160 ----
  161 
  162 If you contribute a function to the GIMP PDB, you credit yourself in the
  163 source code. The above line is for an author which contributed many
  164 functions and he now has a simple macro to credit him. For us regular
  165 users, if we want to specify the credit to ourself we should replace the
  166 above line with the following lines:
  167 
  168 [source,perl]
  169 ----
  170     $author = 'Elvis Presley <the_king@rock.com>';
  171     $copyright = 'Elvis Presley';
  172     $date = '2010';
  173     $since = '2.8';
  174 ----
  175 
  176 Replace the values of +$author+ and +$copyright+ with your own name and
  177 email, replace the value of +$date+ with the date in which you wrote the
  178 function (most functions only specify the year, so try to keep with this
  179 standard instead of adding a full date). And finally, replace the value
  180 of +$since+ with the version of GIMP which will be the first to include
  181 this function. For example, if GIMP 2.6 was released, and 2.8 wasn't
  182 released yet. then new functionality will be added in 2.8 (new
  183 functionality is only added inside new major version releases) and you
  184 should specify 2.8.
  185 
  186 In and Out Arguments
  187 ~~~~~~~~~~~~~~~~~~~~
  188 After the header of the function which contains it's description, you'll
  189 find these lines:
  190 
  191 [source,perl]
  192 ----
  193     @inargs = (
  194         { name => 'layer', type => 'layer',
  195           desc => 'The text layer' }
  196     );
  197 
  198     @outargs = (
  199         { name => 'text', type => 'string',
  200           desc => 'The text from the specified text layer.' }
  201     );
  202 ----
  203 
  204 Here we specify the input arguments of this procedure, together with the
  205 returned arguments. As you can see, each argument has a name, a type and
  206 a description. The name will be used later in our code and it should be
  207 meaningful and be a valid name for a variable in C.
  208 
  209 The type is one of the types listed in
  210 https://gitlab.gnome.org/GNOME/gimp/tree/master/pdb/pdb.pl[pdb/pdb.pl]
  211 inside the +%arg_types+ array. In
  212 https://gitlab.gnome.org/GNOME/gimp/tree/master/pdb/pdb.pl[pdb/pdb.pl]
  213 you can see the corresponding C type for each of the types we specify.
  214 For example, +layer+ type (inside the .pdb file) becomes a variable with
  215 the C type of +GimpLayer *+, and +string+ becomes +gchar *+.
  216 
  217 If I want to add another input variable to the function, it'll look like this:
  218 
  219 [source,perl]
  220 ----
  221     @inargs = (
  222         { name => 'layer', type => 'layer',
  223           desc => 'The text layer' },
  224         { name => 'temp', type => 'int32',
  225           desc => 'My silly number' }
  226     );
  227 
  228     @outargs = (
  229         { name => 'text', type => 'string',
  230           desc => 'The text from the specified text layer.' }
  231     );
  232 ----
  233 
  234 Don't forget to add comma between arguments!
  235 
  236 The actual code
  237 ~~~~~~~~~~~~~~~
  238 
  239 After specifying the arguments we will specify the actual code of the
  240 function inside the following wrapper:
  241 
  242 [source,perl]
  243 ----
  244     %invoke = (
  245         code => <<'CODE'
  246 
  247      ...
  248 
  249 CODE
  250     );
  251 ----
  252 
  253 Now finally, let's take a look at the actual code:
  254 
  255 [source,c]
  256 ----
  257 {
  258   if (gimp_pdb_layer_is_text_layer (layer, FALSE, error))
  259     {
  260       g_object_get (gimp_text_layer_get_text (GIMP_TEXT_LAYER (layer)),
  261                     "text", &text,
  262                     NULL);
  263     }
  264   else
  265     {
  266       success = FALSE;
  267     }
  268 }
  269 ----
  270 
  271 This is a simple code in C - nothing fancy. However, this code uses
  272 functions from inside GIMP's core (hacking on the GIMP core will be the
  273 content for a different guide). The variables +text+ and +layer+, inside
  274 the C code, correspond to the variables we specified in the input/output
  275 arguments (since they have exactly the same name):
  276 
  277 [source,c]
  278 ----
  279     @inargs = (
  280         { name => 'layer', type => 'layer',
  281           desc => 'The text layer' }
  282     );
  283 
  284     @outargs = (
  285         { name => 'text', type => 'string',
  286           desc => 'The text from the specified text layer.' }
  287     );
  288 ----
  289 
  290 If for some reason, our function can fail (for example, in the code
  291 above the second line checks if the passed parameter is indeed a text
  292 layer and not just any layer) then we should add an indication that it
  293 failed by setting the variable +success+ to have the value +FALSE+.
  294 
  295 Now, we need to do two more things to finish our function: add it to
  296 the function list, and configure the includes correctly.
  297 
  298 Registering the function inside the PDB file
  299 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  300 
  301 At the end of the PDB file, you should find the following segments:
  302 
  303 [source,perl]
  304 ----
  305 @headers = qw("libgimpbase/gimpbase.h"
  306               "core/gimpcontext.h"
  307               "text/gimptext.h"
  308               "text/gimptextlayer.h"
  309               "gimppdb-utils.h"
  310               "gimppdberror.h"
  311               "gimp-intl.h");
  312 
  313 @procs = qw(text_layer_new
  314             text_layer_get_text
  315             text_layer_set_text
  316   ...
  317 );
  318 ----
  319 
  320 Inside the +@headers+ there is a list of various header files from the
  321 gimp source. If your code requires a header which is not specified, add
  322 it there.
  323 
  324 Inside the +@procs+ there is a list of the procedures which are exported
  325 by the file. *Make sure you add your procedure to the list!*
  326 
  327 Advanced details
  328 ----------------
  329 
  330 enum arguments
  331 ~~~~~~~~~~~~~~
  332 
  333 In some cases you would like to have arguments which have a value from
  334 an enum (enumeration). Instead of just declaring these as integer values
  335 and telling in your description which value corresponds to which number,
  336 this can be done automatically for you if the desired enum is one of the
  337 enums which are already used by GIMP.
  338 
  339 To make it clearer, let's take a look at +layer_get_mode+ in
  340 https://gitlab.gnome.org/GNOME/gimp/tree/master/pdb/groups/layer.pdb[pdb/groups/layer.pdb]:
  341 
  342 [source,perl]
  343 ----
  344     @outargs = (
  345 	{ name => 'mode', type => 'enum GimpLayerModeEffects',
  346 	  desc => 'The layer combination mode' }
  347     );
  348 ----
  349 
  350 If we take a look at the same procedure as it shows up in the procedure
  351 browser (+gimp_layer_get_mode+), we will see the following return values:
  352 
  353 [options="header",cols="1,1,11"]
  354 |=======================================================================
  355 |Name	|Type	|Description
  356 |mode	|INT32	|
  357 The layer combination mode { NORMAL-MODE (0), DISSOLVE-MODE (1),
  358 BEHIND-MODE (2), MULTIPLY-MODE (3), SCREEN-MODE (4), OVERLAY-MODE (5),
  359 DIFFERENCE-MODE (6), ADDITION-MODE (7), SUBTRACT-MODE (8),
  360 DARKEN-ONLY-MODE (9), LIGHTEN-ONLY-MODE (10), HUE-MODE (11),
  361 SATURATION-MODE (12), COLOR-MODE (13), VALUE-MODE (14),
  362 DIVIDE-MODE (15), DODGE-MODE (16), BURN-MODE (17), HARDLIGHT-MODE (18),
  363 SOFTLIGHT-MODE (19), GRAIN-EXTRACT-MODE (20), GRAIN-MERGE-MODE (21),
  364 COLOR-ERASE-MODE (22), ERASE-MODE (23), REPLACE-MODE (24),
  365 ANTI-ERASE-MODE (25) }
  366 |=======================================================================
  367 
  368 As you can see, all the values of the enum  were listed (the source file
  369 containing this enum is
  370 https://gitlab.gnome.org/GNOME/gimp/tree/master/app/base/base-enums.h[app/base/base-enums.h])
  371 in it's description, and the type for this argument was declared as an
  372 integer value (reminder: enumeration values in C are actually mapped to
  373 numbers, unlike languages such as Java where enumeration values are
  374 indeed a new type in the language).
  375 
  376 Limiting the range of numerical arguments
  377 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  378 
  379 In some cases you would like to limit the range of numerical values
  380 passed as parameters for your PDB function. For example, the width of
  381 newly created images should be limited to be at least 1 (since images
  382 with 0 width don't make sense...) and it also should be limited to some
  383 maximal width (so that it won't be bigger than the maximal size GIMP
  384 supports).
  385 
  386 We can add this sort of range limitations inside the declaration of the
  387 function, and by that we can make sure it won't be called with values
  388 out of range (GIMP will make sure the values are inside the specified
  389 range before it calls our function). To see an example, let's take look
  390 at the procedure image_new from
  391 https://gitlab.gnome.org/GNOME/gimp/tree/master/pdb/groups/image.pdb[pdb/groups/image.pdb]:
  392 
  393 [source,perl]
  394 ----
  395     @inargs = (
  396     { name => 'width', type => '1 <= int32 <= GIMP_MAX_IMAGE_SIZE',
  397       desc => 'The width of the image' },
  398     { name => 'height', type => '1 <= int32 <= GIMP_MAX_IMAGE_SIZE',
  399       desc => 'The height of the image' },
  400     { name => 'type', type => 'enum GimpImageBaseType',
  401       desc => 'The type of image' }
  402     );
  403 ----
  404 
  405 As you can see, inside the +*type*+ field of the first two parameters,
  406 we added a limitation on the range of the parameter. The lower
  407 limitation is a simple number, and the upper limitation is a constant
  408 macro (+GIMP_MAX_IMAGE_SIZE+) defined in
  409 https://gitlab.gnome.org/GNOME/gimp/tree/master/libgimpbase/gimplimits.h[libgimpbase/gimplimits.h].
  410 In order to make sure this constand will indeed be defined when parsing
  411 this function, the file
  412 https://gitlab.gnome.org/GNOME/gimp/tree/master/libgimpbase/gimpbase.h[libgimpbase/gimpbase.h]
  413 (which includes
  414 https://gitlab.gnome.org/GNOME/gimp/tree/master/libgimpbase/gimplimits.h[libgimpbase/gimplimits.h])
  415 was added to the +@headers+ section of the pdb file.
  416 
  417 Now, if you take a look at the code part of this function you won't see
  418 any check that the value is indeed inside the specified range. As we
  419 said, GIMP takes care of this automatically for us so we don't need to
  420 add the check ourselves. Inside the procedure browser, this procedure
  421 would show up like this:
  422 
  423 [options="header",cols="1,1,11"]
  424 |=======================================================================
  425 |Name	|Type	|Description
  426 |width	|INT32	|The width of the image (1 \<= width \<= 262144)
  427 |height	|INT32	|The height of the image (1 \<= height \<= 262144)
  428 |type	|INT32	|The type of image { RGB (0), GRAY (1), INDEXED (2) }
  429 |=======================================================================
  430 
  431 Array arguments
  432 ~~~~~~~~~~~~~~~
  433 In some cases you will want a function which returns an array or a
  434 function which receives an array. Array arguments are specified in a
  435 special way which is a bit different than the other arguments. To see
  436 how array arguments are specified, let's take a look at the +@outargs+
  437 of +vectors_stroke_get_points+ from
  438 https://gitlab.gnome.org/GNOME/gimp/tree/master/pdb/groups/vectors.pdb[pdb/groups/vectors.pdb]:
  439 
  440 [source,perl]
  441 ----
  442     @outargs = (
  443         { name => 'type', type => 'enum GimpVectorsStrokeType',
  444           desc => 'type of the stroke (always GIMP_VECTORS_STROKE_TYPE_BEZIER for now).' },
  445         { name => 'controlpoints', type => 'floatarray',
  446           desc => 'List of the control points for the stroke (x0, y0, x1, y1, ...).',
  447           array => { name => 'num_points',
  448                      desc => 'The number of floats returned.' } },
  449         { name => 'closed', type => 'boolean',
  450           desc => 'Whether the stroke is closed or not.' }
  451     );
  452 ----
  453 
  454 As you can see, the second argument which is of type +floatarray+ is
  455 specified in a different way than the other arguments; In addition to
  456 +name+, +type+ and +desc+, it also has an +*array*+  part. This part
  457 will declare another parameter for this function which will hold the
  458 length of the array (Reminder: in C you need the length of an array
  459 since unlike languages such as python, the length of an array isn't kept
  460 by default).
  461 
  462 As a result of this declaration, two arguments will be created (in this
  463 order):
  464 
  465 --
  466 . +*num_points*+ - a parameter of type +gint32+ which will hold the
  467 length of the array.
  468 . +*controlpoints*+ - a parameter of type +gdouble*+ which will point to
  469 the first element in the array.
  470 --
  471 
  472 Like all the other arguments which are declared in the +@outargs+ and
  473 +@intargs+ parts, their name  value will be the name of the variable in
  474 the code part. If you'll look at the code part of this function,
  475 you'll be able to find these lines:
  476 
  477 [source,c]
  478 ----
  479           num_points = points_array->len;
  480           controlpoints = g_new (gdouble, num_points * 2);
  481 ----
  482 As you can see from the code above, the +controlpoints+ argument starts
  483 just as a pointer to a double (array) - you have to do the allocation of
  484 the array yourself. However, if we would specify an array as an input
  485 argument, then the pointer will point to its beginning.
  486 
  487 Summary
  488 -------
  489 
  490 Hey! Now what - how do I see my function?
  491 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  492 
  493 Compile GIMP again from the source, and pass the flag --with-pdbgen to
  494 the configure script (or to the autogen script if using the autogen
  495 script).
  496 
  497 Conclusions
  498 ~~~~~~~~~~~
  499 Now that you know how a PDB function looks like, you should be able to
  500 add new ones of your own if GIMP needs them (ask on the development list
  501 before working on a new function like this, since you need to see if the
  502 developers agree that it's needed!).
  503 
  504 Don't forget to include the functions inside the right files! Under
  505 https://gitlab.gnome.org/GNOME/gimp/tree/master/pdb/groups[pdb/groups]
  506 you can see many files (fonts.pdb, brush.pdb, layer.pdb, etc.) - *make
  507 sure you add your function in the place which logically suites it!*