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 Tue, 09 Aug 2011 17:08:13 GMT
On Sun, Aug 7, 2011 at 6:43 PM, jonathan wood
<jonathanshawwood@gmail.com> wrote:
> Hi Mike,
>   I've seen variations of this type thing before...  in my case a top level
> svg that contains an <image> who's xlink:href references another document
> (svg in my case).  The referenced svg document had an id'd gradient that was
> in the <defs>...when the gradient was referenced by a shape's fill, the
> transcode would fail. Seems once the DOM (GVT) is booted the calls out to
> the xlnk:href are resolved. The uri for the embedded document seemed to be
> null (null#id on reference)You can try to setDocumentURI("something") on the
> parent...I think I tried that with no success, but needed to work-around
> (base64 data uri worked fine) and move on. I can probably reproduce this
> behavior in a test case if you think it will help resolve your issue.  I
> have not had time to debug it further, but it is on the (long) list.
> On Thu, Aug 4, 2011 at 4:36 PM, Mike Jarmy <mjarmy@gmail.com> wrote:
>>
>> 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: " +
>> file.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);
>>        app.setVisible(true);
>>    }
>>
>> 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.
>>
>> Thanks,
>> Mike Jarmy
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
>> For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
>>

I was actually able to get this working.  It was only happening for
certain files, and I do believe that it had something to do with URIs
embedded in the svg file.  By always setting the URI to an absolute
path I was able to resolve the problem.

This problem may however come back to bite me again.  I have not yet
experimented with reading SVG files from a jar file, as I will
inevitably need to do.  In that case I may have to disallow having SVG
files refer to each other, since its likely there is no real way to
specify a URI to another file inside a jar file.

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


Mime
View raw message