0.0.0

About Alloy-Simple

This project presents a simple, common rendering library on top of Alloy. The idea is to provide a protocol for rendering that isn't too difficult to provide for a backend, and extensive enough to display most interfaces. It does not implement a renderer in itself, only provides an intermediary protocol for the user to rely on.

Implementing the simple protocol in your backend is the easiest way to get rendering of an Alloy interface going, as you can then already rely on the visualisation behaviour for the various components implemented in other projects, such as Presentations.

Protocol

The Simple protocol is split into four sub protocols:

Transforms

The transforms protocol presents a way to perform local, affine coordinate transformations during rendering. Specifically, the following functions are defined:

  • call-with-pushed-transforms / with-pushed-transforms
    Allows dynamically bounding transformations. Any transformation occurring within the body of this call will be when the control flow exits.

  • clip
    Clip the region to the extent, causing anything that should be rendered outside of this region to not be rendered. This can be used to implement the alloy:call-with-constrained-visibility function from Core. The extent specified is local to the current transforms. Clipping withinanother call-with-pushed-transforms extent will cause the actual clipping region to become the union of this and the clipping region of the outer extent. Clipping multiple times within the same transforms is implementation dependent.

  • translate
    Shift the coordinate system to place the origin at the specified point.

  • scale
    Scale the coordinate system to stretch the axes by the specified size.

  • rotate
    Rotate the coordinate system by the specified angle around the Z axis.

  • z-index (place)
    Access the index on which the shapes should be drawn. Shapes that are drawn while a higher z-index is active should be drawn in front of shapes that are drawn with a lower z-index, regardless of the order in which they are drawn. For shapes on the same z-index, it is unspecified whether later shapes will overlap earlier ones or not.

Shapes

In order to render various constructs, Simple offers a bunch of shape objects, which must be created using a corresponding shape function. Once constructed, the shape can be drawn any number of times using alloy:render. The transforms are only applied when the shape is rendered, not when it is constructed. This allows you to re-use the same shape and draw it in various configurations.

All shapes take some geometric primitives from Core as positioning arguments. These primitives may contain relative units. The backend may choose to turn these units into absolute ones at the time of construction of the shape. If the unit relation changes, the user must call reinitialize-instance on the affected shapes. When reinitialize-instance is called, the backend must update the internal coordinates of the shape based on the units that were initially used when the shape was constructed. The user may also pass any of the initial arguments used at shape construction as initargs to reinitialize-instance to update them without creating a new shape instance.

The implementation may return an instance that is not a subclass of shape or the default provided classes for each shape for one of the shape functions. However, the above reinitialize-instance and alloy:render restrictions apply regardless. If an implementation chooses to do this, it must be aware, and potentially provide mitigation for, extension protocols that depend on the class hierarchy not working as expected with the custom instance.

Where applicable, the line-width argument will cause the shape to be rendered as an outline, instead of a filled shape. In such a case it must be an alloy:unit designating the width of the lines.

Where applicable, the pattern argument will change the pattern with which the shape is filled. The pattern may be a colored:color, or an object as returned by request-gradient. If the shape is drawn as an outline, the pattern is only applied to the lines, not to any area the lines might enclose.

The user does not have to call alloy:register on an object returned by a shape function, the object must already be registered if necessary.

