images/icons: add backing-scale arguments

By default, icons render with a backing scale of 2.
This commit is contained in:
Matthew Flatt 2014-01-02 18:57:09 -07:00
parent 5e903441a4
commit 4ee266fd97
14 changed files with 68 additions and 26 deletions

View File

@ -327,7 +327,7 @@ Like @racket[unsafe-flomap-ref], but returns an flvector containing all the comp
@section{Conversion and Construction} @section{Conversion and Construction}
@defproc[(flomap->bitmap [fm flomap]) Any]{ @defproc[(flomap->bitmap [fm flomap] [#:backing-scale backing-scale (>/c 0.0)]) Any]{
Converts a flomap to a @racket[bitmap%]. Converts a flomap to a @racket[bitmap%].
The return type is imprecise because Typed Racket does not support the object system well yet. The return type is imprecise because Typed Racket does not support the object system well yet.

View File

@ -143,6 +143,14 @@ Use @racket[(toolbar-icon-height)] as the @racket[height] argument for common ic
If you cannot, as with the Macro Stepper, send a thinner icon as the @racket[alternate-bitmap] argument to a @racket[switchable-button%].) If you cannot, as with the Macro Stepper, send a thinner icon as the @racket[alternate-bitmap] argument to a @racket[switchable-button%].)
} }
@doc-apply[default-icon-backing-scale]{
The backing scale of DrRacket icons.
A backing scale of 2 means that the icon bitmap internally has two
pixels per drawing unit, so it it renders well a double resolution,
such as Retina display mode for Mac OS X.
}
@doc-apply[plastic-icon-material] @doc-apply[plastic-icon-material]
@doc-apply[rubber-icon-material] @doc-apply[rubber-icon-material]
@doc-apply[glass-icon-material] @doc-apply[glass-icon-material]

View File

