XML MATTERS #39: Scalable Vector Graphics Flexible and portable XML language for graphics David Mertz, Ph.D. Drawn This Way, Gnosis Software, Inc. March 2005 SVG (Scalable Vector Graphics) is an XML format that describes scale-independent graphics, with good support in Free Software and commercial tools. SVG is versatile and powerful, supporting both scripting and animation, as well as the full collection of shapes, fills and curves that you would expect from a vector format. Perhaps best of all, SVG is XML, so lends itself to transformation and/or generation with any of the tools and libraries you might use for XML generally. INTRODUCTION ------------------------------------------------------------------------ The fact is that there were already quite a few powerful vector graphics formats before SVG was first imagined around 2001. Postscript and its cousin PDF are widely used in many applications. More application specific formats include AI (Adobe Illustrator; Postscript based), CDR (CorelDRAW!), CGM (Computer Graphics Metafile), WMF (Windows Metafile), DXF (Autocad), HPGL (Hewlett-Packard Graphics Language), WPG (WordPerfect), and many others. For vector drawings that can even incorporate animation, sound and interactivity, Macromedia's SWF/Flash is common for content distributed on the World Wide Web. The main thing that distinguishes Scalable Vector Graphics from all these other formats is that it is an application of XML. While that same fact means that an equivalent graphic will probably be described considerably more verbosely in SVG than in most other vector formats, it also means SVG is more versatile to programmatic manipulation. In particular, SVG may be manipulated within web browsers (or other applications) using ECMAScript and the Document Object Model (DOM). And equally, SVG may be transformed and/or produced using familiar XML techniques like XSLT, or with XML support libraries. SVG can be mixed with other XML formats using namespaces. Moreover, SVG can even be stylized using CSS. Overall, SVG is a friendly player in XML and web space. Beyond being an XML format, SVG is also a fully open standard published by the W3C (see Resources). Unlike most of the vector formats mentioned above, SVG is free of any patent or copyright restrictions, and its specification is -fully- documented. Like other W3C standards, the specification document itself -is- copyrighted; but under W3C's non-restrictive terms that allow widespread and no-cost reproduction and utilization (e.g. no NDAs attach to reading the specification). GETTING STARTED ------------------------------------------------------------------------ A nice thing about Scalable Vector Graphics is that viewing SVG is already widely supported by most modern web browsers, either natively or via plug-ins. The exact state of support is somewhat in flux, but with the right mojo, you should be able to view SVG using Firefox/Mozilla, KHTML (i.e. Konqueror and Safari), Opera, or Amaya. Using plug-ins from Adobe or Corel you can even coax Internet Explorer into displaying SVG (or so I understand). A number of standalone viewers for SVG also exist, especially utilizing the Free Software Batik SVG Toolkit (part of the Apache XML project). In many cases, you will view SVG files as standalone documents. If so, these files will should be served as MIME type 'image/svg+xml', and will generally have the file extension '.svg'. Gzip compressed SVG files should have the extension '.svgz', and are directly supported by most SVG enabled tools. And SVG file is just an XML file with an appropriate document type declaration. We will see this declaration in several examples below However, perhaps even more commonly, an SVG document can be embedded within a larger document, particularly within an XHTML page. Other compound XML formats, such as OASIS OpenDocument also do or will support, embedding SVG within them. There are, three main ways you might include an SVG graphic within an (X)HTML page: the '' tag, the '' tag, and as an embedded namespace. Unfortunately, exactly which of these actually works depends on your browser and version. For example, I created the following XHTML document (with a doctype intended to support namespace nesting): #---------------------- svg-nested.html -------------------------# SVG as embedded object and nested namespace

Object tag

Your browser is currently unable to display SVG images.

Nested namespace

Four rectangles

Embed tag

Safari/KHTML does the best of the browsers I tried. Even here, the results are better if the file is -named- with an '.html' extension than with an '.xml' extension. Overall '' seems like the most successful approach. You might see this document rendered something like: {Web browser displaying svg-nested.html: http://gnosis.cx/publish/programming/svg-in-html.gif} Incidentally, the examples I present in this article are rather simple combinations of basic shapes, text, colors, etc. But SVG is fully capable of representing complex and attractive drawings. Just to comfort readers, here is the famous Postscript tiger picture included with Ghostscript and other tools, rendered using SVG (I only touched up its overall sizing): {Web browser displaying the famous tiger as SVG: http://gnosis.cx/publish/programming/tiger-safari.gif} FEATURES OF SVG DOCUMENTS ------------------------------------------------------------------------ The prior XHTML example showed you a very basic SVG drawing. The external file 'standalone.svg' that is referenced contains the same elements as are embedded in the XHTML, minus the extra namespace qualifier in the tags. SVG gives you a number of graphic primitives, and each primitive has various XML attributes that further specify the graphic: color, size, position, fill, outline, etc. However, explicit graphic primitives for ellipses, rectangles, polygons, etc.--or for more sophisticated '' elements that might include cubic or quadratic Bezier curves--are often included within '' elements to group several primitives together. The nice thing about a '' group is that it can be scaled, moved, styled, and otherwise modified as a whole. Modifications to the group generally apply to the collection of shapes within them (including nested '' groups). This is especially useful when SVG documents are scripted. All The Way Down One thing to notice about SVG documents is that they are not really XML "all the way down." Syntactically, SVG -is- indeed XML, but a significant portion of the information content of an SVG drawing is contained within comma- and space-delimited data inside SVG attributes. When I mention -information content-, I am not speaking of XML Infoset, but only of the more informal idea of "what does it contain." Doing it this way is a reasonable compromise, by all means, since using child elements for every point or handle that defines a curve would make SVG even more verbose. But XML-level processing techniques like XSLT can thereby not really do much with path data. For example, this is a quadratic Bezier path element: #------------------ Quadratic Bezier Path -----------------------# Or this is a polygon: #------------ Polygon describing a pentagram --------------------# Adding Style I mentioned earlier that you can use CSS selectors and syntax to modify the appearance of SVG drawings. As with HTML and other CSS-supporting formats, you may either specify CSS information inline or as a reference to an external stylesheet. A very simple example of inline CSS is: #--------------------- inline-styled.svg ------------------------# While you can certainly style an entire tag using CSS, a better use for CSS with SVG is probably using class selectors. For example, you might define a variety of types of rectangles within a stylesheet, then attach a 'class' XML attribute to each one in your drawing rather than repeat the full list of colors, fills, strokes, etc. that you define for the class. Just by changing the stylesheet, you can change the overall look of your diagram to make it more suitable for a different context. Reusing Elements Beyond the use of CSS, the 'inline-styled.svg' example showed another nice feature of SVG. You can include predefined content within an SVG document--either content defined within or outside the document being rendered. One way of using predefined content as part of an SVG drawing is with the '' element. In concept, '' in SVG is very similar to '' in HTML. The element simply instructs the rendering client to draw the content of an external image--which may itself be either SVG or a raster image in JPEG or PNG format--inside the current SVG context. Much as if the external image were a regular graphic element, you can size and position it. E.g.: #---- Including external SVG drawing within the current one -----# Perhaps more interesting than the '' tag are the complimentary elements '' and ''. The first, which we saw with the CSS example, lets you create SVG elements that are not directly rendered when defined--normally the SVG rendering model draws each object in exactly the order it occurs within an SVG document, each overlaying the last. But '