From 58467ac5b94f7f66b65ab9127a07e90f304313db Mon Sep 17 00:00:00 2001 From: Neil Toronto Date: Fri, 13 Jan 2012 22:48:28 -0700 Subject: [PATCH] Contracts for almost all icon-producing functions More documentation (Now contains an animated GIF! We have achieved Web 1.0!) Fixed stop sign double-rendering bug Compiled logos size 256 (no rendering time for sizes < 256; intended size almost instantaneous) Please merge into release (cherry picked from commit 0c5ea11056bd24d808d9b901efcef5a2e9ddde39) --- collects/images/icons/arrow.rkt | 44 +- collects/images/icons/control.rkt | 157 ++++--- collects/images/icons/file.rkt | 68 ++- collects/images/icons/misc.rkt | 217 +++++++--- collects/images/icons/stickman.rkt | 63 ++- collects/images/icons/style.rkt | 22 +- collects/images/icons/tool.rkt | 8 +- collects/images/logos.rkt | 302 ++----------- collects/images/private/logos.rkt | 288 +++++++++++++ collects/images/private/utils.rkt | 4 +- collects/images/scribblings/icons.scrbl | 403 +++++++----------- .../images/scribblings/running-stickman.gif | Bin 0 -> 43705 bytes collects/images/tests/icon-tests.rkt | 2 +- 13 files changed, 861 insertions(+), 717 deletions(-) create mode 100644 collects/images/private/logos.rkt create mode 100644 collects/images/scribblings/running-stickman.gif diff --git a/collects/images/icons/arrow.rkt b/collects/images/icons/arrow.rkt index e15626e6b1..bbcdd5f3f8 100644 --- a/collects/images/icons/arrow.rkt +++ b/collects/images/icons/arrow.rkt @@ -7,17 +7,18 @@ "../private/utils.rkt" "style.rkt") -(provide - (activate-contract-out - flat-right-arrow-flomap - flat-right-over-arrow-flomap - right-arrow-flomap left-arrow-flomap up-arrow-flomap down-arrow-flomap - right-over-arrow-flomap left-over-arrow-flomap - right-under-arrow-flomap left-under-arrow-flomap - right-arrow-icon left-arrow-icon up-arrow-icon down-arrow-icon - right-over-arrow-icon left-over-arrow-icon - right-under-arrow-icon left-under-arrow-icon) - (only-doc-out (all-defined-out))) +(provide (activate-contract-out + flat-right-arrow-flomap + flat-right-over-arrow-flomap + right-arrow-icon right-arrow-flomap + left-arrow-icon left-arrow-flomap + up-arrow-icon up-arrow-flomap + down-arrow-icon down-arrow-flomap + right-over-arrow-icon right-over-arrow-flomap + left-over-arrow-icon left-over-arrow-flomap + right-under-arrow-icon right-under-arrow-flomap + left-under-arrow-icon left-under-arrow-flomap) + (only-doc-out (all-defined-out))) (defproc (flat-right-arrow-flomap [color (or/c string? (is-a?/c color%))] [height (and/c rational? (>=/c 0))] @@ -105,12 +106,15 @@ ) flomap? (flomap-flip-horizontal (right-under-arrow-flomap color height material))) -(define-simple-icon-wrapper left-arrow-icon left-arrow-flomap) -(define-simple-icon-wrapper right-arrow-icon right-arrow-flomap) -(define-simple-icon-wrapper up-arrow-icon up-arrow-flomap) -(define-simple-icon-wrapper down-arrow-icon down-arrow-flomap) - -(define-simple-icon-wrapper right-over-arrow-icon right-over-arrow-flomap) -(define-simple-icon-wrapper left-over-arrow-icon left-over-arrow-flomap) -(define-simple-icon-wrapper right-under-arrow-icon right-under-arrow-flomap) -(define-simple-icon-wrapper left-under-arrow-icon left-under-arrow-flomap) +(define-icon-wrappers + ([color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [left-arrow-icon left-arrow-flomap] + [right-arrow-icon right-arrow-flomap] + [up-arrow-icon up-arrow-flomap] + [down-arrow-icon down-arrow-flomap] + [right-over-arrow-icon right-over-arrow-flomap] + [left-over-arrow-icon left-over-arrow-flomap] + [right-under-arrow-icon right-under-arrow-flomap] + [left-under-arrow-icon left-under-arrow-flomap]) diff --git a/collects/images/icons/control.rkt b/collects/images/icons/control.rkt index e0eb70afb8..36c244378a 100644 --- a/collects/images/icons/control.rkt +++ b/collects/images/icons/control.rkt @@ -1,50 +1,57 @@ #lang racket/base -(require racket/class +(require racket/class racket/draw + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" + "../private/deep-flomap.rkt" "../private/utils.rkt" "style.rkt") -(provide (all-defined-out)) +(provide (activate-contract-out + play-icon play-flomap + back-icon back-flomap + fast-forward-icon fast-forward-flomap + rewind-icon rewind-flomap + bar-icon bar-flomap + stop-icon stop-flomap + record-icon record-flomap + pause-icon pause-flomap + step-icon step-flomap + step-back-icon step-back-flomap + continue-icon continue-flomap + continue-back-icon continue-back-flomap) + (only-doc-out (all-defined-out))) -(define play-points - (list '(0 . 0) '(4 . 0) - '(23 . 13) '(23 . 18) - '(4 . 31) '(0 . 31))) +(define (flat-play-flomap color height) + (draw-icon-flomap + 24 32 + (λ (dc) + (send dc set-brush color 'solid) + (send dc draw-polygon (list (cons 0 0) (cons 4 0) + (cons 23 13) (cons 23 18) + (cons 4 31) (cons 0 31)))) + (/ height 32))) -(define (play-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (play-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] - (draw-rendered-icon-flomap - 24 32 (λ (dc) - (send dc set-brush color 'solid) - (send dc draw-polygon play-points)) - (/ height 32) - material))) + (define fm (flat-play-flomap color height)) + (flomap-render-icon fm material))) -(define (fast-forward-flomap color [height (default-icon-height)] [material (default-icon-material)]) - (make-cached-flomap - [height color material] - (draw-rendered-icon-flomap - 32 32 (λ (dc) - (send dc set-brush color 'solid) - (send dc draw-polygon (list '(0 . 0) '(4 . 0) - '(17 . 13) '(17 . 18) - '(4 . 31) '(0 . 31))) - (send dc translate 2 0) - (send dc draw-polygon (list - ;; right side - '(14 . 2) - '(27 . 13) '(27 . 18) - '(14 . 29) - ;; left side - '(8 . 29) - '(18 . 19) '(18 . 12) - '(8 . 2)))) - (/ height 32) - material))) +(defproc (fast-forward-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (define fm (play-flomap color height material)) + (flomap-pin* 3/2 1/2 1 1/2 fm fm)) -(define (stop-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (stop-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (draw-rendered-icon-flomap @@ -54,7 +61,10 @@ (/ height 32) material))) -(define (record-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (record-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (draw-rendered-icon-flomap @@ -64,7 +74,10 @@ (/ height 32) material))) -(define (bar-flomap color height material) +(defproc (bar-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (draw-rendered-icon-flomap @@ -74,52 +87,76 @@ (/ height 32) material))) -(define back-flomap (compose flomap-flip-horizontal play-flomap)) -(define reverse-flomap (compose flomap-flip-horizontal fast-forward-flomap)) +(defproc (back-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (play-flomap color height material))) -(define (pause-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (rewind-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (fast-forward-flomap color height material))) + +(defproc (pause-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/8 height)))) 0) (bar-flomap color height material))) -(define (step-flomap color [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (step-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (play-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (bar-flomap color height material))) -(define (step-back-flomap color [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (step-back-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (back-flomap color height material))) -(define (continue-flomap color [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (continue-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (bar-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (play-flomap color height material))) -(define (continue-back-flomap color [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (continue-back-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (back-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (bar-flomap color height material))) -(define play-icon (compose flomap->bitmap play-flomap)) -(define back-icon (compose flomap->bitmap back-flomap)) -(define fast-forward-icon (compose flomap->bitmap fast-forward-flomap)) -(define reverse-icon (compose flomap->bitmap reverse-flomap)) -(define bar-icon (compose flomap->bitmap bar-flomap)) -(define stop-icon (compose flomap->bitmap stop-flomap)) -(define record-icon (compose flomap->bitmap record-flomap)) -(define pause-icon (compose flomap->bitmap pause-flomap)) -(define step-icon (compose flomap->bitmap step-flomap)) -(define step-back-icon (compose flomap->bitmap step-back-flomap)) -(define continue-icon (compose flomap->bitmap continue-flomap)) -(define continue-back-icon (compose flomap->bitmap continue-back-flomap)) +(define-icon-wrappers + ([color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [play-icon play-flomap] + [back-icon back-flomap] + [fast-forward-icon fast-forward-flomap] + [rewind-icon rewind-flomap] + [bar-icon bar-flomap] + [stop-icon stop-flomap] + [record-icon record-flomap] + [pause-icon pause-flomap] + [step-icon step-flomap] + [step-back-icon step-back-flomap] + [continue-icon continue-flomap] + [continue-back-icon continue-back-flomap]) diff --git a/collects/images/icons/file.rkt b/collects/images/icons/file.rkt index 4d7fedd6f1..f44ea734a8 100644 --- a/collects/images/icons/file.rkt +++ b/collects/images/icons/file.rkt @@ -1,15 +1,25 @@ #lang racket/base -(require racket/draw racket/class +(require racket/class racket/draw + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" "arrow.rkt" "style.rkt") -(provide (all-defined-out)) +(provide (activate-contract-out + floppy-disk-icon floppy-disk-flomap + save-icon save-flomap + load-icon load-flomap + small-save-icon small-save-flomap + small-load-icon small-load-flomap) + (only-doc-out (all-defined-out))) -(define (floppy-disk-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (floppy-disk-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color material] (define scale (/ height 32)) @@ -96,36 +106,54 @@ [fm (flomap-ct-superimpose fm label-fm)]) fm))) -(define (save-flomap arrow-color color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (save-flomap [arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (right-arrow-flomap arrow-color (* 3/4 height) material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (floppy-disk-flomap color height material))) -(define (load-flomap arrow-color color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (load-flomap [arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-hc-append (floppy-disk-flomap color height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/16 height)))) 0) (right-arrow-flomap arrow-color (* 3/4 height) material))) -(define (small-save-flomap arrow-color color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (small-save-flomap [arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-pin* 0 0 11/16 0 (floppy-disk-flomap color height material) (right-arrow-flomap arrow-color (* 3/4 height) material))) -(define (small-load-flomap arrow-color color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (small-load-flomap [arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (flomap-pin* 1 1 5/16 1 (floppy-disk-flomap color height material) (right-arrow-flomap arrow-color (* 3/4 height) material))) -(define floppy-disk-icon (compose flomap->bitmap floppy-disk-flomap)) -(define save-icon (compose flomap->bitmap save-flomap)) -(define load-icon (compose flomap->bitmap load-flomap)) -(define small-save-icon (compose flomap->bitmap small-save-flomap)) -(define small-load-icon (compose flomap->bitmap small-load-flomap)) +(define-icon-wrappers + ([color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [floppy-disk-icon floppy-disk-flomap]) + +(define-icon-wrappers + ([arrow-color (or/c string? (is-a?/c color%))] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [save-icon save-flomap] + [load-icon load-flomap] + [small-save-icon small-save-flomap] + [small-load-icon small-load-flomap]) diff --git a/collects/images/icons/misc.rkt b/collects/images/icons/misc.rkt index 493ed64fba..61b2366202 100644 --- a/collects/images/icons/misc.rkt +++ b/collects/images/icons/misc.rkt @@ -1,12 +1,26 @@ #lang racket/base (require racket/draw racket/class racket/math racket/sequence + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" "style.rkt") -(provide (all-defined-out)) +(provide (activate-contract-out + text-icon text-flomap + recycle-icon recycle-flomap + x-icon x-flomap + check-icon check-flomap + regular-polygon-icon regular-polygon-flomap + octagon-icon octagon-flomap + stop-sign-icon stop-sign-flomap + stop-signs-icon stop-signs-flomap + magnifying-glass-icon magnifying-glass-flomap + left-magnifying-glass-icon left-magnifying-glass-flomap + bomb-icon bomb-flomap + left-bomb-icon left-bomb-flomap) + (only-doc-out (all-defined-out))) ;; =================================================================================================== ;; Unrendered flomaps @@ -37,39 +51,41 @@ (/ height 32))) (define (flat-regular-polygon-flomap sides start color size) - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-brush color 'solid) - (define dθ (/ (* 2 pi) sides)) - (define θs (sequence->list (in-range start (+ start (* 2 pi)) dθ))) - (define max-frac (apply max (append (map (compose abs cos) θs) - (map (compose abs sin) θs)))) - (send dc draw-polygon (for/list ([θ (in-list θs)]) - (cons (+ 15.5 (/ (* 15.5 (cos θ)) max-frac)) - (+ 15.5 (/ (* 15.5 (sin θ)) max-frac)))))) - (/ size 32))) + (let ([start (- start)]) + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-brush color 'solid) + (define dθ (/ (* 2 pi) sides)) + (define θs (sequence->list (in-range start (+ start (* 2 pi)) dθ))) + (define max-frac (apply max (append (map (compose abs cos) θs) + (map (compose abs sin) θs)))) + (send dc draw-polygon (for/list ([θ (in-list θs)]) + (cons (+ 15.5 (/ (* 15.5 (cos θ)) max-frac)) + (+ 15.5 (/ (* 15.5 (sin θ)) max-frac)))))) + (/ size 32)))) ;; =================================================================================================== ;; Rendered flomaps -(define (text-flomap str font color trim? outline? - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (text-flomap [str string?] [font (is-a?/c font%)] + [color (or/c string? (is-a?/c color%))] + [trim? boolean? #t] + [outline (or/c 'auto (and/c rational? (>=/c 0))) 'auto] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (define size (max 32 (send font get-point-size))) (define family (send font get-family)) (define style (send font get-style)) (define weight (send font get-weight)) (define underline? (send font get-underlined)) (define smoothing (send font get-smoothing)) - (define size - (let* ([size (inexact->exact (ceiling height))]) - (min 255 (if trim? (* 2 size) size)))) (make-cached-flomap - [height str family style weight underline? smoothing color trim? outline? material] - (let ([font (make-object font% size family style weight underline? smoothing #t)]) + [height str family style weight underline? smoothing color trim? outline material] + (let ([font (make-object font% size family style weight underline? smoothing #t)] + [outline (if (equal? outline 'auto) (/ height 32) outline)]) (define-values (w h) (get-text-size str font)) - (define outline-amt (if outline? (/ height 32) 0)) - (define ceiling-amt (inexact->exact (ceiling outline-amt))) + (define ceiling-amt (inexact->exact (ceiling outline))) (define fm (let* ([fm (draw-flomap w h (λ (dc) @@ -79,14 +95,19 @@ [fm (if trim? (flomap-trim fm) fm)] [fm (flomap-resize fm #f (- height (* 2 ceiling-amt)))] [fm (flomap-inset fm ceiling-amt)] - [fm (if outline? (flomap-outlined fm outline-amt) fm)]) + [fm (if (outline . > . 0) (flomap-outlined fm outline) fm)]) fm)) (flomap-render-icon fm material)))) -(define (recycle-flomap color [height (default-icon-height)] [material (default-icon-material)]) - (text-flomap "♻" (make-object font% 64 'default) color #t #t height material)) +(defproc (recycle-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (define size (max 1 (min 1024 (inexact->exact (ceiling (* 2 height)))))) + (text-flomap "♻" (make-object font% size 'default) color #t (/ height 64) height material)) -(define (x-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (x-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? (make-cached-flomap [height color material] (define scale (/ height 32)) @@ -96,7 +117,9 @@ [dfm (deep-flomap-raise dfm (* -8 scale))]) (deep-flomap-render-icon dfm material)))) -(define (check-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (check-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? (make-cached-flomap [height color material] (define scale (/ height 32)) @@ -106,29 +129,44 @@ [dfm (deep-flomap-raise dfm (* -12 scale))]) (deep-flomap-render-icon dfm material)))) -(define (regular-polygon-flomap sides start color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (regular-polygon-flomap [sides exact-positive-integer?] + [start real?] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height sides start color material] (flomap-render-icon (flat-regular-polygon-flomap sides start color height) material))) -(define (octagon-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (octagon-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + #:document-body (regular-polygon-flomap 8 (/ (* 2 pi) 16) color height material)) -(define (stop-sign-flomap color [height (default-icon-height)] [material (default-icon-material)]) +(defproc (stop-sign-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? (make-cached-flomap [height color material] (define scale (/ height 32)) - (let* ([indent-fm (fm* 0.5 (x-flomap "black" (* 22 scale)))] + (let* ([indent-fm (fm* 0.5 (flat-x-flomap "black" (* 22 scale)))] [indent-dfm (deep-flomap-raise (flomap->deep-flomap indent-fm) (* -1 scale))] - [fm (regular-polygon-flomap 8 (/ (* 2 pi) 16) color height)] + [fm (flat-regular-polygon-flomap 8 (/ (* 2 pi) 16) color height)] [dfm (flomap->deep-flomap fm)] - [dfm (deep-flomap-cc-superimpose 'add dfm indent-dfm)] [dfm (deep-flomap-icon-style dfm)] + [dfm (deep-flomap-cc-superimpose 'add dfm indent-dfm)] [fm (deep-flomap-render-icon dfm material)]) (flomap-cc-superimpose fm (x-flomap "azure" (* 22 scale) metal-material))))) +(defproc (stop-signs-flomap [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) flomap? + (define fm (stop-sign-flomap color (* height 2/3) material)) + (flomap-pin* 3/16 1/4 0 0 + fm (flomap-pin* 3/16 1/4 0 0 fm fm))) + ;; --------------------------------------------------------------------------------------------------- ;; Magnifying glass @@ -146,9 +184,11 @@ 0.2 0.8 0.0 0.0)) -(define (magnifying-glass-flomap metal-color handle-color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (magnifying-glass-flomap [metal-color (or/c string? (is-a?/c color%))] + [handle-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height metal-color handle-color material] (define scale (/ height 32)) @@ -213,12 +253,21 @@ handle-fm (flomap-pin* 1/2 1/2 1/2 1/2 circle-fm glass-fm)))) +(defproc (left-magnifying-glass-flomap [metal-color (or/c string? (is-a?/c color%))] + [handle-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (magnifying-glass-flomap metal-color handle-color height material))) + ;; --------------------------------------------------------------------------------------------------- ;; Bomb -(define (left-bomb-flomap cap-color bomb-color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (left-bomb-flomap [cap-color (or/c string? (is-a?/c color%))] + [bomb-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height cap-color bomb-color material] (define scale (/ height 32)) @@ -229,15 +278,15 @@ (send dc set-brush "gold" 'solid) (draw-path-commands dc 0 0 - '((m 3.5 0) - (c -5 0 -3.29080284 10.4205 -3 11.5 - 1.1137011 4.1343 2 6.5 0 8.5 - -0.5711131 2.0524 1.5 4 3.5 3.5 - 2.5711131 -2.5524 3.1327042 -5.5355 2 -9.5 - -2 -7 -2 -9 -1.5 -9 - 0 1 -0.5 2 1 3.5 - 2 0.5 4 -1.5 3.5 -3.5 - -2 -2 -2 -5 -5.5 -5)))) + '((m 3.5 0) + (c -5 0 -3.29080284 10.4205 -3 11.5 + 1.1137011 4.1343 2 6.5 0 8.5 + -0.5711131 2.0524 1.5 4 3.5 3.5 + 2.5711131 -2.5524 3.1327042 -5.5355 2 -9.5 + -2 -7 -2 -9 -1.5 -9 + 0 1 -0.5 2 1 3.5 + 2 0.5 4 -1.5 3.5 -3.5 + -2 -2 -2 -5 -5.5 -5)))) scale)] [dfm (flomap->deep-flomap fm)] [dfm (deep-flomap-icon-style dfm)] @@ -281,26 +330,56 @@ (deep-flomap-render-icon sphere-dfm material))) (flomap-lt-superimpose sphere-fm cap-fm fuse-fm))) -(define (stop-signs-flomap color [height (default-icon-height)] [material (default-icon-material)]) - (define fm (stop-sign-flomap color (* height 2/3) material)) - (flomap-pin* 3/16 1/4 0 0 - fm (flomap-pin* 3/16 1/4 0 0 fm fm))) - -(define left-magnifying-glass-flomap (compose flomap-flip-horizontal magnifying-glass-flomap)) -(define bomb-flomap (compose flomap-flip-horizontal left-bomb-flomap)) +(defproc (bomb-flomap [cap-color (or/c string? (is-a?/c color%))] + [bomb-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? + (flomap-flip-horizontal (left-bomb-flomap cap-color bomb-color height material))) ;; =================================================================================================== ;; Bitmaps (icons) -(define text-icon (compose flomap->bitmap text-flomap)) -(define recycle-icon (compose flomap->bitmap recycle-flomap)) -(define regular-polygon-icon (compose flomap->bitmap regular-polygon-flomap)) -(define octagon-icon (compose flomap->bitmap octagon-flomap)) -(define x-icon (compose flomap->bitmap x-flomap)) -(define stop-sign-icon (compose flomap->bitmap stop-sign-flomap)) -(define stop-signs-icon (compose flomap->bitmap stop-signs-flomap)) -(define check-icon (compose flomap->bitmap check-flomap)) -(define magnifying-glass-icon (compose flomap->bitmap magnifying-glass-flomap)) -(define left-magnifying-glass-icon (compose flomap->bitmap left-magnifying-glass-flomap)) -(define bomb-icon (compose flomap->bitmap bomb-flomap)) -(define left-bomb-icon (compose flomap->bitmap left-bomb-flomap)) +(defproc (text-icon [str string?] [font (is-a?/c font%)] + [color (or/c string? (is-a?/c color%))] + [trim? boolean? #t] + [outline (or/c 'auto (and/c rational? (>=/c 0))) 'auto] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (text-flomap str font color trim? outline height material))) + +(defproc (regular-polygon-icon [sides exact-positive-integer?] + [start real?] + [color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (regular-polygon-flomap sides start color height material))) + +(define-icon-wrappers + ([color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [recycle-icon recycle-flomap] + [x-icon x-flomap] + [check-icon check-flomap] + [octagon-icon octagon-flomap] + [stop-sign-icon stop-sign-flomap] + [stop-signs-icon stop-signs-flomap]) + +(define-icon-wrappers + ([metal-color (or/c string? (is-a?/c color%))] + [handle-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [magnifying-glass-icon magnifying-glass-flomap] + [left-magnifying-glass-icon left-magnifying-glass-flomap]) + +(define-icon-wrappers + ([cap-color (or/c string? (is-a?/c color%))] + [bomb-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)]) + [bomb-icon bomb-flomap] + [left-bomb-icon left-bomb-flomap]) diff --git a/collects/images/icons/stickman.rkt b/collects/images/icons/stickman.rkt index cd6cf8124f..69f2e48a3c 100644 --- a/collects/images/icons/stickman.rkt +++ b/collects/images/icons/stickman.rkt @@ -1,13 +1,19 @@ #lang racket/base -(require racket/class racket/vector racket/match racket/math +(require racket/class racket/draw racket/vector racket/match racket/math + racket/contract unstable/latent-contract unstable/latent-contract/defthing "../private/flomap.rkt" "../private/deep-flomap.rkt" "../private/utils.rkt" "style.rkt") -(provide standing-stickman-flomap standing-stickman-icon - running-stickman-flomap running-stickman-icon) +(provide (activate-contract-out + standing-stickman-icon standing-stickman-flomap + running-stickman-icon running-stickman-flomap) + (only-doc-out (all-defined-out))) + +;; =================================================================================================== +;; Common (define (cons+ p1 p2) (match-define (cons x1 y1) p1) @@ -31,6 +37,9 @@ (define shin-length 6.5) (define shoulder-breadth 7) +;; =================================================================================================== +;; Standing + (define standing-torso-angle -90) (define standing-neck-angle 5) (define standing-left-knee-angle 200) @@ -100,9 +109,12 @@ (polar->cartesian (+ standing-right-elbow-angle standing-torso-angle standing-right-hand-angle) lower-arm-length))) -(define (standing-stickman-flomap color arm-color head-color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (standing-stickman-flomap [color (or/c string? (is-a?/c color%))] + [arm-color (or/c string? (is-a?/c color%))] + [head-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height color arm-color head-color material] (flomap-lt-superimpose @@ -161,6 +173,9 @@ (/ height 32) material)))) +;; =================================================================================================== +;; Running + (define running-neck-angle 20) (define running-torso-angle -70) @@ -245,7 +260,7 @@ (define (running-head-flomap t color height material) (make-cached-flomap [height t color material] - (draw-short-rendered-icon-flomap + (draw-rendered-icon-flomap 26 32 (λ (dc) (send dc set-pen "black" line-width 'solid) (send dc set-brush color 'solid) @@ -257,7 +272,7 @@ (define (running-leg-flomap t body? color height material) (make-cached-flomap [height t body? color material] - (draw-short-rendered-icon-flomap + (draw-rendered-icon-flomap 26 32 (λ (dc) (draw-running-leg dc t "black" (+ leg-width (* 2 line-width))) (when body? @@ -270,16 +285,20 @@ (define (running-arm-flomap t color height material) (make-cached-flomap [height t color material] - (draw-short-rendered-icon-flomap + (draw-rendered-icon-flomap 26 32 (λ (dc) (draw-running-arm dc t "black" (+ arm-width (* 2 line-width))) (draw-running-arm dc t color arm-width)) (/ height 32) material))) -(define (running-stickman-flomap t color arm-color head-color - [height (default-icon-height)] - [material (default-icon-material)]) +(defproc (running-stickman-flomap [t rational?] + [color (or/c string? (is-a?/c color%))] + [arm-color (or/c string? (is-a?/c color%))] + [head-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) flomap? (make-cached-flomap [height t color arm-color head-color material] (flomap-lt-superimpose (running-arm-flomap (+ t 0.5) arm-color height material) @@ -288,14 +307,28 @@ (running-head-flomap t head-color height material) (running-arm-flomap t arm-color height material)))) -(define standing-stickman-icon (compose flomap->bitmap standing-stickman-flomap)) -(define running-stickman-icon (compose flomap->bitmap running-stickman-flomap)) +(defproc (standing-stickman-icon [color (or/c string? (is-a?/c color%))] + [arm-color (or/c string? (is-a?/c color%))] + [head-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (standing-stickman-flomap color arm-color head-color height material))) + +(defproc (running-stickman-icon [t rational?] + [color (or/c string? (is-a?/c color%))] + [arm-color (or/c string? (is-a?/c color%))] + [head-color (or/c string? (is-a?/c color%))] + [height (and/c rational? (>=/c 0)) (default-icon-height)] + [material deep-flomap-material-value? (default-icon-material)] + ) (is-a?/c bitmap%) + (flomap->bitmap (running-stickman-flomap t color arm-color head-color height material))) #;; FOR TESTING ONLY: Do not let this find its way into the repo uncommented! (begin (require racket/gui (planet "animated-canvas.rkt" ("williams" "animated-canvas.plt" 2 4))) - (define size 20) + (define size 64) (standing-stickman-icon halt-icon-color "white" halt-icon-color size) diff --git a/collects/images/icons/style.rkt b/collects/images/icons/style.rkt index f40a5454cd..d8e99d8378 100644 --- a/collects/images/icons/style.rkt +++ b/collects/images/icons/style.rkt @@ -2,6 +2,7 @@ (require racket/draw unstable/parameter-group racket/contract unstable/latent-contract/defthing + (for-syntax unstable/latent-contract/serialize-syntax) "../private/flomap.rkt" "../private/deep-flomap.rkt") @@ -24,8 +25,8 @@ (define glass-icon-material (deep-flomap-material-value 'cubic-zirconia 1.0 0.75 0.15 - 0.5 0.2 1.0 - 0.0 0.4 0.25 + 1.0 0.2 1.0 + 0.2 0.4 0.25 0.08)) (define metal-icon-color "lightsteelblue") @@ -51,7 +52,7 @@ (define s (/ (deep-flomap-height dfm) 32)) (let* ([dfm (deep-flomap-emboss dfm (* s 2) (* s 2))] [dfm (deep-flomap-bulge-round dfm (* s 6))] - [dfm (deep-flomap-raise dfm (* s 18))]) + [dfm (deep-flomap-raise dfm (* s 20))]) dfm)) (define (draw-icon-flomap w h draw-proc scale) @@ -93,9 +94,12 @@ ;; =================================================================================================== ;; Syntax for writing icon functions -(define-syntax-rule (define-simple-icon-wrapper icon-fun flomap-fun) - (defproc (icon-fun [color (or/c string? (is-a?/c color%))] - [height (and/c rational? (>=/c 0)) (default-icon-height)] - [material deep-flomap-material-value? (default-icon-material)] - ) (is-a?/c bitmap%) - (flomap->bitmap (flomap-fun color height material)))) +(define-syntax (define-icon-wrappers stx) + (syntax-case stx () + [(_ ([arg-name arg-props ...] ...) + [icon-fun flomap-fun] ...) + (syntax/loc stx + (begin + (defproc (icon-fun [arg-name arg-props ...] ...) (is-a?/c bitmap%) + (flomap->bitmap (flomap-fun arg-name ...))) + ...))])) diff --git a/collects/images/icons/tool.rkt b/collects/images/icons/tool.rkt index 06ccc52b6b..8903f407d8 100644 --- a/collects/images/icons/tool.rkt +++ b/collects/images/icons/tool.rkt @@ -27,8 +27,8 @@ (define (macro-stepper-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) (flomap-ht-append - (text-flomap "#'" (make-object font% 12 'system 'normal 'normal) - macro-stepper-hash-color #t #t height material) + (text-flomap "#'" (make-object font% (max 1 (min 1024 height)) 'system) + macro-stepper-hash-color #t 'auto height material) (make-flomap 4 (max 1 (inexact->exact (round (* 1/32 height)))) 0) (step-flomap syntax-icon-color height material))) @@ -36,8 +36,8 @@ (flomap-pin* 0 0 7/16 0 (step-flomap syntax-icon-color height material) - (text-flomap "#'" (make-object font% 12 'system 'normal 'bold) - macro-stepper-hash-color #t #t (* 3/4 height) material))) + (text-flomap "#'" (make-object font% (max 1 (min 1024 height)) 'system) + macro-stepper-hash-color #t 'auto (* 3/4 height) material))) (define (debugger-flomap [height (toolbar-icon-height)] [material (default-icon-material)]) (flomap-ht-append diff --git a/collects/images/logos.rkt b/collects/images/logos.rkt index c397aa2012..8edff88ae0 100644 --- a/collects/images/logos.rkt +++ b/collects/images/logos.rkt @@ -1,287 +1,33 @@ #lang racket/base -(require racket/draw racket/class racket/match racket/math racket/flonum +(require racket/promise + (prefix-in private- "private/logos.rkt") "private/flomap.rkt" - "private/deep-flomap.rkt" - "icons/style.rkt" - "private/utils.rkt") + "compile-time.rkt" + (for-syntax racket/base + (prefix-in private- "private/logos.rkt") + "private/flomap.rkt")) -(provide plt-logo planet-logo) +(provide plt-logo planet-logo + (rename-out [private-plt-flomap plt-flomap] + [private-planet-flomap planet-flomap])) -(define glass-logo-material - (deep-flomap-material-value - 'cubic-zirconia 0.7 0.6 0.4 - 0.2 0.1 1.0 - 0.2 0.1 0.1 - 0.0)) +;; Use a delay to keep from using more memory than necessary (saves 256KB) +(define standard-plt-logo (delay (compiled-bitmap (private-plt-logo 256)))) -(define lambda-path-commands - '((m 97.5 10) - (c -12.267574371681416 0.22160039646017698 - -23.938206584070794 4.486409061946903 - -35.40358116814159 8.431642279646018 - 5.002013451327434 5.357118980530973 - 4.2474160707964606 7.049306166371681 - 6.430565946902655 6.642370378761062 - 8.354521486725664 -2.0234602477876105 - 20.745877522123894 -6.732496424778761 - 26.26655603539823 2.1904900530973452 - 12.036272707964603 15.204891185840708 - 17.140790371681415 34.66372757522124 - 18.964158300884954 53.635833203539825 - 2.3373978053097346 11.526810053097345 - -21.433330407079644 52.79757139823009 - -28.736806513274335 69.27072283185841 - -11.871354336283186 20.946142017699113 - -22.417494088495573 42.68413054867256 - -35.79320863716814 62.74737614159292 - 3.198686017699115 4.233302088495575 - 7.820428460176991 2.5766558584070793 - 12.171064637168142 1.925754336283186 - 3.714682336283186 -0.5565213451327433 - 7.429373734513274 -1.1130336283185842 - 11.14405607079646 -1.6695504424778762 - 11.979952707964602 -28.4038887079646 - 24.914903221238937 -54.476528141592915 - 36.156529274336286 -83.1860083539823 - 5.122632495575221 -11.831699256637167 - 7.625016637168141 -18.33969500884956 - 13.711282973451327 -26.087614300884955 - 7.215226336283186 4.414282761061947 - 9.363369911504424 15.302112283185838 - 13.299630442477875 22.814352991150443 - 11.600370407079646 29.849948884955747 - 23.150614654867255 59.71926315044247 - 34.09924077876106 89.81329104424779 - 2.8656957168141592 0.9979197168141594 - 5.806954477876106 3.9796174159292033 - 8.525185132743362 1.105811256637168 - 7.150265769911504 -4.4088093451327435 - 15.474823929203538 -7.170211115044248 - 21.428106194690265 -13.26414385840708 - -1.6986936637168142 -8.23685210619469 - -7.156455079646018 -15.941115469026549 - -10.48132417699115 -23.86248042477876 - -21.07570067256637 -42.11971171681416 - -41.39651398230088 -86.79632424778761 - -54.5885927079646 -132.15014060176992 - -4.858603610619468 -14.274800141592921 - -10.841368920353982 -31.4765361840708 - -26.303927504424777 -37.111590060176994 - -3.5224240707964602 -1.0457545628318583 - -7.2342065840707965 -1.2467313274336282 - -10.888935079646018 -1.2461164743362831))) +(define (plt-logo height) + (cond [(height . = . 256) (force standard-plt-logo)] + [(height . <= . 256) + (flomap->bitmap (flomap-resize (bitmap->flomap (force standard-plt-logo)) #f height))] + [else + (private-plt-logo height)])) -(define (draw-lambda dc x y w h) - (define-values (sx sy) (send dc get-scale)) - (draw-path-commands dc x y (scale-path-commands lambda-path-commands (/ w 240) (/ h 240))) - (send dc set-scale sx sy)) -(define blue-θ-start (* -45 (/ pi 180))) -(define blue-θ-end (* 110 (/ pi 180))) +(define standard-planet-logo (delay (compiled-bitmap (private-planet-logo 256)))) -(define logo-red-color (make-object color% 255 36 32)) -(define logo-blue-color (make-object color% 32 36 255)) -(define lambda-outline-color (make-object color% 16 16 64)) -(define (lambda-pen color width) (make-object pen% color width 'solid 'projecting 'miter)) - -(define (make-arc-path x y w h start end [ccw? #t]) - (define p (new dc-path%)) - (send p arc x y w h start end ccw?) - (send p close) - p) - -(define (make-random-flomap c w h) - (build-flomap c w h (λ (k x y i) (random)))) - -(define (flomap-rough fm z-amt) - (match-define (flomap _ c w h) fm) - (fm+ fm (fm* z-amt (make-random-flomap c w h)))) - -(define (plt-flomap height) - (make-cached-flomap - [height] - (define scale (/ height 256)) - (define bulge-fm - (draw-icon-flomap - 256 256 (λ (dc) - (send dc set-pen logo-red-color 2 'transparent) - (send dc set-brush logo-red-color 'solid) - (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-end blue-θ-start)) - (send dc set-pen logo-blue-color 2 'transparent) - (send dc set-brush logo-blue-color 'solid) - (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-start blue-θ-end)) - (send dc set-pen (lambda-pen lambda-outline-color 10)) - (send dc set-brush lambda-outline-color 'solid) - (draw-lambda dc 8 8 240 240)) - scale)) - - (define (lambda-flomap color pen-width) - (draw-icon-flomap - 256 256 (λ (dc) - (send dc set-scale scale scale) - (send dc set-pen (lambda-pen color pen-width)) - (send dc set-brush color 'solid) - (draw-lambda dc 8 8 240 240)) - scale)) - - (let* ([bulge-dfm (flomap->deep-flomap bulge-fm)] - [bulge-dfm (deep-flomap-bulge-spheroid bulge-dfm (* 112 scale))] - [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] - [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 112 scale))] - [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] - [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] - [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] - [fm (flomap-cc-superimpose - fm - (lambda-flomap lambda-outline-color 10) - lambda-fm)] - [fm (flomap-cc-superimpose - (draw-icon-flomap - 256 256 (λ (dc) - (send dc set-pen "lightblue" 2 'solid) - (send dc set-brush "white" 'transparent) - (send dc draw-ellipse 7 7 242 242) - (send dc set-pen lambda-outline-color 4 'solid) - (send dc draw-ellipse 2 2 252 252)) - scale) - fm)]) - fm))) - -(define continents-path-commands - '((m 11.526653 18.937779) - (c 0.05278 0.724075 1.940414 1.202607 0.678885 2.296248 - 0.249172 0.918181 1.040063 1.620575 1.448285 0.308034 - 1.219485 -0.885607 3.250882 -0.938443 3.317014 -2.906655 - -1.599965 -1.033954 -4.029479 -0.431148 -5.444184 0.302373) - (M 11.53125 18.125) - (C 10.786965 18.380649 9.3917452 18.611001 9.1304904 19.245707 - 10.289001 19.269837 11.178405 18.606302 11.53125 18.125) - (M 8.1875 19.65625) - (C 7.2652998 23.370888 8.6787734 19.63772 9.9124431 20.95891 - 10.727811 21.80382 11.739516 20.92275 10.465247 20.422456 - 9.7714766 19.980166 8.3964342 19.699414 8.1875 19.65625) - (M 7.5625 21.125) - (c -0.9196331 -1.962382 -3.205955 1.390782 -4.0978229 2.41995 - -1.707808 2.289408 -2.72190385 5.078558 -2.9334271 7.9238 - 1.0237952 1.983695 5.5272247 2.76676 4.7145431 4.084262 - -0.7368064 1.151552 -0.8906555 2.601652 0.1135446 3.680893 - 2.7495495 2.364498 1.2541019 5.824595 2.5609489 6.229519 - 2.5755284 0.853846 2.7512924 -3.696022 4.1297234 -3.843434 - 0.745066 -1.051147 0.04765 -2.428466 1.056101 -3.411232) - (C 12.318556 36.222109 8.8169859 35.479018 8.6188979 33.8253 - 7.7181807 34.141675 7.0679715 33.334232 6.30372 33.30415 - 5.7220663 34.646967 3.9378253 34.122031 4.3012403 32.699798 - 3.024533 33.043038 4.3605584 31.222879 3.40625 31.28125 - 0.5 33 2.5 26.5 5.0295875 29.903027 - 5.5 30.5 6.9002733 26.371666 8.8261905 25.876953 - 9.8027554 25.533149 9.5159021 24.727855 8.5279357 25.0625 - 7.6214946 24.941384 9.6975411 24.462771 10.075856 24.483273 - 11.540792 24.233047 9.904685 23.334106 9.8601011 22.602389 - 9.0900535 22.676405 9.4028275 22.737933 9.1185443 22.100147 - 6.8948741 22.58513 7.6831847 24.739145 5.9002404 23.244912 - 4.6247757 22.264239 7.321322 21.942832 7.5625 21.125) - (m 15.15625 -0.9375) - (c -1.37421 0.06218 -2.005432 1.159129 -2.784107 1.978327 - -0.114565 1.368674 0.952693 -0.07002 1.385771 0.968032 - 0.953881 -0.129572 -0.01507 -1.993413 1.425543 -2.008859 - -0.269351 0.525838 -0.494795 1.470731 0.411144 1.15174 - -0.646943 0.90275 -1.874871 2.045333 -2.613442 0.960703 - 0.08813 0.809648 -1.042388 0.509104 -1.186702 1.40851 - -0.738698 0.338761 -1.028513 0.375271 -0.383294 1.119927 - -1.340908 -0.226887 -1.979854 2.002883 -0.346874 1.903539 - 3.128783 -3.578714 2.7333 -0.07275 3.379252 -0.61531 - -0.408321 -3.069544 0.823059 1.69915 1.30948 -0.328623 - 0.476726 0.916648 1.583858 0.757279 2.129612 1.386838 - -2.140558 2.214946 -4.171988 -1.055384 -6.363065 -0.232922 - -2.486751 0.823935 -2.418258 3.347586 -3.103635 4.864439 - 0.687061 3.597921 3.669743 1.43585 5.132502 2.724104 - -0.344691 1.08929 0.484513 1.884668 0.473244 3.022942 - -0.01352 2.068761 0.378264 6.65826 1.845318 5.542497 - 1.472489 0.175399 1.430793 -1.740909 2.30904 -2.30502 - -1.36358 -1.181833 2.025569 -1.358588 0.887958 -2.838158 - -0.499809 -1.988948 1.367195 -3.177085 1.789594 -4.928946 - 0.579613 -0.960476 -1.588234 -0.05789 -0.373062 -1.023304 - 0.927113 -0.301781 2.379761 -2.07879 0.994298 -2.428506 - -0.676988 0.933612 -1.737597 -2.080985 -0.549773 -0.651497 - 0.699549 -0.419557 1.900516 1.563553 1.759683 -0.08984 - -0.608903 -3.386912 -2.4601 -6.520148 -5.090986 -8.736865 - -0.200722 0.802307 -1.230158 0.889683 -1.228926 0.0694 - 2.155263 -0.50116 -0.789058 -0.572123 -1.208573 -0.913148) - (M 17.09375 21) - (c -1.221276 0.05745 -0.44882 1.331427 0.232503 0.449916) - (C 17.458514 21.23484 17.234278 21.104353 17.09375 21) - (m -7.5 0.125) - (c -1.2040413 0.60218 1.459244 1.052142 0.289004 0.112253) - (m 8.96875 1.5) - (c 0.38412 0.655402 -0.236077 2.74213 1.030518 1.55154 - 0.0634 -0.524592 -0.59842 -1.401743 -1.030518 -1.55154) - (m -0.21875 0.75) - (c -1.155615 0.198578 0.509999 1.388302 0.06733 0.201634) - (M 10.5 24.53125) - (c -0.117519 1.313533 1.058399 0.642504 0 0))) - -(define water-logo-material - (deep-flomap-material-value - 'cubic-zirconia 1.0 0.7 1.0 - 0.25 0.15 1.0 - 0.15 0.1 0.2 - 0.0)) - -(define logo-under-continents-color "black") -(define logo-continents-color "azure") -(define logo-water-color "lightskyblue") -(define logo-earth-outline-color logo-red-color) - -(define (continents-flomap color height) - (define scale (/ height 32)) - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen lambda-outline-color 3/8 'solid) - (send dc set-brush color 'solid) - (draw-path-commands dc 0 -17 continents-path-commands)) - scale)) - -(define (planet-flomap height) - (make-cached-flomap - [height] - (define scale (/ height 32)) - (define-values (earth-fm earth-z) - (let* ([indent-fm (continents-flomap logo-red-color height)] - [indent-dfm (flomap->deep-flomap indent-fm)] - [indent-dfm (deep-flomap-raise indent-dfm (* -1/8 scale))] - [indent-dfm (deep-flomap-smooth-z indent-dfm (* 1 scale))] - [earth-fm (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen logo-water-color 1/2 'solid) - (send dc set-brush logo-water-color 'solid) - (draw-ellipse/smoothed dc 0.75 0.75 30.5 30.5)) - scale)] - [earth-dfm (flomap->deep-flomap earth-fm)] - [earth-dfm (deep-flomap-bulge-spheroid earth-dfm (* 16 scale))] - [earth-dfm (deep-flomap-cc-superimpose 'add earth-dfm indent-dfm)]) - (values (deep-flomap-render-icon earth-dfm water-logo-material) - (deep-flomap-z earth-dfm)))) - - (define land-fm - (let* ([land-fm (continents-flomap logo-continents-color height)] - [land-dfm (flomap->deep-flomap land-fm)] - ;[land-dfm (deep-flomap-emboss land-dfm (* 2 scale) (* 8 scale))] - [land-dfm (deep-flomap-bulge-spheroid land-dfm (* 16 scale))] - [land-dfm (deep-flomap-smooth-z land-dfm (* 1/2 scale))]) - (deep-flomap-render-icon land-dfm metal-material))) - - (flomap-cc-superimpose - (draw-icon-flomap - 32 32 (λ (dc) - (send dc set-pen "lightblue" 1/2 'solid) - (send dc set-brush "white" 'transparent) - (send dc draw-ellipse 0.5 0.5 31 31) - (send dc set-pen lambda-outline-color 1/2 'solid) - (send dc draw-ellipse -0.25 -0.25 32.5 32.5)) - scale) - earth-fm - land-fm))) - -(define plt-logo (compose flomap->bitmap plt-flomap)) -(define planet-logo (compose flomap->bitmap planet-flomap)) +(define (planet-logo height) + (cond [(height . = . 256) (force standard-planet-logo)] + [(height . <= . 256) + (flomap->bitmap (flomap-resize (bitmap->flomap (force standard-planet-logo)) #f height))] + [else + (private-planet-logo height)])) diff --git a/collects/images/private/logos.rkt b/collects/images/private/logos.rkt new file mode 100644 index 0000000000..dc873b1c72 --- /dev/null +++ b/collects/images/private/logos.rkt @@ -0,0 +1,288 @@ +#lang racket/base + +(require racket/draw racket/class racket/match racket/math racket/flonum + "flomap.rkt" + "deep-flomap.rkt" + "utils.rkt" + "../icons/style.rkt") + +(provide plt-logo planet-logo + plt-flomap planet-flomap) + +(define glass-logo-material + (deep-flomap-material-value + 'cubic-zirconia 0.7 0.6 0.4 + 0.2 0.1 1.0 + 0.2 0.1 0.1 + 0.0)) + +(define lambda-path-commands + '((m 97.5 10) + (c -12.267574371681416 0.22160039646017698 + -23.938206584070794 4.486409061946903 + -35.40358116814159 8.431642279646018 + 5.002013451327434 5.357118980530973 + 4.2474160707964606 7.049306166371681 + 6.430565946902655 6.642370378761062 + 8.354521486725664 -2.0234602477876105 + 20.745877522123894 -6.732496424778761 + 26.26655603539823 2.1904900530973452 + 12.036272707964603 15.204891185840708 + 17.140790371681415 34.66372757522124 + 18.964158300884954 53.635833203539825 + 2.3373978053097346 11.526810053097345 + -21.433330407079644 52.79757139823009 + -28.736806513274335 69.27072283185841 + -11.871354336283186 20.946142017699113 + -22.417494088495573 42.68413054867256 + -35.79320863716814 62.74737614159292 + 3.198686017699115 4.233302088495575 + 7.820428460176991 2.5766558584070793 + 12.171064637168142 1.925754336283186 + 3.714682336283186 -0.5565213451327433 + 7.429373734513274 -1.1130336283185842 + 11.14405607079646 -1.6695504424778762 + 11.979952707964602 -28.4038887079646 + 24.914903221238937 -54.476528141592915 + 36.156529274336286 -83.1860083539823 + 5.122632495575221 -11.831699256637167 + 7.625016637168141 -18.33969500884956 + 13.711282973451327 -26.087614300884955 + 7.215226336283186 4.414282761061947 + 9.363369911504424 15.302112283185838 + 13.299630442477875 22.814352991150443 + 11.600370407079646 29.849948884955747 + 23.150614654867255 59.71926315044247 + 34.09924077876106 89.81329104424779 + 2.8656957168141592 0.9979197168141594 + 5.806954477876106 3.9796174159292033 + 8.525185132743362 1.105811256637168 + 7.150265769911504 -4.4088093451327435 + 15.474823929203538 -7.170211115044248 + 21.428106194690265 -13.26414385840708 + -1.6986936637168142 -8.23685210619469 + -7.156455079646018 -15.941115469026549 + -10.48132417699115 -23.86248042477876 + -21.07570067256637 -42.11971171681416 + -41.39651398230088 -86.79632424778761 + -54.5885927079646 -132.15014060176992 + -4.858603610619468 -14.274800141592921 + -10.841368920353982 -31.4765361840708 + -26.303927504424777 -37.111590060176994 + -3.5224240707964602 -1.0457545628318583 + -7.2342065840707965 -1.2467313274336282 + -10.888935079646018 -1.2461164743362831))) + +(define (draw-lambda dc x y w h) + (define-values (sx sy) (send dc get-scale)) + (draw-path-commands dc x y (scale-path-commands lambda-path-commands (/ w 240) (/ h 240))) + (send dc set-scale sx sy)) + +(define blue-θ-start (* -45 (/ pi 180))) +(define blue-θ-end (* 110 (/ pi 180))) + +(define logo-red-color (make-object color% 255 36 32)) +(define logo-blue-color (make-object color% 32 36 255)) +(define lambda-outline-color (make-object color% 16 16 64)) +(define (lambda-pen color width) (make-object pen% color width 'solid 'projecting 'miter)) + +(define (make-arc-path x y w h start end [ccw? #t]) + (define p (new dc-path%)) + (send p arc x y w h start end ccw?) + (send p close) + p) + +(define (make-random-flomap c w h) + (build-flomap c w h (λ (k x y i) (random)))) + +(define (flomap-rough fm z-amt) + (match-define (flomap _ c w h) fm) + (fm+ fm (fm* z-amt (make-random-flomap c w h)))) + +(define (plt-flomap height) + (make-cached-flomap + [height] + (define scale (/ height 256)) + (define bulge-fm + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-pen logo-red-color 2 'transparent) + (send dc set-brush logo-red-color 'solid) + (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-end blue-θ-start)) + (send dc set-pen logo-blue-color 2 'transparent) + (send dc set-brush logo-blue-color 'solid) + (send dc draw-path (make-arc-path 8 8 239 239 blue-θ-start blue-θ-end)) + (send dc set-pen (lambda-pen lambda-outline-color 10)) + (send dc set-brush lambda-outline-color 'solid) + (draw-lambda dc 8 8 240 240)) + scale)) + + (define (lambda-flomap color pen-width) + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-scale scale scale) + (send dc set-pen (lambda-pen color pen-width)) + (send dc set-brush color 'solid) + (draw-lambda dc 8 8 240 240)) + scale)) + + (let* ([bulge-dfm (flomap->deep-flomap bulge-fm)] + [bulge-dfm (deep-flomap-bulge-spheroid bulge-dfm (* 112 scale))] + [lambda-dfm (flomap->deep-flomap (lambda-flomap "azure" 4))] + [lambda-dfm (deep-flomap-bulge-spheroid lambda-dfm (* 112 scale))] + [lambda-dfm (deep-flomap-smooth-z lambda-dfm (* 3 scale))] + [lambda-fm (deep-flomap-render-icon lambda-dfm metal-material)] + [fm (deep-flomap-render-icon bulge-dfm glass-logo-material)] + [fm (flomap-cc-superimpose + fm + (lambda-flomap lambda-outline-color 10) + lambda-fm)] + [fm (flomap-cc-superimpose + (draw-icon-flomap + 256 256 (λ (dc) + (send dc set-pen "lightblue" 2 'solid) + (send dc set-brush "white" 'transparent) + (send dc draw-ellipse 7 7 242 242) + (send dc set-pen lambda-outline-color 4 'solid) + (send dc draw-ellipse 2 2 252 252)) + scale) + fm)]) + fm))) + +(define continents-path-commands + '((m 11.526653 18.937779) + (c 0.05278 0.724075 1.940414 1.202607 0.678885 2.296248 + 0.249172 0.918181 1.040063 1.620575 1.448285 0.308034 + 1.219485 -0.885607 3.250882 -0.938443 3.317014 -2.906655 + -1.599965 -1.033954 -4.029479 -0.431148 -5.444184 0.302373) + (M 11.53125 18.125) + (C 10.786965 18.380649 9.3917452 18.611001 9.1304904 19.245707 + 10.289001 19.269837 11.178405 18.606302 11.53125 18.125) + (M 8.1875 19.65625) + (C 7.2652998 23.370888 8.6787734 19.63772 9.9124431 20.95891 + 10.727811 21.80382 11.739516 20.92275 10.465247 20.422456 + 9.7714766 19.980166 8.3964342 19.699414 8.1875 19.65625) + (M 7.5625 21.125) + (c -0.9196331 -1.962382 -3.205955 1.390782 -4.0978229 2.41995 + -1.707808 2.289408 -2.72190385 5.078558 -2.9334271 7.9238 + 1.0237952 1.983695 5.5272247 2.76676 4.7145431 4.084262 + -0.7368064 1.151552 -0.8906555 2.601652 0.1135446 3.680893 + 2.7495495 2.364498 1.2541019 5.824595 2.5609489 6.229519 + 2.5755284 0.853846 2.7512924 -3.696022 4.1297234 -3.843434 + 0.745066 -1.051147 0.04765 -2.428466 1.056101 -3.411232) + (C 12.318556 36.222109 8.8169859 35.479018 8.6188979 33.8253 + 7.7181807 34.141675 7.0679715 33.334232 6.30372 33.30415 + 5.7220663 34.646967 3.9378253 34.122031 4.3012403 32.699798 + 3.024533 33.043038 4.3605584 31.222879 3.40625 31.28125 + 0.5 33 2.5 26.5 5.0295875 29.903027 + 5.5 30.5 6.9002733 26.371666 8.8261905 25.876953 + 9.8027554 25.533149 9.5159021 24.727855 8.5279357 25.0625 + 7.6214946 24.941384 9.6975411 24.462771 10.075856 24.483273 + 11.540792 24.233047 9.904685 23.334106 9.8601011 22.602389 + 9.0900535 22.676405 9.4028275 22.737933 9.1185443 22.100147 + 6.8948741 22.58513 7.6831847 24.739145 5.9002404 23.244912 + 4.6247757 22.264239 7.321322 21.942832 7.5625 21.125) + (m 15.15625 -0.9375) + (c -1.37421 0.06218 -2.005432 1.159129 -2.784107 1.978327 + -0.114565 1.368674 0.952693 -0.07002 1.385771 0.968032 + 0.953881 -0.129572 -0.01507 -1.993413 1.425543 -2.008859 + -0.269351 0.525838 -0.494795 1.470731 0.411144 1.15174 + -0.646943 0.90275 -1.874871 2.045333 -2.613442 0.960703 + 0.08813 0.809648 -1.042388 0.509104 -1.186702 1.40851 + -0.738698 0.338761 -1.028513 0.375271 -0.383294 1.119927 + -1.340908 -0.226887 -1.979854 2.002883 -0.346874 1.903539 + 3.128783 -3.578714 2.7333 -0.07275 3.379252 -0.61531 + -0.408321 -3.069544 0.823059 1.69915 1.30948 -0.328623 + 0.476726 0.916648 1.583858 0.757279 2.129612 1.386838 + -2.140558 2.214946 -4.171988 -1.055384 -6.363065 -0.232922 + -2.486751 0.823935 -2.418258 3.347586 -3.103635 4.864439 + 0.687061 3.597921 3.669743 1.43585 5.132502 2.724104 + -0.344691 1.08929 0.484513 1.884668 0.473244 3.022942 + -0.01352 2.068761 0.378264 6.65826 1.845318 5.542497 + 1.472489 0.175399 1.430793 -1.740909 2.30904 -2.30502 + -1.36358 -1.181833 2.025569 -1.358588 0.887958 -2.838158 + -0.499809 -1.988948 1.367195 -3.177085 1.789594 -4.928946 + 0.579613 -0.960476 -1.588234 -0.05789 -0.373062 -1.023304 + 0.927113 -0.301781 2.379761 -2.07879 0.994298 -2.428506 + -0.676988 0.933612 -1.737597 -2.080985 -0.549773 -0.651497 + 0.699549 -0.419557 1.900516 1.563553 1.759683 -0.08984 + -0.608903 -3.386912 -2.4601 -6.520148 -5.090986 -8.736865 + -0.200722 0.802307 -1.230158 0.889683 -1.228926 0.0694 + 2.155263 -0.50116 -0.789058 -0.572123 -1.208573 -0.913148) + (M 17.09375 21) + (c -1.221276 0.05745 -0.44882 1.331427 0.232503 0.449916) + (C 17.458514 21.23484 17.234278 21.104353 17.09375 21) + (m -7.5 0.125) + (c -1.2040413 0.60218 1.459244 1.052142 0.289004 0.112253) + (m 8.96875 1.5) + (c 0.38412 0.655402 -0.236077 2.74213 1.030518 1.55154 + 0.0634 -0.524592 -0.59842 -1.401743 -1.030518 -1.55154) + (m -0.21875 0.75) + (c -1.155615 0.198578 0.509999 1.388302 0.06733 0.201634) + (M 10.5 24.53125) + (c -0.117519 1.313533 1.058399 0.642504 0 0))) + +(define water-logo-material + (deep-flomap-material-value + 'cubic-zirconia 1.0 0.7 1.0 + 0.25 0.15 1.0 + 0.15 0.1 0.2 + 0.0)) + +(define logo-under-continents-color "black") +(define logo-continents-color "azure") +(define logo-water-color "lightskyblue") +(define logo-earth-outline-color logo-red-color) + +(define (continents-flomap color height) + (define scale (/ height 32)) + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen lambda-outline-color 3/8 'solid) + (send dc set-brush color 'solid) + (draw-path-commands dc 0 -17 continents-path-commands)) + scale)) + +(define (planet-flomap height) + (make-cached-flomap + [height] + (define scale (/ height 32)) + (define-values (earth-fm earth-z) + (let* ([indent-fm (continents-flomap logo-red-color height)] + [indent-dfm (flomap->deep-flomap indent-fm)] + [indent-dfm (deep-flomap-raise indent-dfm (* -1/8 scale))] + [indent-dfm (deep-flomap-smooth-z indent-dfm (* 1 scale))] + [earth-fm (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen logo-water-color 1/2 'solid) + (send dc set-brush logo-water-color 'solid) + (draw-ellipse/smoothed dc 0.75 0.75 30.5 30.5)) + scale)] + [earth-dfm (flomap->deep-flomap earth-fm)] + [earth-dfm (deep-flomap-bulge-spheroid earth-dfm (* 16 scale))] + [earth-dfm (deep-flomap-cc-superimpose 'add earth-dfm indent-dfm)]) + (values (deep-flomap-render-icon earth-dfm water-logo-material) + (deep-flomap-z earth-dfm)))) + + (define land-fm + (let* ([land-fm (continents-flomap logo-continents-color height)] + [land-dfm (flomap->deep-flomap land-fm)] + ;[land-dfm (deep-flomap-emboss land-dfm (* 2 scale) (* 8 scale))] + [land-dfm (deep-flomap-bulge-spheroid land-dfm (* 16 scale))] + [land-dfm (deep-flomap-smooth-z land-dfm (* 1/2 scale))]) + (deep-flomap-render-icon land-dfm metal-material))) + + (flomap-cc-superimpose + (draw-icon-flomap + 32 32 (λ (dc) + (send dc set-pen "lightblue" 1/2 'solid) + (send dc set-brush "white" 'transparent) + (send dc draw-ellipse 0.5 0.5 31 31) + (send dc set-pen lambda-outline-color 1/2 'solid) + (send dc draw-ellipse -0.25 -0.25 32.5 32.5)) + scale) + earth-fm + land-fm))) + +(define plt-logo (compose flomap->bitmap plt-flomap)) +(define planet-logo (compose flomap->bitmap planet-flomap)) diff --git a/collects/images/private/utils.rkt b/collects/images/private/utils.rkt index e9256a570a..167ec3aa43 100644 --- a/collects/images/private/utils.rkt +++ b/collects/images/private/utils.rkt @@ -64,9 +64,7 @@ (define (get-total-time-spent) total-time-spent) (define (make-cached-flomap* name proc size . args) - (define rendered-size - (cond [(size . < . 32) 32] - [else (expt 2 (inexact->exact (ceiling (/ (log size) (log 2)))))])) + (define rendered-size (if (size . < . 32) 32 size)) (define fm (weak-value-hash-ref! flomap-cache (list name rendered-size args) (λ () (apply proc rendered-size args)))) (flomap-scale fm (/ size rendered-size))) diff --git a/collects/images/scribblings/icons.scrbl b/collects/images/scribblings/icons.scrbl index 58a193f50d..0f52745d3e 100644 --- a/collects/images/scribblings/icons.scrbl +++ b/collects/images/scribblings/icons.scrbl @@ -3,10 +3,18 @@ @(require scribble/eval unstable/latent-contract/defthing (for-label images/icons/arrow + images/icons/control + images/icons/file + images/icons/misc + images/icons/stickman mrlib/switchable-button racket racket/draw) - images/icons/arrow) + images/icons/arrow + images/icons/control + images/icons/file + images/icons/misc + images/icons/stickman) @(define (author-email) "neil.toronto@gmail.com") @@ -15,7 +23,8 @@ @(define icons-eval (make-base-eval)) -@interaction-eval[#:eval icons-eval (require racket/math racket/list images/icons/style)] +@interaction-eval[#:eval icons-eval (require racket/class racket/draw racket/math racket/list + images/icons/style)] @;{ @section{Introduction (What is an icon, really?)} @@ -41,6 +50,11 @@ It is composed of @(go-icon (solid-icon-color "blue") 16 'diffuse) to connote st The author of this collection is available to adapt or create SVG icons for DrRacket tools, and charges no more than your immortal soul. +@interaction[#:eval icons-eval + (require slideshow/pict) + (cc-superimpose (bitmap (record-icon "forestgreen" 96 glass-icon-material)) + (bitmap (step-icon "azure" 48 plastic-icon-material)))] + @section{Icon Parameters} @doc-apply[toolbar-icon-height]{ @@ -64,303 +78,216 @@ The style of DrRacket icons, used as a default argument throughout the @racketmo @section[#:tag "arrows"]{Arrow Icons} @defmodule[images/icons/arrow] - @interaction-eval[#:eval icons-eval (require images/icons/arrow)] @doc-apply[right-arrow-icon] @doc-apply[left-arrow-icon] @doc-apply[up-arrow-icon] @doc-apply[down-arrow-icon]{ -Cardinal direction arrows. - -@interaction[#:eval icons-eval - (list (right-arrow-icon syntax-icon-color (toolbar-icon-height)) - (left-arrow-icon run-icon-color) - (up-arrow-icon halt-icon-color 37) - (down-arrow-icon "lightblue" 44 glass-icon-material))] +@examples[#:eval icons-eval + (list (right-arrow-icon syntax-icon-color (toolbar-icon-height)) + (left-arrow-icon run-icon-color) + (up-arrow-icon halt-icon-color 37) + (down-arrow-icon "lightblue" 44 glass-icon-material))] } @doc-apply[right-over-arrow-icon] @doc-apply[left-over-arrow-icon] @doc-apply[right-under-arrow-icon] @doc-apply[left-under-arrow-icon]{ -@interaction[#:eval icons-eval - (list (right-over-arrow-icon metal-icon-color (toolbar-icon-height)) - (left-over-arrow-icon dark-metal-icon-color) - (right-under-arrow-icon run-icon-color 37) - (left-under-arrow-icon "lightgreen" 44 glass-icon-material))] +@examples[#:eval icons-eval + (list (right-over-arrow-icon metal-icon-color (toolbar-icon-height)) + (left-over-arrow-icon dark-metal-icon-color) + (right-under-arrow-icon run-icon-color 37) + (left-under-arrow-icon "lightgreen" 44 glass-icon-material))] } @section[#:tag "control"]{Control Icons} -@section[#:tag "file"]{File Icons} +@defmodule[images/icons/control] +@interaction-eval[#:eval icons-eval (require images/icons/control)] -@section[#:tag "tool"]{Tool Icons} - -@section[#:tag "stickman"]{Stickman Icons} - -@section[#:tag "misc"]{Miscellaneous Icons} - -@;{ -@subsection{Control Icons} - -@doc-apply[go-icon] -@doc-apply[bar-icon] +@doc-apply[play-icon] @doc-apply[back-icon] +@doc-apply[fast-forward-icon] +@doc-apply[rewind-icon] +@doc-apply[bar-icon] @doc-apply[stop-icon] @doc-apply[record-icon] +@doc-apply[pause-icon] @doc-apply[step-icon] @doc-apply[step-back-icon] @doc-apply[continue-icon] -@doc-apply[continue-back-icon] -@doc-apply[fast-forward-icon] -@doc-apply[rewind-icon] -@doc-apply[pause-icon]{ -These return typical ``playback'' icons. - -@interaction[#:eval icons-eval +@doc-apply[continue-back-icon]{ +Typical ``playback control'' icons. +For example, a colorful tape deck: +@interaction[#:eval icons-eval (for/list ([make-icon (list rewind-icon continue-back-icon step-back-icon back-icon pause-icon stop-icon - go-icon step-icon + play-icon step-icon continue-icon fast-forward-icon record-icon)] - [style (in-cycle icon-styles)]) - (make-icon (solid-icon-color "darkseagreen") 32 style))] - -The remaining icon @(bar-icon #f 16), returned by @racket[bar-icon], is used to build the others. + [color (list run-icon-color halt-icon-color + syntax-icon-color metal-icon-color + dark-metal-icon-color dark-metal-icon-color + metal-icon-color syntax-icon-color + halt-icon-color run-icon-color + "red")] + [material (in-cycle (list plastic-icon-material + glass-icon-material))]) + (make-icon color 32 material))] +The remaining icon @(bar-icon "red" 16), returned by @racket[bar-icon], is used to build the others. } -@subsection{Arrow Icons} +@section[#:tag "file"]{File Icons} -@doc-apply[up-arrow-icon] -@doc-apply[down-arrow-icon] -@doc-apply[left-arrow-icon] -@doc-apply[right-arrow-icon]{ +@defmodule[images/icons/file] +@interaction-eval[#:eval icons-eval (require images/icons/file)] + +@doc-apply[floppy-disk-icon]{ +@examples[#:eval icons-eval (floppy-disk-icon "gold" 32 glass-icon-material)] +} + +@doc-apply[save-icon] +@doc-apply[small-save-icon] +@doc-apply[load-icon] +@doc-apply[small-load-icon]{ @examples[#:eval icons-eval - (for/list ([make-icon (list up-arrow-icon down-arrow-icon - left-arrow-icon right-arrow-icon)]) - (for/list ([style (in-list icon-styles)]) - (make-icon (solid-icon-color "brown") (default-icon-height) style)))] + (for/list ([make-icon (list save-icon small-save-icon + load-icon small-load-icon)] + [color (list run-icon-color halt-icon-color + metal-icon-color dark-metal-icon-color)]) + (make-icon syntax-icon-color color 32))] } -@subsection{Sign Icons} +@section[#:tag "misc"]{Miscellaneous Icons} -@doc-apply[stop-sign-icon]{ -@examples[#:eval icons-eval (list (stop-sign-icon (default-icon-height) 'diffuse) - (stop-sign-icon (default-icon-height) 'shiny))] +@defmodule[images/icons/misc] +@interaction-eval[#:eval icons-eval (require images/icons/misc)] + +@doc-apply[text-icon]{ +Renders a text string as an icon. For example, +@interaction[#:eval icons-eval + (text-icon "An Important Point!" + (make-object font% 48 'decorative 'normal 'bold #t) + "lightskyblue" #t 2 48)] + +Before rendering, the drawn text is scaled so that it is exactly @racket[height] pixels tall. +Make sure the font is large enough that scaling does not create blurry and jagged edge artifacts, as in the following example: +@interaction[#:eval icons-eval + (text-icon "Q" (make-object font% 32 'default 'normal 'bold) + "green" #t 0 96)] +When @racket[str] contains tall letters or @racket[trim?] is @racket[#f], using @racket[height] as the font size should be sufficient. + +To make it easy to create a large enough font, @racket[text-icon] always interpets font sizes as being in pixels, never points. +See @racket[font%] for details on font sizes. + +If @racket[trim?] is @racket[#f], the drawn text is not cropped before rendering. +Otherwise, it is cropped to the smallest rectangle containing all the non-zero-alpha pixels. +Rendering very small glyphs shows the difference dramatically: +@interaction[#:eval icons-eval + (define font (make-object font% 32 'default)) + (list (text-icon "." font "white") + (text-icon "." font "white" #f))] +Note that both icons are @racket[(default-icon-height)] pixels tall. + +When @racket[outline] is @racket['auto], the outline drawn around the text is @racket[(/ height 32)] pixels wide. + +Because different platforms have slightly different fonts, @racket[text-icon] cannot guarantee the icons it returns have a consistent look or width across all platforms. } -@subsection{Check Icons} - -@doc-apply[check-icon]{ -@examples[#:eval icons-eval - (list (check-icon (solid-icon-color "green") 29 'diffuse) - (check-icon (solid-icon-color "green") 29 'shiny))] +@doc-apply[recycle-icon]{ +Returns the universal recycling symbol, rendered as an icon. +Its implementation calls @racket[text-icon] with the string @racket["\u267b"]. +@examples[#:eval icons-eval (recycle-icon "forestgreen" 48)] } @doc-apply[x-icon]{ -@examples[#:eval icons-eval - (for/list ([color icon-colors] - [style (in-cycle icon-styles)]) - (x-icon color 29 style))] +Returns an ``x'' icon that is guaranteed to look the same on all platforms. +(Anything similar that would be constructed by @racket[text-icon] would differ at least slightly across platforms.) +@examples[#:eval icons-eval (x-icon "red" 32)] } -@subsection{Miscellaneous Icons} +@doc-apply[check-icon]{ +@examples[#:eval icons-eval (check-icon "darkgreen" 32)] +} + +@doc-apply[regular-polygon-icon]{ +Renders the largest regular polygon with @racket[sides] sides, with the first vertex at angle @racket[start], that can be centered in a @racket[height] × @racket[height] box. +@examples[#:eval icons-eval (for/list ([sides (in-range 1 9)] + [material (in-cycle (list plastic-icon-material + glass-icon-material))]) + (regular-polygon-icon sides (* 1/4 pi) "cornflowerblue" 32 + material))] +} + +@doc-apply[octagon-icon]{ +Equivalent to @racket[(regular-polygon-icon 8 (/ (* 2 pi) 16) color height material)]. +@examples[#:eval icons-eval (octagon-icon halt-icon-color 32)] +} + +@doc-apply[stop-sign-icon]{ +@examples[#:eval icons-eval + (stop-sign-icon halt-icon-color 32 glass-icon-material)] +} + +@doc-apply[stop-signs-icon]{ +@examples[#:eval icons-eval + (stop-signs-icon halt-icon-color 32 plastic-icon-material)] +} @doc-apply[magnifying-glass-icon]{ -@examples[#:eval icons-eval (list (magnifying-glass-icon 31 'diffuse) - (magnifying-glass-icon 31 'shiny))] -Note that the uncolorized magnifying glass has a brown handle. -} - -@doc-apply[magnifying-glass-left-icon]{ -@examples[#:eval icons-eval (list (magnifying-glass-left-icon 31 'diffuse) - (magnifying-glass-left-icon 31 'shiny))] -} - -@doc-apply[disk-icon]{ @examples[#:eval icons-eval - (for/list ([color icon-colors] - [style (in-cycle icon-styles)]) - (disk-icon color 33 style))] + (magnifying-glass-icon "azure" "lightblue" 32 glass-icon-material)] } -@doc-apply[earth-icon]{ -@examples[#:eval icons-eval (list (earth-icon 48 'diffuse) - (earth-icon 48 'shiny))] -} - -@doc-apply[moon-icon]{ -@examples[#:eval icons-eval (list (moon-icon 48 'diffuse) - (moon-icon 48 'shiny))] -} - -@subsection{Symbols} - -@doc-apply[hash-quote-icon]{ -@examples[#:eval icons-eval (list (hash-quote-icon (toolbar-icon-height) 'diffuse) - (hash-quote-icon (toolbar-icon-height) 'shiny))] -} - -@doc-apply[plus-icon]{ +@doc-apply[left-magnifying-glass-icon]{ @examples[#:eval icons-eval - (for/list ([color icon-colors] - [style (in-cycle icon-styles)]) - (plus-icon color 24 style))] + (left-magnifying-glass-icon metal-icon-color "red" 32)] } -@doc-apply[times-icon]{ +@doc-apply[bomb-icon]{ @examples[#:eval icons-eval - (for/list ([color icon-colors] - [style (in-cycle icon-styles)]) - (times-icon color 24 style))] + (bomb-icon "azure" "black" 32 glass-icon-material)] } -@subsection{Logos} - -@doc-apply[plt-logo]{ +@doc-apply[left-bomb-icon]{ @examples[#:eval icons-eval - (list (plt-logo 128 'diffuse) (plt-logo 128 'shiny))] + (left-bomb-icon metal-icon-color dark-metal-icon-color 32)] } -@doc-apply[planet-logo]{ -@examples[#:eval icons-eval (list (planet-logo 128 'diffuse) - (planet-logo 128 'shiny))] +@section[#:tag "stickman"]{Stickman Icons} + +@defmodule[images/icons/stickman] +@interaction-eval[#:eval icons-eval (require images/icons/stickman)] + +@doc-apply[standing-stickman-icon]{ +Returns the icon displayed in DrRacket's lower-right corner when no program is running. +@examples[#:eval icons-eval (standing-stickman-icon run-icon-color "white" run-icon-color 64)] } +@doc-apply[running-stickman-icon]{ +Returns a frame of the icon animated in DrRacket's lower-right corner when a program is running. +The frame returned is for time @racket[t] of a run cycle with a one-second period. -@section{Icon Constants and Contracts} - -@;{ -@doc-apply[icon-colors]{ -A list containing the names of allowed icon colors. - -When an SVG icon source file is rendered, it is rendered once directly. Then, for each color corresponding to a symbol in @racket[icon-colors], it is colorized by replacing gradients, and then rendered. - -When loading an icon, a @racket[#f] color name loads an uncolorized rendering. -Every icon can be loaded with a @racket[#f] color name. -An icon can be loaded using any name in @racket[icon-colors] only if its SVG source has gradients that can be colorized. -See @secref["new-icons"] for details. - -The actual hues associated with the color names are the hues of the first seven @racketmodname[plot] color numbers. -The following example illustrates the correspondence: +It is difficult to put a code example in the API documentation that produces an animation. +However, we might use code similar to the following to sample from the run cycle: @interaction[#:eval icons-eval - (require plot) - (for/list ([color (rest icon-colors)]) - (stop-flomap color 48)) - (parameterize ([plot-width 48] - [plot-height 48] - [plot-decorations? #f] - [plot-background-alpha 0]) - (for/list ([n (in-range 7)]) - (plot3d-pict (surface3d (λ (x y) (- (sqr x) (sqr y))) -1 1 -1 1 - #:color n #:line-color n - #:samples 11 #:line-width 1))))] -This example also shows how to use @racketmodname[plot] to create icon @racket[pict]s from mathematical functions. -}} + (for/list ([t (in-range 0 1 1/12)]) + (running-stickman-icon t run-icon-color "white" run-icon-color 32))] +If instead of putting the icons in a list, we call their @racket[save-file] methods and hand-assemble the files into a GIF, we get something like this: -@doc-apply[icon-color/c]{ -A contract that identifies color names. +@centered[@image["scribblings/running-stickman.gif"]] + +Here, the run cycle is sampled and played back at 30 Hz. +The previous example samples the run cycle at 12 Hz, or every @racket[1/12] second. +DrRacket samples it at 12 Hz and plays it back at 5 Hz at the most. + +The stickman's joint angles are defined by continuous periodic functions, so the run cycle can be sampled at any resolution, or at any real-valued time @racket[t]. +The cycle is modeled after the run cycle of the player's avatar in the Commodore 64 game @link["http://en.wikipedia.org/wiki/Impossible_Mission"]{Impossible Mission}. } -@doc-apply[icon-styles]{ -Typical icon styles. +@section[#:tag "tool"]{Tool Icons} -It is not necessary to have a version of each icon in each style. -But if an icon has different styles, it should have these. -} - -@doc-apply[icon-style/c]{ -A contract that identifies icon styles. -} - - -@section{Icon @racket[pict]s} - -@interaction-eval[#:eval icons-eval (require slideshow/pict)] - -It is more flexible, but a little more complicated, to load icons as @racket[pict]s. -As picts, icons can easily be appended, inset, superimposed, blurred, and more. -For example, it is easy to make modern-looking media player controls using @racket[cc-superimpose] and the @racket['shiny] style: -@interaction[#:eval icons-eval - (define media-icon-background (record-flomap 'blue 64 'shiny)) - (list (cc-superimpose media-icon-background - (step-back-flomap 'white 32 'shiny)) - (cc-superimpose media-icon-background - (pause-flomap 'white 32 'shiny)) - (cc-superimpose media-icon-background - (step-flomap 'white 32 'shiny)))] - -Almost all of the functions in preceeding sections are defined in terms of the @racket[pict]-producing functions documented in this section. - -To use these functions effectively, you should require @racketmodname[icons] and @racketmodname[slideshow/pict] together. -Use @racket[bitmap] to convert a @racket[bitmap%] (e.g. an icon) to a @racket[pict], and @racket[pict->bitmap] to convert back. - -Converting from @racket[pict]s to bitmaps can be lossy. For example, converting text can look especially horrible: -@interaction[#:eval icons-eval - (scale (text "Hello" null 10) 5) - (scale (bitmap (pict->bitmap (text "Hello" null 10))) 5)] - -Therefore, when composing icons from parts, try to work only with @racket[pict]s, and convert to an icon using @racket[pict->bitmap] as the last step. - -When composing icons from parts, it is fine to use @racket[pict]s converted from @racket[bitmap%]s. -Without scaling or rotating, the conversion is lossless: -@interaction[#:eval icons-eval - (define not-blurry (magnifying-glass-icon 64 'shiny)) - not-blurry - (for/fold ([icon not-blurry]) ([i (in-range 30)]) - (pict->bitmap (bitmap icon)))] - -Avoid converting between @racket[pict]s and @racket[bitmap%]s more than once if bitmap-backed @racket[pict]s are scaled, rotated by angles that are not multiples of 90 degrees, or superimposed or appended at non-integer coordinates. -Avoid scaling up in general. - -@doc-apply[load-flomap]{ -Corresponds to @racket[load-icon]. In fact, @racket[load-icon] uses @racket[load-flomap] to load the icon as a @racket[pict], and passes it to @racket[pict->bitmap]. -} - -@doc-apply[go-flomap] -@doc-apply[bar-flomap] -@doc-apply[back-flomap] -@doc-apply[stop-flomap] -@doc-apply[record-flomap] -@doc-apply[step-flomap] -@doc-apply[step-back-flomap] -@doc-apply[continue-flomap] -@doc-apply[continue-back-flomap] -@doc-apply[fast-forward-flomap] -@doc-apply[rewind-flomap] -@doc-apply[pause-flomap]{ -These return typical ``playback'' icons, as @racket[pict]s. - -@interaction[#:eval icons-eval - (for/fold ([icon (blank)]) - ([make-flomap (list rewind-flomap continue-back-flomap - step-back-flomap back-flomap - pause-flomap stop-flomap - go-flomap step-flomap - continue-flomap fast-forward-flomap - record-flomap)]) - (hc-append icon (make-flomap 'black 32 'shiny) (blank 12)))] -} - -@doc-apply[up-arrow-flomap]{ Corresponds to @racket[up-arrow-icon]. } -@doc-apply[down-arrow-flomap]{ Corresponds to @racket[down-arrow-icon]. } -@doc-apply[left-arrow-flomap]{ Corresponds to @racket[left-arrow-icon]. } -@doc-apply[right-arrow-flomap]{ Corresponds to @racket[right-arrow-icon]. } - -@doc-apply[stop-sign-flomap]{ Corresponds to @racket[stop-sign-icon]. } -@doc-apply[check-flomap]{ Corresponds to @racket[check-icon]. } -@doc-apply[x-flomap]{ Corresponds to @racket[x-icon]. } -@doc-apply[magnifying-glass-flomap]{ Corresponds to @racket[magnifying-glass-icon]. } -@doc-apply[magnifying-glass-left-flomap]{ Corresponds to @racket[magnifying-glass-left-icon]. } -@doc-apply[disk-flomap]{ Corresponds to @racket[disk-icon]. } -@doc-apply[earth-flomap]{ Corresponds to @racket[earth-icon]. } -@doc-apply[moon-flomap]{ Corresponds to @racket[moon-icon]. } -@doc-apply[hash-quote-flomap]{ Corresponds to @racket[hash-quote-icon]. } -@doc-apply[plus-flomap]{ Corresponds to @racket[plus-icon]. } -@doc-apply[times-flomap]{ Corresponds to @racket[times-icon]. } -@doc-apply[plt-logo-pict]{ Corresponds to @racket[plt-logo]. } -@doc-apply[planet-logo-pict]{ Corresponds to @racket[planet-logo]. } - -} \ No newline at end of file +@section[#:tag "const"]{Icon Constants and Contracts} diff --git a/collects/images/scribblings/running-stickman.gif b/collects/images/scribblings/running-stickman.gif new file mode 100644 index 0000000000000000000000000000000000000000..79d9de52eeb7bd22649aa140242dd220d2bc0c42 GIT binary patch literal 43705 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 literal 0 HcmV?d00001 diff --git a/collects/images/tests/icon-tests.rkt b/collects/images/tests/icon-tests.rkt index fc6817a7f1..a362914aa2 100644 --- a/collects/images/tests/icon-tests.rkt +++ b/collects/images/tests/icon-tests.rkt @@ -37,7 +37,7 @@ ;; Other icons, various colors (define icon-procss - (list (list reverse-icon continue-back-icon step-back-icon back-icon pause-icon + (list (list rewind-icon continue-back-icon step-back-icon back-icon pause-icon stop-icon record-icon play-icon step-icon continue-icon fast-forward-icon) (list right-arrow-icon left-arrow-icon up-arrow-icon down-arrow-icon right-over-arrow-icon left-over-arrow-icon right-under-arrow-icon left-under-arrow-icon)