@ -9,17 +9,19 @@
(begin-for-syntax (begin-for-syntax
(define (save-png bm) (define (save-png bm)
(define p (open-output-bytes)) (define p (open-output-bytes))
(send bm save-file p 'png) (send bm save-file p 'png #:unscaled? #t)
(define bs (get-output-bytes p)) (define bs (get-output-bytes p))
;(printf "Wrote PNG: ~v bytes~n" (bytes-length bs)) ;(printf "Wrote PNG: ~v bytes~n" (bytes-length bs))
bs) bs)
(define (save-jpeg bm quality) (define (save-jpeg bm quality)
(define w (send bm get-width)) (define s (send bm get-backing-scale))
(define h (send bm get-height)) (define (scale v) (inexact->exact (ceiling (* s v))))
(define w (scale (send bm get-width)))
(define h (scale (send bm get-height)))
(define bs (make-bytes (* 4 w h))) (define bs (make-bytes (* 4 w h)))
(send bm get-argb-pixels 0 0 w h bs #t) (send bm get-argb-pixels 0 0 w h bs #t #:unscaled? #t)
(for ([i (in-range 0 (* 4 w h) 4)]) (for ([i (in-range 0 (* 4 w h) 4)])
(define a (bytes-ref bs i)) (define a (bytes-ref bs i))
(bytes-set! bs i 255) (bytes-set! bs i 255)
@ -50,19 +52,21 @@
(unless (and (exact-integer? quality) (<= 0 quality 100)) (unless (and (exact-integer? quality) (<= 0 quality 100))
(raise-type-error 'make-3d-bitmap "(integer-in 0 100)" 1 bm quality)) (raise-type-error 'make-3d-bitmap "(integer-in 0 100)" 1 bm quality))
(cond [(= quality 100) (cond [(= quality 100)
(with-syntax ([bs (datum->syntax ctxt (save-png bm))]) (with-syntax ([bs (datum->syntax ctxt (save-png bm))]
(syntax/loc ctxt (load-png bs)))] [scale (send bm get-backing-scale)])
(syntax/loc ctxt (load-png bs scale)))]
[else [else
(define-values (alpha-bs rgb-bs) (save-jpeg bm quality)) (define-values (alpha-bs rgb-bs) (save-jpeg bm quality))
(with-syntax ([alpha-bs (datum->syntax ctxt alpha-bs)] (with-syntax ([alpha-bs (datum->syntax ctxt alpha-bs)]
[rgb-bs (datum->syntax ctxt rgb-bs)]) [rgb-bs (datum->syntax ctxt rgb-bs)]
(syntax/loc ctxt (load-jpeg alpha-bs rgb-bs)))])) [scale (send bm get-backing-scale)])
(syntax/loc ctxt (load-jpeg alpha-bs rgb-bs scale)))]))
) )
(define (load-png bs) (define (load-png bs scale)
(read-bitmap (open-input-bytes bs) 'png/alpha)) (read-bitmap (open-input-bytes bs) 'png/alpha #:backing-scale scale))
(define (load-jpeg alpha-bs rgb-bs) (define (load-jpeg alpha-bs rgb-bs scale)
(define alpha-bm (read-bitmap (open-input-bytes alpha-bs) 'jpeg)) (define alpha-bm (read-bitmap (open-input-bytes alpha-bs) 'jpeg))
(define rgb-bm (read-bitmap (open-input-bytes rgb-bs) 'jpeg)) (define rgb-bm (read-bitmap (open-input-bytes rgb-bs) 'jpeg))
(define w (send rgb-bm get-width)) (define w (send rgb-bm get-width))
@ -77,8 +81,9 @@
(define a (bytes-ref bs (+ i 2))) (define a (bytes-ref bs (+ i 2)))
(bytes-set! new-bs i a)) (bytes-set! new-bs i a))
(define new-bm (make-bitmap w h)) (define (/* n d) (inexact->exact (ceiling (/ n d))))
(send new-bm set-argb-pixels 0 0 w h new-bs #f) (define new-bm (make-bitmap (/* w scale) (/* h scale) #:backing-scale scale))
(send new-bm set-argb-pixels 0 0 w h new-bs #f #:unscaled? #t)
new-bm) new-bm)
(define-syntax (compiled-bitmap stx) (define-syntax (compiled-bitmap stx)

View File

@ -119,6 +119,7 @@
([#:color color (or/c string? (is-a?/c color%))] ([#:color color (or/c string? (is-a?/c color%))]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[left-arrow-icon left-arrow-flomap] [left-arrow-icon left-arrow-flomap]
[right-arrow-icon right-arrow-flomap] [right-arrow-icon right-arrow-flomap]
[up-arrow-icon up-arrow-flomap] [up-arrow-icon up-arrow-flomap]

View File

@ -181,6 +181,7 @@
([#:color color (or/c string? (is-a?/c color%))] ([#:color color (or/c string? (is-a?/c color%))]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[play-icon play-flomap] [play-icon play-flomap]
[back-icon back-flomap] [back-icon back-flomap]
[fast-forward-icon fast-forward-flomap] [fast-forward-icon fast-forward-flomap]

View File

@ -152,6 +152,7 @@
([#:color color (or/c string? (is-a?/c color%)) "slategray"] ([#:color color (or/c string? (is-a?/c color%)) "slategray"]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[floppy-disk-icon floppy-disk-flomap]) [floppy-disk-icon floppy-disk-flomap])
(define-icon-wrappers (define-icon-wrappers
@ -159,6 +160,7 @@
[#:arrow-color arrow-color (or/c string? (is-a?/c color%)) syntax-icon-color] [#:arrow-color arrow-color (or/c string? (is-a?/c color%)) syntax-icon-color]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[save-icon save-flomap] [save-icon save-flomap]
[load-icon load-flomap] [load-icon load-flomap]
[small-save-icon small-save-flomap] [small-save-icon small-save-flomap]

View File

@ -576,6 +576,7 @@
[#:color color (or/c string? (is-a?/c color%))] [#:color color (or/c string? (is-a?/c color%))]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[regular-polygon-icon regular-polygon-flomap]) [regular-polygon-icon regular-polygon-flomap])
(define-icon-wrappers (define-icon-wrappers
@ -584,6 +585,7 @@
[#:face-color face-color (or/c string? (is-a?/c color%)) light-metal-icon-color] [#:face-color face-color (or/c string? (is-a?/c color%)) light-metal-icon-color]
[#:hand-color hand-color (or/c string? (is-a?/c color%)) "firebrick"] [#:hand-color hand-color (or/c string? (is-a?/c color%)) "firebrick"]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)]) [#:height height (and/c rational? (>=/c 0)) (default-icon-height)])
(height)
[clock-icon clock-flomap] [clock-icon clock-flomap]
[stopwatch-icon stopwatch-flomap]) [stopwatch-icon stopwatch-flomap])
@ -591,6 +593,7 @@
([#:color color (or/c string? (is-a?/c color%)) halt-icon-color] ([#:color color (or/c string? (is-a?/c color%)) halt-icon-color]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[stop-sign-icon stop-sign-flomap] [stop-sign-icon stop-sign-flomap]
[stop-signs-icon stop-signs-flomap]) [stop-signs-icon stop-signs-flomap])
@ -598,6 +601,7 @@
([#:color color (or/c string? (is-a?/c color%))] ([#:color color (or/c string? (is-a?/c color%))]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[foot-icon foot-flomap]) [foot-icon foot-flomap])
(define-icon-wrappers (define-icon-wrappers
@ -605,6 +609,7 @@
[#:handle-color handle-color (or/c string? (is-a?/c color%)) "brown"] [#:handle-color handle-color (or/c string? (is-a?/c color%)) "brown"]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[magnifying-glass-icon magnifying-glass-flomap] [magnifying-glass-icon magnifying-glass-flomap]
[left-magnifying-glass-icon left-magnifying-glass-flomap]) [left-magnifying-glass-icon left-magnifying-glass-flomap])
@ -613,6 +618,7 @@
[#:bomb-color bomb-color (or/c string? (is-a?/c color%)) dark-metal-icon-color] [#:bomb-color bomb-color (or/c string? (is-a?/c color%)) dark-metal-icon-color]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[bomb-icon bomb-flomap] [bomb-icon bomb-flomap]
[left-bomb-icon left-bomb-flomap]) [left-bomb-icon left-bomb-flomap])
@ -622,10 +628,12 @@
[#:shackle-color shackle-color (or/c string? (is-a?/c color%)) light-metal-icon-color] [#:shackle-color shackle-color (or/c string? (is-a?/c color%)) light-metal-icon-color]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[lock-icon lock-flomap]) [lock-icon lock-flomap])
(define-icon-wrappers (define-icon-wrappers
([#:color color (or/c string? (is-a?/c color%)) "black"] ([#:color color (or/c string? (is-a?/c color%)) "black"]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)]) [#:height height (and/c rational? (>=/c 0)) (default-icon-height)])
(height)
[stethoscope-icon stethoscope-flomap] [stethoscope-icon stethoscope-flomap]
[short-stethoscope-icon short-stethoscope-flomap]) [short-stethoscope-icon short-stethoscope-flomap])

View File

@ -319,6 +319,7 @@
[#:head-color head-color (or/c string? (is-a?/c color%)) run-icon-color] [#:head-color head-color (or/c string? (is-a?/c color%)) run-icon-color]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[standing-stickman-icon standing-stickman-flomap]) [standing-stickman-icon standing-stickman-flomap])
(define-icon-wrappers (define-icon-wrappers
@ -328,6 +329,7 @@
[#:head-color head-color (or/c string? (is-a?/c color%)) run-icon-color] [#:head-color head-color (or/c string? (is-a?/c color%)) run-icon-color]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[running-stickman-icon running-stickman-flomap]) [running-stickman-icon running-stickman-flomap])
#;; FOR TESTING ONLY: Do not let this find its way into the repo uncommented! #;; FOR TESTING ONLY: Do not let this find its way into the repo uncommented!

View File

@ -18,6 +18,7 @@
metal-icon-material metal-icon-material
bitmap-render-icon bitmap-render-icon
(activate-contract-out (activate-contract-out
default-icon-backing-scale
default-icon-height default-icon-height
toolbar-icon-height toolbar-icon-height
default-icon-material default-icon-material
@ -42,6 +43,7 @@
(defthing run-icon-color (or/c string? (is-a?/c color%)) #:document-value (defthing run-icon-color (or/c string? (is-a?/c color%)) #:document-value
"lawngreen") "lawngreen")
(defparam default-icon-backing-scale (and/c rational? (>/c 0)) 2)
(defparam default-icon-height (and/c rational? (>=/c 0)) 24) (defparam default-icon-height (and/c rational? (>=/c 0)) 24)
(defparam toolbar-icon-height (and/c rational? (>=/c 0)) 16) (defparam toolbar-icon-height (and/c rational? (>=/c 0)) 16)
@ -175,10 +177,13 @@
(define-syntax (define-icon-wrappers stx) (define-syntax (define-icon-wrappers stx)
(syntax-case stx () (syntax-case stx ()
[(_ (arg ...) [icon-fun flomap-fun] ...) [(_ (arg ...) (scale-arg ...) [icon-fun flomap-fun] ...)
(with-syntax ([(actual-args ...) (apply append (map arg-actual (syntax->list #'(arg ...))))]) (with-syntax ([(actual-args ...) (apply append (map arg-actual (syntax->list #'(arg ...))))]
[backing-arg #'[#:backing-scale backing-scale (and/c rational? (>/c 0.0))
(default-icon-backing-scale)]])
(syntax/loc stx (syntax/loc stx
(begin (begin
(defproc (icon-fun arg ...) (is-a?/c bitmap%) (defproc (icon-fun arg ... backing-arg) (is-a?/c bitmap%)
(flomap->bitmap (flomap-fun actual-args ...))) (let ([scale-arg (* scale-arg backing-scale)] ...)
(flomap->bitmap (flomap-fun actual-args ...) #:backing-scale backing-scale)))
...)))])) ...)))]))

View File

@ -285,34 +285,40 @@
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)] [#:material material deep-flomap-material-value? (default-icon-material)]
[#:outline outline (and/c rational? (>=/c 0)) (/ height 32)]) [#:outline outline (and/c rational? (>=/c 0)) (/ height 32)])
(height outline)
[text-icon text-flomap]) [text-icon text-flomap])
(define-icon-wrappers (define-icon-wrappers
([#:color color (or/c string? (is-a?/c color%)) "forestgreen"] ([#:color color (or/c string? (is-a?/c color%)) "forestgreen"]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[recycle-icon recycle-flomap]) [recycle-icon recycle-flomap])
(define-icon-wrappers (define-icon-wrappers
([#:color color (or/c string? (is-a?/c color%)) halt-icon-color] ([#:color color (or/c string? (is-a?/c color%)) halt-icon-color]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[x-icon x-flomap]) [x-icon x-flomap])
(define-icon-wrappers (define-icon-wrappers
([#:color color (or/c string? (is-a?/c color%)) run-icon-color] ([#:color color (or/c string? (is-a?/c color%)) run-icon-color]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[check-icon check-flomap]) [check-icon check-flomap])
(define-icon-wrappers (define-icon-wrappers
([#:color color (or/c string? (is-a?/c color%)) light-metal-icon-color] ([#:color color (or/c string? (is-a?/c color%)) light-metal-icon-color]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[lambda-icon lambda-flomap]) [lambda-icon lambda-flomap])
(define-icon-wrappers (define-icon-wrappers
([#:color color (or/c string? (is-a?/c color%)) "mediumseagreen"] ([#:color color (or/c string? (is-a?/c color%)) "mediumseagreen"]
[#:height height (and/c rational? (>=/c 0)) (default-icon-height)] [#:height height (and/c rational? (>=/c 0)) (default-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[hash-quote-icon hash-quote-flomap]) [hash-quote-icon hash-quote-flomap])

View File

@ -93,6 +93,7 @@
(define-icon-wrappers (define-icon-wrappers
([#:height height (and/c rational? (>=/c 0)) (toolbar-icon-height)] ([#:height height (and/c rational? (>=/c 0)) (toolbar-icon-height)]
[#:material material deep-flomap-material-value? (default-icon-material)]) [#:material material deep-flomap-material-value? (default-icon-material)])
(height)
[check-syntax-icon check-syntax-flomap] [check-syntax-icon check-syntax-flomap]
[small-check-syntax-icon small-check-syntax-flomap] [small-check-syntax-icon small-check-syntax-flomap]
[macro-stepper-icon macro-stepper-flomap] [macro-stepper-icon macro-stepper-flomap]

View File

@ -408,11 +408,13 @@
(define-icon-wrappers (define-icon-wrappers
([#:height height (and/c rational? (>=/c 0)) 256]) ([#:height height (and/c rational? (>=/c 0)) 256])
(height)
[plt-logo plt-flomap] [plt-logo plt-flomap]
[racket-logo racket-flomap]) [racket-logo racket-flomap])
(define-icon-wrappers (define-icon-wrappers
([#:height height (and/c rational? (>=/c 0)) 96]) ([#:height height (and/c rational? (>=/c 0)) 96])
(height)
[planet-logo planet-flomap] [planet-logo planet-flomap]
[stepper-logo stepper-flomap] [stepper-logo stepper-flomap]
[macro-stepper-logo macro-stepper-logo-flomap]) [macro-stepper-logo macro-stepper-logo-flomap])

View File

@ -39,7 +39,7 @@
(unsafe-flround (unsafe-flround
(unsafe-flmax 0.0 (unsafe-flmin 255.0 (unsafe-fl* x 255.0)))))) (unsafe-flmax 0.0 (unsafe-flmin 255.0 (unsafe-fl* x 255.0))))))
(define (flomap->bitmap fm) (define (flomap->bitmap fm #:backing-scale [backing-scale 1.0])
(match-define (flomap vs c w h) fm) (match-define (flomap vs c w h) fm)
(let* ([fm (case c (let* ([fm (case c
[(0) (make-flomap 4 w h)] [(0) (make-flomap 4 w h)]
@ -68,9 +68,10 @@
(unsafe-bytes-set! bs i2 (unsafe-fl->byte g)) (unsafe-bytes-set! bs i2 (unsafe-fl->byte g))
(unsafe-bytes-set! bs i3 (unsafe-fl->byte b))) (unsafe-bytes-set! bs i3 (unsafe-fl->byte b)))
(define bm (make-bitmap w h)) (define (scale d) (inexact->exact (ceiling (/ d backing-scale))))
(send bm set-argb-pixels 0 0 w h bs #t #t) (define bm (make-bitmap (scale w) (scale h) #:backing-scale backing-scale))
(send bm set-argb-pixels 0 0 w h bs #f #t) (send bm set-argb-pixels 0 0 w h bs #t #t #:unscaled? #t)
(send bm set-argb-pixels 0 0 w h bs #f #t #:unscaled? #t)
bm)) bm))
(define (draw-flomap draw-proc w h) (define (draw-flomap draw-proc w h)

View File

@ -20,17 +20,17 @@
[get-height (-> Integer)] [get-height (-> Integer)]
[get-argb-pixels [get-argb-pixels
(case-> (case->
(Integer Integer Integer Integer Bytes (Integer Integer Integer Integer Bytes [#:unscaled? Boolean]
-> Void) -> Void)
(Integer Integer Integer Integer Bytes Boolean (Integer Integer Integer Integer Bytes Boolean [#:unscaled? Boolean]
-> Void) -> Void)
(Integer Integer Integer Integer Bytes Boolean Boolean (Integer Integer Integer Integer Bytes Boolean Boolean [#:unscaled? Boolean]
-> Void))]))) -> Void))])))
(require/typed (require/typed
"flomap-convert.rkt" "flomap-convert.rkt"
[bitmap->flomap ((Instance Bitmap%) -> flomap)] [bitmap->flomap ((Instance Bitmap%) -> flomap)]
[flomap->bitmap (flomap -> (Instance Bitmap%))] [flomap->bitmap (flomap [#:backing-scale Positive-Real] -> (Instance Bitmap%))]
[draw-flomap ((Any -> Any) Integer Integer -> flomap)]) [draw-flomap ((Any -> Any) Integer Integer -> flomap)])
(provide (all-from-out "flomap-struct.rkt" (provide (all-from-out "flomap-struct.rkt"