Extension to SVG

To illustrate the extension consider the following simple example of some SVG code for widget layout. There are two buttons: pieces of text which are framed with rounded rectangles and which are framed by a larger rectangle. The layout will adjust appropriately if the text or font is modified: the buttons always contain their text while the frame is just large enough to contain the two buttons plus a small amount of padding.

<svg height="100" version="1.1" width="300" xmlns="http://www.w3.org/2000/svg" xmlns:c="http://mcc.id.au/2004/csvg">
 
<-- The panel containing the two buttons -->
<rect fill="#eee" height="50" id="panel" stroke="#ccc" stroke-width="1" width="150" x="50" y="20">
<c:constraint attributeName="x" value="id('button1')/@x - 10"/>
<c:constraint attributeName="y" value="id('button1')/@y - 10"/>
<c:constraint attributeName="width" value="id('button1')/@width + id('button2')/@width + 30"/>
<c:constraint attributeName="height" value="id('button1')/@height + 20"/>
</rect>
 
<-- The OK button -->
<rect fill="#ccc" height="30" id="button1" rx="3" ry="3" stroke="black" stroke-width="1" width="60" x="60" y="30">
<c:constraint attributeName="width" value="c:width(c:bbox(id('button1Label'))) + 10"/>
<c:constraint attributeName="height" value="c:height(c:bbox(id('button1Label'))) + 10"/>
</rect>
<text font-size="16" id="button1Label" text-anchor="middle" x="90" y="53">
OK
<c:constraint attributeName="x" value="id('button1')/@x + id('button1')/@width div 2"/>
<c:constraint attributeName="y" value="id('button1')/@y + id('button1')/@height div 2
+ c:height(c:bbox(.)) div 2
"
/>
</text>
 
<-- The Cancel button -->
<rect fill="#ccc" height="30" id="button2" rx="3" ry="3" stroke="black" stroke-width="1" width="60" x="130" y="30">
<c:constraint attributeName="x" value="id('button1')/@x + id('button1')/@width + 10"/>
<c:constraint attributeName="width" value="c:width(c:bbox(id('button2Label'))) + 10"/>
<c:constraint attributeName="height" value="c:height(c:bbox(id('button2Label'))) + 10"/>
</rect>
<text font-size="16" id="button2Label" text-anchor="middle" x="160" y="53">
Cancel
<c:constraint attributeName="x" value="id('button2')/@x + id('button2')/@width div 2"/>
<c:constraint attributeName="y" value="id('button2')/@y + id('button2')/@height div 2
+ c:height(c:bbox(.)) div 2
"
/>
</text>
 
</svg>
Rendering of the simple.svg example

When viewing this example in a non-CSVG aware browser, the c:constraint elements will be ignored and only the normal, constant values in the SVG element attributes will be used. The button sizes are fixed, though, so if the user happened to change the default font in the user agent's style sheet, the rect dimensions would most likely also have to change. If the constraint extensions are supported in the browser, each c:constraint element defines an expression to be used to determine the value used for a particular attribute. Just like with SMIL animation elements, this computed value will override the constant value specified in the normal SVG attribute.

Let's first look at the OK button. It has normal, constant values for the x, y, rx and ry attributes. The width and height attributes, though, have constraints in terms of the bounding box of the text label. The width of the rect is equal to the width of the label's bounding box plus 10 units padding. Similarly, the height of the rect is equal to the height of the label's bounding box plus 10 units padding. The text's x and y attributes are also defined by expressions so that it can be placed at the right coordinates within the rect. The expressions center the label within the rect.

c:bbox is a built-in function which determines the bounding box of an eleemnt. c:x, c:y, c:width and c:height are accessor functions used to get the properties of the Rect as returned by c:bbox.

The Cancel button is written in an analogous way. But it also has the feature of aligning itself to be next to the OK button. The x attribute of the Cancel button's rect is defined by a constraint whose expression is written in terms of the x and width of the OK button's rect. It will align the left edge of the Cancel button with the right edge of the OK button, with 10 units padding in between.

Finally we come to the rect which serves as the panel containing the two buttons. Its x, y, width and height attributes all have expressions in terms of the dimensions of the rects which form the two buttons.

Components of CSVG

We now describe the extension to SVG in detail. It is minimal.

Expression based attributes

Any animatable attribute can have a c:constraint element specify an expression for it. This will be evaluated at display-time and the value updated when necessary as a result of, for instance, user interaction or resizing of the browser window. These expressions are actually XPath expressions and as such can comprise the operators, functions and location paths that XPath allows. In addition to the core functions of XPath 1.0 there are a number of other built-in functions available, such as accessor functions to get properties of SVG datatypes and functions to return dynamic information about the environment like the SVG canvas dimensions.

Referring to properties of elements in the document is done by using an XPath location that selects the relevant attribute. For example, id('r')/@x will evaluate to the x coordinate of the element with ID "r", a Length. If the actual string value of the attribute is wanted, it could be casted with the XPath string function. Most of the time this is not needed, as SVG values will automatically be converted to strings as necessary. While SVG datatypes such as lengths are supported, they cannot be included as a value in XPath expressions as this would not be parsed. To overcome this, a number of constructor functions have been included to create values of these SVG types. For example, the expression 1cm + 1in is not valid and will result in a parse error. To add these two lengths the expression c:Length('1cm') + c:Length('1in') should be used.

Expressions can also be used for CSS properties.

Variables

There is a new element c:variable which allows the SVG author to define local variables in the document. This allows complex expressions to be broken up and reused. These variables can be referred to in the XPath expressions using the normal XPath syntax, that is, a $ character followed by the variable name. Variables are scoped similarly to those in XSLT documents.

Interaction

When the user needs to be able to interact with the SVG document event handlers can be used, as in standard SVG. These scripts will often be much shorter, however, as the layout logic is within the expressions used on the element attributes. A simple one line function can be used to modify the value of a CSVG variable (not a script variable) which will alter the presentation.


Last updated: 12th February, 2004