Icons in UniCon

The following is a quick description of the file format of the UniCon editor's icons. Since this information is quite fresh and likely to change, the discussion is sketchy, but hopefully useful nonetheless.

Icon Format

The format for describing a new icon in UniCon is quite simple, but the parser is quite finicky. Each icon description is a series of commands, one per line. There must be no blank lines in the description (except at the end), but you may use whatever whitespace you wish on each line.

There are three different kinds of icons in UniCon: one for components, one for connectors, and one for hooks (players or roles). Here is a description of the format for each of these three kinds of icons.

component (type)+
size width height
playerbox upper-left-x upper-left-y lower-right-x lower-right-y
playerrules (rule)*
background
(drawing-command)+
foreground
(drawing-command)+
connector (type)+
size width height
rolerules (rule)*
background
(drawing-command)+
foreground
(drawing-command)+
hook (type)+
size width height
background
(drawing-command)+
foreground
(drawing-command)+
The first line of the format gives the kind of icon, plus a list of the types of components, connectors, or hooks for which this should be the icon. This is a list, rather than a single name, since a given icon can be shared among multiple types. (This sharing is especially useful for hooks.)

The second line gives the size of the icon, in pixels.

Component icons have two idiosyncratic lines: playerbox and playerrules. The playerbox line gives the coordinates (in pixels) of an imaginary rectangle on which the component's players should be placed. The playerrules line is a possibly empty list of rule, where each rule consists of a player type and a side (left, right, top, or bottom). Hence the information on the playerrules line will alternate player type, side, player type, side. Here's an example from the Filter icon:

playerrules StreamIn left StreamOut right 
This line states that players of type StreamIn should be evenly distributed along the left edge of the icon's playerbox, while those of type StreamOut should be evenly distributed on the right. If the component has a player whose type is not mentioned in the playerrules, then UniCon will choose a default side.

For consistency across components, you should choose a playerbox such that the players appear to sit along the edge of the component. The Filter icon (show below) is an interesting case. Since its picture shows its left and right sides curved inward, the playerbox has its left and right sides adjusted so that the players look like they're sitting on the inwardly curved edges:

playerbox 10 0 112 80
Connector icons have a rolerules line that is similar to the playerrules line mentioned above, except that the interpretation of the side is different. For a role, the side tells which in which direction the given type of role should dangle from the connector. Here's an example from the Pipe connector:

rolerules  Source left  Sink right
This line states that roles of type Source should dangle off to the left of the pipe connector, while those of type Sink should dangle off to the right.

All three formats give background and foreground drawing commands. These are the heart of the icon description and tell what the icon should actually look like. Because of the way UniCon's user interface is designed, an icon's appearance is broken up into two aspects: its background and its foreground. The easiest way to illustrate the difference is with an example. Here's the icon for a Filter component, without its players:

The background part of this icon consists of one polygon and looks like this:
while the foreground consists of two black lines and looks like this:
Both parts together make up the final appearance of the icon. The background should consist of only the few minimal drawing commands needed to convey the basic shape of the icon; any other aspect of the icon should be placed in its foreground.

For all three formats, the background command should appear on a line by itself, followed by the drawing commands that constitute the background, one per line. Similarly, the foreground command should appear on a line by itself, followed by the drawing commands that constitute the foreground, one per line. The available drawing commands are discussed below. As a summary, here is the whole icon description for the Filter component.

component Filter
size 120 80
playerbox 10 0 112 80
playerrules StreamIn left   StreamOut right
background
polygon 0 0   0 0   120 0   120 0   110 40   120 80   120 80   0 80   0 80   10 40   0 0 :smooth #t :spline-steps 100
foreground
line 0 0   0 0   120 0   120 0   110 40   120 80   120 80   0 80   0 80   10 40   0 0 :smooth #t :spline-steps 100
line    3 3   3 3   117 3   117 3   107 40   117 77   117 77   3 77   3 77   13 40   3 3 :smooth #t :spline-steps 100

Drawing commands

Each of the drawing commands has the same basic form, consisting of a shape, a list of coordinates (in pixels), and a possibly empty list of options. Each of the different shapes, its expected coordinates, and its options is discussed below.

For an icon whose size is given as W wide by H high, the shapes should be draw in a coordinate system whose upper left corner is the coordinate (0,0) and whose lower right corner is the coordinate (W,H). Notice that this is upside-down from the way the Cartesian coordinate system is typically drawn, since the y-coordinate increases as you move down the screen. Drawing outside the rectangle whose opposite corners are (0,0) and (W,H) is allowed, but discouraged. (The interface makes no guarentees about the appearance of parts of the drawing outside this rectangle.)

