You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by Thomas E Deweese <th...@kodak.com> on 2001/04/10 23:00:38 UTC

RE: problems generating SVG

>>>>> "PA" == Peter Armstrong <ar...@intalio.com> writes:

PA> Looking at the Batik source, I see that on line 305 of
PA> JGVTComponent the following call is made:

PA> g2d.drawRenderedImage(image, null);

PA> And on line 803 of SVGGraphics2D (in drawRenderedImage()), the the
PA> following call is made:

PA> if(xform.getDeterminant() != 0){

PA> without ever checking if xform != null (xform is the second
PA> parameter of the drawRenderedImage method).  So I assume that
PA> either:

PA> 1. This is a bug in either JGVTComponent or SVGGraphics2D.
PA> 2. JGVTComponents are not meant to be painted using SVGGraphics2D.
PA> 3. I've been sloppy and not set some variable that Batik needs.

PA> I'm hoping for #3, but I fear #1 or, even worse, #2.  Any
PA> suggestions would be *much* appreciated.

    The answer is #1. SVGGraphics2D should check for xform==null.
I've got a fix that I need to verify before committing.  I'll mail it
to you (batik-dev will get it from the commit) when I've tested it.

PA> (Should we move this to Batik-Dev?)

    Yes, I think so.

    I've CC'd this into batik-dev, so if batik-users are interested in
the thread please move on over (but I think this just a development
issue now).  Responders should trim batik-users for the CC line
please.

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


RE: problems generating SVG

Posted by Peter Armstrong <ar...@intalio.com>.
>     I realized as I walked out to my car last night, that while you
> should be able to pass SVGGraphics2D into the paint method on a
> JSVGComponent (hence #1, a bug in SVGGraphics2D), you still won't get
> what you want (which is presumably some semblance of the original
> SVG).  What you will get is one large PNG embedded in the SVG file
> (hence #2, JSVGComponent really isn't meant to be painted with
> SVGGraphics2D). The JSVGComponent does a lot of caching of image data
> under the hood, and so it only ever draws a finished image to the
> Graphics passed to it's paint method.

Actually, after I sent that "thanks it's working perfectly now" email to
you, I did a bit more testing and realized that it wasn't working at all.
Then I looked at the generated SVG and saw the PNG images, and figured out
what you just described above.  I realized it was very naive of me to expect
the SVGGraphics2D to do anything but the default behavior (render a
component the best way it knows) with the JSVGComponent it was rendering.

So I decided that I was a bit out of my depth.  What I thought might be
theoretically possible would be to somehow get the JSVGComponent to paint
itself on my SVGGraphics2D (basically, what you just described in your
email), but I didn't know how to do that.  And even if I *could* do this, I
would need to do this self-painting in the correct location: I have many
JSVGComponents in different locations, and if I just got them to blindly
draw themselves on my JSVGComponent, the location information would be gone
and they'd all end up drawing on top of each other in the top left corner.

Am I making sense, or am I missing something completely obvious again?

>    Hope I haven't completely discouraged you.

No, actually.  Thanks to your help, I actually have a working sub-optimal
solution right now:

The paintComponent method of my JPanel that contains the JSVGComponents does
the following:

1. call super.paintComponent(g)
2. call a public drawSelf(g) method to do all my extra drawing

Then, in my drawSelf method, I check if I'm rendering on an SVGGraphics2D.
If so, I draw rectangles with the bounds of each of the JSVGComponents.  So
then (finally) to produce the SVG preview of my document, I just call my
drawSelf method--not paintComponent.  This way, I don't get any of the PNG
images (which actually give me annoying exceptions when they're being
generated), since the JSVGComponents in the panel get painted in the call to
super.paintComponent()--not in drawSelf().  Of course, when the SVG preview
is scaled big it looks terrible since the JSVGComponents are just
represented by rectangles, but for normal usage it's still very useful since
all the other stuff is drawn fine.  The big benefit, of course, is that I
didn't have to write a bunch of extra code myself to generate my (scalable)
preview.

So, I am just going to stick with my sub-optimal solution until either (1)
Batik is modified in a way that lets me try one of the methods you suggested
in your email or (2) the SVGGraphics2D code had a special case added to it
for rendering JSVGComponents as SVG not PNG.

Thank you very much for all your help,
Peter Armstrong


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


RE: problems generating SVG

Posted by Thomas E Deweese <th...@kodak.com>.
    Ok I'm committing 2 sins. 1 following up on myself, and 2 I've
bounced this back to Batik Users (sorry for any whiplash :).

>>>>> "TD" == Thomas E Deweese <th...@kodak.com> writes:

>>>>> "PA" == Peter Armstrong <ar...@intalio.com> writes:
PA> Looking at the Batik source, I see that on line 305 of
PA> JGVTComponent the following call is made:

PA> g2d.drawRenderedImage(image, null);

PA> So I assume that either:

PA> 1. This is a bug in either JGVTComponent or SVGGraphics2D.
PA> 2. JGVTComponents are not meant to be painted using SVGGraphics2D.
PA> 3. I've been sloppy and not set some variable that Batik needs.

PA> I'm hoping for #3, but I fear #1 or, even worse, #2.  Any
PA> suggestions would be *much* appreciated.

TD>     The answer is #1. SVGGraphics2D should check for xform==null.
TD> I've got a fix that I need to verify before committing.  I'll mail
TD> it to you (batik-dev will get it from the commit) when I've tested
TD> it.

    The reason is that the answer is really #1 _AND_ #2 :).

    Remember when I said:

TD>  2) having your paint method defer to an internal method myPaint
TD>     (what ever) and call that method directly when you want "just
TD>     the graphics".  This just helps to avoid any nonsense that
TD>     Swing/AWT might give you (like the not-so-helpful double
TD>     buffering in this case).

    Well swing isn't the only one trying to help you out :) 

    I realized as I walked out to my car last night, that while you
should be able to pass SVGGraphics2D into the paint method on a
JSVGComponent (hence #1, a bug in SVGGraphics2D), you still won't get
what you want (which is presumably some semblance of the original
SVG).  What you will get is one large PNG embedded in the SVG file
(hence #2, JSVGComponent really isn't meant to be painted with
SVGGraphics2D). The JSVGComponent does a lot of caching of image data
under the hood, and so it only ever draws a finished image to the
Graphics passed to it's paint method.

    What you need to do is call the 'paint' method on the root of of
the GraphicsNode tree.  This is slightly complicated by two things.

1) We don't give direct access to the root GraphicsNode from the
   JGVTComponent (base class for JSVGComponent).  I'm going to ask the
   rest of the development group if they think it is ok to do that
   (currently we have set methods but no get...).  You could work
   around this by creating a subclass (the member is protected).

2) The Paint method on GraphicsNode takes something called
   "GraphicsNodeRenderContext".  This isn't a trivial object to
   construct (and has important implications to the rendering, so be
   careful if you decide to build one yourself).  

   The easiest way to get a proper instance of this object is through
   the batik.gvt.renderer.StaticRendererFactory.getRenderContext()
   method (you will need to construct an instance of
   StaticRendererFactory first).

   This is forcing you to go at least one layer deeper in the
architecture than you should need to for what you are trying to
accomplish.  I'm considering some sort of 'short cut' paint method on
JSVGComponent that bypasses all the image caching stuff, but this is
something the dev team needs to discuss.

   Hope I haven't completely discouraged you.

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