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

<!--

   Copyright 2001-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 Thomas.DeWeese@kodak.com                                        -->
<!-- version $Id$ -->
<!-- ====================================================================== -->

<document>
    <header>
        <title>Extending Batik</title>
        <subtitle>Possible extensions</subtitle>
        <authors>
            <person name="Thomas DeWeese" email="thomas.deweese@kodak.com"/>
        </authors>
    </header>

    <body>
        <s1 title="Introduction">
            <p>The goal of this section is to provide an overview of
               the built in extension mechanisms in Batik.  As an open
               source project, people can of course make any extension
               they feel is interesting, however Batik has been
               designed with several forms of extension in mind.</p>

            <p>The main areas extension are anticipated are:</p>
            <ul>
                <li><link href="#customXMLTags"> 
                    Support for custom XML Tags
                    </link></li>
                <li><link href="#imageTagFormats"> 
                    Support for new file formats in the 'image' tag.
                    </link></li>
                <li><link href="#urlProtocols">
                    Support for new protocols in URL references.
                    </link></li>
            </ul>

            <p>
            In general extensions are done through the Service
            Provider Interface mechanism as described in the 
            <link href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service Provider">
            Jar file</link> documentation.
            </p>

            <p>
            This allows for the extension of Batik simply by adding a
            new jar file(s) to the class path, no modification of
            Batik source is required!
            </p>

            <note>
            If you feel that the Batik team has overlooked an
            important area for extension please let your feelings be
            known on the mailing-lists.
            </note>
        </s1>

        <anchor id="customXMLTags" />
        <s1 title="Custom XML Tags">
            <p>
            First one must ask "What does it mean to support custom 
            XML tags?"
            </p>

            <p>
            There are three basic options Batik considers:
            </p>
            <dl>
                <dt> Having your tags appear in the DOM tree. </dt>
                <dd><br/> As long as your custom tags are well formed
                (and preferably valid) XML they will appear in the SVG
                DOM tree.  When rendering Batik will skip branches of
                the tree that use a tag it doesn't know about (so even
                if standard SVG tags are child nodes they will not be
                displayed).  <br/> It is strongly suggested that you
                make use of XML namespaces for your personal tags even
                if you are not planning on validating the XML.  <br/>
                This can be useful if you want to add extra pieces of
                data into the standard SVG drawing.  These might be
                annotations, or other application specific data.  In
                general this wouldn't be particularly useful with
                squiggle (the SVG browser) or the rasterizer, but
                might be very useful if you were writing a custom
                browser, rasterizer, or pre/post processing tools.
                </dd>
    
                <dt> Tags use a custom element in  the DOM tree</dt>
                <dd><br/>

                If you need your tags to use a custom element subclass
                in the DOM tree (for behavioral or performance
                reasons) then you need to provide an <link
                href="#domExtension"> extension to the Batik
                DOM.</link> <br/>

                Doing this gives you the opportunity to override the
                standard methods on DOM elements, or to provide
                additional methods to your DOM elements.  For example
                all of the SVG elements in Batik implement the
                getAttribute methods to respect the CSS styling
                properties.  They also provide additional methods to
                implement the SVG DOM.
                </dd>
    
                <dt> Tags that get rendered.</dt>
                <dd><br/>

                Probably the most common reason to develop custom tags
                is to add new rendering primitives to the SVG
                language.  In this case you must provide an <link
                href="#bridgeExtension"> extension to the Batik
                Bridge</link>.  The bridge extension is resposible for
                constructing the class(es) that will handle the
                rendering of the new primitive in Batik.  <br/>

                In most cases it will also be necessary to write a DOM
                extension to make the tag behave like other SVG tags
                (most notably for support of styling).
                </dd>
            </dl>

            <anchor id="domExtension"/>
            <s2 title="Writing a Batik DOM Extension">
                <p>
                The ability to extend the elements used in the SVG DOM
                tree allows users to provide implementations for nodes
                that can be used in place of Batik's default
                implementation of a node.  This may be done for a
                variety of reasons but is most commonly done to extend
                the behavior of standard node calls (such as to
                include styling in attribute lookup), or to implement
                the DOM interface for a Tag.
                </p>

                <p>
                The key class for building the DOM tree is the
                <code>ExtensibleSVGDOMImplementation</code> class.
                When an instance of this class
                is constructed it searches for instances of the
                <code>org.apache.batik.dom.svg.DomExtension</code>
                Service Provider interface.  It then calls the
                'registerTags' method with it's self for each one.
                This method typically calls
                <code>registerCustomElementFactory</code> for each tag that it
                wishes to handle.
                </p>

                <p>
                With Batik the most likely reason to extend a node is
                to provide proper CSS styling of the node attributes.
                To this end Batik provides a class you can extend:
                <code>org.apache.batik.extension.PrefixableStylableExtensionElement</code>.
                If you derive off this class you are only required to
                implement three methods: <code>getLocalName</code>,
                <code>getNamespaceURI</code>, and <code>newNode</code> 
                (plus constructors).  If all you want is proper style 
                support (commonly the case) then you are done implementing 
                your elements at this point.
                </p>

                <p>
                The distribution comes with a number of examples
		</p>
                <ul>
                  <li><code>org.apache.batik.extension.svg.BatikStarElement</code></li>
                  <li><code>org.apache.batik.extension.svg.BatikRegularPolygonElement</code></li>
                  <li><code>org.apache.batik.extension.svg.BatikHistogramNormalizationElement</code></li>
                  <li><code>org.apache.batik.extension.svg.SolidColorElement</code></li>
                  <li><code>org.apache.batik.extension.svg.ColorSwitchElement</code></li>
                </ul>
		<p>
                Included with these examples is 
                <code>org.apache.batik.extension.svg.BatikDomExtension</code> 
                which is the required instance of <code>DomExtension</code> 
                used to register the elements with the 
                <code>ExtensibleSVGDOMImplementation</code>.
                </p>

                <p>
                When your new element requires new 'presentation attributes' 
                (XML attributes that can be modified through CSS or depending 
                on your view point the other way round, CSS properties that 
                can be specified using XML attributes), you may also need to
                extend the CSS engine.  This can be done by registering a
                custom CSS value factory.  Both of the color examples do
                this (see <code>BatikDomExtension</code>).
                </p>
            </s2>

            <anchor id="bridgeExtension"/>
            <s2 title="Writing a Batik Bridge Extension">
                <p>
                Before you write a bridge extension it may be useful
                to understand what the role the bridge package plays 
                in Batik. The bridge package is responsible for
                creating and maintaining elements in the Graphics
                Vector Toolkit (GVT) tree based on the corresponding
                element in the SVG DOM.  This is done because for a
                variety of reasons the SVG DOM is not well suited for
                rendering, thus GVT tree is used for all rendering and 
                transcoding operations.
                </p>
    
                <p>
                The key class for managing this link is the
                <code>BridgeContext</code>.  This class maintains an
                association between a tag name with namespace and a
                particular bridge instance that will handle it.  The
                work of constructing the proper entity or entities in the 
                GVT tree is then deferred to the Bridge registered for 
                a particular tag.  If no bridge is regiestered nothing is 
                done.
                </p>

                <p>
                New associations can be added by implementors of the
                <code>BridgeExtension</code> Service Provider Interface.  
                This interface has a number of methods that provide
                information about the particular extension being
                registered (including contact information, and the
                list of implemented extensions).  It also has a
                'registerTags' method which is responsible for
                registering the bridge instances with a 
                <code>BridgeContext</code>. All the built in bridges are 
                bundled with a BridgeExtension (in 
                <code>org.apache.batik.bridge</code>),
                as are the example extensions (in 
                <code>org.apache.batik.extension.svg</code>),
                so these are both good places to start.
                </p>
    
                <p>
                The <code>Bridge</code> interface itself is very simple. 
                It only includes methods to get the namespace and local 
                name of the tag the bridge is responsible for.  This
                interface is then extended for each of the major
                concepts present in SVG:
                </p>
                <dl>
                    <dt><link href="#graphicsNodeBridge">
                        GraphicsNodeBridge</link></dt>
                    <dd>
                    These are probably the most common SVG elements
                    they represent graphic elements in what I'll call
                    the "visible" SVG tree. These are the elements
                    most other bridges modify in some way (by clipping,
                    masking, filtering, etc).  
                    <br/>
                    <em>Example tags:</em> svg, g, path, rect.<br/>
                    <em>Example Extensions:</em> BatikRegularPolygonElementBridge, BatikStarElementBridge.
                    </dd>
    
                    <dt>FilterBridge</dt> 
                    <dd>
                    Handles the SVG 'filter' element.  If you wanted
                    to implement a new tag that could be referenced
                    from the 'filter' attribute on an SVG graphics
                    node then you would need to subclass this bridge.
                    However adding new types of filters to the
                    existing SVG 'filter' element is accomplished via
                    the FilterPrimitiveBridge.  
                    <br/>
                    <em>Example tag:</em> filter
                    </dd>
    
                    <dt><link href="#filterPrimitiveBridge">
                        FilterPrimitiveBridge</link></dt> 
                    <dd>
                    Constructs an element in the filter chain applied
                    to an SVG graphics node.  
                    <br/> 
                    <em>Example tags:</em> feBlend, feCompose, ...<br/>
                    <em>Example Extensions:</em> BatikHistogramNormalizationElementBridge
                    </dd>
    
                    <dt><link href="#paintBridge">PaintBridge</link></dt>
                    <dd>
                    Constructs a java Paint object to be used
                    in filling or stroking graphic elements.  
                    <br/>
                    <em>Example tags:</em> gradient, pattern.<br/>
                    <em>Example Extensions:</em> SolidColorBridge, ColorSwitchBridge
                    </dd>
    
                    <dt>ClipBridge</dt>
                    <dd>
                    Constructs a ClipRable to apply to a Graphics Node. 
                    This provides a path that data is clipped to.
                    <br/>
                    <em>Example tag:</em> clip-path.
                    </dd>
    
                    <dt>MarkerBridge</dt> 
                    <dd>
                    Constructs a Marker for annotating the path of a
                    GraphicsNode.  
                    <br/> 
                    <em>Example tag:</em> marker
                    </dd>
    
                    <dt>MaskBridge</dt>
                    <dd>
                    Constructs a Mask Filter to apply to a Graphics
                    Node.  Mask Filters typically modify the alpha
                    channel of the Graphics Node output to make
                    portions fully or partially transparent that
                    wouldn't be otherwise. 
                    <br/> 
                    <em>Example tag:</em> mask.
                    </dd>
                </dl>

                <p>
                Extension writers are free to work with any of the
                above bridges, however the three most common are
                likely to be the <code>GraphicsNodeBridge</code>, the
                <code>FilterPrimitiveBridge</code>, and the 
                <code>PaintBridge</code> (each of which have example
                extensions available for inspection).
                Each of these interfaces has several extremely useful
                subclasses that handle much of the common behavior
                among elements.
                </p>

                <p>
                In some simple cases it is possible to only provide an
                extension to the Bridge and get your desired effect,
                however in most cases you will find that for your
                element to behave like a normal SVG element (for
                example supporting styling) you will need to provide a
                DOM extension as well.
                </p>

                <anchor id="graphicsNodeBridge"/>
                <s3 title="GraphicsNodeBridge">
                    <p>
                    The graphics node bridge is oriented around
                    constructing a new <code>GraphicsNode</code> in the GVT 
                    tree. The <code>GraphicsNode</code> is the basic element 
                    that makes up the GVT tree.  Each <code>GraphicsNode</code>
                    has a <code>paint</code> method that is responsible for 
                    painting the object (including considering clipping, 
                    masking, filtering, and opacity for the node).
                    </p>

                    <p> 
                    If you want to you can implement
                    <code>bridge.GraphicsNodeBridge</code> interface
                    directly or subclass
                    <code>bridge.AbstractGraphicsNodeBridge</code>.
                    This gives you the most flexibility since you can
                    construct your new subclass of
                    <code>gvt.GraphicsNode</code> where you can implement 
                    the paint method to do essentially anything you want,
                    this is also a lot of work (and I'm not going to
                    try and explain everything needed to pull this
                    off).
                    </p>

                    <p>
                    However, if you just want to generate a custom
                    filled or stroked shape the easiest way is to
                    subclass either of the following classes.  In this
                    case you are essentially only responsible for
                    constructing a standard java <code>Shape</code> object to
                    describe the desired area to operate on:
                    </p>
                    <dl>
                        <dt><code>SVGShapeElementBridge</code></dt>
                        <dd>
                        Subclasses of this class only need to implement
                        buildShape, getNamespaceURI, and getLocalName.
                        buildShape generally constructs a
                        <code>java.awt.Shape</code> object and sets it on
                        the provided <code>shapeNode</code> object,
                        however it may adjust other features of the given
                        shape node.
                        </dd>
                        <dt><code>SVGDecoratedShapeElementBridge</code></dt>
                        <dd>
                        This is very similar to SVGShapeElementBridge,
                        except it also handles the standard marker
                        properties.  Markers will be place at each the
                        end of each segment of the path.
                        </dd>
                    </dl>
                    <p>
                    If you decide that you need to implement a new subclass
                    of <code>GraphicsNode</code> I strongly suggest that
                    you derive off of <code>AbstractGraphicsNode</code>
                    as this class does much of the work to behave like
                    a drawn element in SVG (like clipping, filtering, 
                    masking).  In this case you implement 
                    the <code>primitivePaint</code> method
                    instead of the <code>paint</code> method.
                    </p>
                </s3>

                <anchor id="filterPrimitiveBridge"/>
                <s3 title="FilterPrimitiveBridge">
                <p>
                The Filter primitive bridge is concerned with the
                construction of individual elements of the filter
                chain.  Unlike graphics nodes which generally just
                draw new objects on top of the destination, filters
                take existing image data and modify it to apply
                effects.
                </p>

                <p>
                This part of GVT rendering is based on the Java2D
                <code>java.awt.image.renderable.RenderableImage</code>
                and <code>java.awt.image.RenderedImage</code>
                interfaces.  This provides a convenient framework to
                handle image processing (an inherently resolution
                dependent operation) in the resolution independent
                system defined by SVG.
                </p>

                <p>
                The majority of classes for part of Batik are present
                in the <code>batik.ext.awt.image.*</code> package hierarchy 
                which contains a large set of generally useful extensions to 
                the core JDK classes and methods.
                </p>

                <p>
                Note that the <code>FilterPrimitiveBridge</code> is invoked 
                once for each reference to the <code>&lt;filter&gt;</code> 
                tag that the filter primitive is part of.  So if a filter 
                effect is used a half dozen times the <code>createFilter</code>
                method will be called a half dozen times, even though the 
                tag may only appear once in the file. This means that it is
                safe for the Filters returned to be 'fixed' for a
                particular <code>GraphicsNode</code> being filtered.
                </p>

                <p>
                You will notice that Batik uses extended versions of
                the standard <code>Renderable</code> and <code>Rendered</code> 
                image classes to provide additional information about surround
                requirements for operations as well as a few
                convenience methods.  These interfaces are called:
                <code>java.ext.awt.image.renderable.Filter</code> and
                <code>java.ext.awt.image.rendered.CacheableRed</code>.
                Batik contains simple wrapper classes that can take
                the default JDK <code>Renderable</code> and 
                <code>Rendered</code> Image interfaces.  Within the code 
                base the convention 'Red' for classes implementing 
                <code>RenderedImage</code>, and 'Rable' for classes 
                implementing <code>RenderableImage</code> is commonly
                used ('Red' is to be pronounced like the color, and
                'Rable' is to be pronounced like 'horrible' with a
                silent 'h').
                </p>

                <p>
                The <code>FilterPrimitiveBridge</code> really has only
                one method right now: <code>createFilter</code> that must 
                construct an instance of <code>Filter</code> to perform 
                the required operation.  This is still a fairly complex task 
                given the general need to support accessing the various
                standard sources of image data.  To this end there is
                a provided subclass,
                <code>AbstractSVGFilterPrimitiveElementBridge</code>
                This provides convenience methods to handle many common
                tasks.
                </p>

                <p>
                Generally the bulk of the work in writing a filter
                extension is the writing of the Filter instance not
                tying it into the GVT tree.  Batik does contain
                several base classes that make this processes a bit
                easier.
                <code>ext.awt.image.renderable.AbstractRable</code>,
                <code>ext.awt.image.rendered.AbstractRed</code>, and
                <code>ext.awt.image.rendered.AbstractTiledRed</code>.
                <code>TiledRed</code> ties into the Batik tile cache 
                (use this with caution as it is a complex area of 
                the Batik code).
                </p>

                <p>
                The <code>ext.awt.image.rendered</code> and
                <code>renderable</code> packages contain quite a
                number of fairly general examples covering most common
                cases, please refer to them for more detail.
                </p>
                </s3>

                <anchor id="paintBridge"/>
                <s3 title="PaintBridge">
                <p>
                The <code>PaintBridge</code> constructs an instance of the
                <code>java.awt.Paint</code> to be used to fill or stroke
                shapes/text (part of the paint server architecture of
                SVG).
                </p>

                <p>
                Like the filter primitive bridge the <code>PaintBridge</code> 
                is invoked for each reference to the paint.  This makes
                it possible to customize the Paint returned for the
                particular element to be painted.
                </p>

                <p>
                This is how the gradients and patterns are implemented
                in Batik, so it is possible to construct rather
                complex paint effects through this mechanism.
                </p>

                <p>
                For paints you are mostly on your own, because unlike
                the other cases there aren't any really generally useful
                base classes to derive off, the closest is the
                <code>AbstractSVGGradientElementBridge</code> which is
                used to handle most of the radial and linear gradient
                attributes.  
                </p>

                <p>
                The existing gradient paint implementations are in
                <code>ext.awt</code>, the pattern implementation is in
                <code>gvt</code> since it requires access to gvt
                internals.
                </p>
                </s3>
            </s2>
        </s1>

        <anchor id="imageTagFormats" />
        <s1 title="New File Formats">
            <p> 
            When Batik encounters an 'image' element and it determines
            the element does not reference an SVG file. It defers the
            loading of the referenced image to
            <code>org.apache.batik.ext.awt.image.spi.ImageTagRegistry</code>. 
            This class maintains a list of <code>RegistryEntries</code>, 
            generally one for each format.
            </p>
    
            <p>
            Since the formats supported natively by Batik are also
            implemented through this mechanism. The 
            <code>JPEGRegistryEntry</code> and <code>PNGRegistryEntry</code> 
            should be used as good references for extensions.
            </p>
            <s2 title="RegistryEntry">
                <p>
                There are currently two flavors of <code>RegistryEntry</code>:
                </p>
        
                <dl>
                   <dt>URLRegistryEntry</dt>
                   <dd>
                   These take a <code>ParsedURL</code> and try to decide if 
                   the URL is intended for them.  This group of entries is 
                   mostly intended to handle alternate network protocols.  It
                   can also be useful for interfacing with libraries
                   that want a URL instead of a stream.
                   </dd>
        
                   <dt>StreamRegistryEntry</dt>
                   <dd>
                   These work with a markable <code>InputStream</code>. 
                   This is the preferred form of registry entry as it 
                   generally avoids opening a potentially expensive connection
                   multiple times, instead it opens the stream once
                   and relies on mark and reset to allow entries to
                   check the stream.
                   </dd>
                </dl>
            </s2>        
  
            <s2 title="Helper classes">
                <p> 
                There exists quite a number of classes to assist in
                implementing a <code>RegistryEntry</code>.  It is strongly
                recommended that you review these classes and make use
                of them where appropriate.  They will likely save you
                time and improve the integration with Batik.
                </p>
                <dl>
                   <dt>MagicNumberRegistryEntry</dt>
                   <dd>
                    An abstract class that can handle the
                   <code>isCompatibleStream</code> method for formats that 
                   make use of "magic numbers".  Magic numbers are a well 
                   known sequence of bytes at a well known offset in the
                   file, that are commonly used to identify image file formats.
                   </dd>
        
                   <dt>RedRable</dt>
                   <dd>
                   This takes any <code>java.awt.image.RenderedImage</code> and
                   wraps it into a <code>Filter</code> (Batik's subclass of
                   RenderableImage).  This is extremely useful for
                   <em>single resolution</em> file formats.  
                   </dd>
        
                   <dt>DeferRable</dt>
                   <dd>
                   This allows one to load the image in a background
                   thread, rather than hold up the construction of the
                   GVT tree while reading the image (useful since
                   reading the image is generally I/O bound, so it
                   makes a good background task).  This is used by most of
                   the current Image readers.
                   </dd>
        
                   <dt>AbstractRable</dt>
                   <dd>
                   An abstract base class that makes it relatively
                   easy to implement the Filter interface.
                   </dd>
        
                   <dt>AbstractRed</dt>
                   <dd>
                   An abstract base class that makes it relatively
                   easy to implement the CacheableRed interface
                   (Batik's subclass of RenderedImage).
                   </dd>
                </dl>
            </s2>
        </s1>

        <anchor id="urlProtocols" />
        <s1 title="New URL Protocols">
            <p> 

            For a variety of reasons (not the least of which is the
            heavy use of the 'data:' protocol in SVG).  Several parts
            of Batik use a <code>util.ParsedURL</code> instead of the
            JDK's <code>java.net.URL</code> class.
            </p>
            
            <p>
            <code>ParsedURL</code> offers a few advantages over the JDK's 
            URL class. First, it is designed to make minimal use of 
            exceptions, so it is possible to use it to parse a malformed 
            URL and get "the good parts".  Second, it is extensible, so 
            support for new protocols can be added, even protocols that 
            change the normal parsing rules for URLs (such as our friend the 
            'data' protocol).  Third it can automatically check a stream when
            opened for common compression types and decode them for you
            (this behavior can also be bypassed if needed).
            </p>
            
            <p>
            The service class is
            <code>org.apache.batik.util.ParsedURLProtocolHandler</code>.  This
            interface consists of three methods, one returns the protocol
            to be handled, one is for parsing an absolute URL string and
            one is for parsing relative URL strings. Both the parsing
            methods return an object of type ParsedURLData (the instance
            may of course be a subclass of ParsedURLData).
            </p>
            
            <p>
            The <code>ParsedURLData</code> class holds all the data and 
            implements the all the stream handling commands for the 
            ParsedURL class. This allows ProtocolHandlers to return custom 
            subclasses for particular protocols.
            </p>
        </s1>
    </body>
</document>
