MIT/GNU Scheme Reference: Graphics

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

# 17. Graphics

MIT/GNU 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 one type of graphics device is implemented on each operating system.

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.

> 17.1 Opening and Closing of Graphics Devices |  |
> 17.2 Coordinates for Graphics |  |
> 17.3 Drawing Graphics |  |
> 17.4 Characteristics of Graphics Output |  |
> 17.5 Buffering of Graphics Output |  |
> 17.6 Clipping of Graphics Output |  |
> 17.7 Custom Graphics Operations |  |
> 17.8 Images |  |
> 17.9 X Graphics |  | Graphics on the X Window System
> 17.10 Win32 Graphics |  | Graphics on Microsoft Windows and Windows NT
> 17.11 OS/2 Graphics |  | Graphics on IBM OS/2

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.1 Opening and Closing of Graphics Devices

procedure: graphics-type-available? graphics-device-type
  This predicate returns `#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.

procedure: enumerate-graphics-types
  This procedure returns a list of symbols which are the names of all the graphics device types that are supported by the Scheme system. The result is useful in deciding what additional arguments to supply to `make-graphics-device`, as each device type typically has a unique way of specifying the initial size, shape and other attributes.

procedure: make-graphics-device graphics-device-type object ...
  This operation creates and returns a graphics device object. Graphics-device-type is a symbol naming a graphics device type, and both the number and the meaning of the remaining arguments is determined by that type (see the description of each device type for details); graphics-device-type must satisfy `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.

procedure: graphics-close graphics-device
  Closes graphics-device, releasing its resources. Subsequently it is an error to use graphics-device.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.2 Coordinates for Graphics

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`.

procedure: graphics-device-coordinate-limits graphics-device
  Returns (as multiple values) the device coordinate limits for graphics-device. The values, which are exact non-negative integers, are: x-left, y-bottom, x-right, and y-top.

procedure: graphics-coordinate-limits graphics-device
  Returns (as multiple values) the virtual coordinate limits for graphics-device. The values, which are real numbers, are: x-left, y-bottom, x-right, and y-top.

procedure: graphics-set-coordinate-limits graphics-device x-left y-bottom x-right y-top
  Changes the virtual coordinate limits of graphics-device to the given arguments. X-left, y-bottom, x-right, and y-top must be real numbers. Subsequent calls to `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.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.3 Drawing Graphics

The procedures in this section provide the basic drawing capabilities of Scheme's graphics system.

procedure: graphics-clear graphics-device
  Clears the display of graphics-device. Unaffected by the current drawing mode.

procedure: graphics-draw-point graphics-device x y
  Draws a single point on graphics-device at the virtual coordinates given by x and y, using the current drawing mode.

procedure: graphics-erase-point graphics-device x y
  Erases a single point on graphics-device at the virtual coordinates given by x and y. This procedure is unaffected by the current drawing mode.

This is equivalent to

    (lambda (device x y)
      (graphics-bind-drawing-mode device 0
        (lambda ()
          (graphics-draw-point device x y))))

procedure: graphics-draw-line graphics-device x-start y-start x-end y-end
  X-start, y-start, x-end, and y-end must be real numbers. Draws a line on graphics-device that connects the points (x-start, y-start) and (x-end, y-end). The line is drawn using the current drawing mode and line style.

procedure: graphics-draw-text graphics-device x y string
  Draws the characters of string at the point (x, y) on graphics-device, using the current drawing mode. The characteristics of the characters drawn are device-dependent, but all devices are initialized so that the characters are drawn upright, from left to right, with the leftmost edge of the leftmost character at x, and the baseline of the characters at 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.

procedure: graphics-move-cursor graphics-device x y
  Moves the cursor for graphics-device to the point (x, y). The contents of the device's display are unchanged.

procedure: graphics-drag-cursor graphics-device x y
  Draws a line from graphics-device's cursor to the point (x, y), simultaneously moving the cursor to that point. The line is drawn using the current drawing mode and line style.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.4 Characteristics of Graphics Output

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-

procedure: graphics-bind-drawing-mode graphics-device drawing-mode thunk
procedure: graphics-bind-line-style graphics-device line-style thunk
  These procedures bind the drawing mode or line style, respectively, of graphics-device, invoke the procedure thunk with no arguments, then undo the binding when thunk returns. The value of each procedure is the value returned by thunk. Graphics operations performed during thunk's dynamic extent will see the newly bound mode or style as current.

procedure: graphics-set-drawing-mode graphics-device drawing-mode
procedure: graphics-set-line-style graphics-device line-style
  These procedures change the drawing mode or line style, respectively, of graphics-device. The mode or style will remain in effect until subsequent changes or bindings.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.5 Buffering of Graphics Output

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.

procedure: graphics-enable-buffering graphics-device
  Enables buffering for graphics-device. In other words, after this procedure is called, graphics operations are permitted to buffer their drawing requests. This usually means that the drawing is delayed until the buffer is flushed explicitly by the user, or until it fills up and is flushed by the system.

procedure: graphics-disable-buffering graphics-device
  Disables buffering for graphics-device. By default, all graphics devices are initialized with buffering disabled. After this procedure is called, all drawing operations perform their output immediately, before returning.

  Note: `graphics-disable-buffering` flushes the output buffer if necessary.

procedure: graphics-flush graphics-device
  Flushes the graphics output buffer for graphics-device. This operation has no effect for devices that do not support buffering, or if buffering is disabled for the device.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.6 Clipping of Graphics Output

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.

procedure: graphics-set-clip-rectangle graphics-device x-left y-bottom x-right y-top
  Specifies the clip rectangle for graphics-device in virtual coordinates. X-left, y-bottom, x-right, and y-top must be real numbers. Subsequent graphics output is clipped to the intersection of this rectangle and the device's virtual coordinate limits.

procedure: graphics-reset-clip-rectangle graphics-device
  Eliminates the clip rectangle for graphics-device. Subsequent graphics output is clipped to the virtual coordinate limits of the device.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.7 Custom Graphics Operations

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.

procedure: graphics-operation graphics-device name object ...
  Invokes the graphics operation on graphics-device whose name is the symbol name, passing it the remaining arguments. This procedure can be used to invoke the standard operations, as well as custom operations that are specific to a particular graphics device type. The names of the standard graphics operations are formed by removing the `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.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.8 Images

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.

operation: graphics-device create-image width height
  Images are created using the `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.

operation: graphics-device draw-image x y image
  The image is copied into the graphics device at the specified position.

operation: graphics-device draw-subimage x y image im-x im-y w h
  Part of the image is copied into the graphics device at the specified (x, y) position. The part of the image that is copied is the rectangular region at im-x and im-y and of width w and height h. These four numbers are given in device coordinates (pixels).

procedure: image? object
  Returns `#t` if object is an image, otherwise returns `#f`.

procedure: image/destroy image
  This procedure destroys image, returning storage to the system. Programs should destroy images after they have been used because even modest images may use large amounts of memory. Images are reclaimed by the garbage collector, but they may be implemented using memory outside of Scheme's heap. If an image is reclaimed before being destroyed, the implementation might not deallocate that non-heap memory, which can cause a subsequent call to `create-image` to fail because it is unable to allocate enough memory.

procedure: image/height image
  Returns the height of the image in device coordinates.

procedure: image/width image
  Returns the width of the image in device coordinates.

procedure: image/fill-from-byte-vector image bytes
  The contents of image are set in a device-dependent way, using one byte per pixel from bytes (a string). Pixels are filled row by row from the top of the image to the bottom, with each row being filled from left to right. There must be at least `(* (image/height image) (image/width image))` bytes in bytes.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.9 X Graphics

MIT/GNU 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.

> 17.9.1 X Graphics Type |  |
> 17.9.2 Utilities for X Graphics |  |
> 17.9.3 Custom Operations on X Graphics Devices |  |

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.9.1 X Graphics Type

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"`.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.9.2 Utilities for X Graphics

procedure: x-graphics/open-display display-name
  Opens a connection to the display whose name is display-name, returning a display object. If unable to open a connection, `#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`.

procedure: x-graphics/close-display display
  Closes display; after calling this procedure, it is an error to use display for any purpose. Any windows that were previously opened on display are destroyed and their resources returned to the operating system.

procedure: x-close-all-displays
  Closes all open connections to X displays. Equivalent to calling `x-close-display` on all open displays.

procedure: x-geometry-string x y width height
  This procedure creates and returns a standard X geometry string from the given arguments. X and y must be either exact integers or `#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.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.9.3 Custom Operations on X Graphics Devices

Custom operations are invoked using the procedure `graphics-operation`. For example,

    (graphics-operation device 'set-foreground-color "blue")

operation: x-graphics-device set-background-color color-name
operation: x-graphics-device set-foreground-color color-name
operation: x-graphics-device set-border-color color-name
operation: x-graphics-device set-mouse-color color-name
  These operations change the colors associated with a window. Color-name must be a string, which is the X server's name for the desired color. `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.

