Introduction to the Batik project

Thomas DeWeese (thomas.deweese@kodak.com)
Eastman Kodak
1700 Dewey Ave.
Rochester, NY 14650-1805
USA
Tel: (716) 477-8247
Fax: (585) 722-7417

Vincent Hardy (vincent.hardy@sun.com)
Sun Microsystems Inc.
13, avenue Morane Saulnier - B.P. 53
78142 VELIZY Cedex - France
Tel: (33) 04 97 23 90 29
Fax: (33) 04 92 38 78 22

Keywords: SVG, Java, Toolkit, Generation, Browser

Abstract

Batik is an open-source project at the Apache Software Foundation. Batik is a Java(tm) technology based toolkit for applications that want to use Scalable Vector Graphics (SVG) images for various purposes, such as viewing, generation or manipulation. The project's ambition is to give developers a set of core modules which can be used together or individually to support specific SVG solutions. The Batik project is further described at: http://xml.apache.org/batik.
The goal of this session is to introduce SVG content developers to the Batik project and explain what can be done with the Batik software components.

Introduction

Session Goals

Batik is an open-source project at the Apache Software Foundation. Batik is a Java(tm) technology based toolkit for applications that want to use Scalable Vector Graphics (SVG) images for various purposes, such as viewing, generation or manipulation. The project's ambition is to give developers a set of core modules which can be used together or individually to support specific SVG solutions. The Batik project is further described at: http://xml.apache.org/batik.

The goal of this session is to introduce SVG content developers to the Batik project and explain what can be done with the Batik software components.

Agenda

The first part of this session gives some background on the Batik project, how it started, its status, and accomplishments.

The second part of the presentation focuses on how what the Batik components are and how they can be used.

Finally, the last part of the presentation shows demos of how the various components can be used in practice.

Part I: Background

Batik's History

The Batik project started out during the summer of 2000. At that time, several organizations recognized that:

1) several teams in the industry were attempting to implement the SVG specification on the Java platform

2) none of the teams had the resources to do a complete implementation of the SVG specification. Each had different strengths and

3) existing teams and other partners were interested in making a joined open-source effort

Following, Sun convinced the various teams to join into an open-source effort:

a) Kodak, which brought no code but an extremely valuable expertise in image processing

b) INRIA/Koala team, a French research organization that had the most solid SVG implementation at the time

c) ILOG, a French software company that brought resources and expertise.

d) Sun contributed software (from the Java Advanced Imaging team, the Java 2D team, and the XML Technology center, with the SVG generator) and resources

More recently, BitFlash has joined the effort.

Work actively started in October 2000 when the various contributors started to integrate the various contributions while the project infrastructure (CVS code repository, mailing lists, web site, etc...) were put in place. The first release came in December 2000.

The Batik team is made of commiters (who actively work on the code and have rights to modify the Batik code base), contributors (who submit contributions, bug reports and bug fixes) and users (who use the software and sometimes report bugs).

Note: What does Batik mean? Batik is an ancient textile art form from what is currently called Indonesia. This is an especially apt name because Batik often has a vector graphics appearance, as well as the fact that the island of Java is part of Indonesia.

Batik Goals

The goal of the Batik project is to help developers add support for SVG in their applications by delivering software components, which can be easily integrated. Batik delivers core components that can be used either separately or in combinations for various purposes, from exporting graphical data in the SVG format to transcoding SVG images to other formats to adding SVG viewing capability to an application.

Our goal is to deliver "one-stop shopping" for all kinds of SVG tools.

Note that the project provides sample applications built on the Batik components, such as an SVG Browser (called Squiggle), an SVG rasterizer and an SVG pretty printer. However, these applications are examples of what might be done with the Batik components and are not the primary deliverables of the project.

Accomplishments

Cocoon and FOP are both using Batik to handle SVG content.

Started work in October 2000.

Released Beta 1 in December 2000.

Version 1.0 is a fully compliant Static Viewer for SVG (excluding some advanced text features).

Version 1.5 will be a fully compliant viewer with scripting support. 1.5 beta 3 was released in June 2002.

Version 2.0 will be a fully compliant Dynamic Viewer with support for SMIL animation. Work has started since May 2002 and the team got contributions from CSIRO and the XSmile team.

Part II: Batik Components

Batik Use Cases

As we expect SVG to become a dominant format on the Web, it becomes important to be able to deal with SVG content in various contexts. The figure illustrates how and where Batik might prove useful.

On the content creation side, or in the infrastructure, applications can use either the SVG Generator or the SVG DOM to create SVG content. For example, an application can easily export its statistical graphs, or spreadsheet with the SVG generator.

