<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "./dtd/document-v10.dtd">

<!--

   Copyright 2000-2002  The Apache Software Foundation 

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

-->
<!-- ========================================================================= -->
<!-- author spei@cs.uiowa.edu                                                  -->
<!-- author cjolif@ilog.fr                                                     -->
<!-- version $Id$          -->      
<!-- ========================================================================= -->
<document>
    <header>
        <title>SVG Generator: SVGGraphics2D</title>
        <subtitle>A brief of the SVG Generator in Java (SVGGraphics2D)</subtitle>
        <authors>
            <person name="Sheng Pei" email="spei@cs.uiowa.edu"/>
            <person name="Vincent Hardy" email="vincent.hardy@eng.sun.com"/>
	        <person name="Christophe Jolif" email="cjolif@ilog.fr"/>
            <person name="Paul Evenblij" email="paul_evenblij@compuware.com"/>
        </authors>
    </header>

    <body>
        <s1 title="Introduction">

        <figure src="images/svggen.jpg" alt="Batik SVG Generator"/>
        <p>
                As SVG (Scalable Vector Graphics) is emerging as a promising graphics format 
                for a wide range of domains and applications, bridging it with Java becomes important. 
                This page explains how Batik's <code>SVGGraphics2D</code>, referred to as the SVG Generator, makes
                this possible. It is divided into three parts: </p>
                <ul>
                    <li><link href="#whatIsIt">What is <code>SVGGraphics2D</code>?</link></li>
                    <li><link href="#howToUse">How to use <code>SVGGraphics2D</code>?</link></li>
                    <li><link href="#custom">How to customize SVG Generation process?</link></li>
                    <li><link href="#view">How to view the generated SVG document?</link></li>
                </ul>                          

        </s1>

        <anchor id="whatIsIt" />
        <s1 title="What's SVGGraphics2D">
                <p>
                On the Java platform, all rendering goes through the <code>java.awt.Graphics2D</code>
                abstract class, which offers methods such as <code>drawRect</code>, <code>fillRect</code>, or 
                <code>drawString</code>. There are specialized 
                implementations of this abstract class for each type of output, such as a monitor or a printer. 
                <code>SVGGraphics2D</code> is a new implementation of that interface that generates SVG content instead of 
                drawing to a screen or a printer.</p>

                <p>
                <code>SVGGraphics2D</code> provides the following:
                </p>
                <ul>        
                        <li> Allows applications to export their graphics into SVG format. </li> 
                        <li> Does not require any modification of the graphics code to export to SVG. </li>
                        <li> Offers the user the ability to use the DOM API to manipulate the generated document. </li>
                </ul>
                <figure src="images/svggenHighLevelArchi.jpg" alt="High level architecture" />

                <p>
                The above figure shows how the generator works with the DOM API. The W3C has defined an API for representing 
                XML content with a Java programming language object. That API allows programmers to manipulate, create, 
                and/or modify XML content in memory. The DOM API contains interfaces such as <code>Document</code>, 
                <code>Element</code>, and <code>Attr</code>, 
                which model the Java programming language equivalent of XML documents, elements and attributes. 
                </p>
                <p>
                The generator manages a tree of DOM objects that represent the SVG content corresponding to the rendering 
                calls made on the <code>SVGGraphics2D</code> instance. In other words, every time a program invokes a rendering method, 
                such as <code>fillRect</code>, on a <code>SVGGraphics2D</code> instance, a new DOM object, representing 
                the SVG equivalent, is appended 
                to the DOM tree (for example a &lt;rect&gt; element will be appended after the <code>fillRect</code> method 
                has been invoked). 
                </p>
                <p>
                The programmer using this generator can then access the DOM tree to further manipulate it or can directly 
                write the content to an output stream, as we see in the following section. 
                </p>

        </s1>

                <anchor id="howToUse" />
                <s1 title="How to use SVGGraphics2D">
                <p>
                From the figure in the previous section we can see that in order for an instance of <code>SVGGraphics2D</code> to build      
                the SVG content (the DOM tree), an instance of DOM's <code>Document</code> class is needed. The DOM tree is an in-memory
                representation of the SVG document, which can be further manipulated by the user using DOM API or be streamed
                out into any <code>java.io.Writer</code>. 
                </p>
        
                <p>
                The following excerpted code example shows how to generate SVG content from Java graphics.
                </p>
                <source>

import java.awt.Rectangle;
import java.awt.Graphics2D;
import java.awt.Color;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.IOException;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.dom.GenericDOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DOMImplementation;

public class TestSVGGen {

    public void paint(Graphics2D g2d) {
        g2d.setPaint(Color.red);
        g2d.fill(new Rectangle(10, 10, 100, 100));
    }

