MIT Scheme has a simple two-dimensional line-graphics interface that is suitable for many graphics applications. In particular it is often used for plotting data points from experiments. The interface is generic in that it can support different types of graphics devices in a uniform manner. At the present time only two types of graphics device are implemented.
Procedures are available for drawing points, lines, and text; defining the coordinate system; clipping graphics output; controlling some of the drawing characteristics; and controlling the output buffer (for devices that perform buffering). Additionally, devices may support custom operations, such as control of colors.
There are some constraints on the arguments to the procedures described
in this chapter. Any argument named graphics-device must be a
graphics device object that was returned from a call to
make-graphics-device
. Any argument that is a coordinate must be
either an exact integer or an inexact real.
#t
if the graphics system named by the
symbol graphics-device-type is implemented by the Scheme system.
Otherwise it returns #f
, in which case it is an error to attempt
to make a graphics device using graphics-device-type.
make-graphics-device
, as each device type typically has a unique
way of specifying the initial size, shape and other attributes.
graphics-type-available?
. Graphics-device-type may also be
#f
, in which case the graphics device type is chosen by the
system from what is available. This allows completely portable graphics
programs to be written provided no custom graphics operations are used.
When graphics-device-type is #f
no further arguments may be
given; each graphics device type will use some "sensible" defaults.
If more control is required then the program should use one of the two
procedures above to dispatch on the available types.
This procedure opens and initializes the device, which remains valid
until explicitly closed by the procedure graphics-close
.
Depending on the implementation of the graphics device, if this object
is reclaimed by the garbage collector, the graphics device may remain
open or it may be automatically closed. While a graphics device remains
open the resources associated with it are not released.
Each graphics device has two different coordinate systems associated with it: device coordinates and virtual coordinates. Device coordinates are generally defined by low-level characteristics of the device itself, and often cannot be changed. Most device coordinate systems are defined in terms of pixels, and usually the upper-left-hand corner is the origin of the coordinate system, with x coordinates increasing to the right and y coordinates increasing downwards.
In contrast, virtual coordinates are more flexible in the units employed, the position of the origin, and even the direction in which the coordinates increase. A virtual coordinate system is defined by assigning coordinates to the edges of a device. Because these edge coordinates are arbitrary real numbers, any Cartesian coordinate system can be defined.
All graphics procedures that use coordinates are defined on virtual coordinates. For example, to draw a line at a particular place on a device, the virtual coordinates for the endpoints of that line are given.
When a graphics device is initialized, its virtual coordinate system is
reset so that the left edge corresponds to an x-coordinate of -1
,
the right edge to x-coordinate 1
, the bottom edge to y-coordinate
-1
, and the top edge to y-coordinate 1
.
graphics-coordinate-limits
will return the new limits. This
operation has no effect on the device's displayed contents.
Note: This operation usually resets the clip rectangle, although it is not guaranteed to do so. If a clip rectangle is in effect when this procedure is called, it is necessary to redefine the clip rectangle afterwards.
The procedures in this section provide the basic drawing capabilities of Scheme's graphics system.
This is equivalent to
(lambda (device x y) (graphics-bind-drawing-mode device 0 (lambda () (graphics-draw-point device x y))))
The following two procedures provide an alternate mechanism for drawing lines, which is more akin to using a plotter. They maintain a cursor, which can be positioned to a particular point and then dragged to another point, producing a line. Sequences of connected line segments can be drawn by dragging the cursor from point to point.
Many graphics operations have an unspecified effect on the cursor. The following exceptions are guaranteed to leave the cursor unaffected:
graphics-device-coordinate-limits graphics-coordinate-limits graphics-enable-buffering graphics-disable-buffering graphics-flush graphics-bind-drawing-mode graphics-set-drawing-mode graphics-bind-line-style graphics-set-line-style
The initial state of the cursor is unspecified.
Two characteristics of graphics output are so useful that they are supported uniformly by all graphics devices: drawing mode and line style. A third characteristic, color, is equally useful (if not more so), but implementation restrictions prohibit a uniform interface.
The drawing mode, an exact integer in the range 0
to
15
inclusive, determines how the figure being drawn is combined
with the background over which it is drawn to generate the final result.
Initially the drawing mode is set to "source", so that the new output
overwrites whatever appears in that place. Useful alternative drawing
modes can, for example, erase what was already there, or invert it.
Altogether 16 boolean operations are available for combining the source (what is being drawn) and the destination (what is being drawn over). The source and destination are combined by the device on a pixel-by-pixel basis as follows:
Mode Meaning ---- ------- 0 ZERO [erase; use background color] 1 source AND destination 2 source AND (NOT destination) 3 source 4 (NOT source) AND destination 5 destination 6 source XOR destination 7 source OR destination 8 NOT (source OR destination) 9 NOT (source XOR destination) 10 NOT destination 11 source OR (NOT destination) 12 NOT source 13 (NOT source) OR destination 14 (NOT source) OR (NOT destination) 15 ONE [use foreground color]
The line style, an exact integer in the range 0
to 7
inclusive, determines which parts of a line are drawn in the foreground
color, and which in the background color. The default line style,
"solid", draws the entire line in the foreground color.
Alternatively, the "dash" style alternates between foreground and
background colors to generate a dashed line. This capability is useful
for plotting several things on the same graph.
Here is a table showing the name and approximate pattern of the different styles. A `1' in the pattern represents a foreground pixel, while a `-' represents a background pixel. Note that the precise output for each style will vary from device to device. The only style that is guaranteed to be the same for every device is "solid".
Style Name Pattern ----- ------- ------- 0 solid 1111111111111111 1 dash 11111111-------- 2 dot 1-1-1-1-1-1-1-1- 3 dash dot 1111111111111-1- 4 dash dot dot 11111111111-1-1- 5 long dash 11111111111----- 6 center dash 111111111111-11- 7 center dash dash 111111111-11-11-
To improve performance of graphics output, most graphics devices provide some form of buffering. By default, Scheme's graphics procedures flush this buffer after every drawing operation. The procedures in this section allow the user to control the flushing of the output buffer.
Note: graphics-disable-buffering
flushes the output buffer if
necessary.
Scheme provides a rudimentary mechanism for restricting graphics output to a given rectangular subsection of a graphics device. By default, graphics output that is drawn anywhere within the device's virtual coordinate limits will appear on the device. When a clip rectangle is specified, however, output that would have appeared outside the clip rectangle is not drawn.
Note that changing the virtual coordinate limits for a device will usually reset the clip rectangle for that device, as will any operation that affects the size of the device (such as a window resizing operation). However, programs should not depend on this.
In addition to the standard operations, a graphics device may support
custom operations. For example, most devices have custom
operations to control color. graphics-operation
is used to
invoke custom operations.
graphics-
prefix from the corresponding procedure.
For example, the following are equivalent:
(graphics-draw-point device x y) (graphics-operation device 'draw-point x y)
For information on the custom operations for a particular device, see the documentation for its type.
Some graphics device types support images, which are rectangular pieces of picture that may be drawn into a graphics device. Images are often called something else in the host graphics system, such as bitmaps or pixmaps. The operations supported vary between devices, so look under the different device types to see what operations are available. All devices that support images support the following operations.
create-image
graphics operation,
specifying the width and height of the image in device
coordinates (pixels).
(graphics-operation device 'create-image 200 100)
The initial contents of an image are unspecified.
create-image
is a graphics operation rather than a procedure
because the kind of image returned depends on the kind of graphics
device used and the options specified in its creation. The image may be
used freely with other graphics devices created with the same
attributes, but the effects of using an image with a graphics device
with different attributes (for example, different colors) is undefined.
Under X, the image is display dependent.
#t
if object is an image, otherwise returns
#f
.
create-image
to fail because it is
unable to allocate enough memory.
(* (image/height
image) (image/width image))
bytes in bytes.
MIT Scheme supports graphics on Microsoft Windows 3.1 and Microsoft Windows NT 3.1. In addition to the usual operations, there are operations to control the size, position and colors of a graphics window. Win32 devices support images, which are implemented as device independent bitmaps (DIBs).
The Win32 graphics device type is implemented as a top level window.
graphics-enable-buffering
is implemented and gives a 2x to 4x
speedup on many graphics operations. As a convenience, when buffering
is enabled clicking on the graphics window's title bar effects a
graphics-flush
operation. The user has the benefit of the
increased performance and the ability to view the progress in drawing at
the click of a mouse button.
Win32 graphics devices are created by specifying the symbol win32
as the graphics-device-type argument to
make-graphics-device
. The Win32 graphics device type is
implemented as a top-level window and supports color drawing in addition
to the standard Scheme graphics operations.
Graphics devices are opened as follows:
(make-graphics-device 'win32 #!optional width height palette)
where width and height specify the size, in pixels, of the drawing area in the graphics window (i.e. excluding the frame). Palette determines the colors available for drawing in the window.
When a color is specified for drawing, the nearest color available in the palette is used. Permitted values for palette are
'grayscale
'grayscale-128
'standard
#f
or 'system
If palette is not specified then the standard
palette is
used.
Custom operations are invoked using the procedure
graphics-operation
. For example,
(graphics-operation device 'set-foreground-color "blue")
set-background-color
and
set-foreground-color
change the colors to be used when drawing,
but have no effect on anything drawn prior to their invocation. Because
changing the background color affects the entire window, we recommend
calling graphics-clear
on the window's device afterwards.
The foreground color affects the drawing of text, points, lines, ellipses and filled polygons.
Colors are specified in one of three ways:
"red"
, "blue"
, "black"
.
More names can be registered with the define-color
operation.
#(0 0 0)
is black, (0 0
128)
is dark blue and #(255 255 255)
is white.
If the color is not available in the graphics device then the nearest available color is used instead.
define-color
. This returns
the color in its most efficient form for operations
set-foreground-color
or set-background-color
.
(graphics-operation device 'fill-polygon #(0 0 0 1 1 0))
draws a solid triangular region between the points (0, 0), (0, 1) and (1, 0).
".BMP"
extension is added. If a clip rectangle is in
effect when this procedure is called, it is necessary to redefine the
clip rectangle afterwards.
".BMP"
extension is added. The saved bitmap may be incorporated into documents
or printed.
"Scheme Graphics"
at creation.
MIT Scheme supports graphics under the OS/2 Presentation Manager in OS/2 version 2.1 and later. The OS/2 graphics device type is implemented as a top level window. In addition to the usual operations, there are operations to control the size, position, and colors of a graphics window. OS/2 graphics devices support images, which are implemented as memory presentation spaces.
The custom graphics operations defined in this section are invoked using
the procedure graphics-operation
. For example,
(graphics-operation device 'set-foreground-color "blue")
OS/2 graphics devices are created by specifying the symbol os/2
as the graphics-device-type argument to
make-graphics-device
. The OS/2 graphics device type is
implemented as a top-level window and supports color drawing in addition
to the standard Scheme graphics operations.
Graphics devices are opened as follows:
(make-graphics-device 'os/2 #!optional width height)
where width and height specify the size, in pixels, of the drawing area in the graphics window (i.e. excluding the frame).
These operations control the colors used when drawing on an OS/2 graphics device.
#t
if the display supports color.
set-background-color
and
set-foreground-color
change the colors to be used when drawing,
but have no effect on anything drawn prior to their invocation. Because
changing the background color affects the entire window, we recommend
calling graphics-clear
on the window's device afterwards.
The foreground color affects the drawing of text, points, and lines. Colors are specified in one of these ways:
0
and #xffffff
inclusive
"red"
, "blue"
, "black"
. More names
can be registered with the define-color
operation.
0
and #xff
inclusive which specify the intensity of the red, green and blue
components of the color. Thus (0 0 0)
is black, (0 0 128)
is dark blue and (255 255 255)
is white.
If the color is not available in the graphics device then the nearest available color is used instead.
Color names defined by this interface may also be used when setting the colors of the Scheme console window, or the colors of Edwin editor windows.
define-color
. This
returns the color in its most efficient form for operations
set-foreground-color
or set-background-color
.
These operations control the window that contains the OS/2 graphics device. They provide facilities to change the window's size and position; to raise and lower the window relative to other windows on the desktop; to hide or minimize the window, and to restore it from the hidden or minimized state; to activate or deactivate the window (that is, control the keyboard focus); and to control the text that appears in the window's title bar.
The frame size is useful in conjunction with the window position and the desktop size to determine relative placement of the window or to guarantee that the entire window is visible on the desktop.
These operations allow you to read some of the events that are generated by the Presentation Manager and put in the message queue of a graphics-device window.
Note that this operation only works when button events are selected (which is the default).
read-user-event
operation. The mask is specified by setting the bits corresponding to
the event types that you are interested in, as follows:
Number Mask Description ------ ----- ----------- 0 #x01 Button press/release 1 #x02 Close (a command to close the window) 2 #x04 Focus change 3 #x08 Key press/release 4 #x10 Paint 5 #x20 Size change 6 #x40 Visibility change
Note that this operation does not affect any events that are already in the user-event queue. Changing the mask only affects what events will be added to the queue in the future.
An event is a vector whose first element is the event-type number, whose second element is the graphics device that the event refers to, and whose remaining elements provide information about the event. Here is a table of the possible event types and their vector layout:
#(0 device number type x y flags)
0
is usually the left mouse button, 1
is usually
the right button, etc. Type specifies what occurred: 0
means the button was pressed, 1
means the button was released,
2
means the button was clicked, and 3
means the button was
double clicked. X and y are the position of the mouse
pointer at the time of the event, in units of pels (pixels) measured
from the lower left corner of the client area of the associated window.
Finally, flags specifies what shift keys were pressed at the time
of the button event; it is a mask word created by combining zero or more
of the following flags: #x08
means the shift key was pressed,
#x10
means the control key was pressed, and #x20
means the
alt key was pressed.
#(1 device)
#(2 device gained?)
#t
, the keyboard focus is
being gained, and if gained? is #f
, it is being lost.
#(3 device code flags repeat)
#(4 device xl xh yl yh)
#(5 device width height)
#(6 device shown?)
#f
, the window is hidden,
and if it is #t
, the window is shown.
These operations allow you to: change the font used for drawing text in a graphics-device window; take a snapshot of a graphics-device window and return it as an image object; and draw multiple lines efficiently.
"10.Courier"
. You may specify any fixed-pitch font
family, in any point size which is supported for that font family. This
includes both image fonts and outline fonts.
graphics-draw-line
but much faster. The arguments xv
and yv are vectors of coordinates; these vectors must be the same
length, and the length must a multiple of two. The contents of the
vectors are alternating start/end pairs. For example, the following are
equivalent:
(graphics-draw-line device xs ys xe ye) (graphics-operation device 'draw-lines (vector xs xe) (vector ys ye))
MIT Scheme supports graphics in the X window system (version 11).
Arbitrary numbers of displays may be opened, and arbitrary numbers of
graphics windows may be created for each display. A variety of
operations is available to manipulate various aspects of the windows, to
control their size, position, colors, and mapping. The X graphics
device type supports images, which are implemented as Xlib XImage
objects. X display, window, and image objects are automatically closed
if they are reclaimed by the garbage collector.
A graphics device for X windows is created by passing the symbol
x
as the graphics device type name to
make-graphics-device
:
(make-graphics-device 'x #!optional display geometry suppress-map?)
where display is either a display object, #f
, or a string;
geometry is either #f
or a string; and suppress-map?
is a boolean or a vector (see below). A new window is created on the
appropriate display, and a graphics device representing that window is
returned.
Display specifies which X display the window is to be opened on;
if it is #f
or a string, it is passed as an argument to
x-open-display
, and the value returned by that procedure is used
in place of the original argument. Geometry is an X geometry
string, or #f
which means to use the default geometry (which is
specified as a resource).
Suppress-map?, if given, may take two forms. First, it may be a
boolean: if #f
(the default), the window is automatically mapped
after it is created; otherwise, #t
means to suppress this
automatic mapping. The second form is a vector of three elements. The
first element is a boolean with the same meaning as the boolean form of
suppress-map?. The second element is a string, which specifies an
alternative resource name to be used for looking up the window's
resources. The third element is also a string, which specifies a class
name for looking up the window's resources. The default value for
suppress-map? is #f
.
The default resource and class names are "schemeGraphics"
and
"SchemeGraphics"
respectively.
The window is initialized using the resource and class names specified by suppress-map?, and is sensitive to the following resource properties:
Property Class Default -------- ----- ------- geometry Geometry 512x384+0+0 font Font fixed borderWidth BorderWidth 2 internalBorder BorderWidth [border width] background Background white foreground Foreground black borderColor BorderColor [foreground color] cursorColor Foreground [foreground color] pointerColor Foreground [foreground color]
The window is created with a backing_store
attribute of
Always
. The window's name and icon name are initialized to
"scheme-graphics"
.
#f
is returned. Display-name is normally a string, which is an X
display name in the usual form; however, #f
is also allowed,
meaning to use the value of the unix environment variable
DISPLAY
.
x-close-display
on all open displays.
#f
, while width and height must be either exact
non-negative integers or #f
. Usually either x and y
are both specified or both #f
; similarly for width and
height. If only one of the elements of such a pair is specified,
it is ignored.
Examples:
(x-geometry-string #f #f 100 200) => "100x200" (x-geometry-string 2 -3 100 200) => "100x200+2-3" (x-geometry-string 2 -3 #f #f) => "+2-3"
Note that the x and y arguments cannot distinguish between
+0
and -0
, even though these have different meanings in X.
If either of those arguments is 0
, it means +0
in X
terminology. If you need to distinguish these two cases you must create
your own geometry string using Scheme's string and number primitives.
Custom operations are invoked using the procedure
graphics-operation
. For example,
(graphics-operation device 'set-foreground-color "blue")
set-border-color
and set-mouse-color
immediately change the border and mouse-cursor colors.
set-background-color
and set-foreground-color
change the
colors to be used when drawing, but have no effect on anything drawn
prior to their invocation. Because changing the background color
affects the entire window, we recommend calling graphics-clear
on
the window's device afterwards. Color names include both mnemonic
names, like "red"
, and intensity names specified in the
"#rrggbb"
notation.
graphics-clear
on the window's device after
doing so.
XMapWindow
and
XWithdrawWindow
.
XResizeWindow
.
This operation resets the virtual coordinate system and the clip rectangle.
XMoveWindow
. Note that the coordinates x and
y do not take the external border into account, and therefore will
not position the window as you might like. The only reliable way to
position a window is to ask a window manager to do it for you.
XGetDefault
. Resource and property must be strings.
The operation returns the character string corresponding to the
association of resource and property; if no such association
exists, #f
is returned.
#f
is returned.
font-structure
. A
more complete description of these components appears in documentation
of the XLoadQueryFont
Xlib call. start-index
is the index
of the first character available in the font. The min-bounds
and
max-bounds
components are structures of type
x-character-bounds
, and the character-bounds
component is
a vector of the same type.
x-character-bounds
. A more complete description of them appears
in documentation of the XLoadQueryFont
Xlib call.
On Hewlett-Packard computers under the HP-UX operating system, Scheme supports graphics through the Starbase graphics library. Note that the default distribution of Scheme for HP computers does not include support for Starbase -- you must rebuild the microcode to get this support.
(make-graphics-device 'starbase device-name driver-name)
where device-name and driver-name are strings that are used
as the device and driver arguments to the Starbase gopen
call.
The device is opened with kind OUTDEV
and mode 0
. The
device is initialized to have a mapping mode of DISTORT
, and a
line color index of 1
.
#f
, this is reversed: the
background is printed as black and the foreground is not printed.
The text drawn by a Starbase device is controlled by the following characteristics:
1
.
.1
.
0
, 90
, 180
, and
270
. 0
draws left-to-right with upright characters;
90
draws top-to-bottom with characters on their right side;
180
draws right-to-left with upside-down characters; 270
draws bottom-to-top with characters on their left side. The default
rotation is 0
.
0
.