operation: x-graphics-device draw-arc x y radius-x radius-y angle-start angle-sweep fill?

  Operation `draw-arc` draws or fills an arc. An arc is a segment of a circle, which may have been stretched along the x- or y- axis to form an ellipse.

  The parameters x, y, radius-x and radius-y describe the circle and angle-start and angle-sweep choose which part of the circle is drawn. The arc is drawn on the graphics device with the center of the circle at the virtual coordinates given by x and y. radius-x and radius-y determine the size of the circle in virtual coordinate units.

  The parameter angle-start determines where the arc starts. It is measured in degrees in an anti-clockwise direction, starting at 3 o'clock. angle-sweep determines how much of the circle is drawn. It too is measured anti-clockwise in degrees. A negative value means the measurement is in a clockwise direction.

  Note that the angles are determined on a unit circle before it is stretched into an ellipse, so the actual angles that you will see on the computer screen depends on all of: radius-x and radius-y, the window size, and the virtual coordinates.

  If fill? is `#f` then just the segment of the circle is drawn, otherwise the arc is filled in a pie-slice fashion.

  This draws a quarter circle pie slice, standing on its point, with point at virtual coordinates (3,5):

      (graphics-opereration g 'draw-arc 3 5 .5 .5 45 90 #t)

operation: x-graphics-device draw-circle x y radius
operation: x-graphics-device fill-circle x y radius
  These operations draw a circle (outline) or a filled circle (solid) at on the graphics device at the virtual coordinates given by x and y. These operations could be implemented trivially interms of the `draw-arc` operation.

operation: x-graphics-device set-border-width width
operation: x-graphics-device set-internal-border-width width
  These operations change the external and internal border widths of a window. Width must be an exact non-negative integer, specified in pixels. The change takes place immediately. Note that changing the internal border width can cause displayed graphics to be garbled; we recommend calling `graphics-clear` on the window's device after doing so.

operation: x-graphics-device set-font font-name
  Changes the font used when drawing text in a window. Font-name must be a string that is a font name known to the X server. This operation does not affect text drawn prior to its invocation.

operation: x-graphics-device set-mouse-shape shape-number
  Changes the shape of the mouse cursor. Shape-number is an exact non-negative integer that is used as an index into the mouse-shape font; when multiplied by 2 this number corresponds to an index in the file
  ``/usr/include/X11/cursorfont.h`'.

operation: x-graphics-device map-window
operation: x-graphics-device withdraw-window
  These operations control the mapping of windows. They correspond directly to Xlib's `XMapWindow` and `XWithdrawWindow`.

operation: x-graphics-device resize-window width height
  Changes the size of a window. Width and height must be exact non-negative integers. The operation corresponds directly to Xlib's `XResizeWindow`.

  This operation resets the virtual coordinate system and the clip rectangle.

operation: x-graphics-device move-window x y
  Changes the position of a window on the display. X and y must be exact integers. The operation corresponds directly to Xlib's `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.

operation: x-graphics-device get-default resource property
  This operation corresponds directly to Xlib's `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.

operation: x-graphics-device copy-area source-x-left source-y-top width height destination-x-left destination-y-top
  This operation copies the contents of the rectangle specified by source-x-left, source-y-top, width, and height to the rectangle of the same dimensions at destination-x-left and destination-y-top.

operation: x-graphics-device font-structure font-name
  Returns a Scheme equivalent of the X font structure for the font named font-name. If the string font-name does not name a font known to the X server, or names a 16-bit font, `#f` is returned.

procedure: x-font-structure/name font-structure
procedure: x-font-structure/direction font-structure
procedure: x-font-structure/all-chars-exist font-structure
procedure: x-font-structure/default-char font-structure
procedure: x-font-structure/min-bounds font-structure
procedure: x-font-structure/max-bounds font-structure
procedure: x-font-structure/start-index font-structure
procedure: x-font-structure/character-bounds font-structure
procedure: x-font-structure/max-ascent font-structure
procedure: x-font-structure/max-descent font-structure
  These procedures extract the components of the font description structure returned by the X graphics operation `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.

procedure: x-character-bounds/lbearing character-bounds
procedure: x-character-bounds/rbearing character-bounds
procedure: x-character-bounds/width character-bounds
procedure: x-character-bounds/ascent character-bounds
procedure: x-character-bounds/descent character-bounds
  These procedures extract components of objects of type `x-character-bounds`. A more complete description of them appears in documentation of the
  `XLoadQueryFont` Xlib call.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.10 Win32 Graphics

MIT/GNU Scheme supports graphics on Microsoft Windows 95, Windows 98, and Windows NT. 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.

> 17.10.1 Win32 Graphics Type |  |
> 17.10.2 Custom Operations for Win32 Graphics |  | Custom Operations for Win32 Graphics Devices

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.10.1 Win32 Graphics Type

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`
  The window allocates colors from a grayscale palette of approximately 236 shades of gray.

`'grayscale-128`
  The window allocates colors from a grayscale palette of 128 shades of gray.

`'standard`
  The standard palette has good selection of colors and grays.

`#f` or `'system`
  The colors available are those in the system palette. There are usually 16 to 20 colors in the system palette and these are usually sufficent for simple applications like line drawings and x-vs-y graphs of mathematical functions. Drawing with the system palette can be more efficient.

If palette is not specified then the `standard` palette is used.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.10.2 Custom Operations for Win32 Graphics

Custom operations are invoked using the procedure `graphics-operation`. For example,

    (graphics-operation device 'set-foreground-color "blue")

operation: win32-graphics-device set-background-color color-name
operation: win32-graphics-device set-foreground-color color-name
  These operations change the colors associated with a window. Color-name must be of one of the valid color specification forms listed below. `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:

  An integer
    This is the Win32 internal RGB value.

  By name
    A limited number of names are understood by the system. Names are strings, e.g. `"red"`, `"blue"`, `"black"`. More names can be registered with the `define-color` operation.

  RGB (Red-Green-Blue) triples
    A triple is either a vector or list of three integers in the range 0--255 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.

operation: win32-graphics-device define-color name spec
  Define the string name to be the color specified by spec. Spec may be any acceptable color specification. Note that the color names defined this way are available to any Win32 graphics device, and the names do not have to be defined for each device.

  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.

operation: win32-graphics-device find-color name
  Looks up a color previously defined by `define-color`. This returns the color in its most efficient form for operations `set-foreground-color` or `set-background-color`.

operation: win32-graphics-device draw-ellipse left top right bottom
  Draw an ellipse. Left, top, right and bottom indicate the coordinates of the bounding rectangle of the ellipse. Circles are merely ellipses with equal width and height. Note that the bounding rectangle has horizontal and vertical sides. Ellipses with rotated axes cannot be drawn. The rectangle applies to the center of the line used to draw the ellipse; if the line width has been set to greater than 1 then the ellipse will spill outside the bounding rectange by half of the line width.

operation: win32-graphics-device fill-polygon points
  Draws a filled polygon using the current foreground color. Points is a vector of real numbers. The numbers are in the order x1 y1 x2 y2 ... xn yn. For example,

      (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).

operation: win32-graphics-device load-bitmap pathname
  The graphics device contents and size are initialized from the windows bitmap file specified by pathname. If no file type is supplied then a `".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.

operation: win32-graphics-device save-bitmap pathname
  The graphics device contents are saved as a bitmap to the file specified by pathname. If no file type is supplied then a `".BMP"` extension is added. The saved bitmap may be incorporated into documents or printed.

operation: win32-graphics-device move-window x y
  The graphics device window is moved to the screen position specified by x and y.

operation: win32-graphics-device resize-window width height
  The graphics device window is resized to the specified width and height in device coordinates (pixels). If a clip rectangle is in effect when this procedure is called, it is necessary to redefine the clip rectangle afterwards.

operation: win32-graphics-device set-line-width width
  This operation sets the line width for future drawing of lines, points and ellipses. It does not affect existing lines and has no effect on filled polygons. The line width is specified in device units. The default and initial value of this parameter is 1 pixel.

operation: win32-graphics-device set-window-name name
  This sets the window title to the string name. The window is given the name `"Scheme Graphics"` at creation.

operation: win32-graphics-device set-font handle
  Sets the font for drawing text. Currently not well supported. If you can get a Win32 font handle it can be used here.

operation: win32-graphics-device copy-area source-x-left source-y-top width height destination-x-left destination-y-top
  This operation copies the contents of the rectangle specified by source-x-left, source-y-top, width, and height to the rectangle of the same dimensions at destination-x-left and destination-y-top.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 17.11 OS/2 Graphics

MIT/GNU 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")

> 17.11.1 OS/2 Graphics Type |  |
> 17.11.2 Color Operations for OS/2 Graphics |  |
> 17.11.3 Window Operations for OS/2 Graphics |  |
> 17.11.4 Event Operations for OS/2 Graphics |  |
> 17.11.5 Miscellaneous Operations for OS/2 Graphics |  |

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.11.1 OS/2 Graphics Type

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).

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.11.2 Color Operations for OS/2 Graphics

These operations control the colors used when drawing on an OS/2 graphics device.

operation: os2-graphics-device color?
  This operation returns `#t` if the display supports color.

operation: os2-graphics-device set-background-color color-name
operation: os2-graphics-device set-foreground-color color-name
  These operations change the colors associated with a window. Color-name must be one of the valid color specification forms listed below. `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:

  An integer between `0` and `#xffffff` inclusive
    This is the OS/2 internal RGB value.

  By name
    A limited number of names are understood by the system. Names are strings, e.g. `"red"`, `"blue"`, `"black"`. More names can be registered with the `define-color` operation.

  RGB (Red-Green-Blue) triples
    A triple is a list of three integers between `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.

operation: os2-graphics-device define-color name spec
  Define the string name to be the color specified by spec. Spec may be any acceptable color specification. Note that the color names defined this way are available to any OS/2 graphics device, and the names do not have to be defined for each device.

  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.

operation: os2-graphics-device find-color name
  Looks up a color previously defined by `define-color`. This returns the color in its most efficient form for operations `set-foreground-color` or `set-background-color`.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.11.3 Window Operations for OS/2 Graphics

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.

operation: os2-graphics-device window-position
  This operation returns the position of the graphics-device window on the desktop. The position is returned as two values (see section 12.3 Continuations), which are the x and y coordinates of the position. These coordinates are in units of pels (pixels), and measure the distance between the lower left hand corner of the desktop and the lower left hand corner of the graphics device window's frame.

operation: os2-graphics-device set-window-position x y
  The graphics-device window is moved to the screen position specified by x and y. The coordinates x and y are in units of pels (pixels), and measure the distance between the lower left hand corner of the desktop and the lower left hand corner of the graphics device window's frame.

operation: os2-graphics-device window-size
  This operation returns the size of the client area of the graphics-device window. The client area is the part of the window that you draw on; it does not include the window frame, title bar, etc. The size is returned as two values (see section 12.3 Continuations), which are the width and height of the client area in units of pels (pixels).

operation: os2-graphics-device set-window-size width height
  This operation sets the size of the client area of the graphics-device window to the specified width and height, which are in units of pels (pixels). The client area is the part of the window that you draw on; it does not include the window frame, title bar, etc.

operation: os2-graphics-device window-frame-size
  This operation returns the size of the graphics-device window's frame. This includes the client area, as well as the border, title bar, etc. The size is returned as two values (see section 12.3 Continuations), which are the width and height of the frame in units of pels (pixels).

  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.

operation: os2-graphics-device desktop-size
  This operation returns the size of the OS/2 desktop. The size is returned as two values (see section 12.3 Continuations), which are the width and height of the frame in units of pels (pixels).

operation: os2-graphics-device raise-window
  This operation raises the graphics-device window so that it is on top of any other windows on the desktop.

operation: os2-graphics-device lower-window
  This operation lowers the graphics-device window so that it is below all other windows on the desktop.

operation: os2-graphics-device hide-window
  This operation hides the graphics-device window. The window disappears from the desktop, but still appears in the window list.

operation: os2-graphics-device minimize-window
  This operation minimizes the graphics-device window. The window disappears from the desktop, but still appears in the window list. Depending on how you have configured your desktop, the window may appear as an icon, either on the desktop or in the minimized window viewer.

operation: os2-graphics-device maximize-window
  This operation maximizes the graphics-device window. This causes the window to fill the entire desktop.

operation: os2-graphics-device restore-window
  This operation restores the graphics-device window to its normal state. If the window is hidden or minimized, it is shown again, at its former position on the desktop. If the window is maximized, it is returned to its normal size.

operation: os2-graphics-device activate-window
  This operation makes the graphics-device window be the active window. This causes the window to be put in front of all other windows on the desktop, highlights its frame, and gives it the keyboard focus.

operation: os2-graphics-device deactivate-window
  This operation deactivates the graphics-device window if it was active (otherwise it has no effect). This causes some other window to be chosen to be active in its place.

operation: os2-graphics-device set-window-title title
  This operation changes the text that appears in the graphics device window's title bar. The new text is given by title, which must be a string.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.11.4 Event Operations for OS/2 Graphics

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.

operation: os2-graphics-device read-button
  This operation waits for the user to push a mouse button inside the client area of the graphics-device window. It then returns four values (see section 12.3 Continuations) which are: the button number; the x and y coordinates of the mouse pointer at the time the button was pressed, in pels (pixels) relative to the lower left hand corner of the client area; and the graphics device that the mouse pointer was over at the time the button was pressed.

  Note that this operation only works when button events are selected (which is the default).

operation: os2-graphics-device select-user-events mask
  This operation sets the event-selection mask for the graphics device to mask. The event-selection mask is an exact non-negative integer that specifies which types of incoming events are to be saved in the user-event queue for later retrieval by the `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       #x001   Button press/release
      1       #x002   Close (close the window) [WM_CLOSE]
      2       #x004   Focus change [WM_SETFOCUS]
      3       #x008   Key press/release [WM_CHAR]
      4       #x010   Paint [WM_PAINT]
      5       #x020   Size change [WM_SIZE]
      6       #x040   Visibility change [WM_SHOW]
      7       #x080   Command [WM_COMMAND]
      8       #x100   Help [WM_HELP]
      9       #x200   Mouse-move [WM_MOUSEMOVE]

  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.

operation: os2-graphics-device read-user-event
  This operation returns the next user event available from the user-event queue. If there are no events in the queue, the operation waits for an event to arrive before returning.

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)`
  A button event. Number is the button number, for example button number `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)`
  A close event. The user has selected the close button from the system menu, or typed `Alt-f4`.

`#(2 device gained?)`
  A focus event. If gained? is `#t`, the keyboard focus is being gained, and if gained? is `#f`, it is being lost.