    public static void main(String [] args) throws IOException {

        // Get a DOMImplementation
        DOMImplementation domImpl =
            GenericDOMImplementation.getDOMImplementation();

        // Create an instance of org.w3c.dom.Document
        Document document = domImpl.createDocument(null, "svg", null);

        // Create an instance of the SVG Generator
        SVGGraphics2D svgGenerator = new SVGGraphics2D(document);

        // Ask the test to render into the SVG Graphics2D implementation
        TestSVGGen test = new TestSVGGen();
        test.paint(svgGenerator);

        // Finally, stream out SVG to the standard output using UTF-8
        // character to byte encoding
        boolean useCSS = true; // we want to use CSS style attribute
        Writer out = new OutputStreamWriter(System.out, "UTF-8");
        svgGenerator.stream(out, useCSS);
    }
}</source>

                <p>
                We can see that generating SVG content from our <code>TestSVGGen</code> instance is a three step
                process:
                </p>
                <p>
                1. Create an instance of <code>org.w3c.dom.Document</code> that the generator will use to build its XML content;
                create an SVG generator using the <code>Document</code> instance.</p>
                        <source>

// Get a DOMImplementation
DOMImplementation domImpl =
    GenericDOMImplementation.getDOMImplementation();

// Create an instance of org.w3c.dom.Document
Document document = domImpl.createDocument(null, "svg", null);

// Create an instance of the SVG Generator
SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
</source>
                <p>
                2. Invoke the rendering code on our SVG generator. In our example, we invoke <code>TestSVGGen</code>'s 
                   <code>paint</code> method: </p>
                        <source>

// Ask the test to render into the SVG Graphics2D implementation
TestSVGGen test = new TestSVGGen();
test.paint(svgGenerator);
</source>
                <p>
                3. Stream out the SVG content. The SVG generator can stream its content into any <code>java.io.Writer</code>. In our 
                        example, we stream the content to the standard output stream:   </p>
                        <source>

// Finally, stream out SVG to the standard output using UTF-8
// character to byte encoding
boolean useCSS = true; // we want to use CSS style attribute
Writer out = new OutputStreamWriter(System.out, "UTF-8");
svgGenerator.stream(out, useCSS);
</source>
                        <p>
                        SVG has two ways of expressing properties, such as the fill color: either XML attributes or CSS inline properties. 
                        The 'useCss' parameter allows the user to control that option. 
                        </p>
                </s1>
  <anchor id="custom" />
  <s1 title="SVG Generator Customization">
  <p>
   In the previous section, we have just seen that the SVG generation process can be customized to output SVG style as XML attributes or CSS inline properties. In this section we will talk about some examples of more advanced customizations.
  </p>
  <p>
         Instead of creating the <code>SVGGraphics2D</code> just by using the <code>Document</code> that will be used as a factory for creating the SVG elements, we can use the constructor that use an <code>SVGGeneratorContext</code> instance. By providing your own <code>SVGGeneratorContext</code> instance, you will be able to do advanced customization. You will find below several examples of possible customizations.
  </p>
  <s2 title="Have your own comment in the generated SVG file">
  <p>
  We begin with the simplest possible example. If you integrate the Batik SVG generator in your own Java application, you may want to specialize the comment generated in the XML code. You can proceed as below.
  </p>
  <source>

SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
ctx.setComment("Generated by FooApplication with Batik SVG Generator");
SVGGraphics2D g2d = new SVGGraphics2D(ctx, false);
  </source>

  </s2>
  <s2 title="Use Embedded SVG Fonts in the generated SVG file">
  <p>
  In order to have a self-contained SVG file that doesn't have to use system fonts to be displayed, you can embed the fonts you used for drawing strings in the SVG file through the SVG fonts facility.
  </p>
  <source>

SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
ctx.setEmbeddedFontsOn(true);
SVGGraphics2D g2d = new SVGGraphics2D(ctx, true);
  </source>

  </s2>

  <s2 title="Customizing the way images are stored">
  <p>
        Every time you call one of the <code>drawImage</code> methods provided by the <code>Graphics2D</code> class,
        a default representation of your image is created in a location and put in a default file. For instance, a base64
        encoding is created and embedded in the SVG file by default. Alternatively, you
        can choose to have your images written to separate files in a predefined directory, in one of the two raster
        formats required by the SVG specification, JPEG, PNG or Tiff.
  </p>
  <p>
        You can change the default behavior by explicitly providing the image handler to be used by the SVG generator.
        Once again, you use the SVGGeneratorContext for this. In the example below, all images are converted to PNG
        format and written to directory "res/images".
  </p>
  <source>

SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
GenericImageHandler ihandler = new ImageHandlerPNGEncoder("res/images", null);
ctx.setImageHandler(ihandler);
SVGGraphics2D g2d = new SVGGraphics2D(ctx, false);
  </source>
  <p>
        Using the default image handlers results in a new copy of the image data being written to the SVG file or an
        external file, for every single <code>drawImage</code> call. If you use the same images over and over again,
        then this may result in an SVG file containing a lot of redundant data. At the price of a slight performance
        penalty during initial generation of the SVG DOM tree, you can choose to have your image data reused. For this
        you use a specialized image handler, as shown below.
  </p>
  <source>

SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);

// Reuse our embedded base64-encoded image data
GenericImageHandler ihandler = new CachedImageHandlerBase64Encoder();
ctx.setGenericImageHandler(ihandler);

SVGGraphics2D g2d = new SVGGraphics2D(ctx, false);
  </source>
  <p>
        With the caching image handlers, it is even possible to reuse the same copy of your image data across
        several different SVG documents. Just keep a reference to the image handler, and pass it to the
        <code>SVGGraphics2D</code> instance used for generating the SVG DOM tree. The following
        simplified example shows how different SVG trees might be created by separate SVG generators,
        efficiently storing any common images just once.
  </p>
  <source>
  
class MySVGGenerator {
    // the image handler will write all images files to "res/images"
    private static ImageHandler ihandler =
        new CachedImageHandlerPNGEncoder("res/images", null);
    
    public void generateSVG(JPanel myCanvas, OutputStream outStream) {
        DOMImplementation domImpl =
            GenericDOMImplementation.getDOMImplementation();
        Document myFactory = domImpl.createDocument(null, "svg", null);
        SVGGeneratorContext ctx =
            SVGGeneratorContext.createDefault(myFactory);
        ctx.setGenericImageHandler(ihandler);
            
        SVGGraphics2D svgGenerator =
            new SVGGraphics2D(ctx, false);

        // create the SVG DOM tree
        myCanvas.paintComponent(svgGenerator);
        
        Writer out = new OutputStreamWriter(outStream, "UTF-8");
        svgGenerator.stream(out, true);
    }
}  </source>

  </s2>

  <s2 title="Customizing the generated SVG style">
  <p>
           Your needs in matter of styling may be different from the two provided options (XML attributes or CSS inline properties). For example you may want to put the CSS properties in a stylesheet SVG element section and reference them through the class attribute. In this case you will need to define a new <code>StyleHandler</code> as below.
  </p>
  <source>

public class StyleSheetStyleHandler implements StyleHandler {
    private CDATASection styleSheet;
    // Build the handler with a reference to the StyleSheet section
    public StyleSheetStyleHandler(CDATASection styleSheet) {
        this.styleSheet = styleSheet;
    }
    public void setStyle(Element element, Map styleMap,
                         SVGGeneratorContext generatorContext) {
        Iterator iter = styleMap.keySet().iterator();
	// create a new class id in the style sheet
        String id = generatorContext.getIDGenerator().generateID("C");
        styleSheet.appendData("."+id+" {");
	// append each key/value pairs
        while (iter.hasNext()) {
            String key = (String)iter.next();
            String value = (String)styleMap.get(key);
            styleSheet.appendData(key+":"+value+";");
        }
        styleSheet.appendData("}\n");
	// reference the class id of the style sheet on the element to 
	// be styled
        element.setAttribute("class", id);
    }
}</source>
  <p>
           Then you can create and use an <code>SVGGraphics2D</code> with a correctly configured 
	   <code>SVGGeneratorContext</code>.
  </p>
  <source>

// configure the SVGGraphics2D for a given Document myFactory
SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
CDATASection styleSheet = myFactory.createCDATASection("");
ctx.setStyleHandler(new StyleSheetStyleHandler(styleSheet));
SVGGraphics2D g2d = new SVGGraphics2D(ctx, false);

// use the g2d to dump drawings (component.paint(g2d))

// add a style sheet to the definition section
SVGSVGElement root = (SVGSVGElement)g2d.getRoot();
Element defs = root.getElementById(SVGSyntax.ID_PREFIX_GENERIC_DEFS);
Element style = myFactory.createElementNS(SVGSyntax.SVG_NAMESPACE_URI, 
                                          SVGSyntax.SVG_STYLE_TAG);
style.setAttributeNS(null, SVGSyntax.SVG_TYPE_ATTRIBUTE, "text/css");
style.appendChild(styleSheet);
defs.appendChild(style);

