Hi, I am using Batik's JSVGComponent to render SVG content on various Graphics2D contexts (e.g. BufferedImages or Lowagie's PdfGraphics2D). Before getting to my current problem I would like to remark that this task turned out to be more complicated than I expected and perhaps it makes sense to give a short narrative of process. Most likely I missed something and I would very much appreciate if someone could point me in the right direction. Hopefully this is interesting reading for the API designers to see how someone furnished with an average brain, the current documentation and limited time to accomplish the task, can end up. It is been a while that I wrote the code so I might be a bit inaccurate in the description of the problems encountered but the general picture should be correct.
Issue 1: The program I am writing is a command line tool that requires to load and paint SVG documents synchronously. Since I could not find a synchronous API, I created LoadingSynchronizer class implementing SVGDocumentLoaderListener that I pass to JSVGComponent.addSVGDocumentLoaderListener(). The code is not trivial as it uses synchronized methods, notifications and timeouts. Luckily I remembered that similar code was used in the MediaTracker. Issue 2: Once the document is loaded the GVT tree has to be created synchronously. Using the same pattern as for issue 1, I ended up with another 64 lines of code implementing GVTTreeBuilderListener and passing it in a call to JSVGComponent.addGVTTreeBuilderListener(). Issue 3: Since I need to read documents not only from URLs but also from InputSources additional code was necessary because I failed to find an API call for that. To implement this I subclassed SAXDocumentFactory to make the method SAXDocumentFactory.createDocument(InputSource) public and loaded the document from there. That document is then passed to the component using JSVGComponent.setDocument(). Finding the SAXDocumentFactory as the class to load the document (avoiding cloning) was not obvious (I think I read the batik source to find that as I did quite a lot of batik source reading on other occasions too). Issue 4: I subclassed SVGUserAgentAdapter to store the asynchronously reported error messages (Some searching involved in finding this, I think to remember). Issue 5: I subclassed SVGComponent to give access to the protected members gvtRoot and svgDocument. The first is needed to call paint() on (I can't remember why, but for some reason it is not possible to call paint() on the JSVGComponent) and the latter is needed to retrieve the "viewBox" property from the document element. The whole thing took about 350 lines of code and quite some time in barking up wrong trees. OK, enough complaining, now the real issue: The application requires the SVG document to paint at it's specified size meaning that if the SVG root tag specifies a certain size, then it should paint at that size into the Graphics2D context. In other words, if the "width" property on the svg root element is set to "10cm" then a rectangle filling the entire space should be exactly 10cm wide. That works fine (apart from a mysterious correction factor of 0.75) as long as the document does not have a "viewBox" set. Example: The following document is correctly sized: <svg width="10cm ....> <rect width="10cm" .../> </svg> The following not: <svg width="10cm viewBox="0 0 10 10" ....> <rect width="10" .../> </svg> I also observed that JSVGComponent.getViewBoxTransform() returns the same value regardless whether or not the document has a "viewBox". The documentation states "Returns the transform from viewBox coords to screen coords" so I would think that this behavior is a bug. I resorted to grabbing and parsing the "viewBox" property from the DOM tree and computing the transform from it. Thanks, Alex -- View this message in context: http://batik.2283329.n4.nabble.com/General-difficulties-and-problems-getting-the-size-right-in-painting-an-SVG-document-containing-a-vi-tp4100365p4100365.html Sent from the Batik - Users mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: batik-users-unsubscr...@xmlgraphics.apache.org For additional commands, e-mail: batik-users-h...@xmlgraphics.apache.org