Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Troubles with porting a script to Gimp3
#1
Hello!

I have trouble with porting a script written in Script-Fu from Gimp2 to Gimp3. I managed to run the script, but when script execution finished, I've got the following error: argument 1 must be: number. Unfortunately, I cannot understand why this error occurs. Could anyone review my code and help me to make the script working. The script is below:
Code:
#!/usr/bin/env gimp-script-fu-interpreter-3.0

; Adds labels to a layer
; Works with Gimp v.3

(define (script-fu-add-labels image drawables user-text font font-size
                              font-color x y outline-toggle outline-color
                              outline-thickness)

 (let* ((current-layer (vector-ref drawables 0))
        (off-x (car (gimp-drawable-get-offsets current-layer)))
        (off-y (cadr (gimp-drawable-get-offsets current-layer)))

        (text-layer)
        (text-layer-position-x (+ off-x x))
        (text-layer-position-y (+ off-y y))
        (text-layer-outline)
        (text-layer-vectors)
        (text-layer-group)
        (text-layer-group-name)
        (text-foreground-color-old)

        (parent-layer-type 0)
        (parent-layer-name)
        (parent-layer-group (car (gimp-item-get-parent current-layer)))

        (old-background (car (gimp-context-get-background))))

   (cond ((= #t (car (gimp-item-id-is-channel current-layer))) (set! layer-type 1))
         ((= #t (car (gimp-item-is-group current-layer))) (set! layer-type 1))
         ((= #t (car (gimp-item-id-is-layer-mask current-layer))) (set! layer-type 1))
         ((= #t (car (gimp-item-id-is-selection current-layer))) (set! layer-type 1))
         ((= #t (car (gimp-item-id-is-text-layer current-layer))) (set! layer-type 1)))

   (gimp-image-undo-group-start image)

   (if (= 1 parent-layer-type)
     (begin
       (set! parent-layer-name (car (gimp-item-get-name current-layer)))
       (gimp-message
         (string-append "Cannont add the label to the layer " parent-layer-name)))
     (begin
       (set! text-layer (car (gimp-text-font image -1 text-layer-position-x
                                                 text-layer-position-y user-text 2 #t
                                                 font-size POINTS font)))
       (gimp-text-layer-set-color text-layer font-color)
       (when (= outline-toggle #t)
         (set! text-layer-group (car (gimp-layer-group-new image)))
         (set! text-layer-group-name
           (string-append "Text_" (car (gimp-text-layer-get-text
                                         text-layer))))
         (set! text-layer-vectors (car (gimp-vectors-new-from-text-layer image
                                                                         text-layer)))
         (set! text-layer-outline (car (gimp-layer-copy text-layer #t)))
         (set! text-foreground-color-old (car (gimp-context-get-foreground)))
         (gimp-item-set-name text-layer-group text-layer-group-name)
         (gimp-image-insert-layer image text-layer-group 0 0)
         (gimp-image-insert-vectors image text-layer-vectors 0 -1)
         (gimp-image-reorder-item image text-layer text-layer-group 0)
         (gimp-image-insert-layer image text-layer-outline text-layer-group -1)
         (gimp-context-set-foreground outline-color)
         (gimp-context-set-stroke-method 0)
         (gimp-context-set-line-width outline-thickness)
         (gimp-drawable-edit-stroke-item text-layer-outline text-layer-vectors)
         (gimp-context-set-foreground text-foreground-color-old)
         (gimp-item-set-expanded text-layer-group #f)
         (gimp-item-set-lock-position text-layer-outline #t))
       (gimp-item-set-lock-position text-layer #t)))

   (gimp-displays-flush)
   (gimp-image-undo-group-end image)))

(script-fu-register-filter "script-fu-add-labels"
                   _"Add labels"
                   _""
                   ""
                   ""
                   ""
                   "*"
                   SF-ONE-OR-MORE-DRAWABLE
                   SF-STRING        _"Label" "A"
                   SF-FONT        _"Font" "Arial Bold"
                   SF-ADJUSTMENT _"Font size"         (list 50 5 100 1 10 0 1)
                   SF-COLOR _"Font color"          (list 0 0 0)
                   SF-ADJUSTMENT _"Offset X"         (list 6 0 500 1 10 0 1)
                   SF-ADJUSTMENT _"Offset Y"         (list 6 0 500 1 10 0 1)
                   SF-TOGGLE _"Outline" #f
                   SF-COLOR _"Outline color"          (list 255 255 255)
                   SF-ADJUSTMENT _"Outline thickness"         (list 1 0 5 1 1 0 1)
                   )

(script-fu-menu-register "script-fu-add-labels"
                        "<Image>/Figures")
Reply
#2
You sprinkle the code with identifiable calls to (print ...) (if running from the script-fu console) or (gimp-message ...) (if running from the menus) and you can quickly determine between which print/gimp-message calls the error occurs, which should lead you to the culprit...
Reply
#3
(03-03-2025, 11:37 AM)Ofnuts Wrote: You sprinkle the code with identifiable calls to (print ...) (if running from the script-fu console) or (gimp-message ...) (if running from the menus) and you can quickly determine between which print/gimp-message calls the error occurs, which should lead you to the culprit...

Thank you for your reply. I was trying to find where the error occurs in the code, but with no success. I have reverted some code to the one that was working in Gimp2. Here it is:


Code:
(let* ((off-x (car (gimp-drawable-get-offsets drawables)))
      (off-y (cadr (gimp-drawable-get-offsets drawables)))


With these changes in the script, posted earlier, I can start Gimp normally and run the script. But now I've got another error: "Error: in script, expected type: numeric for argument 1 to gimp-drawable-get-offsets". This error appears when the script executes gimp-
drawable-get-offsets for the first time. Now I can't understand why this error occurs. In Gimp console, if I run the following code:

Code:
(define (off-x x) (car (gimp-drawable-get-offsets x)))
(off-x 1)

I can get the correct result, when providing the function with correct drawable. However, I can't understand why I'm getting an error in the script.
Reply
#4
After searching for internet, I came to the following code:
Code:
(let* ((off-x (car (gimp-drawable-get-offsets (vector-ref drawables 0))))
      (off-y (cadr (gimp-drawable-get-offsets (vector-ref drawables 0))))

But still, I've got another error saying that car: argument 1 must be: pair when assigns off-x variable. Could anyone explain what is wrong with this code.
Reply
#5
In Gimp3 your "drawables" argument is a list (or a vector) of drawables and no longer a unique drawable. So either you iterate the list (if you accept desveral drawables) or you pick the fist element. There are registration flags to tell if you accept 0, 1, or more drawables.
Reply
#6
(03-04-2025, 03:50 PM)Ofnuts Wrote: In Gimp3 your "drawables" argument is a list (or a vector) of drawables and no longer a unique drawable. So either you iterate the list (if you accept desveral drawables) or you pick the fist element. There are registration flags to tell if you accept 0, 1, or more drawables.

Thank you for your suggestion. I have included the flag SF-ONE-DRAWABLE, but nothing has changed.

After more careful reading, I came to the following. If I use v3 dialect of Script-Fu, i.e., by inserting the following code at the top of the script:
Code:
(script-fu-use-v3)
and run the script as it was described here
https://www.gimp-forum.net/Thread-Script-fu-V3-plug-ins
I get the following error:
Code:
car: argument 1 must be: pair
however, if I'm using v2 dialect of Script-Fu and start the script as usual one, the error is different
Code:
Error: runtime: resource ID of improper subclass. (1 2573)
this code
Code:
(let* ((off-x (car (gimp-drawable-get-offsets (vector-ref drawables 0))))
     (off-y (cadr (gimp-drawable-get-offsets (vector-ref drawables 0))))
works fine, and I cannot figure out where this error came from.
Reply
#7
SF-ONE-DRAWABLE doesn't change the structure of the script arguments (you still get a list, even if it has only one element). It is only a flag used by the UI to enable/disable the menu entry depending on application state (and technically, you would still have to check that you have only one drawable in th elist, because you could hypothetically be called by another script that could ignore the flag.
Reply
#8
(03-05-2025, 07:41 AM)Ofnuts Wrote: SF-ONE-DRAWABLE doesn't change the structure of the script arguments (you still get a list, even if it has only one element). It is only a flag used by the UI to enable/disable the menu entry depending on application state (and technically, you would still have to check that you have only one drawable in th elist, because you could hypothetically be called by another script that could ignore the flag.

Thank you for your suggestion. I have almost re-written the script into Script-Fu v.3 dialect. But now I have another problem. The following code is expected to check whether the drawable is a group, a layer mask, a selection, or a text layer to prevent the text to be added to either of these.
Code:
(cond (#t (gimp-item-is-group (vector-ref drawables 0))) (set! parent-layer-type 1)
          (#t (gimp-item-id-is-layer-mask (vector-ref drawables 0))) (set! parent-layer-type 1)
          (#t (gimp-item-id-is-selection (vector-ref drawables 0))) (set! parent-layer-type 1)
          (#t (gimp-item-id-is-text-layer (vector-ref drawables 0))) (set! parent-layer-type 1))

However, this code always sets the parent-layer-type to 0, even when drawable is a normal layer. Unfortunately, with this code, I cannot figure out how to select active drawable. Interestingly, that this code works fine and selects active drawable
Code:
(layer-width (gimp-drawable-get-width (vector-ref drawables 0)))

Am I missing something with the conditional code?
Reply
#9
I can help with the API, but not with Scheme... If I had to do something like this, i would rewrite the whole thing in Python...
Reply
#10
(03-05-2025, 05:26 PM)Ofnuts Wrote: I can help with the API, but not with Scheme... If I had to do something like this, i would rewrite the whole thing in Python...

I agree with you, that Python would be better, but I'm not a programmer and rewriting this code in Python is far beyond my expertise. Anyway, thank you for your suggestions. You helped me a lot.
Reply


Forum Jump: