/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
- #lang racket/base
- (provide define/chk
- x-place?
- y-place?
- mode?
- angle?
- side-count?
- image-color?
- pen-style?
- pen-cap?
- pen-join?
- check-mode/color-combination)
- (require htdp/error
- racket/class
- lang/posn
- racket/gui/base
- "../../mrlib/image-core.ss"
- (for-syntax racket/base
- racket/list))
- ;
- ;
- ;
- ;
- ;
- ;
- ; ;; ;; ;;
- ; ;; ;; ;;
- ; ;;;; ;;;;;;;;; ;;;; ;;;; ;;;; ;;;;;; ;;;; ;;;; ;; ;;; ;; ;; ;;; ;;;;;;
- ; ;; ;; ;;;; ;;;; ;;;;;; ;;;; ;;;;;; ;;;;;; ;; ;; ;;;;;; ;;;;; ;; ;;;;;; ;;;;;;
- ; ;;;;;;;; ;; ;; ;;; ;;; ;; ;;; ;; ;; ;;;;;;;;;;; ;;;;; ;; ;; ;; ;;; ;;
- ; ;;; ;; ;; ;;; ;;; ;; ;;; ;; ;; ;;; ;;; ;;;;; ;; ;; ;; ;;; ;;
- ; ;;; ;; ;; ;; ;;;;;; ;; ;;;;;; ;; ;; ;;; ;; ;;;;;; ;; ;; ;; ;; ;; ;;;;;;
- ; ;;;; ;; ;; ;;;; ;; ;;;; ;; ;; ;;;; ;;;; ;; ;;; ;; ;; ;; ;;;;;
- ; ;; ;;;
- ; ;;;;;
- ;
- ;
- (define-syntax define/chk
- (Îť (stx)
- (syntax-case stx ()
- [(define/chk (fn-name args ... . final-arg) body ...)
- (identifier? #'final-arg)
- (let ([len (length (syntax->list #'(args ...)))])
- (with-syntax ([(i ...) (build-list len add1)])
- #`(define (fn-name args ... . final-arg)
- (let ([args (check/normalize 'fn-name 'args args i)] ...
- [final-arg (map/i (Îť (x j) (check/normalize 'fn-name 'final-arg x (+ #,len j)))
- final-arg)])
- body ...))))]
- [(define/chk (fn-name args ...) body ...)
- (with-syntax ([(i ...) (build-list (length (syntax->list #'(args ...))) add1)])
- #'(define (fn-name args ...)
- (let ([args (check/normalize 'fn-name 'args args i)] ...)
- body ...)))])))
- (define (map/i f l)
- (let loop ([l l]
- [i 0])
- (cond
- [(null? l) null]
- [else (cons (f (car l) i)
- (loop (cdr l) (+ i 1)))])))
- ;; check/normalize : symbol symbol any number -> any
- ;; based on the name of the argument, checks to see if the input
- ;; is valid and, if so, transforms it to a specific kind of value
- ;; width, height -> number
- ;; mode -> 'outline 'solid
- ;; color -> (is-a?/c color<%>)
- (define (check/normalize fn-name argname arg i)
- (case argname
- [(x-place)
- (check-arg fn-name
- (x-place? arg)
- 'x-place
- i
- arg)
- (let ([sym (if (string? arg)
- (string->symbol arg)
- arg)])
- (if (eq? sym 'center)
- 'middle
- sym))]
- [(y-place)
- (check-arg fn-name
- (y-place? arg)
- 'y-place
- i
- arg)
- (let ([sym (if (string? arg)
- (string->symbol arg)
- arg)])
- (if (eq? sym 'center)
- 'middle
- sym))]
- [(image image1 image2 image3)
- (check-arg fn-name
- (image? arg)
- 'image
- i
- arg)
- (to-img arg)]
- [(mode)
- (check-arg fn-name
- (mode? arg)
- 'mode
- i
- arg)
- (if (string? arg)
- (string->symbol arg)
- arg)]
- [(width height radius radius1 radius2 side-length side-length1 side-length2
- side-a side-b side-c)
- (check-arg fn-name
- (and (real? arg)
- (not (negative? arg)))
- 'non\ negative\ real\ number
- i arg)
- arg]
- [(point-count)
- (check-arg fn-name
- (and (integer? arg)
- (>= arg 2))
- 'integer\ greater\ than\ 2
- i arg)
- arg]
- [(dx dy x1 y1 x2 y2 pull1 pull2)
- (check-arg fn-name
- (real? arg)
- 'real\ number
- i arg)
- arg]
- [(factor x-factor y-factor)
- (check-arg fn-name
- (and (real? arg)
- (positive? arg))
- 'positive\ real\ number
- i arg)
- arg]
- [(side-count)
- (check-arg fn-name
- (side-count? arg)
- 'side-count
- i arg)
- arg]
- [(step-count)
- (check-arg fn-name
- (step-count? arg)
- 'step-count
- i arg)
- arg]
- [(angle angle1 angle2 angle-a angle-b angle-c)
- (check-arg fn-name
- (angle? arg)
- 'angle\ in\ degrees
- i arg)
- (if (< arg 0)
- (+ arg 360)
- arg)]
- [(color)
- (check-arg fn-name (or (image-color? arg) (pen? arg)) 'image-color-or-pen i arg)
- ;; return either a string, color, or a pen,
- ;; (technically, the string case is redundant,
- ;; but since there may be saved files that have
- ;; strings in the color positions we leave them
- ;; here too; note that using a pen struct means
- ;; 'smoothed mode, but a color (or string) means
- ;; 'aligned mode, so that's not redundant).
- (cond
- [(color? arg) arg]
- [(pen? arg) arg]
- [else
- (let* ([color-str
- (if (symbol? arg)
- (symbol->string arg)
- arg)])
- (if (send the-color-database find-color color-str)
- color-str
- "black"))])]
- [(color-list)
- (check-arg fn-name (and (list? arg) (andmap image-color? arg)) 'color-list i arg)
- arg]
- [(string)
- (check-arg fn-name (string? arg) 'string i arg)
- arg]
- [(font-size)
- (check-arg fn-name (and (integer? arg) (<= 1 arg 255)) 'font-size i arg)
- (if (exact? arg)
- arg
- (inexact->exact arg))]
- [(face)
- (check-arg fn-name (or (not arg) (string? arg)) 'face i arg)
- arg]
- [(family)
- (check-arg fn-name (memq arg '(default decorative roman script swiss modern symbol system)) 'family i arg)
- arg]
- [(style)
- (check-arg fn-name (memq arg '(normal italic slant)) 'style i arg)
- arg]
- [(weight)
- (check-arg fn-name (memq arg '(normal bold light)) 'weight i arg)
- arg]
- [(underline)
- (and arg #t)]
- [(posns)
- (check-arg fn-name
- (and (list? arg)
- (andmap posn? arg))
- 'list-of-posns
- i arg)
- (check-arg fn-name
- (>= (length arg) 3)
- 'list-of-at-least-three-posns
- i arg)
- arg]
- [(int0-255-1 int0-255-2 int0-255-3)
- (check-arg fn-name (and (integer? arg) (<= 0 arg 255))
- 'integer\ between\ 0\ and\ 255 i arg)
- arg]
- [(real-0-255)
- (check-arg fn-name (and (integer? arg) (<= 0 arg 255))
- 'real\ number\ between\ 0\ and\ 255 i arg)
- arg]
-
- [(pen-style)
- (check-arg fn-name (pen-style? arg) 'pen-style i arg)
- (if (string? arg)
- (string->symbol arg)
- arg)]
- [(pen-cap)
- (check-arg fn-name (pen-cap? arg) 'pen-cap i arg)
- (if (string? arg)
- (string->symbol arg)
- arg)]
- [(pen-join)
- (check-arg fn-name (pen-join? arg) 'pen-join i arg)
- (if (string? arg)
- (string->symbol arg)
- arg)]
- [(filename)
- (check-arg fn-name (path-string? arg) 'path-string i arg)
- arg]
- [else
- (error 'check "the function ~a has an argument with an unknown name: ~s"
- fn-name
- argname)]))
- (define (y-place? arg)
- (member arg '("top" top "bottom" bottom "middle" middle "center" center "baseline" baseline "pinhole" pinhole)))
- (define (x-place? arg)
- (member arg '("left" left "right" right "middle" middle "center" center "pinhole" pinhole)))
- (define (mode? arg)
- (member arg '(solid outline "solid" "outline")))
- (define (angle? arg)
- (and (real? arg)
- (< -360 arg 360)))
- (define (side-count? i)
- (and (integer? i)
- (3 . <= . i)))
- (define (step-count? i)
- (and (integer? i)
- (1 . <= . i)))
- (define (image-color? c) (or (symbol? c) (string? c) (color? c)))
- (define (pen-style? arg)
- (member (if (string? arg) (string->symbol arg) arg)
- '(solid dot long-dash short-dash dot-dash)))
- (define (pen-cap? arg)
- (member (if (string? arg) (string->symbol arg) arg)
- '(round projecting butt)))
- (define (pen-join? arg)
- (member (if (string? arg) (string->symbol arg) arg)
- '(round bevel miter)))
- ;; checks the dependent part of the 'color' specification
- (define (check-mode/color-combination fn-name i mode color)
- (cond
- [(eq? mode 'solid)
- (check-arg fn-name (image-color? color) 'image-color i color)]
- [(eq? mode 'outline)
- (void)]))