GIMP Script-fu

Artifact [4647efe626]
Login

Artifact 4647efe626931ee3ca6064d8da69ac689e2e791b:


; 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 2 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.
;
; The GNU Public License is available at
; http://www.gnu.org/copyleft/gpl.html

(define (script-fu-sg-expand-strip image drawable)
  (let* ((layer (car (gimp-image-get-active-layer image)))
         (layer-name (car (gimp-drawable-get-name layer)))
         (bounds (gimp-drawable-mask-intersect layer))
         (sel-x (cadr bounds))
         (sel-y (caddr bounds))
         (sel-width (cadddr bounds))
         (sel-height (car (cddddr bounds)))
         (image-width (car (gimp-image-width image)))
         (image-height (car (gimp-image-height image)))
         (offset-x (car (gimp-drawable-offsets layer)))
         (offset-y (cadr (gimp-drawable-offsets layer)))    
         (width (car (gimp-drawable-width layer)))
         (height (car (gimp-drawable-height layer)))
         (old-message-handler (car (gimp-message-get-handler)))
         (floating-sel 0)
         (buffer "")
         (error? #f) )
    (gimp-context-push)
    (gimp-image-undo-group-start image)
    (if (or (not (zero? (car (gimp-selection-is-empty image))))
             (zero? (car bounds)) )
      (set! error? #t)    
      (begin 
        (set! buffer (car (gimp-edit-named-copy layer "strip")))
        (cond 
          ((= sel-width width) ; expand horizontal strip
            (unless (= sel-height height)
              (let* ((move-up (truncate (/ sel-height 2)))
                     (move-down (- sel-height move-up)) )
                (gimp-layer-resize layer width (+ height sel-height) 0 move-up)
                (unless (zero? sel-y)
                  (gimp-rect-select image offset-x offset-y width sel-y CHANNEL-OP-REPLACE FALSE 0)
                  (set! floating-sel (car (gimp-selection-float layer 0 (- move-up))))
                  (gimp-floating-sel-anchor floating-sel) )
                (unless (= (+ sel-y sel-height) height)
                  (gimp-rect-select image 
                                    offset-x 
                                    (+ offset-y sel-y sel-height) 
                                    width 
                                    (- height sel-y sel-height) 
                                    CHANNEL-OP-REPLACE 
                                    FALSE 
                                    0 )
                  (set! floating-sel (car (gimp-selection-float layer 0 move-down)))
                  (gimp-floating-sel-anchor floating-sel) )
                (set! floating-sel (car (gimp-edit-named-paste layer buffer FALSE)))
                (gimp-layer-scale-full floating-sel
                                       width
                                       (* 2 sel-height) 
                                       TRUE
                                       INTERPOLATION-CUBIC )
                (gimp-layer-set-offsets floating-sel 
                                        offset-x 
                                        (+ offset-y (- sel-y move-up)) )
                (gimp-floating-sel-anchor floating-sel)
                (gimp-rect-select image
                                  offset-x
                                  (- (+ offset-y sel-y) move-up)
                                  width
                                  (* 2 sel-height)
                                  CHANNEL-OP-REPLACE 
                                  FALSE 
                                  0 ))))
                
          ((= sel-height height) ; expand vertical strip
            (unless (= sel-width width)
              (let* ((move-left (truncate (/ sel-width 2)))
                     (move-right (- sel-width move-left)) )
                (gimp-layer-resize layer (+ width sel-width) height move-left 0)
                (unless (zero? sel-x)
                  (gimp-rect-select image offset-x offset-y sel-x height CHANNEL-OP-REPLACE FALSE 0)
                  (set! floating-sel (car (gimp-selection-float layer (- move-left) 0)))
                  (gimp-floating-sel-anchor floating-sel) )
                (unless (= (+ sel-x sel-width) width)
                  (gimp-rect-select image 
                                    (+ offset-x sel-x sel-width) 
                                    offset-y
                                    (- width sel-x sel-width) 
                                    height
                                    CHANNEL-OP-REPLACE 
                                    FALSE 
                                    0 )
                  (set! floating-sel (car (gimp-selection-float layer move-right 0)))
                  (gimp-floating-sel-anchor floating-sel) )
                (set! floating-sel (car (gimp-edit-named-paste layer buffer FALSE)))
                (gimp-layer-scale-full floating-sel
                                       (* 2 sel-width)
                                       height
                                       TRUE
                                       INTERPOLATION-CUBIC )
                (gimp-layer-set-offsets floating-sel 
                                        (+ offset-x (- sel-x move-left))
                                        offset-y )
                (gimp-floating-sel-anchor floating-sel)
                (gimp-rect-select image
                                  (- (+ offset-x sel-x) move-left)
                                  offset-y
                                  (* 2 sel-width)
                                  height
                                  CHANNEL-OP-REPLACE 
                                  FALSE 
                                  0 ))))
          (else ;; error - selection must span the entire layer
            (set! error? #t) ))))
    (if error?
      (gimp-message "Selection must span either the entire width or height of layer")
      (let ((x (car (gimp-drawable-offsets layer)))
            (y (cadr (gimp-drawable-offsets layer))) )
        (gimp-buffer-delete buffer)
        (gimp-image-resize image 
                           (- image-width (min 0 x))
                           (- image-height (min 0 ))
                           (abs (min 0 x))
                           (abs (min 0 y)) )
        (set! x (car (gimp-drawable-offsets layer)))
        (set! y (cadr (gimp-drawable-offsets layer)))
        (gimp-image-resize image
                           (max image-width (+ x (car (gimp-drawable-width layer))))
                           (max image-height (+ y (car (gimp-drawable-height layer))))
                           0
                           0 )
        (if (= sel-width width) ; horizontal strip
          (cond
            ((zero? sel-y) 
              (gimp-rect-select image
                                x
                                y
                                width
                                (* 2 sel-height)
                                CHANNEL-OP-REPLACE 
                                FALSE 
                                0 ))
            ((= (+ sel-y sel-height) height)
              (gimp-rect-select image
                                x
                                (- (+ y (car (gimp-drawable-height layer))) (* 2 sel-height))
                                width
                                (* 2 sel-height)
                                CHANNEL-OP-REPLACE 
                                FALSE 
                                0 ))))
        (if (= sel-height height) ; vertical strip
          (cond
            ((zero? sel-x) 
              (gimp-rect-select image
                                x
                                y
                                (* 2 sel-width)
                                height
                                CHANNEL-OP-REPLACE 
                                FALSE 
                                0 ))
            ((= (+ sel-x sel-width) width)
              (gimp-rect-select image
                                (- (+ x (car (gimp-drawable-width layer))) (* 2 sel-width))
                                y
                                (* 2 sel-width)
                                height
                                CHANNEL-OP-REPLACE 
                                FALSE 
                                0 ))))))

    (set! image-width (car (gimp-image-width image)))
    (set! image-height (car (gimp-image-height image)))
    (gimp-image-undo-group-end image)
    (gimp-context-pop)
    (gimp-displays-flush)
    )
  )

(script-fu-register "script-fu-sg-expand-strip"
 "Expand Strip"
 "Expand the strip under the selection, resizing layer and image if necessary"
 "Saul Goode"
 "Saul Goode"
 "October 2011"
 "RGB*,GRAY*"
 SF-IMAGE    "Image"    0
 SF-DRAWABLE "Drawable" 0
 )
(script-fu-menu-register "script-fu-sg-expand-strip"
 "<Image>/Layer/"
 )