; Custom Font Rel 10 ; Created by Tin Tran ; Comments directed to http://gimpchat.com or http://gimpscripts.com ; ; License: GPLv3 ; 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 3 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. ; ; To view a copy of the GNU General Public License ; visit: http://www.gnu.org/licenses/gpl.html ; ; ; ------------ ;| Change Log | ; ------------ ; Rel 1: Initial release ; Rel 2: Justify, Letter and Line spacing added ; Rel 3: "FILLED" Justify added ; Rel 4: named layers properly if merge layers is not selected, if merge layers is selected it'll autocrop image ; Rel 5: use lowercase letters if uppercase isn't defined, ; use uppercase letters if lowercase isn't defined, ; use 'space.png' if ' .png' isn't defined ; Rel 6: does not report warning when finding newline character ('\n') ; Rel 7: use paths/vectors of the same name to define where actual character is located and character's width...if no vectors aren't found, it assumes that center of layer is where character is located and width of layer is width of character ; Rel 8: fix bug, use image width to calculate offset to move layer when vector is defined because vectors positions are relative to image coordinates and not layer coordinates ; Rel 9: fix bug, use layer's width to calculate offset to move layer when vector is defined but factor in layer's offset as well. ; Rel 10: prompts for .xcf file instead of having the user having to have .xcf file opened. (define (script-fu-custom-font ;image layer xcffilename text justification letter-spacing line-spacing merge ) (let* ( (dummy 0) (image (car (gimp-xcf-load dummy xcffilename xcffilename))) (width (car (gimp-image-width image))) (height (car (gimp-image-height image))) (charList ()) (char 0) (layer-name 0) (new-image 0) (source-layer 0) (background-layer 0) (new-display 0) (floating-sel 0) (layer-width-half 0) (layer-height 0) (count 0) (countline 0) (offset 0) (offsetline 0) (linewidth 0) (characters-layers ()) (move-layer 0) (move-x 0) (lines ()) (widths ()) (maxwidth 0) (character-counts ()) (character-count 0) (item-index 0) (character-offset 0) (found-vector 0) ) ;(gimp-image-undo-disable image); DN = NO UNDO (gimp-context-push) (gimp-image-undo-group-start image) ;undo-group in one step ;creates a new image with a single background layer to work with (set! new-image (car (gimp-image-new width height RGB))) ;creates new image (set! background-layer (car (gimp-layer-new new-image width height RGBA-IMAGE "background" 100 NORMAL-MODE))) (gimp-image-insert-layer new-image background-layer 0 0) (set! charList (map (lambda (x) (make-string 1 x)) (string->list text))) ;create the list of letters (set! charList (append charList (list "\n"))) ;make it end with newline character (while (not (null? charList)) (set! char (car charList)) ;default layer-name to whatever character is appended with .png (set! layer-name (string-append char ".png")) ;if it's a space we'll look for space.png layer (set! source-layer (car (gimp-image-get-layer-by-name image layer-name))) (if (< source-layer 0) (begin (if (string=? char "\n") (begin ;if it's newline character do not check ) (begin (if (string=? char " ") (begin (gimp-message (string-append "layer:' .png' not found trying 'space.png'")) (set! layer-name "space.png") ) (begin (if (string=? char (string-downcase char)) (begin (gimp-message (string-append "layer:'" char ".png' not found trying uppercase")) (set! layer-name (string-append (string-upcase char) ".png")) ) (begin (if (string=? char (string-upcase char)) (begin (gimp-message (string-append "layer:'" char ".png' not found trying lowercase")) (set! layer-name (string-append (string-downcase char) ".png")) ) (begin ) ) ) ) ) ) ) ) )) ; if its' new line character we do what needs to be done like shifting the line to justification and reset variables to initial states (if (string=? char "\n") (begin (if (= justification 0) ;LEFT (begin (set! move-x 0) ) (begin (if (= justification 1) ;RIGHT (begin (set! move-x (- 0 linewidth)) ) (begin (if (= justification 2) ;CENTER\ (begin (set! move-x (- 0 (/ linewidth 2))) ) ) ) ) ) ) (set! lines (append lines (list characters-layers))) ;loop through our characters-layers and translate it aoordingly based on move-x for justification (while (not (null? characters-layers)) (set! move-layer (car characters-layers)) (gimp-layer-translate move-layer move-x 0) (set! characters-layers (cdr characters-layers)) ) (set! character-counts (append character-counts (list count))) (set! count 0) (set! offset 0) (set! widths (append widths (list linewidth))) (set! maxwidth (max linewidth maxwidth)) (set! linewidth 0) (set! characters-layers ()) (set! countline (+ countline 1)) (if (= countline 0) ;first time don't move it just calculate layer-width-half (begin ) (begin ;second time and onward after that we add last calculated half ;recalculate half add that then move it (set! layer-height (car (gimp-drawable-height floating-sel))) (set! offsetline (+ offsetline layer-height)) (set! offsetline (+ offsetline line-spacing)) ) ) ) (begin (set! source-layer (car (gimp-image-get-layer-by-name image layer-name))) (if (< source-layer 0) (begin (gimp-message (string-append "Layer not found: " layer-name )) )) (gimp-selection-all image) (gimp-edit-copy source-layer) ;paste it in new image as a floating selection then make it a layer (set! floating-sel (car (gimp-edit-paste background-layer TRUE))) (gimp-floating-sel-to-layer floating-sel) (gimp-item-set-name floating-sel layer-name) ;move it to the right place ;see if a vector has been defined for it then use it as spacing (set! found-vector (car(gimp-image-get-vectors-by-name image layer-name))) (if (>= found-vector 0) (begin (define stroke (vector-ref (cadr(gimp-vectors-get-strokes found-vector)) 0)) (define points (caddr(gimp-vectors-stroke-get-points found-vector stroke))) (define firstX (vector-ref points 2)) (define secondX (vector-ref points (- (vector-length points) 4))) (define minX (min firstX secondX)) (define maxX (max firstX secondX)) ;(gimp-message (string-append (number->string minX) " ---> " (number->string maxX))) ) (begin ) ) ;if a vector is defined for it always move it with offset based on center of vector (if (>= found-vector 0) (begin (define source-layer-width (car (gimp-drawable-width source-layer))) (define source-layer-offset-x (car (gimp-drawable-offsets source-layer))) (define relocate-offset (- (/ source-layer-width 2.0) (/ (+ (- minX source-layer-offset-x) (- maxX source-layer-offset-x)) 2))) (gimp-layer-translate floating-sel relocate-offset 0) ) ) (if (= count 0) ;first time don't move it just calculate layer-width-half (begin (if (>= found-vector 0) (begin (set! layer-width-half (/ (- maxX minX) 2.0)) (set! offset (+ offset layer-width-half)) (gimp-layer-translate floating-sel offset offsetline) ) (begin (set! layer-width-half (/ (car (gimp-drawable-width floating-sel)) 2.0)) (set! offset (+ offset layer-width-half)) (gimp-layer-translate floating-sel offset offsetline) ) ) ) (begin ;second time and onward after that we add last calculated half ;recalculate half add that then move it (if (>= found-vector 0) (begin (set! offset (+ offset letter-spacing)) (set! offset (+ offset layer-width-half)) (set! layer-width-half (/ (- maxX minX) 2.0)) (set! offset (+ offset layer-width-half)) (gimp-layer-translate floating-sel offset offsetline) (set! linewidth (+ linewidth letter-spacing)) ) (begin (set! offset (+ offset letter-spacing)) (set! offset (+ offset layer-width-half)) (set! layer-width-half (/ (car (gimp-drawable-width floating-sel)) 2.0)) (set! offset (+ offset layer-width-half)) (gimp-layer-translate floating-sel offset offsetline) (set! linewidth (+ linewidth letter-spacing)) ) ) ) ) (set! characters-layers (append characters-layers (list floating-sel))) (set! linewidth (+ linewidth (* layer-width-half 2))) (set! count (+ count 1)) ) ) (set! charList (cdr charList)) ) ;endwhile ;FILLED JUSTIFICATION is a little more MATH :D (if (= justification 3) ;FILLED (begin (while (not (null? lines)) (set! characters-layers (car lines)) (set! linewidth (list-ref widths item-index)) (set! character-count (list-ref character-counts item-index)) (set! move-x (/ (- maxwidth linewidth) (max (- character-count 1) 1))) (set! character-offset 0) (while (not (null? characters-layers)) (set! move-layer (car characters-layers)) (gimp-layer-translate move-layer character-offset 0) (set! character-offset (+ character-offset move-x)) (set! characters-layers (cdr characters-layers)) ) (set! lines (cdr lines)) (set! item-index (+ item-index 1)) ) ) ) (gimp-image-remove-layer new-image background-layer) (gimp-image-resize-to-layers new-image) (if (= merge TRUE) (begin (set! background-layer (car (gimp-image-merge-visible-layers new-image 0))) (gimp-item-set-name background-layer "custom font") (plug-in-autocrop 1 new-image background-layer) ) ) ;create new display for our new-image (set! new-display (car (gimp-display-new new-image))) ;creates new display for image ;(gimp-image-undo-enable image) ;DN = NO UNDO (gimp-image-undo-group-end image) ;undo group in one step (gimp-context-pop) (gimp-displays-flush) (gimp-image-delete image) ) ) ;end of define (script-fu-register "script-fu-custom-font" ;function name "/Script-Fu/Create New/Custom Font ..." ;menu register "Creates an image of text using the custom font layers" ;description "Tin Tran" ;author name "copyright info and description" ;copyright info or description "2016" ;date ;"RGB*, GRAY*" ;mode "" ;mode ;SF-IMAGE "Image" 0 ;SF-DRAWABLE "Layer" 0 ;SF-STRING "Text" "Gimp Chat" SF-FILENAME ".xcf Font File" "" SF-TEXT "Multiline text" "Gimp Chat\nCustom Font\nIs Awesome" SF-OPTION "Justification" '("LEFT" "RIGHT" "CENTER" "FILLED") SF-ADJUSTMENT "Letter Spacing" '(0 -1000 1000 1 10 0 0) SF-ADJUSTMENT "Line Spacing" '(0 -1000 1000 1 10 0 0) SF-TOGGLE "Merge Layers" TRUE )