Envision includes an interface to standard Xlib graphics, but at a higher level of abstraction than Xlib. We do not provide support for high-end graphics capabilities (e.g. 3D polygon rendering). However, we have tried to design our system so that such an extension could be added at a later date.
Windows are created and managed using the following functions. Notice that windows can also be closed via the window manager, so it is not silly for user code to inquire whether the window is still live. Attempts to perform graphics operations on a window that is no longer live will generate errors, but they won't crash the coprocessor.
A colormap is a real-grid with 1D domain [0..255] and 3D codomain [0.0 .. 1.0]. Each window is created with the default colormap.
The contents of a window can be retrieved using the function window-contents. This extracts the subsection specified by xrange and yrange (each of which is a pair of numbers) and returns it as a sheet.
Objects are displayed on a window using the function draw, with the following syntactic forms:
Each object comes equipped with an internal coordinate system. The center-point argument (a 2D point) specifies where the origin of the object's coordinate system is to be placed in the window's coordinate system. In the third and fourth syntactic forms, each coordinate should be a number.
The options input is a list of (keyword value) pairs, used to alter the default behavior of the drawing interface. The useful options may differ from object to object. If a non-useful option is passed to draw, the implementation may either flag an error or silently ignore it. All options are optional: the implementation must provide some reasonable default behavior.
Unless otherwise specified, all objects support the keywords color and scaling. The value of color is an integer naming a cell in the colormap, either the default colormap or one installed by the user. The value of the scaling option is a real number, specifying a scaling of the object's internal coordinate system (linear about its origin). Notice that for some objects (e.g. polygons) this not only changes the size of the displayed shape, but also alters its distance from the center of the object's internal coordinate system and thus from the specified center-point.
Coordinates within the object and the center-point, as well as parameters in the options list, may be inexact reals. They will be rounded before the actual low-level Xlib graphics calls are executed. The implementation should avoid rounding inexact numbers early, when this could cause quantization errors. In particular, if the scaling option is present, the object must be scaled prior to rounding.
When missing values are allowed in a geometrical object (typically inside a sheet, see the page on geometrical objects for details), draw is to treat them as transparent. For example, a manifold with 1D domain and 2D codomain is drawn as connected curve. Missing values in the manifold cause the curve to be drawn with gaps.
All scheme objects can be used as input to draw. However, only the following are guaranteed to display nicely:
When an object cannot be displayed nicely, it is displayed as well as possible. For example, a simple default would be to draw the string created by (format #f "~s" object).
In the basic Envision system, only 2D objects display nicely. However, we plan to include a simple system for displaying 3D objects, in the demo package. This demo will project each 3D object onto a 2D object, and call DRAW on the 2D object.
Strings are drawn as strings. The scaling keyword may not be useful. Rather, one needs the following keywords (?): font, point-size, origin-located-at (values: center, lower-left)
A 1D sheet displays nicely if it has a 2D codomain: values in the codomain are interpreted as locations on the window.
The only type of 2D sheet that displays nicely is an integer-grid with a 1D codomain. Its values are copied directly to the window pixelwise. Missing values should ideally display as transparent. Since the current X substrate does not support transparency, 2D sheets only display nicely if they are created with missing values disallowed. For similar reasons, 2D sheets only display nicely if their codomain is 8 bits deep.
Only the focus area of the sheet is displayed, not the entire storage area (if the two are different). Notice that this is nicely handled by Xlib.
The keywords color and size do not apply to 2D sheets. Download a new colormap if you don't like the colors. Apply your favorite interpolation or sampling operation if you don't like the size: scaling in draw will slow it down massively and the best method of scaling depends on your application.
The origin of 2D sheet's internal coordinate system is the (0,0) point in its domain, wherever that happens to be in the raw storage sheet.
If your image representation contains a 2D sheet of another type, or several 2D sheets (e.g. three components of a color image) you must write a program to translate these values into 8-bit colormap values. There is no standard way to do this translation: it depends on the application and your personal preferences. (A sample displayer is provided in the demos that come with this system.)
Points are drawn as points. Line-segments and line-segment bundles are drawn as line segments. Line segment bundles are only guaranteed to display nicely if they have a 1D discrete domain and 2D codomain.
Points support the option point-radius. Line-segments and line-segment-bundles support the option line-thickness.
Bulk drawing operations may be used to draw line-segment bundles if the graphics substrate supports them and if (a) the sheets are declared as containing no missing values or (b) the graphics substrate supports missing values. Alternatively, the implementation may use a loop and a slower graphics call. The method may be decided at run-time, depending on the type of the input object.
Polygons, polygon-bundles, ellipses and ellipse-bundles are displayed as filled by default. They can be drawn as outlines by specifying the value #f for the option filled?. They also support the line-thickness option, which ignored if the object is drawn filled.
Polygon-bundles and ellipse-bundles are only guaranteed to display nicely if they have a 1D discrete domain and a 2D codomain.
For polygons and polygon-bundles, the best choice of Xlib function almost certainly depends on the specific type of the incoming object. For example, the implementer may wish to call XFillRectangle (or one of its relatives) if the polygons are rectangular, as this is almost certainly faster than the general polygon filling operation. Similarly, it may be important to inspect the input for whether missing values are possible.
The implementer should try to select the fastest drawing method available for each input object. This is certain to differ between sites and between different implementations and over time. Therefore, user code should not depend on which rendering calls are used. The point of having a high-level drawing interface is to shield user code from such details and, thus, allow the code to be portable.
Ownership, Maintenance and Disclaimers
Last modified