I have an SVG which contains a little unnecessary "padding" (i.e. there's transparent pixels surrounding the image):
<svg style="border: 1px dashed black" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="150" height="100" viewBox="0 0 150 100" xml:space="preserve">
<desc>Created with Fabric.js 4.4.0</desc>
<defs>
</defs>
<g transform="matrix(1 0 0 1 75 50)">
<g style="">
<g transform="matrix(0.83 0 0 0.83 0 0.75)" id="path3914">
<path style="stroke: rgb(0,0,0); stroke-width: 3; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-opacity: 0; fill-rule: nonzero; opacity: 1;" transform=" translate(-106.37, -106.56)" d="M 173.5258 164.62704 L 39.223861 164.7471 L 106.27086 48.378182 Z" stroke-linecap="round"/>
</g>
<g transform="matrix(4.99 0 0 4.99 0.5 5.36)" style="" id="text6366">
<text x="-2.82" y="1.18" xml:space="preserve" font-family="Times New Roman" font-size="3.76296" font-style="normal" font-weight="normal" style="stroke: rgb(0,0,0); stroke-width: 0.166666; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;">ME</text>
</g>
<g transform="matrix(4.99 0 0 4.99 0.79 26.98)" style="" id="text397">
<text x="-3.18" y="1.33" xml:space="preserve" font-family="Times New Roman" font-size="4.23334" font-style="normal" font-weight="normal" style="stroke: rgb(0,0,0); stroke-width: 0.2; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;">322</text>
</g>
</g>
</g>
</svg>
<p><strong>NOTE:</strong> The border was added for this question to demonstrate the padding.</p>
I want to programmatically "trim" or crop the viewbox to exclude the transparent portion. I referenced Remove whitespace from SVG and Get bounding box of svg element? to draft up this method using Batik:
public static String trim(String svgXml) throws ParserConfigurationException, SAXException, IOException,
TransformerFactoryConfigurationError, TransformerException {
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());
SVGDocument document = factory.createSVGDocument("file://localhost/c:/", new StringReader(svgXml));
GVTBuilder builder = new GVTBuilder();
BridgeContext context = new BridgeContext(new UserAgentAdapter());
GraphicsNode node = builder.build(context, document);
Rectangle2D boundingBox = node.getSensitiveBounds();
String x = String.valueOf(boundingBox.getX());
String y = String.valueOf(boundingBox.getY());
String width = String.valueOf(boundingBox.getWidth());
String height = String.valueOf(boundingBox.getHeight());
String viewBox = String.join(" ", x, y, width, height);
Element svgNode = (Element) stream(document.getChildNodes())
.filter(n -> n.getNodeName().equalsIgnoreCase("svg")).findFirst().get();
svgNode.setAttribute("viewBox", viewBox);
svgNode.setAttribute("width", width);
svgNode.setAttribute("height", height);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(document), new StreamResult(stream));
return stream.toString();
}
This works as expected. The final SVG is without whitespace:
However, when I use this same code with a different graphic, it does not work:
<svg style="border: 1px dashed black" width="50mm" height="50mm" viewBox="0 0 400 400" version="1.1" id="svg5"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs2" />
<g id="layer1">
<path style="fill:#000000;fill-opacity:0;stroke:#000000;stroke-width:5.56777;stroke-dasharray:none" id="path1025" d="m 132.29166,145.88567 188.95027,327.27148 -377.900552,-10e-6 z" transform="matrix(0.83095221,0,0,0.95950522,90.073162,-97.347212)" />
<text xml:space="preserve" style="font-size:40.8983px;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.885595;stroke-dasharray:none" x="198.31625" y="228.99879" id="text1081"><tspan style="font-size:40.8983px;fill:#000000;fill-opacity:1;stroke-width:0.885595;stroke-dasharray:none" x="198.31625" y="228.99879" id="tspan1443">ME</tspan></text>
<text xml:space="preserve" style="font-size:40.8983px;text-align:center;text-anchor:middle;fill:#000000;stroke:#000000;stroke-width:0.885595" x="196.43968" y="269.51633" id="text347"><tspan id="tspan345" style="stroke-width:0.885595" x="196.43968" y="269.51633">373</tspan></text>
</g>
</svg>
This is the resultant image:
It seems clear to me that that GraphicsNode#getSensitiveBounds() is producing inaccurate bounds, but why? Is there a way to fix this?

