PageRenderTime 161ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/src/editcolor.sc

https://bitbucket.org/bunny351/ezd
Scala | 354 lines | 303 code | 51 blank | 0 comment | 4 complexity | 8b3c0adb7a9468cff1e1d8492abfcb5f MD5 | raw file
  1. ;;; ezd - easy drawing for X11 displays.
  2. ;;;
  3. ;;; Variable colors are adjusted using the tool implemented in this module.
  4. ;* Copyright 1990-1993 Digital Equipment Corporation
  5. ;* All Rights Reserved
  6. ;*
  7. ;* Permission to use, copy, and modify this software and its documentation is
  8. ;* hereby granted only under the following terms and conditions. Both the
  9. ;* above copyright notice and this permission notice must appear in all copies
  10. ;* of the software, derivative works or modified versions, and any portions
  11. ;* thereof, and both notices must appear in supporting documentation.
  12. ;*
  13. ;* Users of this software agree to the terms and conditions set forth herein,
  14. ;* and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
  15. ;* right and license under any changes, enhancements or extensions made to the
  16. ;* core functions of the software, including but not limited to those affording
  17. ;* compatibility with other hardware or software environments, but excluding
  18. ;* applications which incorporate this software. Users further agree to use
  19. ;* their best efforts to return to Digital any such changes, enhancements or
  20. ;* extensions that they make and inform Digital of noteworthy uses of this
  21. ;* software. Correspondence should be provided to Digital at:
  22. ;*
  23. ;* Director of Licensing
  24. ;* Western Research Laboratory
  25. ;* Digital Equipment Corporation
  26. ;* 250 University Avenue
  27. ;* Palo Alto, California 94301
  28. ;*
  29. ;* This software may be distributed (but not offered for sale or transferred
  30. ;* for compensation) to third parties, provided such third parties agree to
  31. ;* abide by the terms and conditions of this notice.
  32. ;*
  33. ;* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  34. ;* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  35. ;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  36. ;* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  37. ;* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  38. ;* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  39. ;* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  40. ;* SOFTWARE.
  41. (module editcolor)
  42. (include "struct.sch")
  43. (include "events.sch")
  44. (include "commands.sch")
  45. (include "interact.sch")
  46. (include "ezd.sch")
  47. (include "ginfo.sch")
  48. (include "xternal.sch")
  49. (define EDIT-COLOR-DELTA 0)
  50. ;;; A variable color is "edited" by creating a control panel for it. Any
  51. ;;; number of control panels may exist at any one time.
  52. (define (MAKE-COLOR-CONTROL-PANEL color)
  53. ;;; Control panel configuration information.
  54. (define WS 10) ; whitespace
  55. (define SLIDE-W 256) ; slider width
  56. (define SLIDE-H 20) ; slider height
  57. (define HEX-W 50)
  58. (define COLOR-IND 20) ; indicator parameters
  59. (define COLOR-MIN 0)
  60. (define COLOR-MAX 255)
  61. (define COLOR-VALUE 0)
  62. (define COLOR-JUMP 1)
  63. (define (ROW-Y x) (+ ws (* (+ slide-h ws) x)))
  64. ;;; Information related to the variable color being edited.
  65. (define RED #f)
  66. (define GREEN #f)
  67. (define BLUE #f)
  68. (define GRAY #f)
  69. (define HUE #f)
  70. (define SATURATION #f)
  71. (define VALUE #f)
  72. (define PANEL
  73. (string->symbol (string-append "EVC-" (symbol->string color))))
  74. ;;; Draw the hex value of a slider.
  75. (define (DRAW-HEX name row value)
  76. (ezd `(object ,name
  77. (text ,(+ ws slide-w ws) ,(row-y row) ,hex-w
  78. ,slide-h right center
  79. ,(number->string value 16)))))
  80. ;;; Set indicators on a change of RGB value.
  81. (define (SET-FROM-RGB slider r g b)
  82. (unless (eq? red r)
  83. (set! red r)
  84. (if (not (eq? slider 'red))
  85. (set-attributes panel 'red `(value ,r)))
  86. (draw-hex 'red-hex 0 r))
  87. (unless (eq? green g)
  88. (set! green g)
  89. (if (not (eq? slider 'green))
  90. (set-attributes panel 'green `(value ,g)))
  91. (draw-hex 'green-hex 1 g))
  92. (unless (eq? blue b)
  93. (set! blue b)
  94. (if (not (eq? slider 'blue))
  95. (set-attributes panel 'blue `(value ,b)))
  96. (draw-hex 'blue-hex 2 b))
  97. (when (= r g b)
  98. (set! gray r)
  99. (if (not (eq? slider 'gray))
  100. (set-attributes panel 'gray `(value ,gray))))
  101. (let ((name-delta (rgb->color r g b)))
  102. (ezd `(set-variable-color ,color
  103. ,(+ (* 256 (+ (* 256 r) g)) b))
  104. `(set-attributes ,panel name-key (text ,name-delta))))
  105. (unless (memq slider '(hue saturation value))
  106. (let* ((r (/ r 255))
  107. (g (/ g 255))
  108. (b (/ b 255))
  109. (maxrgb (max r g b))
  110. (minrgb (min r g b))
  111. (delta (- maxrgb minrgb)))
  112. (set! value maxrgb)
  113. (if (positive? maxrgb)
  114. (set! saturation (/ delta maxrgb))
  115. (set! saturation 0))
  116. (if (zero? saturation)
  117. (set! hue 0)
  118. (let ((rc (/ (- maxrgb r) delta))
  119. (gc (/ (- maxrgb g) delta))
  120. (bc (/ (- maxrgb b) delta)))
  121. (cond ((= r maxrgb)
  122. (set! hue (- bc gc)))
  123. ((= g maxrgb)
  124. (set! hue (+ 2 (- rc bc))))
  125. (else (set! hue (+ 4 (- gc rc)))))
  126. (set! hue (* hue 60))
  127. (if (negative? hue)
  128. (set! hue (+ hue 360)))))
  129. (set-attributes panel 'hue `(value ,hue))
  130. (set-attributes panel 'saturation
  131. `(value ,saturation))
  132. (set-attributes panel 'value `(value ,value)))))
  133. ;;; Set indicators on a keyboard input.
  134. (define (SET-FROM-KEYBOARD)
  135. (let* ((value (car *user-event-misc*))
  136. (number (string->number value))
  137. (name (and (not number) (color->rgb value))))
  138. (cond ((and number (exact? number) (>= 0 number))
  139. (set-from-rgb #f
  140. (bit-and 255 (bit-rsh number 16))
  141. (bit-and 255 (bit-rsh number 8))
  142. (bit-and 255 number)))
  143. (name (apply set-from-rgb #f name))
  144. (else (ezd `(bell))))))
  145. ;;; Set indicators on a change of HSV values.
  146. (define (SET-FROM-HSV slider h s v)
  147. (let ((scaled-v (inexact->exact (* v 255))))
  148. (set! hue h)
  149. (set! saturation s)
  150. (set! value v)
  151. (if (zero? s)
  152. (set-from-rgb slider scaled-v scaled-v scaled-v)
  153. (let* ((h (/ (if (= h 360) 0 h) 60))
  154. (i (inexact->exact (floor h)))
  155. (f (- h i))
  156. (p (inexact->exact (* 255 v (- 1 s))))
  157. (q (inexact->exact (* 255 v (- 1 (* s f)))))
  158. (t (inexact->exact (* 255 v (- 1 (* s (- 1 f)))))))
  159. (case i
  160. ((0) (set-from-rgb slider scaled-v t p))
  161. ((1) (set-from-rgb slider q scaled-v p))
  162. ((2) (set-from-rgb slider p scaled-v t))
  163. ((3) (set-from-rgb slider p q scaled-v))
  164. ((4) (set-from-rgb slider t p scaled-v))
  165. ((5) (set-from-rgb slider scaled-v p q)))))))
  166. ;;; Load rgb.txt and draw the control panel.
  167. (rgb-values)
  168. (ezd '(save-drawing)
  169. `(set-drawing ,panel)
  170. '(object color-name)
  171. `(slider red ,ws ,(row-y 0) ,slide-w ,slide-h ,color-ind
  172. ,color-min ,color-max ,color-value ,color-jump
  173. ,(lambda () (set-from-rgb 'red (car *user-event-misc*)
  174. green blue))
  175. red)
  176. `(slider green ,ws ,(row-y 1) ,slide-w ,slide-h ,color-ind
  177. ,color-min ,color-max ,color-value ,color-jump
  178. ,(lambda () (set-from-rgb 'green red (car *user-event-misc*)
  179. blue))
  180. green)
  181. `(slider blue ,ws ,(row-y 2) ,slide-w ,slide-h ,color-ind
  182. ,color-min ,color-max ,color-value ,color-jump
  183. ,(lambda () (set-from-rgb 'blue red green
  184. (car *user-event-misc*)))
  185. blue)
  186. `(slider gray ,ws ,(row-y 3) ,slide-w ,slide-h ,color-ind
  187. ,color-min ,color-max ,color-value ,color-jump
  188. ,(lambda () (set-from-rgb 'gray (car *user-event-misc*)
  189. (car *user-event-misc*)
  190. (car *user-event-misc*)))
  191. gray)
  192. `(slider hue ,ws ,(row-y 4) ,slide-w ,slide-h 28 0 360 0 3
  193. ,(lambda () (set-from-hsv 'hue (car *user-event-misc*)
  194. saturation value)))
  195. `(text ,(+ ws slide-w ws) ,(row-y 4) ,hex-w ,slide-h center center
  196. "Hue")
  197. `(slider saturation ,ws ,(row-y 5) ,slide-w ,slide-h .08 0 1 0 .01
  198. ,(lambda () (set-from-hsv 'saturation hue
  199. (car *user-event-misc*) value)))
  200. `(text ,(+ ws slide-w ws) ,(row-y 5) ,hex-w ,slide-h center center
  201. "Sat.")
  202. `(slider value ,ws ,(row-y 6) ,slide-w ,slide-h .08 0 1 0 .01
  203. ,(lambda () (set-from-hsv 'value hue saturation
  204. (car *user-event-misc*))))
  205. `(text ,(+ ws slide-w ws) ,(row-y 6) ,hex-w ,slide-h center center
  206. "Value")
  207. `(string-input name-key ,ws ,(row-y 7) ,slide-w ,slide-h
  208. "" ,set-from-keyboard)
  209. `(push-button ok ,(+ ws slide-w ws) ,(row-y 7) ,hex-w ,slide-h
  210. "OK" ,(lambda () (ezd '(save-drawing)
  211. `(set-drawing ,panel)
  212. '(clear)
  213. `(delete-window ,panel)
  214. '(restore-drawing))))
  215. `(window ,panel ,(+ 100 edit-color-delta) ,(+ 100 edit-color-delta)
  216. ,(+ ws slide-w ws hex-w ws) ,(row-y 8) fixed-size
  217. ,(string-append "Edit variable color "
  218. (symbol->string color)))
  219. `(overlay ,panel ,panel))
  220. (apply set-from-rgb #f (getprop color 'isa-color))
  221. (ezd '(restore-drawing))
  222. (set! edit-color-delta (remainder (+ edit-color-delta 20) 100)))
  223. ;;; R-G-B coordinates are converted to a color name by the following procedure.
  224. ;;; It returns a string that is the name of the closest color followed by
  225. ;;; a string of the form "+xx +xx +xx" that is the offsets to add to each
  226. ;;; pair of hex digits defining the color to get the named color. The deltas
  227. ;;; are not supplied when the color is exact.
  228. (define (RGB->COLOR red green blue)
  229. (let loop ((l (rgb-values)) (delta (* 3 (* 256 256 256)))
  230. (delta-name "black") (deltas (list 256 256 256)))
  231. (if (pair? l)
  232. (let* ((rgb (caar l))
  233. (name (cadar l))
  234. (dr (- (car rgb) red))
  235. (dg (- (cadr rgb) green))
  236. (db (- (caddr rgb) blue))
  237. (d (+ (abs (* dr dr dr)) (abs (* dg dg dg))
  238. (abs (* db db db)))))
  239. (cond ((zero? d)
  240. (loop '() d name (list dr dg db)))
  241. ((< d delta)
  242. (loop (cdr l) d name (list dr dg db)))
  243. (else (loop (cdr l) delta delta-name deltas))))
  244. (string-append delta-name
  245. (if (equal? deltas '(0 0 0))
  246. ""
  247. (string-append " " (number->string (car deltas) 16) " "
  248. (number->string (cadr deltas) 16) " "
  249. (number->string (caddr deltas) 16)))))))
  250. ;;; A color name is converted to it's R-G-B coordinates by the following
  251. ;;; procedure. Either a list of rgb values is returned, or #f indicating that
  252. ;;; the name was not found.
  253. (define (COLOR->RGB name)
  254. (let loop ((l (rgb-values)))
  255. (if (pair? l)
  256. (if (equal? (cadar l) name) (caar l) (loop (cdr l)))
  257. #f)))
  258. ;;; The following function returns a list of entries of the form:
  259. ;;;
  260. ;;; ((r-value g-value b-value) color-name)
  261. ;;;
  262. ;;; from the COLOR-DEFINITION-FILE.
  263. (define COLOR-DEFINITION-FILE "/usr/lib/X11/rgb.txt")
  264. (define RGB-VALUES
  265. (let ((values '()))
  266. (define NAME-BUFFER #f)
  267. (define (READ-NAME fh)
  268. (let loop () (when (char-whitespace? (peek-char fh))
  269. (read-char fh)
  270. (loop)))
  271. (let loop ((i 0))
  272. (if (eq? (peek-char fh) #\newline)
  273. (set! name-buffer (make-string i))
  274. (let ((char (read-char fh)))
  275. (loop (+ i 1))
  276. (if name-buffer
  277. (if (eq? char #\space)
  278. (set! name-buffer #f)
  279. (string-set! name-buffer i
  280. (char-downcase char)))))))
  281. name-buffer)
  282. (define (READ-RGB-FILE fh)
  283. (let* ((r (read fh))
  284. (g (read fh))
  285. (b (read fh)))
  286. (if (eof-object? r)
  287. '()
  288. (let ((name (read-name fh)))
  289. (if name
  290. (cons (list (list r g b) name)
  291. (read-rgb-file fh))
  292. (read-rgb-file fh))))))
  293. (lambda ()
  294. (if (null? values)
  295. (let ((fh (open-input-file color-definition-file)))
  296. (set! values (read-rgb-file fh))
  297. (close-input-port fh)))
  298. values)))
  299. ;;; A variable color is edited by the command EDIT-VARIABLE-COLOR.
  300. (define-ezd-command
  301. `(edit-variable-color ,variable-color?)
  302. "(edit-variable-color variable-color)"
  303. make-color-control-panel)