In the infrastructure, SVG can be used to represent all types of 2D graphical data: engineering diagrams, advertisements, animations, etc... If the image needs to be served to a client that does not support SVG, the SVG transcoders can be used to turn the SVG content into other formats, such as PNG, JPEG, or PDF. Batik helps Web Services exchange, manipulate and transform graphics: because it is an XML syntax, it blends well with all the other XML technologies found in that space.

Finally, while some browsers might support SVG natively, but, for others it might be necessary to offer viewing of SVG content in an applet or a separate application: the Batik UI Component can be used for this sort of data visualization.

These are just a few examples and there are other creative uses for Batik. The user and developer mailing lists show that developers are using Batik for a wide array of applications, such as leveraging GVT (Batik's core rendering framework, Graphic Vector Toolkit) to be the core rendering engine in an engineering drawing tool, or using SVG and Batik to render mathematical expressions described in MathML (an XML syntax for mathematics).

Another project example is an SVG validator built on Batik. This is a W3C project led by Thierry Kormann of ILOG and Chris Lilley, the SVG Working Group chair. The hope is to ensure that content truly conforms to the specification, checking for unknown attributes or unknown CSS properties/values. This project leverages the Batik toolkit.

Generating SVG Content

The image is from JChemPaint, an open-source project to make a general purpose editor for 2D chemical structures. This project uses the svggen package from Batik to translate the contents of the editor window into a static SVG file. This gives them an easy way to export high quality viewable/printable content.

Batik contains a utility to convert True Type Fonts to the SVG format. This can be very useful to subset fonts which can then be embedded in SVG files, which is better than relying on system fonts.

The Batik DOM implementation can be used to generate SVG content, for example business cards as the ones shown here.

Viewing SVG Content

The SVG Browser (Squiggle) is a simple Java application that allows users to view SVG content. With it users can zoom, pan and rotate, print, view the source, view the dom tree, check memory usage and control user options such as preferred language or proxy servers.

JSVGCanvas is a general purpose Swing component that can be used to display any SVG document. This makes it trivial for any Java application to add support for displaying SVG content. This class is used for all the display aspects of the SVG Viewer.

An example of using the JSVGCanvas in an application is the tool we are using to display our SVG presentation. It is a very simple Java application which uses a frameless window containing an JSVGCanvas.

Finally, note that the Squiggle SVG Browser lets users capture the current state of an SVG document which is useful when the state of the document is modified over time (by scripts).

Converting SVG documents to bitmaps

If all you want to work with is a "normal" (raster) image, Batik can help.

The SVG Rasterizer is a command line Java application that allows one to convert SVG content to traditional raster formats. Currently JPEG, PNG, and TIFF are supported. Eventually, we may add more formats, especially now that Java Image I/O has been released with JDK 1.4.

The rasterizer application offers a large number of options such as control over the width, height and resolution of the image. You can also control the portion of the image to be converted as well as its background color. Note that the user can decide to let scripts be run before the image is converted, thus enabling dynamically generated images to be converted as well as static images.

If you want to render SVG content inside your own application, and for whatever reason JSVGCanvas is not useful, you might want to use the ImageRenderer class, which is how both the JSVGCanvas and the ImageTranscoder classes get a rasterized version of the SVG document.

Imaging experts and people who have existing imaging infrastructure associated with Java Advanced Imaging will be interested to know that in addition to the Renderer interface, Batik's filters are implemented using the RenderedImage and RenderableImage interfaces. This makes it relatively easy to feed SVG data into JAI rendering chains, and vice versa.

Pretty Printing SVG

When handling large number of SVG files (such as when building a whole site in SVG), it is useful to format these files easily. The SVG Pretty Printer included in the Batik distribution is meant to help doing that and lets users apply a number of options to their SVG contents, such as the DOCTYPE, line width, tabulation width and more.

Part III: Demos

SVG & Media Types

<?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?>
<?xml-stylesheet type="text/css" href="../../resources/style/cssMediaScreen.css" media="screen"?>
<?xml-stylesheet type="text/css" href="../../resources/style/cssMediaProjection.css" media="projection"?>
<?xml-stylesheet type="text/css" href="../../resources/style/cssMediaPrint.css" media="print"?>

This example shows how an SVG image can leverage the CSS @media rules to create content which can adapt to different output media such as screen, presentation or print.

cssMediaA cssMediaB

The demonstration shows a sample SVG file which produces radically different rendering depending on the selected media type, something the Squiggle browser lets you control.

Finally, the demonstration shows that the Batik rasterizer lets you control for which media type a raster image should be created, thus letting the user create various rendering of the same SVG image, one for each media type it supports.

Structuring Content

...
<!-- ============================================================= -->
<!-- Batik sample mark                                             -->
<!-- ============================================================= -->
<use xlink:href="batikLogo.svg#Batik_Tag_Box" />
....

markers

This demonstration shows a simple example of how structuring SVG content with 'external' <use> element can help reduce content management cost as it makes it easy to modify and maintain SVG content. The example also shows that this is a better solution compared to re-using SVG content by using scripts and getURL/parseXML to dynamically include content.

Conclusion

Summary

The Batik software delivers components to application developers who can integrate them for building applications around SVG. For example, it is possible to build a graphical SVG editor based on the Batik components.

Content developers will find a number of utilities and tools in the Batik project which will help them dealing with SVG content. For example, the SVG pretty printer and SVG True Type font converter help manage content and create SVG files which will render consistently across platforms. Of course, the Batik Squiggle browser is useful to visualize SVG content and manipulate options such as CSS parameters or preferred user language.

Additional Technical Information

Architecture

There are thee major areas to the Batik Architecture.

The first area are the pieces that construct SVG DOM trees. These include the svggen package, which uses a Graphics2D to build an SVG DOM tree, and our Document Factory class, which parse XML to generate an SVGDocument.

The second area are the pieces that work directly off the DOM tree. There are a number of these. Just to name a few our DOM implementation (of course), the Transcoders (which can also handle building the DOM tree internally), an SVG Pretty Printer, which outputs nicely formatted XML, and the bridge package.

The bridge package is responsible for constructing and maintaining a view of the DOM tree that is more suitable for rendering purposes. This is called the GVT or the 'Graphics Vector Toolkit'.

The GVT tree represents the hub of the third piece of the Batik toolkit, which is the piece responsible for rendering and interacting with SVG content.

This piece includes the JSVGCanvas, which is used by the viewer application, a Renderer package that simplifies the task of rendering a GVT tree, and the GVT tree, and all it's classes.

Using ImageTranscoder

public static void writeJPEG(String uri,
                             OutputStream dst) {
    
    ImageTranscoder trans = new JPEGTranscoder();
    trans.addTranscodingHint
        (JPEGTranscoder.KEY_XML_PARSER_CLASSNAME,
         "org.apache.crimson.parser.XMLReaderImpl");

    try {
        trans.transcode(new TranscoderInput(uri),
                        new TranscoderOutput(dst));
    } catch (TranscoderException te) { ... }
}

The Transcoder API is a high level API and it hides a lot of the details. Therefore, it is a good starting point.

The code constructs a JPEG Transcoder, and calls the transcode method with the URI of the input XML and an Output Stream that will have JPEG data written to it.

As you can see you can specify the XML parser that should be used. There are also hints for the compression level to use, and final image size that can be specified.

Using JSVGCanvas 1/2

public static SVGDocument read(String uri) {
    SVGDocumentFactory df 
        = new SAXSVGDocumentFactory
          ("org.apache.crimson.parser.XMLReaderImpl");

    try {
        return df.createDocument(uri);
    } catch (java.io.IOException ioe) {
        ioe.printStackTrace();
    }
    return null;
}

This code shows all the work needed for reading an SVG Document from a URL and constructing an SVG Document from it.

First we construct an instance of the SVG document factory for SVG from Batik's dom.jpeg package. Then we use its 'createDocument' method to build the SVGDocument that we then return to the caller.

Note that it allows you to specify which SAX parser it should use.

Using JSVGCanvas 2/2

public static JComponent createSVGCanvas
             (SVGDocument document) {
    JSVGCanvas canvas = new JSVGCanvas();
    canvas.setSVGDocument(document);
    return canvas;
}

This is all it takes to show an SVGDocument in your Java application. Construct the Canvas, and provide the document. This will automatically fill the Canvas with the SVG content according to the outermost svg tag's viewPort settings.

Creating SVG Content 1/3

Graphics2D g = ...; // e.g., SVGGraphics2D
g.setPaint(new Color(125, 72, 255));
g.fillRect(10, 10, 200, 50);
g.setPaint(Color.white);
g.setFont(new Font("SunSansCondensed-Heavy", Font.PLAIN, 20));
g.drawString("Hello Java 2D to SVG", 40, 40);<g>
  <g fill="rgb(125, 72, 255)" stroke="rgb(125, 72, 255)" >
     <rect x="10" y="10" width="200" height="50" stroke="none" />
  </g>
  <g font-family="SunSansCondensed-Heavy" fill="white" font-size="20" 
     stroke="white" >
     <text x="40" y="40" stroke="none" >Hello Java 2D to SVG</text>
  </g>
</g>

<g>
  <g fill="rgb(125, 72, 255)" stroke="rgb(125, 72, 255)" >
     <rect x="10" y="10" width="200" height="50" stroke="none" />
  </g>
  <g font-family="SunSansCondensed-Heavy" fill="white" font-size="20" 
     stroke="white" >
     <text x="40" y="40" stroke="none" >Hello Java 2D to SVG</text>
  </g>
</g>

On the Java platform, the Graphics2D abstract class is the embodiment of the Java 2D API and represents the interface programs used to do any type of rendering: drawing strings of text, fill shapes with arbitrary types of paints (e.g., solid colors, transparent colors, gradient paints patterns), or draw images.

There are different concrete implementations of the abstract Graphics2D class for the different outputs. That is, a different concrete implementation of Graphics2D will be used to render to a screen, or to render to a printer. The advantage of having all the implementations extend the same abstract base class, is that programs only depend on the interface and not on concrete implementations: the same code will work for any implementation of the Java 2D API, which is why that API is said to be output device independent.

The output device independence is illustrated in the first code snippet of the slide where you can see that the rendering calls made on the Graphics2D object (g), are the same no matter what the concrete implementation of Graphics2D is.

The SVGGraphics2D class is an implementation of Graphics2D. As a consequence, a Java program that does rendering will be able to use it without modification. This new implementation of Graphics2D generates SVG content, instead of drawing to a screen or a printer.

The second half of the slide shows the SVG content generated by the SVGGraphics2D class. The big advantage of that class is that it can be used by any Java program that does graphics as easily as these programs print or draw to a screen, with no code changes.

Creating SVG Content (2/3)

// Create an instance of HelloSVG
HelloSVG helloSVG = new HelloSVG(...);

// SVGGraphics2D extends Graphics2D
SVGGraphics2D svgGenerator = ...;

// Now, ask helloSVG to render into our
// custom Graphics2D implementation
helloSVG.paint(svgGenerator);

// Finally, stream out SVG to the standard output
Writer outWriter = new OutputStreamWriter(System.out, "UTF-8");
svgGenerator.stream(outWriter);

This slide illustrates how an application doing some arbitrary rendering (the HelloSVG class in our example), can work with the SVGGraphics2D class to export SVG content because SVGGraphics2D extends the abstract Graphics2D class.

The SVGGraphics2D class leverages the extensible architecture of the Java 2D API and allows all Java applications to export their graphics to the SVG format.

Creating SVG Content (3/3)

import org.w3c.dom.*;

Document doc = ...; // Depends on DOM implementation
Element svgRoot = doc.createElement("svg");
svgRoot.setAttribute("width", "500");
svgRoot.setAttribute("height", "500");
...
Element rect = doc.createElement("rect");
rect.setAttribute("fill", "red");
...

This simple example is a reminder that because SVG is an XML syntax, any DOM implementation can be used to create and manipulate SVG content.

Of course, using the SVG DOM extension makes creating SVG content easier in some cases, but it is not required, as shown in this slide's example.

Exporting to other Formats

Graphics2D g = ...; // Depends on actual implementation
g.setPaint(Color.red); 
...
g.fillRect(20, 30, 600, 300); 

In the Batik architecture, SVG documents are loaded into a DOM structure and an equivalent internal object oriented representation of the graphic is created (a GVT tree) through the Bridge module, which is responsible for building and maintaining the relation between the DOM tree and the GVT tree.

A GVT tree can paint itself into a Graphics2D object (an abstract class that embodies the output independent rendering API of the Java 2D API).

Leveraging both GVT and the Graphics2D extensible API, it is fairly easy to write converters from SVG to other formats for static graphics: only a new Graphics2D implementation is needed which, instead of drawing to a screen or a printer, will create a document in the desired format. For example, it is easy to imagine a PDFGraphics2D implementation that would generate PDF content or a WMFGraphics2D implementation that would generate WMF content.

One of the goals of the Batik team is to grow a library of Graphics2D implementation to offer multiple output formats to which SVG documents could be converted.

Using Batik Server Side

This slide shows a simple example of how Batik components might be used server side. In that example, a Web application serves statistical graphics (e.g., stock quotes) to its clients.

The client sends a request (1) which the server turns into a database query (2) after analysis. Then, it uses the data to dynamically build an SVG graphic (3), for example, using the SVGGraphics2D generator or the SVG DOM API. Finally, the server streams the image back to the client (4). If the client supports SVG, then the SVG content can be streamed out as is, otherwise, the SVG image can be converted to another format (such as a JPEG image) before it is sent to the client.


Valid XHTML 1.1!