// dump the root content to a given Writer myWriter
g2d.stream(root, myWriter);

  </source>
  </s2>
  <s2 title="Extending Paint object to SVG element translation">
  <p>
          The <code>SVGGraphics2D</code> is able to generate SVG elements for generic Java 2D objects, but you sometimes have your own classes such as implementations of the Java 2D <code>java.awt.Paint</code> interface. In this case, you will need to write an <code>ExtensionHandler</code> that you will set on your <code>SVGGeneratorContext</code>.
  </p>
  <p>
          In the following example we define the first draft of an <code>ExtensionHandler</code> allowing to translate a Batik implementation of the <code>java.awt.Paint</code> interface named <code>org.apache.batik.ext.awt.LinearGradientPaint</code>. 
  </p>
  <source>
  class SubExtensionHandler extends DefaultExtensionHandler 
  {
    public SVGPaintDescriptor handlePaint(Paint paint,
                                          SVGGeneratorContext generatorCtx) 
    {
      if (paint instanceof LinearGradientPaint) {
          LinearGradientPaint gradient = (LinearGradientPaint)paint;
	  String id = generatorCtx.getIDGenerator().generateID("gradient");
          Element grad = generatorCtx.getDOMFactory().
               createElementNS(SVGSyntax.SVG_NAMESPACE_URI, 
                               SVGSyntax.SVG_LINEAR_GRADIENT_TAG);
          grad.setAttributeNS(null, SVGSyntax.SVG_ID_ATTRIBUTE, id);
          grad.setAttributeNS(null, 
	                      SVGSyntax.SVG_GRADIENT_UNITS_ATTRIBUTE, 
	                      SVGSyntax.SVG_USER_SPACE_ON_USE_VALUE);
          Point2D pt = gradient.getStartPoint();
          grad.setAttributeNS(null, "x1", pt.getX());
          grad.setAttributeNS(null, "y1", pt.getY());
          pt = gradient.getEndPoint();
          grad.setAttributeNS(null, "x2", pt.getX());
          grad.setAttributeNS(null, "y2", pt.getY());
          switch (gradient.getCycleMethod()) {
           case MultipleGradientPaint.REFLECT:
	     grad.setAttributeNS(null, 
	                         SVGSyntax.SVG_SPREAD_METHOD_ATTRIBUTE,
	                         SVGSyntax.SVG_REFLECT_VALUE);
	   break;
           case MultipleGradientPaint.REPEAT:
	     grad.setAttributeNS(null, 
	                         SVGSyntax.SVG_SPREAD_METHOD_ATTRIBUTE,
	                         SVGSyntax.SVG_REPEAT_VALUE);
	   break;
	   // pad is the default...
          }

	  // here we should write the transform of the gradient
	  // in the transform attribute.

	  // here we should write the stops of the gradients as 
	  // children elements.

	  return new SVGPaintDescriptor("url(#"+ref+")", 
	                                SVGSyntax.SVG_OPAQUE_VALUE, grad);
      } else
        return null; // let the default mechanism do its job
    }
  }

  </source>
  <p>
You should then set it on the <code>SVGGeneratorContext</code> by using the <code>setExtensionHandler</code> method.
  </p>
  <source>

SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(myFactory);
ctx.setExtensionHandler(new SubExtensionHandler());
SVGGraphics2D g2d = new SVGGraphics2D(ctx, false);</source>
  </s2>
  </s1>

    <anchor id="view"/>
    <s1 title="How to view the generated SVG document">

        <p>The following code example illustrates how to view the SVG content generated
           by an <code>SVGGraphics2D</code> object.</p>

<source>
import org.apache.batik.swing.*;
import org.apache.batik.svggen.*;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.w3c.dom.*;
import org.w3c.dom.svg.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
SVGDocument doc = (SVGDocument)impl.createDocument(svgNS, "svg", null);

SVGGraphics2D g = new SVGGraphics2D(doc);

// Draw into g. For example:
// 
Shape circle = new Ellipse2D.Double(0,0,50,50);
g.setPaint(Color.red);
g.fill(circle);
g.translate(60,0);
g.setPaint(Color.green);
g.fill(circle);
g.translate(60,0);
g.setPaint(Color.blue);
g.fill(circle);
g.setSVGCanvasSize(new Dimension(180,50));

// The following populates the document root with the 
// generated SVG content.
Element root = doc.getDocumentElement();
g.getRoot(root);

// Now, display the document
JSVGCanvas canvas = new JSVGCanvas();
JFrame f = new JFrame();
f.getContentPane().add(canvas);
canvas.setSVGDocument(doc);
f.pack();
f.setVisible(true);</source>
    </s1>
    </body>
</document>
