SVG Off Road and Stretched

Table of Contents

SVG Off Road
SVG Stretched
Why Stretch SVG?
Rich, Shaped, Multi-Lingual Text
New and Enhanced Animations
New Graphical Elements

SVG can do more than just display exciting graphic content. SVG can also be the vehicle for widespread use of graphics throughout an otherwise ‘traditional’ software application—alongside and interacting with other types of display components, modified dynamically, and extended with custom elements. This paper describes the main SVG-related features of an application that does just this: a product to assist business analysts specify the requirements of a system (from which Stephen Withall’s book “Software Requirement Patterns” is a spin-off).

Taking SVG off road means venturing beyond a dedicated piece of screen real estate where SVG rules (where an SVG document defines everything that’s displayed, and SVG software is in complete control). SVG off road encounters non-SVG content displayed in various ways, and must react sensibly to it. In particular, this application can display documents of various kinds, and display additional information in independent layers above it (while the original document shows through underneath). SVG is an excellent medium for defining the content of these layers (which are referred to as ‘frills’, displayed using ‘frillers’).

Four types of frillers are demonstrated here, all of which use SVG (though they’re not forced to; future frillers need not). Firstly, ‘Overlay’, for displaying fixed (or semi-fixed) information—such as material common to all slides in a presentation. Secondly, ‘Spur’, to display small symbols at places where the underlying document contains secondary (hidden) information. These symbols must move and adjust themselves whenever the document is edited or changes its display (for example, when it scrolls). Clicking on a spur causes more information to be displayed, using another friller. Thirdly, ‘Caption’, to display additional text, such as a comment from a reviewer of the document. Fourthly, ‘Pearl’ (as in ‘pearl of wisdom’), to provide animated, interactive guidance on how to write a particular section of a specification.

This sort of environment places extra demands on SVG that it does not face when it is used stand-alone:

  1. Each SVG document must be changed dynamically in response to changes to the underlying document (and sometimes other frillers too), as mentioned for ‘spurs’ above. SVG does not need to be enhanced to meet this demand, but enhancements make it easier.

  2. SVG elements must be resized and repositioned when the display window is resized (and these can in turn cause yet more elements to be adjusted). To achieve this, the SVG document must define how we want to position and size elements, not just where and how big (in absolute terms). The answer is to define the requisite attributes using expressions, which are described later in this paper.

  3. SVG is used to display content (principally text-based content) that is defined elsewhere. An SVG document is used to define how to display particular types of content. Further, introducing that content on to the screen is often done animatedly—for which new types of animation elements have been introduced, both for convenience and to achieve special effects.

Another characteristic of this environment is that the role of SVG documents subtly changes. In common SVG usage, there is a one-to-one mapping from an SVG document as written to an SVG document as displayed (ignoring references to external resources). Here, however, a written SVG document act as a template, from which separate instances are created and edited for display. In some cases (such as ‘spurs’), the instances bear little resemblance to the template. The SVG templates act as one visual aspect of the application’s configuration.

Having multiple frillers displaying SVG documents simultaneously adds other complications—albeit relatively minor ones. User interaction and event handling have to involve all frillers, and there might be multiple animation ‘engines’ (one active and one paused, for example).

On the other hand, this approach is highly modular, which means that each piece is considerably simpler than it would if it had more responsibilities. This is especially beneficial for the (non-SVG) software that displays the underlying document: it need know nothing about what’s going on above. Indeed, these frillers work with unmodified standard Java GUI components.

Another benefit is a clear distinction (as clear as we’re likely to find) between the semantic and the visual aspects of the application’s configuration (with SVG documents and style sheets taking care of the visual). That is, regarded as a model-view-controller (MVC) architecture, this separates the model and view parts.

Meeting all these challenges with standard SVG is difficult (if not impossible), so this application has stretched SVG with a wide range of enhancements, which is the subject of the next section.

Before enhancing SVG (or, indeed, enhancing anything), one should understand one’s reasons for doing so—because if your motivations aren’t clear, your results are liable to lack coherence. Here are some good reasons (which underpin most of the enhancements described in the following sections):

  1. To display things that are impossible, impractical or tedious to achieve in another way. (It’s worth recognizing that this reason can be sub-divided into the serious and the frivolous, with a continuous range in between.)

  2. To capture the intent (meaning, purpose) of the elements, rather than merely their appearance.

  3. To make elements easier to write, edit and understand.

  4. To make SVG documents more concise (smaller).

  5. To avoid repetition (and consequently errors, and save time and effort).

  6. To avoid the need for scripts (or to simplify scripts).