`#(3 device code flags repeat)`
  A keyboard event. This is much too complicated to describe here. See the OS/2 toolkit documentation for details.

`#(4 device xl xh yl yh)`
  A paint event. Part of the graphics-device window that was obscured has been revealed and the Presentation Manager is informing the window that it must repaint that area. Scheme will take care of the painting for you, so this event isn't very useful.

`#(5 device width height)`
  A size-change event. The size of the graphics-device window has changed, and width and height specify the new size in pels (pixels).

`#(6 device shown?)`
  A visibility event. Indicates that the graphics-device window has been hidden or revealed. If shown? is `#f`, the window is hidden, and if it is `#t`, the window is shown.

`#(7 device source mouse?)`
`#(8 device source mouse?)`
  A menu command. Source specifies which menu item was selected to cause this event, and mouse? is a boolean indicating whether the item was selected with the mouse or the keyboard. The event-type number `7` indicates a command from a ``WM_COMMAND`' message, while `8` is a command from a ``WM_HELP`' message.

`#(9 device x y hit-test flags)`
  The mouse was moved. X and y specify the position of the mouse, hit-test contains the hit-test information, and flags specifies the modifier keys that were pressed at the time.

operation: os2-graphics-device discard-events
  This operation discards any events that are in the user-event queue. This is sometimes useful when you want to prompt the user for some input and don't want to consider any previous input.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 17.11.5 Miscellaneous Operations for OS/2 Graphics

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.

operation: os2-graphics-device set-font font-name
  This operation sets the font used for drawing text in the graphics-device window. Font-name is a string describing the font; this string is in the form "<point-size>.<family-name>", for example, `"10.Courier"`. You may specify any fixed-pitch font family, in any point size that is supported for that font family. This includes both image fonts and outline fonts.

operation: os2-graphics-device capture-image x-left y-bottom x-right y-top
  This operation creates and returns an image that contains part of the client area of the graphics-device window. The portion of the client area that is selected is specified by the four coordinate arguments, which are given in the current virtual coordinates for the device. See section 17.8 Images, for more information about manipulating images.

operation: os2-graphics-device draw-lines xv yv
  This operation draws multiple disjoint lines; it is like multiple calls to `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 be 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))

[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated by Chris Hanson on September, 19 2003 using texi2html