Drawing options can be thought of as keyword parameters to the drawing command. Each option consists of a keyword, which begins with a colon, and a value. Depending on the option, the value is either a string (given between double quotes), a number, or a boolean (#t for true, #f for false).

Here is a summary of the drawing commands, largely quoted from STk's canvas man page.

Arc Command

Items of type arc appear on the display as arc-shaped regions. An arc is a section of an oval delimited by two angles (specified by the :start and :extent options) and displayed in one of several ways (specified by the :style option). Arcs are created with widget procedures of the following form:
arc x1 y1 x2 y2 (option)*
The arguments x1, y1, x2, and y2 give the coordinates of two diagonally opposite corners of a rectangular region enclosing the oval that defines the arc.

The following options are supported for arcs:

:extent degrees
Specifies the size of the angular range occupied by the arc. The arc's range extends for degrees degrees counter-clockwise from the starting angle given by the :start option. Degrees may be negative. If it is greater than 360 or less than -360, then degrees modulo 360 is used as the extent.
:fill color
Fill the region of the arc with color. Color should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". If color is an empty string (the default), then then the arc will not be filled.
:outline color
Color specifies a color to use for drawing the arc's outline; it should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". This option defaults to "black". If color is specified as an empty string then no outline is drawn for the arc.
:start degrees
Specifies the beginning of the angular range occupied by the arc. Degrees is given in units of degrees measured counter-clockwise from the 3-o'clock position; it may be either positive or negative.
:style type
Specifies how to draw the arc. If type is "pieslice" (the default) then the arc's region is defined by a section of the oval's perimeter plus two line segments, one between the center of the oval and each end of the perimeter section. If type is "chord" then the arc's region is defined by a section of the oval's perimeter plus a single line segment connecting the two end points of the perimeter section. If type is "arc" then the arc's region consists of a section of the perimeter alone. In this last case the :fill option is ignored.
:width outlineWidth
Specifies the width of the outline to be drawn around the arc's region, in any of the forms described in the COORDINATES section above. If the :outline option has been specified as an empty string then this option has no effect. Wide outlines will be drawn centered on the edges of the arc's region. This option defaults to 1.0.

Line Command

Items of type line appear on the display as one or more connected line segments or curves. Lines are created with widget procedures of the following form:
line x1 y1 ... xn yn  (option)*
The arguments x1 through yn give the coordinates for a series of two or more points that describe a series of connected line segments.

The following options are supported for lines:

:arrow where
Indicates whether or not arrowheads are to be drawn at one or both ends of the line. Where must have one of the values "none" (for no arrowheads), "first" (for an arrowhead at the first point of the line), "last" (for an arrowhead at the last point of the line), or "both" (for arrowheads at both ends). This option defaults to "none".
:arrowshape shape
This option indicates how to draw arrowheads. The shape argument must be a list with three elements, each specifying a distance in any of the forms described in the COORDINATES section above. The first element of the list gives the distance along the line from the neck of the arrowhead to its tip. The second element gives the distance along the line from the trailing points of the arrowhead to the tip, and the third element gives the distance from the outside edge of the line to the trailing points. If this option isn't specified then Tk picks a ``reasonable'' shape.
:capstyle style
Specifies the ways in which caps are to be drawn at the endpoints of the line. Style may be one of "butt", "projecting", or "round". If this option isn't specified then it defaults to "butt". Where arrowheads are drawn the cap style is ignored.
:fill color
Color specifies a color to use for drawing the line; it should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". It may also be an empty string, in which case the line will be transparent. This option defaults to "black".
:joinstyle style
Specifies the ways in which joints are to be drawn at the vertices of the line. Style may be one of "bevel", "miter", or "round". If this option isn't specified then it defaults to "miter". If the line only contains two points then this option is irrelevant.
:smooth boolean
Boolean must be either #t (true) or #f (false). It indicates whether or not the line should be drawn as a curve. If so, the line is rendered as a set of Bezier splines: one spline is drawn for the first and second line segments, one for the second and third, and so on. Straight-line segments can be generated within a curve by duplicating the end-points of the desired line segment.
:splinesteps number
Specifies the degree of smoothness desired for curves: each spline will be approximated with number line segments. This option is ignored unless the :smooth option is true.
:width lineWidth
LineWidth specifies the width of the line, in any of the forms described in the COORDINATES section above. Wide lines will be drawn centered on the path specified by the points. If this option isn't specified then it defaults to 1.0.

Oval Command

Items of type oval appear as circular or oval regions on the display. Each oval may have an outline, a fill, or both. Ovals are created with widget procedures of the following form:
oval x1 y1 x2 y2  (option)*
The arguments x1, y1, x2, and y2 give the coordinates of two diagonally opposite corners of a rectangular region enclosing the oval. The oval will include the top and left edges of the rectangle not the lower or right edges. If the region is square then the resulting oval is circular; otherwise it is elongated in shape.

The following options are supported for ovals:

:fill color
Fill the area of the oval with color. Color should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". If color is an empty string (the default), then then the oval will not be filled.
:outline color
Color specifies a color to use for drawing the oval's outline; it should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". This option defaults to "black". If color is an empty string then no outline will be drawn for the oval.
:width outlineWidth
outlineWidth specifies the width of the outline to be drawn around the oval, in any of the forms described in the COORDINATES section above. If the :outline option hasn't been specified then this option has no effect. Wide outlines are drawn centered on the oval path defined by x1, y1, x2, and y2. This option defaults to 1.0.

Polygon Command

Items of type polygon appear as polygonal or curved filled regions on the display. Polygons are created with widget procedures of the following form:
polygon x1 y1 ... xn yn  (option)*
The arguments x1 through yn specify the coordinates for three or more points that define a closed polygon. The first and last points may be the same; whether they are or not, Tk will draw the polygon as a closed polygon.

The following options are supported for polygons:

:fill color
Color specifies a color to use for filling the area of the polygon; it should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". If color is an empty string then the polygon will be transparent. This option defaults to "black".
:outline color
Color specifies a color to use for drawing the polygon's outline; it should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". If color is an empty string then no outline will be drawn for the polygon. This option defaults to empty (no outline).
:smooth boolean
Boolean must be either #t (true) or #f (false). It indicates whether or not the polygon should be drawn with a curved perimeter. If so, the outline of the polygon becomes a set of Bezier splines, one spline for the first and second line segments, one for the second and third, and so on. Straight-line segments can be generated in a smoothed polygon by duplicating the end-points of the desired line segment.
:splinesteps number
Specifies the degree of smoothness desired for curves: each spline will be approximated with number line segments. This option is ignored unless the :smooth option is true.
:width outlineWidth
OutlineWidth specifies the width of the outline to be drawn around the polygon, in any of the forms described in the COORDINATES section above. If the :outline option hasn't been specified then this option has no effect. This option defaults to 1.0. Polygon items are different from other items such as rectangles, ovals and arcs in that interior points are considered to be ``inside'' a polygon (e.g. for purposes of the find closest and find overlapping widget commands) even if it is not filled. For most other item types, an interior point is considered to be inside the item only if the item is filled or if it has neither a fill nor an outline. If you would like an unfilled polygon whose interior points are not considered to be inside the polygon, use a line item instead.

Rectangle Command

Items of type rectangle appear as rectangular regions on the display. Each rectangle may have an outline, a fill, or both. Rectangles are created with widget procedures of the following form:
rectangle x1 y1 x2 y2  (option)*
The arguments x1, y1, x2, and y2 give the coordinates of two diagonally opposite corners of the rectangle (the rectangle will include its upper and left edges but not its lower or right edges).

The following options are supported for rectangles:

:fill color
Fill the area of the rectangle with color, which should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". If color is an empty string (the default), then the rectangle will not be filled.
:outline color
Draw an outline around the edge of the rectangle in color. Color should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". This option defaults to "black". If color is an empty string then no outline will be drawn for the rectangle.
:width outlineWidth
OutlineWidth specifies the width of the outline to be drawn around the rectangle, in any of the forms described in the COORDINATES section above. If the :outline option hasn't been specified then this option has no effect. Wide outlines are drawn centered on the rectangular path defined by x1, y1, x2, and y2. This option defaults to 1.0.

Text Command

A text item displays a string of characters on the screen in one or more lines. Text items are created with widget procedures of the following form:
text x y  (option)*
The arguments x and y specify the coordinates of a point used to position the text on the display (see the options below for more information on how text is displayed).

The following options are supported for text items:

:anchor anchorPos
AnchorPos tells how to position the text relative to the positioning point for the text; it must be one of "n", "ne", "e", "se", "s", "sw", "w", "nw", or "center". For example, if anchorPos is "center" then the text is centered on the point; if anchorPos is "n" then the text will be drawn such that the top center point of the rectangular region occupied by the text will be at the positioning point. This option defaults to "center".
:fill color
Color specifies a color to use for filling the text characters; it should be the name of a color in quotes, such as "red", "blue", or "lemon chiffon". If this option isn't specified then it defaults to "black".
:font fontName
Specifies the font to use for the text item. FontName may be a fontname given in the standard X format. Fourteen-point Times Roman, for example, is typically given as "*-times-medium-r-normal*140*". If this option isn't specified, it defaults to a system-dependent font.
:justify how
Specifies how to justify the text within its bounding region. How must be one of the values "left", "right", or "center". This option will only matter if the text is displayed as multiple lines. If the option is omitted, it defaults to "left".
:text string
String specifies the characters to be displayed in the text item. Newline characters cause line breaks. The characters in the item may also be changed with the insert and delete widget procedures. This option defaults to an empty string.
:width lineLength
Specifies a maximum line length for the text, in any of the forms described in the COORDINATES section above. If this option is zero (the default) the text is broken into lines only at newline characters. However, if this option is non-zero then any line that would be longer than lineLength is broken just before a space character to make the line shorter than lineLength; the space character is treated as if it were a newline character.