xmlgraphics-batik-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mike Jarmy <mja...@gmail.com>
Subject Re: rendering directly to java.awt.Graphics2D
Date Thu, 04 Aug 2011 20:36:29 GMT
On Wed, Aug 3, 2011 at 3:39 PM, Mike Jarmy <mjarmy@gmail.com> wrote:
> On Wed, Aug 3, 2011 at 1:03 PM, Mike Jarmy <mjarmy@gmail.com> wrote:
>> I'm working with a custom widget toolkit that is built directly on top
>> of java.awt -- in other words I'm not using Swing, or SWT, or anything
>> other than a framework built on plain old AWT.
>> I'd like to be able to render (and animate) SVG drawings directly onto
>> a java.awt.Graphics2D instance.  However, I'm having a bit of trouble
>> figuring out how exactly to do that with batik.  I *think* that I need
>> to decode my SVG drawing into a GVT tree, and then render the tree.
>> However I can't figure out which part of batik I need in order to do
>> the rendering.  Transcoder and SVGGraphics2D do not seem to be quite
>> what I want. Actually, I haven't yet figured out the
>> decoding-to-GVT-step either, but I'm assuming that's pretty
>> straightforward.
>> So can anyone give me a pointer on how to do this?  Perhaps just point
>> me to an existing example?  My first goal is to just get static images
>> rendering.
>> After that, I'll need to get animation working.  I'm assuming that
>> supporting animation will entail updating the drawing's current time
>> every so oftern on a separate thread, via the AnimationEngine, and
>> then re-rendering the updated GVT?
>> I *could* do all this by rendering into a static java.awt.Image, and
>> then bliting the Image (i.e. roll my own double-buffering), but I'd
>> prefer to figure out how to just draw directly onto a Graphics2D
>> instance first.  That's because the framework I'm using already has
>> some double-buffering, so I most likely wont need to do that with the
>> SVG rendering.
>> Thanks,
>> Mike Jarmy
>> P.S. FYI, I'll probably never need to support handling interactive user input.
> OK, I have discovered the GraphicsNode.paint(Graphics2D g2d)  method,
> which may be all I need to call once I actually get a valid GVT build.
>  However, I'm having trouble building a GVT from a
> java.io.InputStream.  Here is the code I'm using:
>            String parser = XMLResourceDescriptor.getXMLParserClassName();
>            SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
> //            String uri = "http://www.example.org/document.svg";
>            Document document = f.createDocument(null, inputStream);
>            UserAgent userAgent = new UserAgentAdapter();
>            DocumentLoader loader = new DocumentLoader(userAgent);
>            BridgeContext bctx = new BridgeContext(userAgent, loader);
>            bctx.setDynamicState( BridgeContext.DYNAMIC );
>            GVTBuilder builder = new GVTBuilder();
>            this.gvtRoot = builder.build(bctx, document);
> This code fails at the call to GVTBuilder.build(), with the following error:
> Invalid CSS document.
> Unable to make sense of URL for connection
>        at org.apache.batik.css.engine.CSSEngine.parseStyleSheet(CSSEngine.java:1149)
>        at org.apache.batik.dom.svg.SVGDOMImplementation.createCSSEngine(SVGDOMImplementation.java:117)
>        at org.apache.batik.dom.ExtensibleDOMImplementation.createCSSEngine(ExtensibleDOMImplementation.java:212)
>        at org.apache.batik.bridge.BridgeContext.initializeDocument(BridgeContext.java:378)
>        at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:55)
>        at com.tridium.svg.ui.BSvgDrawing.loadDrawing(BSvgDrawing.java:305)
> Could that be because I'm passing a null value in for the URI when I
> create the document from the InputStream?  I have noticed that I get
> the same error no matter what I pass in for the URI.  Is there perhaps
> a better way to construct a Document from an InputStream?
> Thanks,
> Mike Jarmy

I have this working now in a simple "hello, world" style, java app,
using the following approach:

    public static void main(String[] args) throws Exception
        // make the file, along with its input stream and URI
        File file = new File("D:\\aaa\\svg\\samples\\batik70.svg");
        FileInputStream inputStream = new FileInputStream(file);
        String uri = file.toURL().toString();

System.out.println("File " + file.getAbsolutePath() + " exists: " +

        // create the document
        String parser = XMLResourceDescriptor.getXMLParserClassName();
        SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
        Document document = f.createDocument(uri, inputStream);

        // create the GVT
        UserAgent userAgent = new UserAgentAdapter();
        DocumentLoader loader = new DocumentLoader(userAgent);
        BridgeContext bctx = new BridgeContext(userAgent, loader);
        bctx.setDynamicState( BridgeContext.DYNAMIC );
        GVTBuilder builder = new GVTBuilder();
        GraphicsNode gvtRoot = builder.build(bctx, document);

        AwtApp app = new AwtApp(gvtRoot);

AwtApp just calls gvtRoot.paint(Graphics2D) from within a custom
java.awt.Canvas.  This works perfectly.

However, when I run the same code within my company's software
framework, I'm still getting this:

Invalid CSS document.
Unable to make sense of URL for connection
   at org.apache.batik.css.engine.CSSEngine.parseStyleSheet(CSSEngine.java:1149)
   at org.apache.batik.dom.svg.SVGDOMImplementation.createCSSEngine(SVGDOMImplementation.java:117)
   at org.apache.batik.dom.ExtensibleDOMImplementation.createCSSEngine(ExtensibleDOMImplementation.java:212)
   at org.apache.batik.bridge.BridgeContext.initializeDocument(BridgeContext.java:378)
   at org.apache.batik.bridge.GVTBuilder.build(GVTBuilder.java:55)
   at com.tridium.svg.ui.BSvgDrawing.main(BSvgDrawing.java:535)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at com.tridium.sys.Nre.runClass(Nre.java:209)
   at com.tridium.sys.Nre.main(Nre.java:152)

Obviously this isn't batik's fault, since my test app works just fine
in a 'normal' vanilla environment.

Clearly the framework is doing something different, but I'm somewhat
at a loss to say what it could be.  One possibility is that the
problem could be caused by classloading.  Our framework using custom
ClassLoaders, one per jar file.  I have all of the batik jar files
actually stuffed into one big jar file, as per our general approach.
Could that have something to do with this problem?

Any other ideas?  If not then I'm on my own, since I have batik doing
what I want it to do in a simple app.

Mike Jarmy

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

View raw message