improve canvas-drawing docs

This commit is contained in:
Matthew Flatt 2011-01-06 07:43:14 -07:00
parent 71904f2ca6
commit 4f56618c6d
3 changed files with 81 additions and 34 deletions

View File

@ -450,6 +450,7 @@ or when the document has been ended already.
} }
@defmethod[(end-page) @defmethod[(end-page)
void?]{ void?]{
@ -458,18 +459,18 @@ Ends a single page, relevant only when drawing to a printer or
For printer or PostScript output, an exception is raised if For printer or PostScript output, an exception is raised if
@scheme[end-page] is called when a page is not currently started by @scheme[end-page] is called when a page is not currently started by
@method[dc<%> start-page]. @method[dc<%> start-page].}
}
@defmethod[(erase) @defmethod[(erase)
void?]{ void?]{
Erases the drawing region by filling it with white and, for a drawing For a drawing context that has an alpha channel, @method[dc<%> erase]
context that keeps an alpha channel, sets all alphas to zero. sets all alphas to zero. Similarly, for a transparent canvas,
@method[dc<%> erase] erases all drawing to allow the background window
} to show through. For other drawing contexts that have no alpha channel
or transparency, @method[dc<%> erase] fills the drawing context with
white.}
@defmethod[(flush) void?]{ @defmethod[(flush) void?]{

View File

@ -3,8 +3,9 @@
@defclass/title[canvas% object% (canvas<%>)]{ @defclass/title[canvas% object% (canvas<%>)]{
A @scheme[canvas%] object is a general-purpose window for drawing A @scheme[canvas%] object is a general-purpose window for drawing and
and handling events. handling events. See @racket[canvas<%>] for information about drawing
onto a canvas.
@defconstructor[([parent (or/c (is-a?/c frame%) (is-a?/c dialog%) @defconstructor[([parent (or/c (is-a?/c frame%) (is-a?/c dialog%)
@ -52,12 +53,15 @@ The @scheme[style] argument indicates one or more of the following styles:
@racket['no-autoclear]} @racket['no-autoclear]}
@item{@scheme['no-autoclear] --- prevents automatic erasing of the @item{@scheme['no-autoclear] --- prevents automatic erasing of the
canvas before calls to @method[canvas% on-paint]} canvas by the windowing system; see @racket[canvas<%>] for
information on canvas refresh}
@item{@scheme['transparent] --- the canvas is automatically ``erased'' @item{@scheme['transparent] --- the canvas is ``erased'' by the
before an update using it's parent window's background; see @racket[canvas<%>] windowing system by letting its parent show through; see
for information on the interaction of @racket['transparent] and offscreen buffering; @racket[canvas<%>] for information on window refresh and on the
the result is undefined if this flag is combined with @scheme['no-autoclear]} interaction of @racket['transparent] and offscreen buffering; the
result is undefined if this flag is combined with
@scheme['no-autoclear]}
@item{@scheme['no-focus] --- prevents the canvas from accepting the @item{@scheme['no-focus] --- prevents the canvas from accepting the
keyboard focus when the canvas is clicked, or when the keyboard focus when the canvas is clicked, or when the

View File

@ -10,34 +10,76 @@ The @scheme[canvas<%>] interface is implemented by two classes:
@itemize[ @itemize[
@item{@scheme[canvas%] --- a canvas for arbitrary drawing and @item{@scheme[canvas%] --- a canvas for arbitrary drawing and
event handling} event handling; and}
@item{@scheme[editor-canvas%] --- a canvas for displaying @item{@scheme[editor-canvas%] --- a canvas for displaying
@scheme[editor<%>] objects} @scheme[editor<%>] objects.}
] ]
To draw onto a canvas, get its device context (see To draw onto a canvas, get its device context via @method[canvas<%>
@method[canvas<%> get-dc]). get-dc]. There are two basic approaches to updating a canvas:
@itemlist[
@item{Drawing normally occurs during the canvas's @method[canvas<%>
on-paint] callback. The @racket[canvas%] class supports a
@racket[paint-callback] initialization argument to be called
from the default @method[canvas<%> on-paint] method.
A canvas's @method[canvas<%> on-paint] method is called
automatically as an event when the windowing system determines
that the canvas must be updated, such as when the canvas is
first shown or when it is resized. Use the @method[window<%>
refresh] method to explicitly trigger an @method[canvas<%>
on-paint] call from the windowing system. (Multiple refresh
requests before @method[canvas<%> on-paint] can be called are
coaleced into a single @method[canvas<%> on-paint] call.)
Before the windowing system calls @method[canvas<%> on-paint],
it may erase the canvas's background (see @method[dc<%>
erase]), depending on the style of the canvas (e.g., as
determined by the @racket[style] initialization argument for
@racket[canvas%]). Even when the canvas's style suppresses
explicit clearing of the canvas, a canvas may be erased by the
windowing system due to window-moving and -resizing
operations. For a transparent canvas, ``erased'' means that the
canvas's parent window shows through.}
@item{Drawing can also occur at any time outside an @method[canvas<%>
on-paint] call form the windowing system, including from
threads other than the @tech{handler thread} of the canvas's
eventspace. Drawing outside an @method[canvas<%> on-paint]
callback from the system is transient in the sense that
windowing activity can erase the canvas, but the drawing is
persistent as long as no windowing refresh is needed.
Calling an @method[canvas<%> on-paint] method directly is the
same as drawing outside an @method[canvas<%> on-paint] callback
from the windowing system.}
]
Drawing to a canvas's drawing context actually renders into an Drawing to a canvas's drawing context actually renders into an
offscreen buffer. The buffer is automatically flushed to the screen by offscreen buffer. The buffer is automatically flushed to the screen
a background thread, explicitly via the @method[canvas<%> flush] asynchronously, explicitly via the @method[canvas<%> flush] method, or
method, or explicitly via @racket[flush-display]---unless flushing explicitly via @racket[flush-display]---unless flushing has been
has been disabled for the canvas. The @method[canvas<%> disabled for the canvas. The @method[canvas<%> suspend-flush] method
suspend-flush] method suspends flushing for a canvas until a matching suspends flushing for a canvas until a matching @method[canvas<%>
@method[canvas<%> resume-flush] calls; calls to @method[canvas<%> resume-flush] calls; calls to @method[canvas<%> suspend-flush] and
suspend-flush] and @method[canvas<%> resume-flush] can be nested, in @method[canvas<%> resume-flush] can be nested, in which case flushing
which case flushing is suspended until the outermost @method[canvas<%> is suspended until the outermost @method[canvas<%> suspend-flush] is
suspend-flush] is balanced by a @method[canvas<%> resume-flush]. balanced by a @method[canvas<%> resume-flush]. An @method[canvas<%>
on-paint] call from the windowing system is implicitly wrapped with
@method[canvas<%> suspend-flush] and @method[canvas<%> resume-flush]
calls.
In the case of a transparent canvas (i.e., one that is created with In the case of a transparent canvas, line and text smoothing can
@racket['transparent] style), line and text smoothing can depend on depend on the window that serves as the canvas's background. For
the window that serves as the canvas's background. For example, example, smoothing may color pixels differently depending on whether
smoothing may color pixels differently depending on whether the target the target context is white or gray. Background-sensitive smoothing
context is white or gray. Background-sensitive smoothing is supported is supported only if a relatively small number of drawing commands are
only if a relatively small number of drawing commands are recorded in recorded in the canvas's offscreen buffer, however.
the canvas's offscreen buffer, however.
@defmethod*[([(accept-tab-focus) @defmethod*[([(accept-tab-focus)