1#lang scribble/manual 2 3@(require (for-label pict pict/shadow racket/base racket/contract racket/class racket/draw) 4 scribble/eval) 5 6@(define the-eval (make-base-eval)) 7@(the-eval '(require pict pict/shadow)) 8 9@title{Shadows} 10 11@defmodule[pict/shadow] 12 13These pict transformations add shadows or blurring in various shapes and 14forms. 15 16@defproc[(blur [p pict?] 17 [h-radius (and/c real? (not/c negative?))] 18 [v-radius (and/c real? (not/c negative?)) h-radius]) 19 pict?]{ 20 21Blurs @racket[p] using an iterated box blur that approximates a 22gaussian blur. The @racket[h-radius] and @racket[v-radius] arguments 23control the strength of the horizontal and vertical components of the 24blur, respectively. They are given in terms of pict units, which may 25not directly correspond to screen pixels. 26 27The @racket[blur] function takes work proportional to 28@racketblock[(* (pict-width p) (pict-height p))] 29but it may be sped up by a factor of up to @racket[(processor-count)] 30due to the use of @racket[future]s. 31 32@examples[#:eval the-eval 33(blur (text "blur" null 40) 5) 34(blur (text "more blur" null 40) 10) 35(blur (text "much blur" null 40) 20) 36(blur (text "horiz. blur" null 40) 10 0) 37] 38The resulting pict has the same bounding box as @racket[p], so when 39picts are automatically @racket[clip]ped (as in Scribble documents), 40the pict should be @racket[inset] by the blur radius. 41@examples[#:eval the-eval 42(inset (blur (text "more blur" null 40) 10) 10) 43] 44 45@history[#:added "1.4"]{} 46} 47 48@defproc[(shadow [p pict?] 49 [radius (and/c real? (not/c negative?))] 50 [dx real? 0] 51 [dy real? dx] 52 [#:color color (or/c #f string? (is-a?/c color%)) #f] 53 [#:shadow-color shadow-color (or/c #f string? (is-a?/c color%)) #f]) 54 pict?]{ 55 56Creates a shadow effect by superimposing @racket[p] over a 57blurred version of @racket[p]. The shadow is offset from @racket[p] by 58(@racket[dx], @racket[dy]) units. 59 60If @racket[color] is not @racket[#f], the foreground part is 61@racket[(colorize p color)]; otherwise it is just @racket[p]. If 62@racket[shadow-color] is not @racket[#f], the shadow part is produced 63by blurring @racket[(colorize p shadow-color)]; otherwise it is 64produced by blurring @racket[p]. 65 66The resulting pict has the same bounding box as @racket[p]. 67 68@examples[#:eval the-eval 69(inset (shadow (text "shadow" null 50) 10) 10) 70(inset (shadow (text "shadow" null 50) 10 5) 10) 71(inset (shadow (text "shadow" null 50) 72 5 0 2 #:color "white" #:shadow-color "red") 73 10) 74] 75 76@history[#:added "1.4"]{} 77} 78 79@defproc[(shadow-frame [pict pict?] ... 80 [#:sep separation real? 5] 81 [#:margin margin real? 20] 82 [#:background-color bg-color (or/c string? (is-a?/c color%)) "white"] 83 [#:frame-color frame-color (or/c string? (is-a?/c color%)) "gray"] 84 [#:frame-line-width frame-line-width (or/c real? #f 'no-frame) 0] 85 [#:shadow-side-length shadow-side-length real? 4] 86 [#:shadow-top-y-offset shadow-top-y-offset real? 10] 87 [#:shadow-bottom-y-offset shadow-bottom-y-offset real? 4] 88 [#:shadow-descent shadow-descent (and/c real? (not/c negative?)) 40] 89 [#:shadow-alpha-factor shadow-alpha-factor real? 3/4] 90 [#:blur blur-radius (and/c real? (not/c negative?)) 20]) 91 pict?]{ 92 93Surrounds the @racket[pict]s with a rectangular frame that casts a 94symmetric ``curled paper'' shadow. 95 96The @racket[pict]s are vertically appended with @racket[separation] 97space between them. They are placed on a rectangular background of 98solid @racket[bg-color] with @racket[margin] space on all sides. A 99frame of @racket[frame-color] and @racket[frame-line-width] is added 100around the rectangle, unless @racket[frame-line-width] is 101@racket['no-frame]. The rectangle casts a shadow that extends 102@racket[shadow-side-length] to the left and right, starts 103@racket[shadow-top-y-offset] below the top of the rectangle and 104extends to @racket[shadow-bottom-y-offset] below the bottom of the 105rectangle in the center and an additional @racket[shadow-descent] 106below that on the sides. The shadow is painted using a linear 107gradient; @racket[shadow-alpha-factor] determines its density at the 108center. Finally, the shadow is blurred by @racket[blur-radius]; all 109previous measurements are pre-blur measurements. 110 111@examples[#:eval the-eval 112(shadow-frame (text "text in a nifty frame" null 60)) 113] 114 115@history[#:added "1.4"]{} 116} 117 118@(close-eval the-eval) 119