The following shape functions are available, though the implementation may offer more:

  • line-strip
    Generates a sequence of connected line segments. The points argument must be a list or vector of alloy:points.

  • curve
    Generates a sequence of Bezier curves. The points argument must be a list or vector of alloy:points. Each curve segment consists of four points, the first and last of which are the endpoints, and the second and third being the respective control points. Each successive curve requires only three additional points, as the endpoint of the previous curve is used as the start point of the current.

  • rectangle
    Generates an axis-aligned rectangle from an alloy geometry object.

  • ellipse
    Generates an axis-aligned ellipse from an alloy geometry object.. The bounds specifies the outer bounding box of the ellipse, meaning the ellipse touches the centres of the rectangle spanned by the extent.

  • polygon
    Generates a closed polygon. The points argument must be a list or vector of alloy:points.

  • icon
    Generates an icon displaying the specified image. The image must be an object returned by request-image on the same renderer. The bounds argument specifies the maximal bounding box which the rendered image may not exceed, and which is used for alignment of the image. The halign and valign designate the horizontal and vertical alignment within the bounding box. May be either :left, :middle, :right, :bottom, :top. The size argument specifies the size of the image as rendered within the bounds, and defaults to the pixel size of the image.

  • text
    Generates a text rendering of the given string and styling. The bounds argument specifies the maximal bounding box which the rendered text may not exceed, and which is used for alignment. The direction argument must be a keyword designating the text direction, and may be either :right for left-to-right, :left for right-to-left, :down for top-to-bottom right-to-left. The halign and valign arguments specify text is aligned within the bounding box and must be either :start, :middle, or :end for horizontal alignment, and :top, :middle, or :bottom for vertical alignment. The argument must be an alloy:unit designating the height of one text line, otherwise known as an em. The font must be an object returned by request-font on the same renderer.

  • cursor
    Generates a text cursor for the given position within the text. The text argument must be an object returned by text on the same renderer. The primary feature of this is that the cursor shape will have the correct positioning within the text to be rendered, accounting for layouting and other factors.

  • selection
    Generates a text selection for the given region within the text. The text argument must be an object returned by text on the same renderer. The primary feature of this is that the selection shape will be correct, accounting for layouting and other factors.

Shared Resources

Some parts of rendering might require heavy and slow resource allocation in the renderer. To alleviate this problem, the Simple protocol requires you to explicitly allocate certain resources as needed:

  • request-image
    This will load the specified image into the renderer and prepare it for rendering. Returned is an object that can be used for the icon shape. The data argument may be any data type as specified by the implementation. Any implementation must support octet vectors with RGBA pixel data. In that case, the user must supply the size argument as well, however. For requests that are sufficiently similar, the same object may be returned.

  • request-font
    This will load the requested font into the renderer and analyse it for text rendering. Returned is an object that can be used for the font argument of the text shape. The family argument may be a string denoting the font family to load, with the additional arguments constraining the font features more explicitly, or it may be the symbol :default for which the implementation must return a default font. The implementation may extend the allowed data types for the family as well. For requests that are sufficiently similar, the same object may be returned.

  • request-gradient
    This will generate a gradient suitable for use with any shape's pattern argument. The type argument may be one of the following:

    • linear

    • radial

    • angle

    • diamond

    An implementation may provide additional gradient types.
    The start and stop arguments must be points designating the bounds of the gradient. The gradient will fill all of the shape it is used with, but the start and stop bounds designate the area within which the gradient stops apply. Stops must be a list of cons, each of which has a (single-float 0 1) in its car and a colored:color in its cdr.

The user does not have to call alloy:register on an object returned by a resource function, the object must already be registered if necessary. The implementation may choose to load the resource immediately, or defer the loading process. However, the resource must be loaded no later than when it is first effectively used during the rendering of a shape object.

Render Behaviour

Simple also specifies the following two functions that influence the rendering behaviour:

  • clear
    Cause the specified screen region to be cleared to whatever the renderer considers to be the "empty" colour.

  • composite-mode
    Change how newly drawn shapes are blended onto previously drawn shapes, especially ones that lie below it. The following modes are specified, though a renderer may add others:

    • :source-over

    • :destination-over

    • :source-in

    • :source-out

    • :destination-in

    • :destination-out

    • :destination-atop

    • :add

    • :multiply

    • :difference

    • :invert

Default Implementations

Simple provides standard implementations for all of the shapes – without the actual rendering thereof, of course – as well as a standard implementation of the transforms protocol, using a 3x3 transforms matrix for the coordinate system representation.

If using a transformation matrix is convenient for your backend, all you need to do is inherit from transformed-renderer. From there on out you can access the current transform matrix with transform-matrix. You will still need to implement clipping, however.

System Information

0.0.0
Yukari Hafner
zlib

Definition Index