title: getBBox for embedded SVG element with batik
body: <p>I am writing an application which is to create a HTML document which contains a number of embedded SVGs. </p>
  
  <p>The application has the following characteristics:</p>
  
  <ol>
  <li><p>It must run headless in a server environment</p></li>
  <li><p>It uses existing code which manipulates the DOM in order to create the SVGs and other items in the document</p></li>
  <li><p>The existing code uses the <code>getBBox()</code> method in order to determine sizes of various dynamically created elements, so as to calculate the layout of the SVGs.</p></li>
  <li><p>As additional information, although I do not think it affects the question: the SVG generation code is written in Javascript and uses the D3 library. I am using <a href="https://github.com/joeferner/node-java" rel="nofollow">node-java</a> to facilitate this. However, the problem I am currently experiencing is easily reproduced in a pure Java <a href="http://sscce.org/" rel="nofollow">SSCE</a> (see below).</p></li>
  </ol>
  
  <p>I am trying to use <a href="https://xmlgraphics.apache.org/batik/" rel="nofollow">Apache Batik</a> to provide the SVG DOM implementation.</p>
  
  <p>My problem is that I have so far been unable to get the <code>getBBox()</code> to return a non-null value in the case where an SVG element is embedded in a larger XML document.</p>
  
  <p>Here is an example that illustrates the problem:</p>
  
  <pre><code>import org.w3c.dom.*;
  import org.w3c.dom.svg.*;
  import org.apache.batik.anim.dom.SVGDOMImplementation;
  import org.apache.batik.bridge.UserAgent;
  import org.apache.batik.bridge.UserAgentAdapter;
  import org.apache.batik.bridge.DocumentLoader;
  import org.apache.batik.bridge.BridgeContext;
  import org.apache.batik.bridge.GVTBuilder;
  
  class BatikDomEmbedded {
  
      public static void main(String [ ] args) {
  
          DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); 
          SVGDocument doc = (SVGDocument) impl.createDocument(null, "html", null);
  
          Element html = doc.getDocumentElement();
          Element body = doc.createElement("body");
          html.appendChild(body);
  
          Element svg = doc.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg"); 
          svg.setAttributeNS(null, "width", "500");
          svg.setAttributeNS(null, "height", "100");
          body.appendChild(svg);
  
          UserAgent userAgent = new UserAgentAdapter(); 
          DocumentLoader loader    = new DocumentLoader(userAgent); 
          BridgeContext ctx       = new BridgeContext(userAgent, loader); 
          ctx.setDynamicState(BridgeContext.DYNAMIC); 
          GVTBuilder builder   = new GVTBuilder(); 
          builder.build(ctx, svg); 
  
          Element rect = doc.createElementNS(SVGDOMImplementation.SVG_NAMESPACE_URI, "rect");
          rect.setAttributeNS(null, "x", "100"); 
          rect.setAttributeNS(null, "y", "100"); 
          rect.setAttributeNS(null, "width", "150"); 
          rect.setAttributeNS(null, "height", "200"); 
          svg.appendChild(rect); 
  
          SVGRect bbox = ((SVGLocatable)rect).getBBox(); 
  
          System.out.println("X: " + bbox.getX() + "\nY: " + bbox.getY() + 
              "\nHeight: " + bbox.getHeight() + "\nWidth: " + bbox.getWidth());     
      }       
  
  }
  </code></pre>
  
  <p>Running this code results in a null pointer exception when dereferencing bbox.</p>
  
  <p>If I alter the code slightly to make the document a standalone SVG document then it works OK.</p>
  
  <p>The chief difference between these scenarios (other than that the SVG element is not the root document element) is that in the working case, the call to <code>builder.build(ctx, ...);</code> supplies an SVGDocument as the second argument, but in the non-working case it is an SVGElement (of type 'svg').</p>
  
  <p>Is there any way to get <code>getBBox()</code> working in this case where the svg element is embedded in a larger document (and in fact there may be multiple SVGs in this document)?</p>