3.5. Adding Additional Functionality

Let us continue with our training and add some functionality to our script.

3.5.1. Creating A New Image

In the previous lesson, we created an empty function and registered it with GIMP. In this lesson, we want to provide functionality to our script — we want to create a new image, add the user's text to it and resize the image to fit the text exactly.

Once you know how to set variables, define functions and access list members, the rest is all downhill — all you need to do is familiarize yourself with the functions available in GIMP's procedural database and call those functions directly. Open the Secțiune 12.8, „Navigatorul de proceduri”.

Let's begin by making a new image. We'll create a new variable, theImage, set to the result of calling GIMP's built-in function gimp-image-new.

As you can see from the DB Browser, the function gimp-image-new takes three parameters — the image's width, height and the type of image. Because we'll later resize the image to fit the text, we'll make a 10×10 pixels RGB image. We'll store the image's width and sizes in some variables, too, as we'll refer to and manipulate them later in the script.

        (define (script-fu-text-box inText inFont inFontSize inTextColor)
        (let*
              (
                 ; define our local variables
                 ; create a new image:
                 (theImageWidth  10)
                 (theImageHeight 10)
                 (theImage (car
                                (gimp-image-new
                                 theImageWidth
                                 theImageHeight
                                 RGB
                                )
                           )
                 )
                 (theText)     ;a declaration for the text
                               ;we create later
      

Note: We used the value RGB to specify that the image is an RGB image. We could have also used 0, but RGB is more descriptive when we glance at the code.

You should also notice that we took the head of the result of the function call. This may seem strange, because the database explicitly tells us that it returns only one value — the ID of the newly created image. However, all GIMP functions return a list, even if there is only one element in the list, so we need to get the head of the list.

3.5.2. Adding A New Layer To The Image

Now that we have an image, we need to add a layer to it. We'll call the gimp-layer-new function to create the layer, passing in the ID of the image we just created. (From now on, instead of listing the complete function, we'll only list the lines we're adding to it. You can see the complete script here.) Because we've declared all of the local variables we'll use, we'll also close the parentheses marking the end of our variable declarations:

        ;create a new layer for the image:
           (theLayer
                     (car
                          (gimp-layer-new
                           theImage
                           theImageWidth
                           theImageHeight
                           RGB-IMAGE
                           "layer 1"
                           100
                           LAYER-MODE-NORMAL
                          )
                      )
            )
         ) ;end of our local variables
      

Once we have the new layer, we need to add it to the image:

        (gimp-image-insert-layer theImage theLayer 0 0)
      

Now, just for fun, let's see the fruits of our labors up until this point, and add this line to show the new, empty image:

(gimp-display-new theImage)

Save your work, select FiltersScript-FuRefresh Scripts, run the script and a new image should pop up. It will probably contain garbage (random colors), because we haven't erased it. We'll get to that in a second.

3.5.3. Adding The Text

Go ahead and remove the line to display the image (or comment it out with a (;) as the first character of the line).

Before we add text to the image, we need to set the background and foreground colors so that the text appears in the color the user specified. We'll use the gimp-context-set-back/foreground functions:

        (gimp-context-set-background '(255 255 255) )
        (gimp-context-set-foreground inTextColor)
      

With the colors properly set, let's now clean out the garbage currently in the image by filling the drawable with the background color:

        (gimp-drawable-fill theLayer BACKGROUND-FILL)
      

With the image cleared, we're ready to add some text:

        (set! theText
                      (car
                           (gimp-text-fontname
                            theImage theLayer
                            0 0
                            inText
                            0
                            TRUE
                            inFontSize PIXELS
                            inFont)
                       )
        )
      

Although a long function call, it's fairly straightforward if you go over the parameters while looking at the function's entry in the DB Browser. Basically, we're creating a new text layer and assigning it to the variable theText.

Now that we have the text, we can grab its width and height and resize the image and the image's layer to the text's size:

        (set! theImageWidth   (car (gimp-drawable-width  theText) ) )
        (set! theImageHeight  (car (gimp-drawable-height theText) ) )

        (gimp-image-resize theImage theImageWidth theImageHeight 0 0)

        (gimp-layer-resize theLayer theImageWidth theImageHeight 0 0)
      

If you're like me, you're probably wondering what a drawable is when compared to a layer. The difference between the two is that a drawable is anything that can be drawn into, including layers but also channels, layer masks, the selection, etc; a layer is a more specific version of a drawable. In most cases, the distinction is not important.

With the image ready to go, we can now re-add our display line:

        (gimp-display-new theImage)
      

Save your work, refresh the database and give your first script a run!

3.5.4. Clearing The Dirty Flag

If you try to close the image created without first saving the file, GIMP will ask you if you want to save your work before you close the image. It asks this because the image is marked as dirty, or unsaved. In the case of our script, this is a nuisance for the times when we simply give it a test run and don't add or change anything in the resulting image — that is, our work is easily reproducible in such a simple script, so it makes sense to get rid of this dirty flag.

To do this, we can clear the dirty flag after displaying the image:

        (gimp-image-clean-all theImage)
      

This will set dirty count to 0, making it appear to be a clean image.

Whether to add this line or not is a matter of personal taste. I use it in scripts that produce new images, where the results are trivial, as in this case. If your script is very complicated, or if it works on an existing image, you will probably not want to use this function.