; 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. ; This script reads in a data file containing a list of ; RIO button information. ; The data file uses Lisp/Scheme style lists and commenting (comments ; start with a semi-colon and extend to the end of the line). ; The first non-comment line of the data file should be a list containing ; the field names of the RIO button addresses wrapped in parentheses. ; For example: ; ; ; THIS IS A COMMENT AND IGNORED ; ( 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ) ; ; This "header" list should be followed by the LINE containing the ; actual data to be substituted into the template file. The data should ; be text strings and appear in the same order as the fields specified in ; the header list. ; ; ("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "CTRL" "ALT") ; ; ; The currently open image is used as a template with the upper layers having ; names that match the field names. These field layers are used to determine ; the location and size of the text (this layer is otherwise ignored). ; The name text is centered within the bounds of this field template layer. ; ; (define (script-fu-sg-goobie image datafilename save-xcf save-jpeg save-png save-dir vert-justification size-handling) ;; Perform a search for the largest font that will fit within ;; the cell. ; (define (calc-fontsize text font width height) (let loop ((fontsize 6) ;; minimum possible fontsize (last-extents nil) (last-fontsize 3) (adjust 2) ) (let ((extents (gimp-text-get-extents-fontname text fontsize PIXELS font))) (if (or (= last-fontsize fontsize) (equal? extents last-extents)) (max fontsize 6) (if (or (> (car extents) width) (> (cadr extents) height)) (loop (truncate (* last-fontsize (+ (* (- adjust 1) 0.5) 1))) last-extents last-fontsize (+ (* (- adjust 1) 0.5) 1) ) (loop (truncate (* fontsize adjust)) extents fontsize adjust )))))) (define (create-data-layer image field-name field-data) (let ((frame-layer (let loop ((layers (vector->list (cadr (gimp-image-get-layers image))))) (if (null? layers) #f (if (string=? field-name (car (gimp-drawable-get-name (car layers)))) (car layers) (loop (cdr layers)) ))))) (if frame-layer (if (= (car (gimp-drawable-is-text-layer frame-layer)) 1) (let ((x (car (gimp-drawable-offsets frame-layer))) (y (cadr (gimp-drawable-offsets frame-layer))) (w (car (gimp-drawable-width frame-layer))) (h (car (gimp-drawable-height frame-layer))) (font (car (gimp-text-layer-get-font frame-layer))) (size (car (gimp-text-layer-get-font-size frame-layer))) ) (gimp-image-set-active-layer image frame-layer) (gimp-text-layer-set-text frame-layer field-data) (let ((extents (gimp-text-get-extents-fontname field-data size PIXELS font ))) (when (and (zero? size-handling) (or (> (car extents) w) (> (cadr extents) h) )) (gimp-text-layer-set-font-size frame-layer (calc-fontsize field-data font w h) PIXELS) ) (case vert-justification ((0) ; center (gimp-layer-set-offsets frame-layer x (+ y (/ (- h (cadr extents)) 2)) )) ((1) ; top (gimp-layer-set-offsets frame-layer x y )) ((2) ; bottom (gimp-layer-set-offsets frame-layer x (- (+ y h) (cadr extents)) ))))) (gimp-message "Field layer is not a text layer") ) (begin (gimp-message (string-append "Field layer not found: " field-name)) )) frame-layer )) ;; ---------------------------------------------------------------------- ;; Main processing start here ; (let* ((inport (open-input-file datafilename)) (field-names (map symbol->string (read inport))) (filetag (car field-names)) ) (gimp-image-undo-freeze image) (gimp-context-push) (let entry-loop ((fields (read inport))) (unless (eof-object? fields) (let ((temp-image (car (gimp-image-duplicate image))) (filename #f) ) (let field-loop ((field-names field-names) (field-values fields) ) (unless (null? field-values) (when (string=? (car field-names) filetag) (set! filename (car field-values)) ) (create-data-layer temp-image (car field-names) (car field-values)) (field-loop (cdr field-names) (cdr field-values)) )) (if filename (let ((fullname (string-append save-dir DIR-SEPARATOR filename ))) (unless (zero? save-xcf) (let ((filename (string-append fullname ".xcf"))) (gimp-xcf-save TRUE temp-image (car (gimp-image-get-active-layer image)) filename filename ))) (unless (zero? save-png) (let ((layer (car (gimp-image-merge-visible-layers temp-image CLIP-TO-IMAGE ))) (filename (string-append fullname ".png")) ) (file-png-save2 RUN-NONINTERACTIVE temp-image layer filename filename FALSE ; interlace 9 FALSE ; bkgd (car (gimp-drawable-has-alpha layer)) FALSE ; offs FALSE ; phys FALSE ; time TRUE ; comment FALSE ; svtrans ))) (unless (zero? save-jpeg) (let ((layer (car (gimp-image-flatten temp-image))) (filename (string-append fullname ".jpg")) ) (file-jpeg-save RUN-NONINTERACTIVE temp-image layer filename filename 0.93 0 ; smoothing 1 ; optimize 1 ; progressive "" ; comment 0 ; subsmp (0-4) 1 ; baseline 0 ; restart 0 ;dct )))) (gimp-message "Error encountered") ) ; (gimp-image-delete temp-image) ) (entry-loop (read inport)) )) (close-input-port inport) (gimp-context-pop) (gimp-image-undo-thaw image) ) ) (script-fu-register "script-fu-sg-goobie" "Goobie (MFD)..." "Create MFD image based on template image" "Frank Galatis" "Saul Goode" "June 2012" "*" SF-IMAGE "Image" 0 SF-FILENAME "Data file" "example.data" SF-TOGGLE "Save as XCF" FALSE SF-TOGGLE "Save as JPEG" TRUE SF-TOGGLE "Save as PNG" FALSE SF-DIRNAME "Save directory" "" SF-OPTION "Vertical justification" '("Center" "Top" "Bottom") SF-OPTION "Font sizing (if too large)" '("Fit" "Crop" "Overflow") ) (script-fu-menu-register "script-fu-sg-goobie" "/File" )