File: coffee.scm

package info (click to toggle)
gimp 3.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 222,880 kB
  • sloc: ansic: 870,914; python: 10,965; lisp: 10,857; cpp: 7,355; perl: 4,536; sh: 1,753; xml: 972; yacc: 609; lex: 348; javascript: 150; makefile: 42
file content (144 lines) | stat: -rw-r--r-- 5,263 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
; Chris Gutteridge (cjg@ecs.soton.ac.uk)
; At ECS Dept, University of Southampton, England.

; 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.
;
; You should have received a copy of the GNU General Public License
; along with this program.  If not, see <https://www.gnu.org/licenses/>.


(define (script-fu-coffee-stain inImage inLayers inNumber inDark inGradient)

  ; Use v3 binding of return values from PDB calls
  (script-fu-use-v3)

  (let* (
        (theImage inImage)
        (theHeight (gimp-image-get-height theImage))
        (theWidth  (gimp-image-get-width theImage))
        (theNumber inNumber)
        (theSize (min theWidth theHeight))
        (theStain 0)
        (theThreshold 0)
        (theSpread 0)
        )

    (gimp-context-push)
    (gimp-context-set-defaults)

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

    (while (> theNumber 0)
      (set! theNumber (- theNumber 1))
      (set! theStain (gimp-layer-new theImage _"Stain" theSize theSize
                                     RGBA-IMAGE 100
                                     ; inDark is [0, 1] not [#f, #t]
                                     (if (= inDark TRUE)
                                        LAYER-MODE-DARKEN-ONLY
                                        LAYER-MODE-NORMAL)))

      (gimp-image-insert-layer theImage theStain 0 0)
      (gimp-selection-all theImage)
      (gimp-drawable-edit-clear theStain)

      (let ((blobSize (/ (random (- theSize 40)) (+ (random 3) 1))))
        (if (< blobSize 32) (set! blobSize 32))
        (gimp-image-select-ellipse theImage
				   CHANNEL-OP-REPLACE
				   (/ (- theSize blobSize) 2)
				   (/ (- theSize blobSize) 2)
				   blobSize blobSize)
      )

      ; Clamp spread value to 'gegl:noise-spread' limits.
      ; This plugin calls 'gegl:noise-spread' indirectly via distress-selection.
      ; gegl:noise-spread seems to have a limit of 512.
      ; Here we limit to 200, for undocumented reasons.
      (set! theSpread (/ theSize 25))
      (if (> theSpread 200) (set! theSpread 200))

      ; Threshold to distress-selection now allows [0, 1.0] including zero.
      ; Formerly, it allowed [1, 254] (strange, but documented.)
      ;
      ; Here we generate a random non-uniform weighted towards center.
      ; The distribution of the product (or sum) of two random numbers is non-uniform.

      ; random seems not standardized in Scheme, our version is MSRG in script-fu-compat.init.
      ; It yields random uniform integers, except 0.
      ;
      ; (+ (random 15) 1) yields [2, 16] uniform.
      ; The original formula, a product of random numbers, yields [3, 255] non-uniform.
      ; To accommodate changes to distress-selection, we use the old formula, and divide by 255.
      ; When you instead just generate a single random float, stains are smaller.
      (set! theThreshold (/
                            (- (* (+ (random 15) 1) (+ (random 15) 1)) 1) ; original formula
                            255))

      ; !!! This call is not via the PDB so SF does not range check args.
      ; The script is in the interpreter state and doesn't require a PDB call.
      ;
      ; The called SF plugin is not yet converted to v3 binding, so switch back to v2
      ; and use TRUE instead of #t
      (script-fu-use-v2)
      (script-fu-distress-selection theImage (vector theStain)
                                    theThreshold
                                    theSpread 4 2 TRUE TRUE)
      ; back to v3, this is a loop
      (script-fu-use-v3)


      (gimp-context-set-gradient inGradient)

      ; only fill if there is a selection
      ; First element of returned list is a boolean.
      (if (car (gimp-selection-bounds theImage))
        (gimp-drawable-edit-gradient-fill theStain
            GRADIENT-SHAPEBURST-DIMPLED 0
            #f 1 0
            #t
            0 0 0 0)
      )

      (gimp-layer-set-offsets theStain
                              (- (random theWidth) (/ theSize 2))
                              (- (random theHeight) (/ theSize 2)))
    )

    (gimp-selection-none theImage)

    (gimp-image-undo-group-end theImage)

    (gimp-displays-flush)

    (gimp-context-pop)
  )
)

; Register as a filter

; !!! Enabled for any non-zero count of layers.
; Requires an image, to which we add layers.
; Argument inLayers is not used.

(script-fu-register-filter "script-fu-coffee-stain"
  _"_Stain..."
  _"Add layers of stain or blotch marks"
  "Chris Gutteridge"
  "1998, Chris Gutteridge / ECS dept, University of Southampton, England."
  "25th April 1998"
  "RGB*"
  SF-ONE-OR-MORE-DRAWABLE
  SF-ADJUSTMENT _"Number of stains to add"      '(3 1 10 1 2 0 0)
  SF-TOGGLE     _"Darken only" #t
  SF-GRADIENT   _"Gradient to color stains"    "Coffee"
)

(script-fu-menu-register "script-fu-coffee-stain" "<Image>/Filters/Decor")