/racket-5-0-2-bin-i386-osx-mac-dmg/collects/2htdp/private/img-err.rkt

http://github.com/smorin/f4f.arc · Racket · 286 lines · 243 code · 11 blank · 32 comment · 40 complexity · 6d544e9af3a518b79304f23ab343888b MD5 · raw file

  1. #lang racket/base
  2. (provide define/chk
  3. x-place?
  4. y-place?
  5. mode?
  6. angle?
  7. side-count?
  8. image-color?
  9. pen-style?
  10. pen-cap?
  11. pen-join?
  12. check-mode/color-combination)
  13. (require htdp/error
  14. racket/class
  15. lang/posn
  16. racket/gui/base
  17. "../../mrlib/image-core.ss"
  18. (for-syntax racket/base
  19. racket/list))
  20. ;
  21. ;
  22. ;
  23. ;
  24. ;
  25. ;
  26. ; ;; ;; ;;
  27. ; ;; ;; ;;
  28. ; ;;;; ;;;;;;;;; ;;;; ;;;; ;;;; ;;;;;; ;;;; ;;;; ;; ;;; ;; ;; ;;; ;;;;;;
  29. ; ;; ;; ;;;; ;;;; ;;;;;; ;;;; ;;;;;; ;;;;;; ;; ;; ;;;;;; ;;;;; ;; ;;;;;; ;;;;;;
  30. ; ;;;;;;;; ;; ;; ;;; ;;; ;; ;;; ;; ;; ;;;;;;;;;;; ;;;;; ;; ;; ;; ;;; ;;
  31. ; ;;; ;; ;; ;;; ;;; ;; ;;; ;; ;; ;;; ;;; ;;;;; ;; ;; ;; ;;; ;;
  32. ; ;;; ;; ;; ;; ;;;;;; ;; ;;;;;; ;; ;; ;;; ;; ;;;;;; ;; ;; ;; ;; ;; ;;;;;;
  33. ; ;;;; ;; ;; ;;;; ;; ;;;; ;; ;; ;;;; ;;;; ;; ;;; ;; ;; ;; ;;;;;
  34. ; ;; ;;;
  35. ; ;;;;;
  36. ;
  37. ;
  38. (define-syntax define/chk
  39. (Îť (stx)
  40. (syntax-case stx ()
  41. [(define/chk (fn-name args ... . final-arg) body ...)
  42. (identifier? #'final-arg)
  43. (let ([len (length (syntax->list #'(args ...)))])
  44. (with-syntax ([(i ...) (build-list len add1)])
  45. #`(define (fn-name args ... . final-arg)
  46. (let ([args (check/normalize 'fn-name 'args args i)] ...
  47. [final-arg (map/i (Îť (x j) (check/normalize 'fn-name 'final-arg x (+ #,len j)))
  48. final-arg)])
  49. body ...))))]
  50. [(define/chk (fn-name args ...) body ...)
  51. (with-syntax ([(i ...) (build-list (length (syntax->list #'(args ...))) add1)])
  52. #'(define (fn-name args ...)
  53. (let ([args (check/normalize 'fn-name 'args args i)] ...)
  54. body ...)))])))
  55. (define (map/i f l)
  56. (let loop ([l l]
  57. [i 0])
  58. (cond
  59. [(null? l) null]
  60. [else (cons (f (car l) i)
  61. (loop (cdr l) (+ i 1)))])))
  62. ;; check/normalize : symbol symbol any number -> any
  63. ;; based on the name of the argument, checks to see if the input
  64. ;; is valid and, if so, transforms it to a specific kind of value
  65. ;; width, height -> number
  66. ;; mode -> 'outline 'solid
  67. ;; color -> (is-a?/c color<%>)
  68. (define (check/normalize fn-name argname arg i)
  69. (case argname
  70. [(x-place)
  71. (check-arg fn-name
  72. (x-place? arg)
  73. 'x-place
  74. i
  75. arg)
  76. (let ([sym (if (string? arg)
  77. (string->symbol arg)
  78. arg)])
  79. (if (eq? sym 'center)
  80. 'middle
  81. sym))]
  82. [(y-place)
  83. (check-arg fn-name
  84. (y-place? arg)
  85. 'y-place
  86. i
  87. arg)
  88. (let ([sym (if (string? arg)
  89. (string->symbol arg)
  90. arg)])
  91. (if (eq? sym 'center)
  92. 'middle
  93. sym))]
  94. [(image image1 image2 image3)
  95. (check-arg fn-name
  96. (image? arg)
  97. 'image
  98. i
  99. arg)
  100. (to-img arg)]
  101. [(mode)
  102. (check-arg fn-name
  103. (mode? arg)
  104. 'mode
  105. i
  106. arg)
  107. (if (string? arg)
  108. (string->symbol arg)
  109. arg)]
  110. [(width height radius radius1 radius2 side-length side-length1 side-length2
  111. side-a side-b side-c)
  112. (check-arg fn-name
  113. (and (real? arg)
  114. (not (negative? arg)))
  115. 'non\ negative\ real\ number
  116. i arg)
  117. arg]
  118. [(point-count)
  119. (check-arg fn-name
  120. (and (integer? arg)
  121. (>= arg 2))
  122. 'integer\ greater\ than\ 2
  123. i arg)
  124. arg]
  125. [(dx dy x1 y1 x2 y2 pull1 pull2)
  126. (check-arg fn-name
  127. (real? arg)
  128. 'real\ number
  129. i arg)
  130. arg]
  131. [(factor x-factor y-factor)
  132. (check-arg fn-name
  133. (and (real? arg)
  134. (positive? arg))
  135. 'positive\ real\ number
  136. i arg)
  137. arg]
  138. [(side-count)
  139. (check-arg fn-name
  140. (side-count? arg)
  141. 'side-count
  142. i arg)
  143. arg]
  144. [(step-count)
  145. (check-arg fn-name
  146. (step-count? arg)
  147. 'step-count
  148. i arg)
  149. arg]
  150. [(angle angle1 angle2 angle-a angle-b angle-c)
  151. (check-arg fn-name
  152. (angle? arg)
  153. 'angle\ in\ degrees
  154. i arg)
  155. (if (< arg 0)
  156. (+ arg 360)
  157. arg)]
  158. [(color)
  159. (check-arg fn-name (or (image-color? arg) (pen? arg)) 'image-color-or-pen i arg)
  160. ;; return either a string, color, or a pen,
  161. ;; (technically, the string case is redundant,
  162. ;; but since there may be saved files that have
  163. ;; strings in the color positions we leave them
  164. ;; here too; note that using a pen struct means
  165. ;; 'smoothed mode, but a color (or string) means
  166. ;; 'aligned mode, so that's not redundant).
  167. (cond
  168. [(color? arg) arg]
  169. [(pen? arg) arg]
  170. [else
  171. (let* ([color-str
  172. (if (symbol? arg)
  173. (symbol->string arg)
  174. arg)])
  175. (if (send the-color-database find-color color-str)
  176. color-str
  177. "black"))])]
  178. [(color-list)
  179. (check-arg fn-name (and (list? arg) (andmap image-color? arg)) 'color-list i arg)
  180. arg]
  181. [(string)
  182. (check-arg fn-name (string? arg) 'string i arg)
  183. arg]
  184. [(font-size)
  185. (check-arg fn-name (and (integer? arg) (<= 1 arg 255)) 'font-size i arg)
  186. (if (exact? arg)
  187. arg
  188. (inexact->exact arg))]
  189. [(face)
  190. (check-arg fn-name (or (not arg) (string? arg)) 'face i arg)
  191. arg]
  192. [(family)
  193. (check-arg fn-name (memq arg '(default decorative roman script swiss modern symbol system)) 'family i arg)
  194. arg]
  195. [(style)
  196. (check-arg fn-name (memq arg '(normal italic slant)) 'style i arg)
  197. arg]
  198. [(weight)
  199. (check-arg fn-name (memq arg '(normal bold light)) 'weight i arg)
  200. arg]
  201. [(underline)
  202. (and arg #t)]
  203. [(posns)
  204. (check-arg fn-name
  205. (and (list? arg)
  206. (andmap posn? arg))
  207. 'list-of-posns
  208. i arg)
  209. (check-arg fn-name
  210. (>= (length arg) 3)
  211. 'list-of-at-least-three-posns
  212. i arg)
  213. arg]
  214. [(int0-255-1 int0-255-2 int0-255-3)
  215. (check-arg fn-name (and (integer? arg) (<= 0 arg 255))
  216. 'integer\ between\ 0\ and\ 255 i arg)
  217. arg]
  218. [(real-0-255)
  219. (check-arg fn-name (and (integer? arg) (<= 0 arg 255))
  220. 'real\ number\ between\ 0\ and\ 255 i arg)
  221. arg]
  222. [(pen-style)
  223. (check-arg fn-name (pen-style? arg) 'pen-style i arg)
  224. (if (string? arg)
  225. (string->symbol arg)
  226. arg)]
  227. [(pen-cap)
  228. (check-arg fn-name (pen-cap? arg) 'pen-cap i arg)
  229. (if (string? arg)
  230. (string->symbol arg)
  231. arg)]
  232. [(pen-join)
  233. (check-arg fn-name (pen-join? arg) 'pen-join i arg)
  234. (if (string? arg)
  235. (string->symbol arg)
  236. arg)]
  237. [(filename)
  238. (check-arg fn-name (path-string? arg) 'path-string i arg)
  239. arg]
  240. [else
  241. (error 'check "the function ~a has an argument with an unknown name: ~s"
  242. fn-name
  243. argname)]))
  244. (define (y-place? arg)
  245. (member arg '("top" top "bottom" bottom "middle" middle "center" center "baseline" baseline "pinhole" pinhole)))
  246. (define (x-place? arg)
  247. (member arg '("left" left "right" right "middle" middle "center" center "pinhole" pinhole)))
  248. (define (mode? arg)
  249. (member arg '(solid outline "solid" "outline")))
  250. (define (angle? arg)
  251. (and (real? arg)
  252. (< -360 arg 360)))
  253. (define (side-count? i)
  254. (and (integer? i)
  255. (3 . <= . i)))
  256. (define (step-count? i)
  257. (and (integer? i)
  258. (1 . <= . i)))
  259. (define (image-color? c) (or (symbol? c) (string? c) (color? c)))
  260. (define (pen-style? arg)
  261. (member (if (string? arg) (string->symbol arg) arg)
  262. '(solid dot long-dash short-dash dot-dash)))
  263. (define (pen-cap? arg)
  264. (member (if (string? arg) (string->symbol arg) arg)
  265. '(round projecting butt)))
  266. (define (pen-join? arg)
  267. (member (if (string? arg) (string->symbol arg) arg)
  268. '(round bevel miter)))
  269. ;; checks the dependent part of the 'color' specification
  270. (define (check-mode/color-combination fn-name i mode color)
  271. (cond
  272. [(eq? mode 'solid)
  273. (check-arg fn-name (image-color? color) 'image-color i color)]
  274. [(eq? mode 'outline)
  275. (void)]))