These reasons go very much hand in hand (are mutually reinforcing), especially 2-6, and there is a lot of overlap between them. For instance, smaller documents are almost inevitably easier to write and have less repetition.

The remainder of this paper describes various ways in which this application stretches SVG beyond the standard: new elements and other features. They are all implemented and running (although they’re not all complete or taken as far as they usefully could be). Some of these enhancements have been made to achieve the functionality described in the ‘SVG Off Road’ section above—but many have been added for other purposes (though generally for one or more of the reasons just listed).

All these enhancements have been developed in isolation, with little attention paid to what others might be doing. They’re not all original. This paper does not advocate their inclusion in the SVG standard, and leaves it to the reader to judge the wider merits of each one.

None of these enhancements involve the use of scripts (other than trivially, to call a method in response to a user action). Scripts would considerably inflate the SVG documents used, and make hard-to-follow code visible—and so contravene most of the reasons listed above, as well as making the application fragile and insecure.

The editing and display of large bodies of well-formatted, rich text is an essential feature of many software applications, including the one this paper describes. The textual elements in SVG were not designed for this purpose—quite reasonably. Though the SVG <text> element (with its friends, <tspan> and <tref>) is capable of rendering any text one could reasonably want, they cannot be regarded as ‘heavy duty’. The <textArea> element introduced in SVG Tiny is a help in the ‘tiny’ environments it is designed for, but not in a serious desktop application. Rather than dwell on what is required, let’s move on directly to the description of an alternative used in this application, and what it’s capable of.

The <label> element is a container of rich text. A <label> is the child of another (‘labellable’) element that defines the shape in which text is to be drawn. At present, only rectangular elements are ‘labellable’ (<rect>, <image>, <use> plus the <page>, <cylinder> and <lozenge> elements described below). A labellable element can contain multiple labels, which can then display pieces of styled text at different positions within it (top, bottom, middle, left, right).

An open, non-prescriptive approach has been taken to what a <label> can contain. A label’s children can be a mixture of text and any XML elements. A style sheet is used to decide the appearance of each type of XML element (according to its element name). To achieve this, individual styles use a range of new properties for spacing lines and paragraphs, bullet characters, indents, and vertical and horizontal alignment.

In addition, a set of element classes is implemented for particular types of formatting: for ordered and unordered lists; and customary styling of text runs (italic, bold, underline, color and so on). One special element is <pick>, which allows alternative pieces of text to be defined in multiple languages; only the text in the prevailing language is displayed, which can be changed animatedly when the user wishes—using transition animations, described in the section that follows. This helps text play its part in the visual richness that sets SVG apart from more workaday formats (such as HTML).

Standard SVG animations suit many purposes and their attributes offer a dizzying range of options—but this very flexibility sometimes makes creating a simple animation more work than it otherwise would. And some animation effects cannot be achieved using the standard elements (at least, not in a way that a reasonable person could achieve in practice). This application introduces two new roles for animations (in addition to the ‘normal’, or general purpose, role that existing animations are deemed to fill):

  1. Transitions, to gradually switch from one manifestation of an element to another—in particular, to switch from one language to another. Two types of transition are implemented, and more are likely to follow.

  2. Introducing graphical elements (bringing them on to the screen), and removing them again. This is a frequent task, and perhaps the commonest single use of animation. This is referred to as the ‘ingress’ and ‘egress’ of elements—collectively gresses. Achieving ingress or egress using standard SVG (typically <animateMotion>, <animateTransform>, or <animate> to change opacity) fails to state this as their purpose, involves more attributes than ought to be necessary (such as the off-screen position from which to move from), and can necessitate changes if the target element is modified. The behavior of a move (<animateMotion>) gress also adjusts automatically to suit the size of the display window and panning. Elements have been introduced for a couple of types of gresses (plus the transitions, which can be used as gresses too).

The role of each animation element can be stated explicitly (via a ‘role’ attribute), or it can be deduced implicitly. Most elements support only a subset of the possible roles.

The “SVG Off Road” section above mentioned the need to define how graphical elements are to be positioned and sized, not merely giving them fixed values. Expressions—formulas that express what you want to achieve—are a powerful and elegant way to do this. (It’s not the only possible way. Bespoke positionally-aware elements were tried, but they were ugly and inflexible.) Here are a few example attributes:

  • width="MainCircle@r * 2"

  • x="FirstRect.right + 5mm"

  • x="((view.Width - 760) / 2) + view.X"

