move racket/draw overview to the Guide and expand it

--- plus some minor collateral API improvements
This commit is contained in:
Matthew Flatt 2010-11-27 15:53:49 -07:00
parent 0b19c6e798
commit 8b3165d55b
16 changed files with 2017 additions and 385 deletions

View File

@ -28,24 +28,40 @@
(properties #:check-immutable check-immutable
[[brush-style-symbol? style] 'solid])
(init-rest args)
(super-new)
(init [(_color color) black]
[(_style style) 'solid]
[(_stipple stipple) #f])
(case-args
args
[() (void)]
[([color% _color]
[brush-style-symbol? _style])
(set! color (color->immutable-color _color))
(set! style _style)]
[([string? _color]
[brush-style-symbol? _style])
(set! color (send the-color-database find-color _color))
(set! style _style)]
(init-name 'brush%))
(set! color
(cond
[(string? _color) (or (send the-color-database find-color _color) black)]
[(color . is-a? . color%)
(color->immutable-color _color)]
[else
(raise-type-error (init-name 'brush%)
"string or color%"
_color)]))
(set! style
(if (brush-style-symbol? _style)
_style
(raise-type-error (init-name 'brush%)
"brush style symbol"
_style)))
(define immutable? #f)
(define lock-count 0)
(define stipple #f)
(when _stipple
(unless (_stipple . is-a? . bitmap%)
(raise-type-error (init-name 'brush%)
"bitmap% or #f"
_stipple))
(set-stipple _stipple))
(super-new)
(define/public (set-immutable) (set! immutable? #t))
(define/public (is-immutable?) (or immutable? (positive? lock-count)))
(define/public (adjust-lock v) (set! lock-count (+ lock-count v)))
@ -71,7 +87,6 @@
(define/public (get-color) color)
(define stipple #f)
(def/public (get-stipple) stipple)
(def/public (set-stipple [(make-or-false bitmap%) s])
(check-immutable 'set-stipple)
@ -95,7 +110,8 @@
(values (color->immutable-color _color) _style)]
[([string? _color]
[brush-style-symbol? _style])
(values (send the-color-database find-color _color)
(values (or (send the-color-database find-color _color)
black)
_style)]
(method-name 'find-or-create-brush 'brush-list%))])
(let ([key (vector (send col red) (send col green) (send col blue)

View File

@ -36,15 +36,20 @@
(define 2pi (* 2 pi))
(define black (send the-color-database find-color "black"))
(define (copy-color c)
(if (send c is-immutable?)
c
(let ([c (make-object color%
(color-red c)
(color-green c)
(color-blue c))])
(send c set-immutable)
c)))
(if (string? c)
(or (send the-color-database find-color c)
black)
(if (send c is-immutable?)
c
(let ([c (make-object color%
(color-red c)
(color-green c)
(color-blue c))])
(send c set-immutable)
c))))
(define -bitmap-dc% #f)
(define (install-bitmap-dc-class! v) (set! -bitmap-dc% v))
@ -268,7 +273,6 @@
(define contexts (make-vector (vector-length font-maps) #f))
(define desc-layoutss (make-vector (vector-length font-maps) #f))
(define black (send the-color-database find-color "black"))
(define pen (send the-pen-list find-or-create-pen "black" 1 'solid))
(define brush (send the-brush-list find-or-create-brush "white" 'solid))
(define font (send the-font-list find-or-create-font 12 'default))
@ -554,11 +558,11 @@
(define/private (brush-draws?)
(not (eq? (send brush get-style) 'transparent)))
(def/public (set-text-foreground [color% c])
(def/public (set-text-foreground [(make-alts color% string?) c])
(set! text-fg (copy-color c)))
(def/public (set-text-background [color% c])
(def/public (set-text-background [(make-alts color% string?) c])
(set! text-bg (copy-color c)))
(def/public (set-background [color% c])
(def/public (set-background [(make-alts color% string?) c])
(set! pen-stipple-s #f)
(set! brush-stipple-s #f)
(set! bg (copy-color c)))

View File

@ -42,33 +42,58 @@
[[pen-style-symbol? style] 'solid]
[[pen-width? width] 0])
(init-rest args)
(super-new)
(init [(_color color) black]
[(_width width) 0]
[(_style style) 'solid]
[(_cap cap) 'round]
[(_join join) 'round]
[(_stipple stipple) #f])
(case-args
args
[() (void)]
[([color% _color]
[pen-width? _width]
[pen-style-symbol? _style]
[pen-cap-symbol? [_cap 'round]]
[pen-join-symbol? [_join 'round]])
(set! color (color->immutable-color _color))
(set! width _width)
(set! style _style)
(set! cap _cap)
(set! join _join)]
[([string? _color]
[pen-width? _width]
[pen-style-symbol? _style]
[pen-cap-symbol? [_cap 'round]]
[pen-join-symbol? [_join 'round]])
(set! color (send the-color-database find-color _color))
(set! width _width)
(set! style _style)
(set! cap _cap)
(set! join _join)]
(init-name 'pen%))
(set! color
(cond
[(string? _color) (or (send the-color-database find-color _color) black)]
[(color . is-a? . color%)
(color->immutable-color _color)]
[else
(raise-type-error (init-name 'pen%)
"string or color%"
_color)]))
(set! width
(if (pen-width? _width)
_width
(raise-type-error (init-name 'pen%)
"real in [0, 255]"
_width)))
(set! style
(if (pen-style-symbol? _style)
_style
(raise-type-error (init-name 'pen%)
"pen style symbol"
_style)))
(set! cap
(if (pen-cap-symbol? _cap)
_cap
(raise-type-error (init-name 'pen%)
"pen cap symbol"
_cap)))
(set! join
(if (pen-join-symbol? _join)
_join
(raise-type-error (init-name 'pen%)
"pen join symbol"
_join)))
(when _stipple
(unless (_stipple . is-a? . bitmap%)
(raise-type-error (init-name 'pen%)
"bitmap% or #f"
_stipple))
(set-stipple _stipple))
(super-new)
(define immutable? #f)
(define lock-count 0)
@ -78,7 +103,7 @@
(define/private (check-immutable s)
(when (or immutable? (positive? lock-count))
(error (method-name 'brush% s) "object is ~a"
(error (method-name 'pen% s) "object is ~a"
(if immutable? "immutable" "locked"))))
(define/public (set-color . args)
@ -128,7 +153,8 @@
[pen-style-symbol? _style]
[pen-cap-symbol? [_cap 'round]]
[pen-join-symbol? [_join 'round]])
(values (send the-color-database find-color _color)
(values (or (send the-color-database find-color _color)
black)
_width _style _cap _join)]
(method-name 'find-or-create-pen 'pen-list%))])
(let ([key (vector (send col red) (send col green) (send col blue)

View File

@ -145,50 +145,56 @@
[(syntax? s) (loop (syntax-e s) ops)]
[else (loop ((car ops) s) (cdr ops))])))
(define ((do-eval ev) s)
(define (extract-to-evaluate s)
(let loop ([s s][expect #f])
(syntax-case s (code:comment eval:alts eval:check)
[(code:line v (code:comment . rest))
(loop (extract s cdr car) expect)]
[(code:comment . rest)
(list (list (void)) "" "")]
(values #f expect)]
[(eval:alts p e)
(loop (extract s cdr cdr car) expect)]
[(eval:check e expect)
(loop (extract s cdr car)
(list (syntax->datum (datum->syntax #f (extract s cdr cdr car)))))]
[else
(let ([r (with-handlers ([(lambda (x)
(not (exn:break? x)))
(lambda (e)
(list (if (exn? e)
(exn-message e)
(format "uncaught exception: ~s" e))
(get-output ev)
(get-error-output ev)))])
(list (let ([v (do-plain-eval ev s #t)])
(if (call-in-sandbox-context
ev
(let ([cp (current-print)])
(lambda ()
(and (eq? (current-print) cp)
(print-as-expression)))))
(make-reader-graph (copy-value v (make-hasheq)))
(box
(call-in-sandbox-context
(values s expect)])))
(define ((do-eval ev) s)
(let-values ([(s expect) (extract-to-evaluate s)])
(if s
(let ([r (with-handlers ([(lambda (x)
(not (exn:break? x)))
(lambda (e)
(list (if (exn? e)
(exn-message e)
(format "uncaught exception: ~s" e))
(get-output ev)
(get-error-output ev)))])
(list (let ([v (do-plain-eval ev s #t)])
(if (call-in-sandbox-context
ev
(lambda ()
(let ([s (open-output-string)])
(parameterize ([current-output-port s])
(map (current-print) v))
(get-output-string s)))))))
(get-output ev)
(get-error-output ev)))])
(when expect
(let ([expect (do-plain-eval ev (car expect) #t)])
(unless (equal? (car r) expect)
(raise-syntax-error 'eval "example result check failed" s))))
r)])))
(let ([cp (current-print)])
(lambda ()
(and (eq? (current-print) cp)
(print-as-expression)))))
(make-reader-graph (copy-value v (make-hasheq)))
(box
(call-in-sandbox-context
ev
(lambda ()
(let ([s (open-output-string)])
(parameterize ([current-output-port s])
(map (current-print) v))
(get-output-string s)))))))
(get-output ev)
(get-error-output ev)))])
(when expect
(let ([expect (do-plain-eval ev (car expect) #t)])
(unless (equal? (car r) expect)
(raise-syntax-error 'eval "example result check failed" s))))
r)
(values (list (list (void)) "" "")))))
(define (install ht v v2)
@ -337,9 +343,11 @@
(define-syntax-rule (quote-expr e) 'e)
(define (do-interaction-eval ev e)
(parameterize ([current-command-line-arguments #()])
(do-plain-eval (or ev (make-base-eval)) e #f))
"")
(let-values ([(e expect) (extract-to-evaluate e)])
(when e
(parameterize ([current-command-line-arguments #()])
(do-plain-eval (or ev (make-base-eval)) e #f)))
""))
(define-syntax interaction-eval
(syntax-rules ()

View File

@ -86,22 +86,18 @@ To avoid creating multiple brushes with the same characteristics, use
@xmethod[dc<%> set-brush].
@defconstructor*/make[(()
([color (is-a?/c color%)]
[style (one-of/c 'transparent 'solid 'opaque
'xor 'hilite 'panel
'bdiagonal-hatch 'crossdiag-hatch
'fdiagonal-hatch 'cross-hatch
'horizontal-hatch 'vertical-hatch)])
([color-name string?]
[style (one-of/c 'transparent 'solid 'opaque
'xor 'hilite 'panel
'bdiagonal-hatch 'crossdiag-hatch
'fdiagonal-hatch 'cross-hatch
'horizontal-hatch 'vertical-hatch)]))]{
@defconstructor[([color (or/c string? (is-a?/c color%)) "black"]
[style (one-of/c 'transparent 'solid 'opaque
'xor 'hilite 'panel
'bdiagonal-hatch 'crossdiag-hatch
'fdiagonal-hatch 'cross-hatch
'horizontal-hatch 'vertical-hatch)
'solid]
[stipple (or/c #f (is-a?/c bitmap%))
#f])]{
When no argument are provided, the result is a solid black brush.
Otherwise, the result is a brush with the given color and style. For
Otherwise, the result is a brush with the given color, style, and stipple. For
the case that the color is specified using a name, see
@scheme[color-database<%>] for information about color names; if the
name is not known, the brush's color is black.

View File

@ -11,12 +11,35 @@
@racketmodname[racket/draw] library provides all of the class,
interface, and procedure bindings defined in this manual.}
For an overview of the drawing library, see @secref["draw" #:doc
'(lib "scribblings/guide/guide.scrbl")].
@table-of-contents[]
@;------------------------------------------------------------------------
@include-section["guide.scrbl"]
@include-section["reference.scrbl"]
@include-section["bitmap-class.scrbl"]
@include-section["bitmap-dc-class.scrbl"]
@include-section["brush-class.scrbl"]
@include-section["brush-list-class.scrbl"]
@include-section["color-class.scrbl"]
@include-section["color-database-intf.scrbl"]
@include-section["dc-intf.scrbl"]
@include-section["dc-path-class.scrbl"]
@include-section["font-class.scrbl"]
@include-section["font-list-class.scrbl"]
@include-section["font-name-directory-intf.scrbl"]
@include-section["gl-config-class.scrbl"]
@include-section["gl-context-intf.scrbl"]
@include-section["pdf-dc-class.scrbl"]
@include-section["pen-class.scrbl"]
@include-section["pen-list-class.scrbl"]
@include-section["point-class.scrbl"]
@include-section["post-script-dc-class.scrbl"]
@include-section["ps-setup-class.scrbl"]
@include-section["region-class.scrbl"]
@include-section["draw-funcs.scrbl"]
@include-section["draw-unit.scrbl"]
@;------------------------------------------------------------------------

View File

@ -1,227 +0,0 @@
#lang scribble/doc
@(require scribble/eval
"common.ss")
@title[#:tag "overview"]{Overview}
Drawing with @racketmodname[racket/draw] uses a @deftech{device context}
(@deftech{DC}), which is an instance of the @scheme[dc<%>]
interface. For example, the @racket[post-script-dc%] class implements
a @racket[dc<%>] for drawing to a PostScript file, while @racket[bitmap-dc%]
draws to a bitmap. When using the @racketmodname[racket/gui] library for GUIs,
the @method[canvas<%> get-dc] method of a
canvas returns a @scheme[dc<%>] instance for drawing into the canvas
window.
Tools that are used for drawing include the following: @scheme[pen%]
objects for drawing lines and shape outlines, @scheme[brush%]
objects for filling shapes, @scheme[bitmap%] objects for storing
bitmaps, and @scheme[dc-path%] objects for describing paths to draw
and fill.
The following example uses the GUI library as well as the drawing
library. It creates a frame with a drawing canvas, and then draws a
round, blue face with square, yellow eyes and a smiling, red mouth:
@schemeblock[
(code:comment @#,t{Make some pens and brushes})
(define no-pen (make-object pen% "BLACK" 1 'transparent))
(define no-brush (make-object brush% "BLACK" 'transparent))
(define blue-brush (make-object brush% "BLUE" 'solid))
(define yellow-brush (make-object brush% "YELLOW" 'solid))
(define red-pen (make-object pen% "RED" 2 'solid))
(code:comment @#,t{Define a procedure to draw a face})
(define (draw-face dc)
(send dc #,(:: dc<%> set-pen) no-pen)
(send dc #,(:: dc<%> set-brush) blue-brush)
(send dc #,(:: dc<%> draw-ellipse) 50 50 200 200)
(send dc #,(:: dc<%> set-brush) yellow-brush)
(send dc #,(:: dc<%> draw-rectangle) 100 100 10 10)
(send dc #,(:: dc<%> draw-rectangle) 200 100 10 10)
(send dc #,(:: dc<%> set-brush) no-brush)
(send dc #,(:: dc<%> set-pen) red-pen)
(let ([-pi (atan 0 -1)])
(send dc #,(:: dc<%> draw-arc) 75 75 150 150 (* 5/4 -pi) (* 7/4 -pi))))
(code:comment @#,t{Make a 300 x 300 frame})
(define frame (new frame% [label "Drawing Example"]
[width 300]
[height 300]))
(code:comment @#,t{Make the drawing area, and set its paint callback})
(code:comment @#,t{to use the @racket[draw-face] function:})
(define canvas (new canvas%
[parent frame]
[paint-callback (lambda (c dc) (draw-face dc))]))
(code:comment @#,t{Show the frame})
(send frame #,(:: top-level-window<%> show) #t)
]
Suppose that @scheme[draw-face] creates a particularly complex face that
takes a long time to draw. We might want to draw the face once into
an offscreen bitmap, and then have the paint callback copy the cached
bitmap image onto the canvas whenever the canvas is updated. To draw
into a bitmap, we first create a @scheme[bitmap%] object, and then
we create a @scheme[bitmap-dc%] to direct drawing commands into the
bitmap:
@schemeblock[
(code:comment @#,t{... pens, brushes, and @scheme[draw-face] are the same as above ...})
(code:comment @#,t{Create a 300 x 300 bitmap})
(define face-bitmap (make-object bitmap% 300 300))
(code:comment @#,t{Create a drawing context for the bitmap})
(define bm-dc (make-object bitmap-dc% face-bitmap))
(code:comment @#,t{A bitmap's initial content is undefined; clear it before drawing})
(send bm-dc #,(:: dc<%> clear))
(code:comment @#,t{Draw the face into the bitmap})
(draw-face bm-dc)
(code:comment @#,t{Make a 300 x 300 frame})
(define frame (new frame% [label "Drawing Example"]
[width 300]
[height 300]))
(code:comment @#,t{Make a drawing area whose paint callback copies the bitmap})
(define canvas
(new canvas% [parent frame]
[paint-callback
(lambda (canvas dc)
(send dc #,(:: dc<%> draw-bitmap) face-bitmap 0 0))]))
(code:comment @#,t{Show the frame})
(send frame #,(:: top-level-window<%> show) #t)
]
For all types of DCs, the drawing origin is the top-left corner of the
DC. When drawing to a window or bitmap, DC units initially correspond
to pixels, but the @method[dc<%> set-scale] method changes the
scale. When drawing to a PostScript or printer device, DC units
initially correspond to points (1/72 of an inch).
More complex shapes are typically best implemented with
@deftech{paths}. The following example uses paths to draw the
Racket logo. It also enables smoothing, so that the logo's curves are
anti-aliased when smoothing is available. (Smoothing is always
available under Mac OS X, smoothing is available under Windows XP or
when @filepath{gdiplus.dll} is installed, and smoothing is available
under X when Cairo is installed before GRacket is compiled.)
@(begin
#readerscribble/comment-reader
[schemeblock
(require racket/math) ; for @scheme[pi]
;; Construct paths for a 630 x 630 logo
(define left-lambda-path ;; left side of the lambda
(let ([p (new dc-path%)])
(send p #,(:: dc-path% move-to) 153 44)
(send p #,(:: dc-path% line-to) 161.5 60)
(send p #,(:: dc-path% curve-to) 202.5 49 230 42 245 61)
(send p #,(:: dc-path% curve-to) 280.06 105.41 287.5 141 296.5 186)
(send p #,(:: dc-path% curve-to) 301.12 209.08 299.11 223.38 293.96 244)
(send p #,(:: dc-path% curve-to) 281.34 294.54 259.18 331.61 233.5 375)
(send p #,(:: dc-path% curve-to) 198.21 434.63 164.68 505.6 125.5 564)
(send p #,(:: dc-path% line-to) 135 572)
p))
(define left-logo-path ;; left side of the lambda and circle
(let ([p (new dc-path%)])
(send p #,(:: dc-path% append) left-lambda-path)
(send p #,(:: dc-path% arc) 0 0 630 630 (* 235/360 2 pi) (* 121/360 2 pi) #f)
p))
(define bottom-lambda-path
(let ([p (new dc-path%)])
(send p #,(:: dc-path% move-to) 135 572)
(send p #,(:: dc-path% line-to) 188.5 564)
(send p #,(:: dc-path% curve-to) 208.5 517 230.91 465.21 251 420)
(send p #,(:: dc-path% curve-to) 267 384 278.5 348 296.5 312)
(send p #,(:: dc-path% curve-to) 301.01 302.98 318 258 329 274)
(send p #,(:: dc-path% curve-to) 338.89 288.39 351 314 358 332)
(send p #,(:: dc-path% curve-to) 377.28 381.58 395.57 429.61 414 477)
(send p #,(:: dc-path% curve-to) 428 513 436.5 540 449.5 573)
(send p #,(:: dc-path% line-to) 465 580)
(send p #,(:: dc-path% line-to) 529 545)
p))
(define bottom-logo-path
(let ([p (new dc-path%)])
(send p #,(:: dc-path% append) bottom-lambda-path)
(send p #,(:: dc-path% arc) 0 0 630 630 (* 314/360 2 pi) (* 235/360 2 pi) #f)
p))
(define right-lambda-path
(let ([p (new dc-path%)])
(send p #,(:: dc-path% move-to) 153 44)
(send p #,(:: dc-path% curve-to) 192.21 30.69 233.21 14.23 275 20)
(send p #,(:: dc-path% curve-to) 328.6 27.4 350.23 103.08 364 151)
(send p #,(:: dc-path% curve-to) 378.75 202.32 400.5 244 418 294)
(send p #,(:: dc-path% curve-to) 446.56 375.6 494.5 456 530.5 537)
(send p #,(:: dc-path% line-to) 529 545)
p))
(define right-logo-path
(let ([p (new dc-path%)])
(send p #,(:: dc-path% append) right-lambda-path)
(send p #,(:: dc-path% arc) 0 0 630 630 (* 314/360 2 pi) (* 121/360 2 pi) #t)
p))
(define lambda-path ;; the lambda by itself (no circle)
(let ([p (new dc-path%)])
(send p #,(:: dc-path% append) left-lambda-path)
(send p #,(:: dc-path% append) bottom-lambda-path)
(let ([t (make-object dc-path%)])
(send t #,(:: dc-path% append) right-lambda-path)
(send t #,(:: dc-path% reverse))
(send p #,(:: dc-path% append) t))
(send p #,(:: dc-path% close))
p))
;; This function draws the paths with suitable colors:
(define (paint-plt dc)
;; Paint white lambda, no outline:
(send dc #,(:: dc<%> set-pen) "BLACK" 0 'transparent)
(send dc #,(:: dc<%> set-brush) "WHITE" 'solid)
(send dc #,(:: dc<%> draw-path) lambda-path)
;; Paint outline and colors...
(send dc #,(:: dc<%> set-pen) "BLACK" 0 'solid)
;; Draw red regions
(send dc #,(:: dc<%> set-brush) "RED" 'solid)
(send dc #,(:: dc<%> draw-path) left-logo-path)
(send dc #,(:: dc<%> draw-path) bottom-logo-path)
;; Draw blue region
(send dc #,(:: dc<%> set-brush) "BLUE" 'solid)
(send dc #,(:: dc<%> draw-path) right-logo-path))
;; Create a frame to display the logo on a light-purple background:
(define f (new frame% [label "Racket Logo"]))
(define c
(new canvas%
[parent f]
[paint-callback
(lambda (c dc)
(send dc #,(:: dc<%> set-background) (make-object color% 220 200 255))
(send dc #,(:: dc<%> clear))
(send dc #,(:: dc<%> set-smoothing) 'smoothed)
(send dc #,(:: dc<%> set-origin) 5 5)
(send dc #,(:: dc<%> set-scale) 0.5 0.5)
(paint-plt dc))]))
(send c #,(:: canvas<%> min-client-width) (/ 650 2))
(send c #,(:: canvas<%> min-client-height) (/ 650 2))
(send f show #t)
])
Drawing effects are not completely portable across platforms or across
types of DC. Drawing in smoothed mode tends to produce more reliable
and portable results than in unsmoothed mode, and drawing with paths
tends to produce more reliable results even in unsmoothed
mode. Drawing with a pen of width 0 or 1 in unsmoothed mode in an
unscaled DC produces relatively consistent results for all platforms,
but a pen width of 2 or drawing to a scaled DC looks significantly
different in unsmoothed mode on different platforms and destinations.

View File

@ -89,27 +89,24 @@ A pen of size @scheme[0] uses the minimum line size for the
@defconstructor*/make[(()
([color (is-a?/c color%)]
[width (real-in 0 255)]
[style (one-of/c 'transparent 'solid 'xor 'hilite
'dot 'long-dash 'short-dash 'dot-dash
'xor-dot 'xor-long-dash 'xor-short-dash
'xor-dot-dash)]
[cap-style (one-of/c 'round 'projecting 'butt)]
[join-style (one-of/c 'round 'bevel 'miter)])
([color-name string?]
[width (real-in 0 255)]
[style (one-of/c 'transparent 'solid 'xor 'dot 'hilite
'long-dash 'short-dash 'dot-dash
'xor-dot 'xor-long-dash 'xor-short-dash
'xor-dot-dash)]
[cap-style (one-of/c 'round 'projecting 'butt)]
[join-style (one-of/c 'round 'bevel 'miter)]))]{
@defconstructor[([color (or/c string? (is-a?/c color%)) "black"]
[width (real-in 0 255) 0]
[style (one-of/c 'transparent 'solid 'xor 'hilite
'dot 'long-dash 'short-dash 'dot-dash
'xor-dot 'xor-long-dash 'xor-short-dash
'xor-dot-dash)
'solid]
[cap (one-of/c 'round 'projecting 'butt)
'round]
[join (one-of/c 'round 'bevel 'miter)
'round]
[stipple (or/c #f (is-a?/c bitmap%))
#f])]{
When no argument are provided, the result is a solid black pen of
width @scheme[0]. Otherwise, the result is a pen with the given
color, width, style, cap style, and join style. For the case that the color is specified
color, width, style, cap style, join style, and stipple.
For the case that the color is specified
using a name, see @scheme[color-database<%>] for information about
color names; if the name is not known, the pen's color is black.

View File

@ -1,29 +0,0 @@
#lang scribble/doc
@(require "common.ss")
@title[#:style '(toc reveal)]{Reference}
@local-table-of-contents[]
@include-section["bitmap-class.scrbl"]
@include-section["bitmap-dc-class.scrbl"]
@include-section["brush-class.scrbl"]
@include-section["brush-list-class.scrbl"]
@include-section["color-class.scrbl"]
@include-section["color-database-intf.scrbl"]
@include-section["dc-intf.scrbl"]
@include-section["dc-path-class.scrbl"]
@include-section["font-class.scrbl"]
@include-section["font-list-class.scrbl"]
@include-section["font-name-directory-intf.scrbl"]
@include-section["gl-config-class.scrbl"]
@include-section["gl-context-intf.scrbl"]
@include-section["pdf-dc-class.scrbl"]
@include-section["pen-class.scrbl"]
@include-section["pen-list-class.scrbl"]
@include-section["point-class.scrbl"]
@include-section["post-script-dc-class.scrbl"]
@include-section["ps-setup-class.scrbl"]
@include-section["region-class.scrbl"]
@include-section["draw-funcs.scrbl"]
@include-section["draw-unit.scrbl"]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,642 @@
#lang scribble/doc
@(require scribble/manual
"guide-utils.ss"
scribble/eval
scribble/racket
(for-syntax racket/base)
(for-label racket/draw
racket/math
racket/gui))
@(define draw-eval (make-base-eval))
@interaction-eval[#:eval draw-eval (require racket/class
racket/draw)]
@interaction-eval[#:eval draw-eval (define (copy-bitmap bm0)
(let ([w (send bm0 get-width)]
[h (send bm0 get-height)])
(let ([bm (make-bitmap w h)])
(let ([dc (make-object bitmap-dc% bm)])
(send dc draw-bitmap bm0 0 0)
(send dc set-bitmap #f))
bm)))]
@interaction-eval[#:eval draw-eval (define (line-bitmap mode)
(let* ([bm (make-bitmap 30 4)]
[dc (make-object bitmap-dc% bm)])
(send dc set-smoothing mode)
(send dc draw-line 0 2 30 2)
(send dc set-bitmap #f)
bm))]
@interaction-eval[#:eval draw-eval (define (path-bitmap zee join brush?)
(let* ([bm (make-bitmap 40 40)]
[dc (new bitmap-dc% [bitmap bm])])
(send dc set-smoothing 'aligned)
(send dc set-pen (new pen% [width 5] [join join]))
(if brush?
(send dc set-brush blue-brush)
(send dc set-brush "white" 'transparent))
(send dc draw-path zee 5 5)
(send dc set-bitmap #f)
bm))]
@(define-syntax-rule (define-linked-method name interface)
(define-syntax name
(make-element-id-transformer
(lambda (stx)
#'(method interface name)))))
@(define-linked-method draw-line dc<%>)
@(define-linked-method draw-rectangle dc<%>)
@(define-linked-method set-pen dc<%>)
@(define-linked-method set-font dc<%>)
@(define-linked-method set-clipping-region dc<%>)
@(define-linked-method set-alpha dc<%>)
@(define-linked-method get-pen dc<%>)
@(define-linked-method set-brush dc<%>)
@(define-linked-method get-brush dc<%>)
@(define-linked-method set-smoothing dc<%>)
@(define-linked-method draw-path dc<%>)
@(define-linked-method draw-ellipse dc<%>)
@(define-linked-method draw-text dc<%>)
@(define-linked-method draw-bitmap dc<%>)
@(define-linked-method get-text-extent dc<%>)
@(define-linked-method set-text-foreground dc<%>)
@(define-linked-method draw-arc dc<%>)
@(define-linked-method erase dc<%>)
@(define-linked-method set-stipple brush%)
@(define-linked-method line-to dc-path%)
@(define-linked-method curve-to dc-path%)
@(define-linked-method move-to dc-path%)
@(define-linked-method append dc-path%)
@(define-linked-method arc dc-path%)
@(define-linked-method reverse dc-path%)
@(define-linked-method ellipse dc-path%)
@(define-linked-method translate dc<%>)
@(define-linked-method scale dc<%>)
@(define-linked-method rotate dc<%>)
@(define-linked-method set-path region%)
@title[#:tag "draw"]{Drawing}
The @racketmodname[racket/draw] library provides a drawing API that is
based on the PostScript drawing model. It supports line drawing, shape
filling, bitmap copying, alpha blending, and affine transformations
(i.e., scale, rotation, and translation).
@guideother{See @secref["classes"] for an introduction to classes and
interfaces in Racket.}
Drawing with @racketmodname[racket/draw] requires a @deftech{drawing context}
(@deftech{DC}), which is an instance of the @scheme[dc<%>]
interface. For example, the @racket[post-script-dc%] class implements
a @racket[dc<%>] for drawing to a PostScript file, while @racket[bitmap-dc%]
draws to a bitmap. When using the @racketmodname[racket/gui] library for GUIs,
the @method[canvas<%> get-dc] method of a
canvas returns a @scheme[dc<%>] instance for drawing into the canvas
window.
@; ------------------------------------------------------------
@section{Lines and Simple Shapes}
To draw into a bitmap, first create the bitmap with
@racket[make-bitmap], and then create a @racket[bitmap-dc%] that draws
into the new bitmap:
@racketblock+eval[
#:eval draw-eval
(define target (make-bitmap 30 30)) (code:comment "A 30x30 bitmap")
(define dc (new bitmap-dc% [bitmap target]))
]
Then, use methods like @method[dc<%> draw-line] on the @tech{DC} to draw
into the bitmap. For example, the sequence
@racketblock+eval[
#:eval draw-eval
(send dc draw-rectangle
0 10 (code:comment @#,t{Top-left at (0, 10), 10 pixels down from top-left})
30 10) (code:comment @#,t{30 pixels wide and 10 pixels high})
(send dc draw-line
0 0 (code:comment @#,t{Start at (0, 0), the top-left corner})
30 30) (code:comment @#,t{and draw to (30, 30), the bottom-right corner})
(send dc draw-line
0 30 (code:comment @#,t{Start at (0, 30), the bottom-left corner})
30 0) (code:comment @#,t{and draw to (30, 0), the top-right corner})
]
draws an ``X'' on top of a smaller rectangle into the bitmap @racket[target]. If
you save the bitmap to a file with @racket[(send target #,(:: bitmap% save-file)
"box.png" 'png)], the @filepath{box.png} contains the image
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap target)]}
in PNG format.
A line-drawing drawing operation like @racket[draw-line] uses the
@tech{DC}'s current @defterm{pen} to draw the line. A pen has a color,
line width, and style, where pen styles include @racket['solid],
@racket['long-dash], and @racket['transparent]. Enclosed-shape
operations like @racket[draw-rectangle] use both the current pen and
the @tech{DC}'s current @deftech{brush}. A brush has a color and style,
where brush styles include @racket['solid], @racket['cross-hatch], and
@racket['transparent].
@margin-note{In DrRacket, instead of saving @racket[target] to a file
viewing the image from the file, you can use @racket[(require
racket/gui)] and @racket[(make-object image-snip% target)] to view the
bitmap in the DrRacket interactions window.}
For example, set the brush and pen before the drawing operations to
draw a thick, red ``X'' on a green rectangle with a thin, blue border:
@racketblock+eval[
#:eval draw-eval
(send dc set-brush "green" 'solid)
(send dc set-pen "blue" 1 'solid)
(send dc draw-rectangle 0 10 30 10)
(send dc set-pen "red" 3 'solid)
(send dc draw-line 0 0 30 30)
(send dc draw-line 0 30 30 0)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap target)]}
To draw a filled shape without an outline, set the pen to
@racket['transparent] mode (with any color and line width). For
example,
@racketblock+eval[
#:eval draw-eval
(send dc set-pen "white" 1 'transparent)
(send dc set-brush "black" 'solid)
(send dc draw-ellipse 5 5 20 20)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap target)]}
By default, a @racket[bitmap-dc%] draws solid pixels without smoothing
the boundaries of shapes. To enable smoothing, set the
smoothing mode to either @racket['smoothed] or @racket['aligned]:
@racketblock+eval[
#:eval draw-eval
(send dc set-smoothing 'aligned)
(send dc set-brush "black" 'solid)
(send dc draw-ellipse 4 4 22 22) (code:comment @#,t{a little bigger})
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap target)]}
The difference between @racket['aligned] mode and @racket['smoothed]
mode is related to the relatively coarse granularity of pixels in a
bitmap. Conceptually, drawing coordinates correspond to the lines
between pixels, and the pen is centered on the line. In
@racket['smoothed] mode, drawing on a line causes the pen to draw at
half strength on either side of the line, which produces the following
result for a 1-pixel black pen:
@centered[@interaction-eval-show[#:eval draw-eval (line-bitmap 'smoothed)]]
but @racket['aligned] mode shifts drawing coordinates to make the pen
fall on whole pixels, so a 1-pixel black pen draws a single line of
pixels:
@centered[@interaction-eval-show[#:eval draw-eval (line-bitmap 'aligned)]]
@; ------------------------------------------------------------
@section{Pen, Brush, and Color Objects}
The @racket[set-pen] and @racket[set-brush] methods of a @tech{DC}
accept @scheme[pen%] and @scheme[brush%] objects, which group
together pen and brush settings.
@schemeblock+eval[
#:eval draw-eval
(require racket/math)
(define no-pen (new pen% [style 'transparent]))
(define no-brush (new brush% [style 'transparent]))
(define blue-brush (new brush% [color "blue"]))
(define yellow-brush (new brush% [color "yellow"]))
(define red-pen (new pen% [color "red"] [width 2]))
(define (draw-face dc)
(send dc set-smoothing 'aligned)
(send dc set-pen no-pen)
(send dc set-brush blue-brush)
(send dc draw-ellipse 25 25 100 100)
(send dc set-brush yellow-brush)
(send dc draw-rectangle 50 50 10 10)
(send dc draw-rectangle 90 50 10 10)
(send dc set-brush no-brush)
(send dc set-pen red-pen)
(send dc draw-arc 37 37 75 75 (* 5/4 pi) (* 7/4 pi)))
(define target (make-bitmap 150 150))
(define dc (new bitmap-dc% [bitmap target]))
(draw-face dc)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap target)]}
The @racket[get-pen] and @racket[get-brush] methods return a
@tech{DC}'s current pen and brush, so they can be restored after
changing them temporarily for drawing.
Besides grouping settings, a @racket[pen%] or @racket[brush%] object
includes extra settings that are not available by using
@racket[set-pen] or @racket[set-brush] directly. For example, a pen or
brush can have a @deftech{stipple}, which is a bitmap that is used
instead of a solid color when drawing. For example, if
@filepath{water.png} has the image
@centered{@image["water.png"]}
then it can be loaded with @racket[read-bitmap] and installed as the
stipple for @racket[blue-brush]:
@schemeblock+eval[
#:eval draw-eval
(send blue-brush set-stipple (read-bitmap "water.png"))
(send dc erase)
(draw-face dc)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap target)]}
Along similar lines, a @racket[color%] object lets you specify a color
through its red, green, and blue components instead of a built-in
color name. Due to the way that @racket[color%] initialization is
overloaded, use @racket[make-object%] instead of @racket[new] to
instantiate @racket[color%]:
@schemeblock+eval[
#:eval draw-eval
(define red-pen
(new pen% [color (make-object color% 200 100 150)] [width 2]))
(send dc erase)
(draw-face dc)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap target)]}
@; ------------------------------------------------------------
@section{Transformations}
Any coordinates or lengths supplied to drawing commends are
transformed by a @tech{DC}'s current transformation matrix. The
transformation matrix can scale an image, draw it at an offset, or
rotate all drawing. The transformation can be set directly, or the
current transformation can be transformed further with methods like
@racket[scale], @racket[translate], or @racket[rotate]:
@schemeblock+eval[
#:eval draw-eval
(send dc erase)
(send dc scale 0.5 0.5)
(draw-face dc)
(send dc rotate (/ pi 2))
(send dc translate 0 150)
(draw-face dc)
(send dc translate 0 -150)
(send dc rotate (/ pi 2))
(send dc translate 150 150)
(draw-face dc)
(send dc translate -150 -150)
(send dc rotate (/ pi 2))
(send dc translate 150 0)
(draw-face dc)
]
Use the @method[dc<%> get-transformation] method to get a @tech{DC}'s
current transformation, and restore a saved transformation (or any
affine transformation) using @method[dc<%> set-transformation].
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap target)]}
@; ------------------------------------------------------------
@section{Drawing Paths}
Drawing functions like @racket[draw-line] and @racket[draw-rectangle]
are actually convenience functions for the more general
@racket[draw-path] operation. The @racket[draw-path] operation takes
a @deftech{path}, which describes a set of line segments and curves
to draw with the pen and---in the case of closed set of lines and
curves---fill with the current brush.
An instance of @racket[dc-path%] holds a path. Conceptually, a path
has a current pen position that is manipulated by methods like
@racket[move-to], @racket[line-to], and @racket[curve-to]. The
@racket[move-to] method starts a sub-path, and @racket[line-to] and
@racket[curve-to] extend it. The @racket[close] method moves the pen
from its current position in a straight line to its starting
position, completing the sub-path and forming a closed path that can
be filled with the brush. A @racket[dc-path%] object can have
multiple closed sub-paths and one final open path, where the open
path is drawn only with the pen.
For example,
@racketblock+eval[
#:eval draw-eval
(define zee (new dc-path%))
(send zee move-to 0 0)
(send zee line-to 30 0)
(send zee line-to 0 30)
(send zee line-to 30 30)
]
creates an open path. Drawing this path with a black pen of width 5
and a transparent brush produces
@centered{@interaction-eval-show[#:eval draw-eval (path-bitmap zee 'round #f)]}
Drawing a single path with three line segments is not the same as
drawing three separate lines. When multiple line segments are drawn at
once, the corner frm one line to the next is shaped according to the
pen's join style. The image above uses the default @racket['round]
join style. With @racket['miter], line lines are joined with sharp
corners:
@centered{@interaction-eval-show[#:eval draw-eval (path-bitmap zee 'miter #f)]}
If the sub-path in @racket[zee] is closed with @racket[close], then
all of the corners are joined, including the corner at the initial
point:
@racketblock+eval[
#:eval draw-eval
(send zee close)
]
@centered{@interaction-eval-show[#:eval draw-eval (path-bitmap zee 'miter #f)]}
Using @racket[blue-brush] instead of a transparent brush causes the
interior of the path to be filled:
@centered{@interaction-eval-show[#:eval draw-eval (path-bitmap zee 'miter #t)]}
When a sub-path is not closed, it is implicitly closed for brush
filling, but left open for pen drawing. When both a pen and brush are
available (i.e., not transparent), then the brush is used first, so
that the pen draws on top of the brush.
At this point we can't resist showing an extended example using
@racket[dc-path%] to draw the Racket logo:
@racketblock+eval[
#:eval draw-eval
(define red-brush (new brush% [stipple (read-bitmap "fire.png")]))
(define left-lambda-path
(let ([p (new dc-path%)])
(send p move-to 153 44)
(send p line-to 161.5 60)
(send p curve-to 202.5 49 230 42 245 61)
(send p curve-to 280.06 105.41 287.5 141 296.5 186)
(send p curve-to 301.12 209.08 299.11 223.38 293.96 244)
(send p curve-to 281.34 294.54 259.18 331.61 233.5 375)
(send p curve-to 198.21 434.63 164.68 505.6 125.5 564)
(send p line-to 135 572)
p))
(define left-logo-path
(let ([p (new dc-path%)])
(send p append left-lambda-path)
(send p arc 0 0 630 630 (* 235/360 2 pi) (* 121/360 2 pi) #f)
p))
(define bottom-lambda-path
(let ([p (new dc-path%)])
(send p move-to 135 572)
(send p line-to 188.5 564)
(send p curve-to 208.5 517 230.91 465.21 251 420)
(send p curve-to 267 384 278.5 348 296.5 312)
(send p curve-to 301.01 302.98 318 258 329 274)
(send p curve-to 338.89 288.39 351 314 358 332)
(send p curve-to 377.28 381.58 395.57 429.61 414 477)
(send p curve-to 428 513 436.5 540 449.5 573)
(send p line-to 465 580)
(send p line-to 529 545)
p))
(define bottom-logo-path
(let ([p (new dc-path%)])
(send p append bottom-lambda-path)
(send p arc 0 0 630 630 (* 314/360 2 pi) (* 235/360 2 pi) #f)
p))
(define right-lambda-path
(let ([p (new dc-path%)])
(send p move-to 153 44)
(send p curve-to 192.21 30.69 233.21 14.23 275 20)
(send p curve-to 328.6 27.4 350.23 103.08 364 151)
(send p curve-to 378.75 202.32 400.5 244 418 294)
(send p curve-to 446.56 375.6 494.5 456 530.5 537)
(send p line-to 529 545)
p))
(define right-logo-path
(let ([p (new dc-path%)])
(send p append right-lambda-path)
(send p arc 0 0 630 630 (* 314/360 2 pi) (* 121/360 2 pi) #t)
p))
(define lambda-path
(let ([p (new dc-path%)])
(send p append left-lambda-path)
(send p append bottom-lambda-path)
(let ([t (new dc-path%)])
(send t append right-lambda-path)
(send t reverse)
(send p append t))
(send p close)
p))
(define (paint-racket dc)
(send dc set-pen "black" 0 'transparent)
(send dc set-brush "white" 'solid)
(send dc draw-path lambda-path)
(send dc set-pen "black" 4 'solid)
(send dc set-brush red-brush)
(send dc draw-path left-logo-path)
(send dc draw-path bottom-logo-path)
(send dc set-brush blue-brush)
(send dc draw-path right-logo-path))
(define racket-logo (make-bitmap 170 170))
(define dc (new bitmap-dc% [bitmap racket-logo]))
(send dc set-smoothing 'smoothed)
(send dc translate 5 5)
(send dc scale 0.25 0.25)
(paint-racket dc)
]
@centered{@interaction-eval-show[#:eval draw-eval racket-logo]}
In addition to the core @racket[move-to], @racket[line-to],
@racket[curve-to], and @racket[close] methods, a @racket[dc-path%]
includes many convenience methods, such as @racket[ellipse] for adding
a closed elliptical sub-path to the path.
@; ------------------------------------------------------------
@section{Text}
Draw text using the @racket[draw-text] method, which takes a string to
draw and a location for the top-left of the drawn text:
@racketblock+eval[
#:eval draw-eval
(define text-target (make-bitmap 100 30))
(define dc (new bitmap-dc% [bitmap text-target]))
(send dc set-brush "white" 'transparent)
(send dc draw-rectangle 0 0 100 30)
(send dc draw-text "Hello, World!" 5 1)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap text-target)]}
The font used to draw text is determined by the @tech{DC}'s current
font. A font is described by a @racket[font%] object and installed
with @racket[set-font]. The color of drawn text which is separate from
either the pen or brush, can be set using
@racket[set-text-foreground].
@racketblock+eval[
#:eval draw-eval
(send dc erase)
(send dc set-font (make-object font% 14 'roman 'normal 'bold))
(send dc set-text-foreground "blue")
(send dc draw-rectangle 0 0 100 30)
(send dc draw-text "Hello, World!" 5 1)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap text-target)]}
To compute the size that will be used by drawn text, use
@racket[get-text-extent], which returns four values: the total width,
total height, difference between the baseline and total height, and
extra space (if any) above the text in a line. For example, the result
of @racket[get-text-extent] can be used to position text within the
center of a box:
@racketblock+eval[
#:eval draw-eval
(send dc erase)
(send dc draw-rectangle 0 0 100 30)
(define-values (w h d a) (send dc get-text-extent "Hello, World!"))
(send dc draw-text "Hello, World!" (/ (- 100 w) 2) (/ (- 30 h) 2))
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap text-target)]}
@; ------------------------------------------------------------
@section{Alpha Channels and Alpha Blending}
When you create or @racket[erase] a bitmap, the content is
nothing. ``Nothing'' isn't the same as white; it's the absence of
drawing. For example, if you take @racket[text-target] from the
previous section and copy it onto another @tech{DC} using
@racket[draw-bitmap], then the black rectangle and blue text is
transferred, and the background is left alone:
@racketblock+eval[
#:eval draw-eval
(define new-target (make-bitmap 100 30))
(define dc (new bitmap-dc% [bitmap new-target]))
(send dc set-pen "black" 1 'transparent)
(send dc set-brush "pink" 'solid)
(send dc draw-rectangle 0 0 100 30)
(send dc draw-bitmap text-target 0 0)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap new-target)]}
The information about which pixels of a bitmap are drawn (as opposed
to ``nothing'') is the bitmap's @deftech{alpha channel}. Not all
@tech{DC}s keep an alpha channel, but bitmaps created with
@racket[make-bitmap] keep an alpha channel by default. Bitmaps loaded
with @racket[read-bitmap] preserve transparency in the image file
through the bitmap's alpha channel.
An alpha channel isn't all or nothing. When the edges text is
anti-aliased by @racket[draw-text], for example, the pixels are
partially transparent. When the pixels are transferred to another
@tech{DC}, the partially transparent pixel is blended with the target
pixel in a process called @deftech{alpha blending}. Furthermore, a
@tech{DC} has an alpha value that is applied to all drawing
operations; an alpha value of @racket[1.0] corresponds to solid
drawing, an alpha value of @racket[0.0] makes the drawing have no
effect, and values in between make the drawing translucent.
For example, setting the @tech{DC}'s alpha to @racket[0.25] before
calling @racket[draw-bitmap] causes the blue and black of the ``Hello,
World!'' bitmap to be quarter strength as it is blended with the
destination image:
@racketblock+eval[
#:eval draw-eval
(send dc erase)
(send dc draw-rectangle 0 0 100 30)
(send dc set-alpha 0.25)
(send dc draw-bitmap text-target 0 0)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap new-target)]}
@; ------------------------------------------------------------
@section{Clipping}
In addition to tempering the opacity of drawing operations, a
@tech{DC} has a @deftech{clipping region} that constrains all drawing to
inside the region. In the simplest case, a clipping region corresponds
to a closed path, but it can also be the union, intersection,
subtraction, or exclusive-or of two paths.
For example, a clipping region could be set to three circles to clip
the drawing of a rectangle (with the 0.25 alpha still in effect):
@racketblock+eval[
#:eval draw-eval
(define r (new region%))
(let ([p (new dc-path%)])
(send p ellipse 00 0 35 30)
(send p ellipse 35 0 30 30)
(send p ellipse 65 0 35 30)
(send r set-path p))
(send dc set-clipping-region r)
(send dc set-brush "green" 'solid)
(send dc draw-rectangle 0 0 100 30)
]
@centered{@interaction-eval-show[#:eval draw-eval (copy-bitmap new-target)]}
The clipping region can be viewed as a convenient alternative to path
filling or drawing with stipples. Conversely, stippled drawing can be
viewed as a convenience alternative to clipping repeated calls of
@racket[draw-bitmap].
@; ------------------------------------------------------------
@section{Portability}
Drawing effects are not completely portable across platforms or across
types of DC. For example. drawing to a bitmap produced by
@racket[make-bitmap] may produce slightly different results than
drawing to one produced by @racketmodname[racket/gui]'s
@racket[make-screen-bitmap], but drawing to a bitmap from
@racket[make-screen-bitmap] should be the same as drawing to an
onscreen @racket[canvas%]. Fonts and text, especially, can vary across
platforms and types of @tech{DC}, but so can the precise set of pixels
touched by drawing a line.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,53 @@
#lang scribble/doc
@(require scribble/manual
"guide-utils.ss")
@title[#:tag "graphics" #:style 'toc]{Graphics and GUIs}
Racket provides many libraries for graphics and graphical user
interfaces (GUIs):
@itemlist[
@item{The @racketmodname[racket/draw] library provides basic drawing
tools, including @tech{drawing contexts} such as bitmaps and
PostScript files.
See @secref["draw"] for an overview.}
@item{The @racketmodname[racket/gui] library provides GUI widgets
such as windows, buttons, checkboxes, and text fields. The
library also includes a sophisticated and extensible text
editor.}
@item{The @racketmodname[slideshow/pict] library provides a more
functional abstraction layer over @racketmodname[racket/draw].
This layer is especially useful for creating slide
presentations with @seclink[#:doc '(lib
"scribblings/slideshow/slideshow.scrbl") "top"]{Slideshow}, but
it is also useful for creating images for @seclink[#:doc '(lib
"scribblings/scribble/scribble.scrbl") "top"]{Scribble}
documents or other drawing tasks. Pictures created with the
@racketmodname[slideshow/pict] library can be rendered to any
@tech{drawing context}.
See @other-doc['(lib "scribblings/slideshow/slideshow.scrbl")]
for more information.}
@item{The @racket[2htdp/image] library is similar to
@racketmodname[slideshow/pict]. It is more streamlined for
pedagogical use, but also slightly more specific to screen and
bitmap drawing.
See @racket[2htdp/image] for more information.}
@item{The @racketmodname[sgl] library provides OpenGL for 3-D
graphics. The context for rendering OpenGL can be a window or
bitmap created with @racketmodname[racket/gui].
See @other-doc['(lib "sgl/scribblings/sgl.scrbl")] for more
information.}
]
@include-section["draw.scrbl"]

View File

@ -52,6 +52,8 @@ precise details to @|Racket| and other reference manuals.
@include-section["languages.scrbl"]
@include-section["graphics.scrbl"]
@include-section["performance.scrbl"]
@include-section["running.scrbl"]

View File

@ -4,10 +4,6 @@
@title{More Libraries}
@other-manual['(lib "scribblings/gui/gui.scrbl")] describes the Racket
graphics toolbox, whose core is implemented by the @exec{gracket}
executable.
@other-manual['(lib "scribblings/foreign/foreign.scrbl")] describes
tools for using Racket to access libraries that are normally used by C
programs.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB