Hi,

First a little background about what I am trying to do. I have a Javascript / 
D3 based charting engine being used in one of our projects, and this charting 
engine is required to work both in a web browser and in an offline backend to 
prepare static chart images.

For the latter case I am using node.js as the JS execution environment and 
Batik (with node-java bridge) to provide the DOM implementation.

For the most part it is working well, but I have a few strange anomalies.

The chart engine uses the getBBox method to determine the size of various items 
and adjust margins etc accordingly. What I am finding is that batik does not 
take into account rotation of text when calculating the bounding box, while 
browser DOM engines do.

To illustrate this, consider the following svg:

<?xml version="1.0" standalone="no"?>
<svg width="1000" height="1000" version="1.1" 
xmlns="http://www.w3.org/2000/svg";>
    
    <g id="one">
        <g transform="translate(0,100)">
            <line x1="0" y1="0" x2="100" y2="0" style="stroke: black;"/>
            <text y="1em" x="0">Hello</text>
        </g>
        <g transform="translate(200,100)">
            <line x1="0" y1="0" x2="100" y2="0" style="stroke: black;"/>
            <text y="1em" x="0">Hello</text>
        </g>
    </g>
    
    <g id="two">
        <g transform="translate(0,500)">
            <line x1="0" y1="0" x2="100" y2="0" style="stroke: black;"/>
            <text y="1em" x="0" transform="rotate(-90)">Hello</text>
        </g>
        <g transform="translate(200,500)">
            <line x1="0" y1="0" x2="100" y2="0" style="stroke: black;"/>
            <text y="1em" x="0" transform="rotate(-90)">Hello</text>
        </g>
    </g>

</svg>

and the following little java program:

import java.io.IOException;

import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.util.XMLResourceDescriptor;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import java.io.FileOutputStream;

import org.w3c.dom.Document;
import org.w3c.dom.svg.SVGGElement;
import org.w3c.dom.svg.SVGRect;

class BatikBboxTest {

    public static void main(String [ ] args) {
        
        try {
            
            String parser = XMLResourceDescriptor.getXMLParserClassName();
            SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
            String uri = "file:test.svg";
            Document document = f.createSVGDocument(uri);

            PNGTranscoder transcoder = new PNGTranscoder();
            TranscoderInput input = new TranscoderInput(document);
            FileOutputStream ostream = new FileOutputStream("test.png");
            TranscoderOutput output = new TranscoderOutput(ostream);
            
            transcoder.transcode(input, output);
            ostream.flush();
            ostream.close();
            
            SVGGElement g1 = (SVGGElement)document.getElementById("one");
            SVGRect box1 = g1.getBBox();
            System.out.printf("getBBox = x=%f,y=%f - w=%f,h=%f\n", box1.getX(), 
box1.getY(), box1.getWidth(), box1.getHeight());
            
            SVGGElement g2 = (SVGGElement)document.getElementById("two");
            SVGRect box2 = g2.getBBox();
            System.out.printf("getBBox = x=%f,y=%f - w=%f,h=%f\n", box2.getX(), 
box2.getY(), box2.getWidth(), box2.getHeight());

        } catch (Exception ex) {
            System.err.println("Error: "+ex);
        }
        
    }
   
}

The output I get from this is:

getBBox = x=0.000000,y=-29.761719 - w=100.000000,h=29.761719
getBBox = x=0.000000,y=-29.761719 - w=100.000000,h=29.761719

I have an equivalent in-browser version here: 
https://rawgit.com/harmic/a57f37bd6d3773f3a6e900779cdc7941/raw/909c3222abf8627c34ae9ac24ca8c3572fad7222/test_bbox_textrot.html

In this version you get the output:

getBBox = x=0,y=100 - w=300,h=19
getBBox = x=0,y=464 - w=300,h=35

Note that the height is different for the first and second <g>, because the 
text in the second <g> is rotated.

That is what I was expecting, but Batik does not do it.

Another strange thing is that batik gives the X and Y coordinates of the <g>'s 
as being the same, even though they clearly are not. The browsers get it right.

I am using Java 1.8 & Batik 1.7. The HTML/JS equivalent works OK with Chrome 50 
and FF 45.

Thanks for any insights!

Regards
Mike



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

Reply via email to