A sweet feature of expressions is that they add considerable power to many attributes in many elements without adding a single attribute to a single element.

Expressions can use the four common arithmetic operators, a range of trigonometric and familiar mathematical functions (min, max, sqrt and so on), standard boolean operators, and random numbers. Variables in expressions can refer to the values of attributes (the ‘r’ attribute in the ‘MainCircle’ element, in the first example), methods in element classes (the getRight() method in the ‘FirstRect’ element, in the second example), and details about the screen (such as its width or height, ‘view.Width’ and ‘view.X’, in the third example).

Expressions are data type-aware. So an expression that yields the wrong type of value for the attribute it belongs to will be rejected. And fixed values valid for that data type are allowed within an expression (as in the ‘5mm’ in the second expression).

Expressions have been implemented, in this application, as an XML feature (not for SVG alone). Any attribute in any XML can have its value defined by an expression, provided its data type is one that supports expressions. (Only data types used in defining the size and position of SVG elements are ‘expressionable’ thus far: floating point numbers and SVG lengths, plus lengths of time. But this is a recent enhancement, and the possible uses of expressions are many and varied.)

You can probably draw anything using a tiny number of SVG graphical elements. (Would <path>, <text> and <image> suffice?) But who would use a <path> when a <line>, <rect> or <ellipse> would do the job? And why is that? Because these elements are easier to understand and simpler. Let’s face it, who can comfortably read the ‘d’ attribute of a<path>? A <path>’s intent is certainly not self-evident.

A range of new graphical elements have been implemented in the application described in this paper. They are divided here into two categories—general purpose (flexible) elements, and specific shapes—to help the reader judge how widely applicable they might be. Elements categorized as general purpose are likely to prove useful in any environment; specific shapes are more liable to be useful only in certain domains.

Two new general purpose graphical elements have proved to be very helpful and are widely used:

  • <boundary>: A <boundary> draws the nett shape of its children. <paths> are often used to represent the combining of several shapes, but in doing so the original shapes are lost. A <boundary> can do the same thing but retains those shapes, so it can easily be edited and is straightforward to understand. The simplest type of boundary adds its children together, but other combining operations are possible: subtract, intersect and exclusive-or. The children of a <boundary> are not themselves drawn, but any <label> elements they contain are (that is, their text). In this way, <boundary> elements can be used as the basis for captions, which display of extra information about an object to which it points (where an arrowed line that’s part of the caption does the pointing).

  • <multiplicity>: A <multiplicity> draws a shape (defined by a child element) multiple times, in a straight line defined by a ‘Direction’ attribute. It was implemented to signify the presence of multiple objects (in technical diagrams), but finds other uses too. Two dimensional arrays of objects can be created by nesting <multiplicity> elements.

Notable non-standard specific shape elements implemented are:

  • <regularPolygon>. A <regularPolygon> is a straightforward element, which is defined by the number of sides it has plus the circle on which its points lie. (Indeed, the regular polygon class extends the circle element class, so it shares all its attributes.) It can also optionally have a ‘RotateAngle’ attribute that defines the angle of one of the points to the vertical. <regularPolygon> was implemented as a stepping-stone towards the <star> element.

  • <star>: A <star> can be defined using the same attributes as a <regularPolygon> (except it has a ‘Points’ attribute instead of a ‘Sides’ attribute, because it makes more sense), but it has a couple of extras. Firstly it can (optionally) have an ‘InnerCirclePercent’, which specifies the radius of the circle on which the inner points reside, expressed as a percentage of the main (outside) circle’s radius. Secondly it can have an ‘OrientTo’ attribute, to specify a co-ordinate towards which the star is to point.

  • <cloud>: As we enter the era of cloud computing, will people want to draw clouds more often? The <cloud> element takes care of what is otherwise a tricky object to draw. A <cloud> is based on an <ellipse>, so its size and position are defined using an <ellipse>’s attributes for those things. Its complexity means a <cloud> element has a relatively large number of attributes, its main characteristics being its visual style (two are supported: simple lines, or complex crescents), and the number of ‘bumps’ that define its outline. The actual appearance of each cloud is randomized (to make each one unique), though a particular cloud can be made invariable by means of a ‘RandomSeed’ attribute.