xmlgraphics-batik-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thomas DeWeese <Thomas.DeWe...@Kodak.com>
Subject Re: Bogus SVG XML output
Date Thu, 09 Dec 2004 20:57:07 GMT
Archie Cobbs wrote:

> I've found a bug in Batik (I think) and would appreciate any comments,
> confirmation, workarounds, etc.

    The workaround is simple replace this:

use.setAttributeNS(XLINK_NS, "href", "#" + BOX_ID);

    With this:

use.setAttributeNS(XLINK_NS, "xlink:href", "#" + BOX_ID);

> The first one is correct but the second one is not, because the
> "href" attribute is incorrectly put in the null namespace.

    The question is if it is the XML serializer's responsibility to
provide 'prefixes' for tags that don't have them.  Remember that
you could even create an attribute in a namespace that lacks any
xmlns:<prefix> decl.  Should the serializer then 'create' a
prefix (and add the xmlns attribute)?

    To be honest I haven't had the time or interest to see what
DOM 3 Load/Store say on this topic.  But the fix is pretty simple
and I think that it should work with any implementation.

> The program's output is shown below as well (pretty printed) and
> you can see the bogus <use> tag. If you try to view this SVG with
> sqiggle, for example, it will barf on it.
> 
> I'm using JDK 1.4.2... this could be a JDK bug as well.
> 
> Thanks,
> -Archie
> 
> __________________________________________________________________________
> Archie Cobbs      *        CTO, Awarix        *      http://www.awarix.com
> 
> 
> ----------------------------- TEST PROGRAM ------------------------------
> 
> import java.io.File;
> import java.io.StringReader;
> import javax.swing.JFrame;
> import javax.swing.SwingUtilities;
> import javax.xml.transform.Transformer;
> import javax.xml.transform.TransformerFactory;
> import javax.xml.transform.dom.DOMResult;
> import javax.xml.transform.dom.DOMSource;
> import javax.xml.transform.stream.StreamResult;
> import javax.xml.transform.stream.StreamSource;
> import org.apache.batik.bridge.UpdateManagerEvent;
> import org.apache.batik.bridge.UpdateManagerListener;
> import org.apache.batik.swing.JSVGCanvas;
> import org.apache.batik.swing.gvt.GVTTreeRendererAdapter;
> import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
> import org.apache.batik.swing.gvt.GVTTreeRendererListener;
> import org.w3c.dom.Document;
> import org.w3c.dom.Node;
> import org.w3c.dom.svg.SVGDocument;
> import org.w3c.dom.svg.SVGElement;
> 
> public class BatikBug extends GVTTreeRendererAdapter
>   implements UpdateManagerListener {
> 
>     private static final TransformerFactory FACTORY
>       = TransformerFactory.newInstance();
> 
>     private static final String SVG_NS = "http://www.w3.org/2000/svg";
>     private static final String XLINK_NS = "http://www.w3.org/1999/xlink";
>     private static final String TOP_ID = "top";
>     private static final String BOX_ID = "box";
> 
>     private static final String INPUT = ""
>       + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
>       + "<svg viewBox=\"0 0 100 100\" width=\"400\" height=\"400\""
>       + " xmlns=\"" + SVG_NS + "\" xmlns:xlink=\"" + XLINK_NS + "\">"
>       + "<defs>"
>       + "<rect id=\"" + BOX_ID + "\" x=\"0\" y=\"0\" width=\"30\" height=\"30\""
>       + " fill=\"#00ff00\"/>"
>       + "</defs>"
>       + "<g id=\"" + TOP_ID + "\">"
>       + "<use xlink:href=\"#" + BOX_ID + "\" transform=\"translate(10, 10)\"/>"
>       + "</g>"
>       + "</svg>";
> 
>     private final JSVGCanvas canvas;
>     private final String filename;
>     private SVGDocument doc;
>     private Node top;
>     private boolean ready;
> 
>     public BatikBug(String filename) throws Exception {
>         this.filename = filename;
>         this.canvas = new JSVGCanvas();
>         DOMResult domResult = new DOMResult();
>         FACTORY.newTransformer().transform(
>           new StreamSource(new StringReader(INPUT)), domResult);
>         canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
>         canvas.setDocument((Document)domResult.getNode());
>         canvas.addGVTTreeRendererListener(this);
>         canvas.addUpdateManagerListener(this);
>         JFrame frame = new JFrame("BatikBug");
>         frame.getContentPane().add(canvas);
>         frame.pack();
>         frame.show();
>     }
> 
>     private void accessDocument(Runnable r) {
>         try {
>             canvas.getUpdateManager().getUpdateRunnableQueue().invokeAndWait(r);
>         } catch (InterruptedException e) {
>             e.printStackTrace();
>         }
>     }
> 
>     private void addBox(final int x, final int y) {
>         accessDocument(new Runnable() {
>             public void run() {
>                 SVGElement use = (SVGElement)doc
>                   .createElementNS(SVG_NS, "use");
>                 use.setAttributeNS(XLINK_NS, "href", "#" + BOX_ID);
>                 use.setAttributeNS(null, "x", "" + x);
>                 use.setAttributeNS(null, "y", "" + y);
>                 top.appendChild(use);
>                 System.out.println("added new <use> node at " + x + ", " + y);
>             }
>         });
>     }
> 
>     private void export() {
>         System.out.println("exporting to `" + filename + "'...");
>         accessDocument(new Runnable() {
>             public void run() {
>                 try {
>                     System.out.println("starting export transform");
>                     FACTORY.newTransformer().transform(new DOMSource(doc),
>                         new StreamResult(new File(filename)));
>                     System.out.println("finished export transform");
>                 } catch (Exception e) {
>                     e.printStackTrace();
>                 }
>             }
>         });
>         System.out.println("exported SVG to `" + filename + "'");
>     }
> 
>     public void gvtRenderingCompleted(GVTTreeRendererEvent event) {
>         System.out.println("document is rendered");
>         doc = canvas.getSVGDocument();
>         top = doc.getElementById(TOP_ID);
>         ready = true;
>         synchronized (this) {
>             notify();
>         }
>     }
> 
>     public void go() throws InterruptedException {
>         synchronized (this) {
>             while (!ready)
>                 wait();
>         }
>         addBox(60, 60);
>         export();
>         try {
>             Thread.sleep(5000);
>         } catch (InterruptedException e) {
>         }
>     }
> 
>     public static void main(String[] args) throws Exception {
>         if (args.length != 1) {
>                 System.err.println("Usage: java BatikBug filename");
>                 System.exit(1);
>         }
>         new BatikBug(args[0]).go();
>     }
> 
>     public void managerResumed(UpdateManagerEvent e) {
>         System.out.println("manager resumed");
>     }
>     public void managerStarted(UpdateManagerEvent e) {
>         System.out.println("manager started");
>     }
>     public void managerStopped(UpdateManagerEvent e) {
>         System.out.println("manager stopped");
>     }
>     public void managerSuspended(UpdateManagerEvent e) {
>         System.out.println("manager suspended");
>     }
>     public void updateCompleted(UpdateManagerEvent e) {
>         System.out.println("update completed");
>     }
>     public void updateFailed(UpdateManagerEvent e) {
>         System.out.println("update failed");
>     }
>     public void updateStarted(UpdateManagerEvent e) {
>         System.out.println("update started");
>     }
> }
> 
> ------------------- BOGUS OUTPUT (pretty printed) ------------------------
> 
> 
> <?xml version="1.0" encoding="UTF-8"?>
> 
> <svg contentScriptType="text/ecmascript" width="400"
>    xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify"
>    contentStyleType="text/css" viewBox="0 0 100 100" height="400"
>    preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg"
>    version="1.0">
>   <defs>
>     <rect x="0" y="0" fill="#00ff00" width="30" height="30" id="box"/>
>   </defs>
>   <g id="top">
>     <use transform="translate(10, 10)"
>        xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#box"
>        xlink:type="simple" xlink:actuate="onRequest" xlink:show="replace"/>
>     <use x="60" y="60" xmlns:xlink="http://www.w3.org/1999/xlink"
>        href="#box" xlink:type="simple" xlink:actuate="onRequest"
>        xlink:show="replace"/>
>   </g>
> </svg>
> 
> 
> 
> *
> Confidentiality Notice: This e-mail message, including any attachments, is for the sole
use of the intended recipient(s) and may contain confidential and privileged information.
Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the
intended
> recipient, please contact the sender by reply e-mail and destroy all copies of the original
message.
> *
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: batik-users-help@xml.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org


Mime
View raw message