Search code examples
javasvgurifilechooserbatik

Getting different results loading SVG files from URIs


Background

The JavaFX program MyApp will import SVG images, parse the transform and shape information from the files, and display the shapes in a class that extends the JavaFX Canvas. The part that’s giving strange results is in the initial stages, getting a file system URI for an SVG image and parsing it.

The strange part is that I have two methods of doing the same thing, but one of them works (using FileChooser) and the other one doesn’t (using the class loader MyApp.class.getResource(pathString)). Both generate a valid URI to the same file, and both URIs are fed to a batik SAXSVGDocumentFactory.

I’ve checked with a FileReader on both URIs to make sure that the text is read the same from both.

Problem code (simplified)

FileChooser importer = new FileChooser();

URI uriBad = MyApp.class.getResource(“my_file.svg”).toURI();
URI uriGood = importer.showOpenDialog(myJavafxStage).toURI();

SAXSVGDocumentFactory documentFactory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());

SVGDocument vectorDocumentBad = documentFactory.createSVGDocument(uriBad);
SVGDocument vectorDocumentGood = documentFactory.createSVGDocument(uriGood);

I expected to be able to parse vectorDocumentBad and vectorDocumentGood just the same, but the transform information that I get using the same parsing function is wrong for the former document created, corresponding to uriBad.

Output from bad URI

PARSING SVG
NODE_RootGraphicsNode without style or transform info
GROUP_RootGraphicsNode: 0.0,0.0
    GROUP_CanvasGraphicsNode: NaN,NaN
        SHAPE_ShapeNode: NaN,NaN
        SHAPE_ShapeNode: NaN,NaN
        SHAPE_ShapeNode: NaN,NaN
        SHAPE_ShapeNode: NaN,NaN
        SHAPE_ShapeNode: NaN,NaN
        SHAPE_ShapeNode: NaN,NaN
        ...

Output from good URI

PARSING SVG
NODE_RootGraphicsNode without style or transform info
GROUP_RootGraphicsNode: 0.0,0.0
    GROUP_CanvasGraphicsNode: 164.0199324823223,-6.723440123593414
        SHAPE_ShapeNode: 164.0199324823223,-6.723440123593414
        SHAPE_ShapeNode: 164.0199324823223,-6.723440123593414
        SHAPE_ShapeNode: 164.0199324823223,-6.723440123593414
        SHAPE_ShapeNode: 164.0199324823223,-6.723440123593414
        SHAPE_ShapeNode: 164.0199324823223,-6.723440123593414
        ...

SVG Document

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="181.957" height="238.119"
     viewBox="0 0 181.957 238.119" overflow="visible" enable-background="new 0 0 181.957 238.119;" xml:space="preserve">

<path fill="none" stroke="#46B035" stroke-width="7" d="M58.726,11.278c0,0-2.5,4.75,2.667,16.333s12.7,13.745,12.7,13.745"/>
<linearGradient id="XMLID_18_" gradientUnits="userSpaceOnUse" x1="51.5977" y1="130.6812" x2="84.5962" y2="162.1797">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_18_)" stroke="#56278A" stroke-width="2" cx="70.75" cy="148.962" r="24.751"/>
<linearGradient id="XMLID_19_" gradientUnits="userSpaceOnUse" x1="107.0942" y1="194.0854" x2="140.0934" y2="225.5846">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_19_)" stroke="#56278A" stroke-width="2" cx="126.247" cy="212.368" r="24.751"/>
<linearGradient id="XMLID_20_" gradientUnits="userSpaceOnUse" x1="76.2715" y1="167.9692" x2="109.2707" y2="199.4684">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_20_)" stroke="#56278A" stroke-width="2" cx="95.424" cy="186.251" r="24.751"/>
<linearGradient id="XMLID_21_" gradientUnits="userSpaceOnUse" x1="120.1133" y1="167.0015" x2="153.1125" y2="198.5006">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_21_)" stroke="#56278A" stroke-width="2" cx="139.265" cy="185.284" r="24.751"/>
<linearGradient id="XMLID_22_" gradientUnits="userSpaceOnUse" x1="124.1118" y1="119.4976" x2="157.111" y2="150.9967">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_22_)" stroke="#56278A" stroke-width="2" cx="143.264" cy="137.779" r="24.751"/>
<linearGradient id="XMLID_23_" gradientUnits="userSpaceOnUse" x1="76.6772" y1="104.4282" x2="109.6764" y2="135.9274">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_23_)" stroke="#56278A" stroke-width="2" cx="95.83" cy="122.71" r="24.751"/>
<linearGradient id="XMLID_24_" gradientUnits="userSpaceOnUse" x1="129.5947" y1="32.1802" x2="162.5939" y2="63.6793">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_24_)" stroke="#56278A" stroke-width="2" cx="148.748" cy="50.462" r="24.751"/>
<linearGradient id="XMLID_25_" gradientUnits="userSpaceOnUse" x1="137.0527" y1="71.9644" x2="170.0519" y2="103.4635">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_25_)" stroke="#56278A" stroke-width="2" cx="156.206" cy="90.247" r="24.751"/>
<linearGradient id="XMLID_26_" gradientUnits="userSpaceOnUse" x1="107.0933" y1="81.6763" x2="140.0924" y2="113.1754">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_26_)" stroke="#56278A" stroke-width="2" cx="126.246" cy="99.958" r="24.752"/>
<linearGradient id="XMLID_27_" gradientUnits="userSpaceOnUse" x1="87.5947" y1="22.1807" x2="120.5939" y2="53.6798">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_27_)" stroke="#56278A" stroke-width="2" cx="106.748" cy="40.462" r="24.751"/>
<linearGradient id="XMLID_28_" gradientUnits="userSpaceOnUse" x1="48.5972" y1="43.1802" x2="81.5963" y2="74.6793">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_28_)" stroke="#56278A" stroke-width="2" cx="67.75" cy="61.461" r="24.751"/>
<linearGradient id="XMLID_29_" gradientUnits="userSpaceOnUse" x1="6.5986" y1="50.106" x2="39.5985" y2="81.6057">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_29_)" stroke="#56278A" stroke-width="2" cx="25.751" cy="68.388" r="24.751"/>
<linearGradient id="XMLID_30_" gradientUnits="userSpaceOnUse" x1="26.7363" y1="97.314" x2="59.7355" y2="128.8131">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_30_)" stroke="#56278A" stroke-width="2" cx="45.889" cy="115.596" r="24.751"/>
<linearGradient id="XMLID_31_" gradientUnits="userSpaceOnUse" x1="102.9971" y1="46.4272" x2="135.9962" y2="77.9264">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_31_)" stroke="#56278A" stroke-width="2" cx="122.15" cy="64.709" r="24.752"/>
<linearGradient id="XMLID_32_" gradientUnits="userSpaceOnUse" x1="73.0938" y1="62.1743" x2="106.0929" y2="93.6734">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_32_)" stroke="#56278A" stroke-width="2" cx="92.247" cy="80.457" r="24.752"/>
<linearGradient id="XMLID_33_" gradientUnits="userSpaceOnUse" x1="37.436" y1="74.3335" x2="70.4352" y2="105.8326">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_33_)" stroke="#56278A" stroke-width="2" cx="56.589" cy="92.616" r="24.752"/>
<linearGradient id="XMLID_34_" gradientUnits="userSpaceOnUse" x1="90.9429" y1="143.8394" x2="123.9414" y2="175.3379">
    <stop  offset="0" style="stop-color:#FFFFFF"/>
    <stop  offset="0.736" style="stop-color:#573993"/>
</linearGradient>
<circle fill="url(#XMLID_34_)" stroke="#56278A" stroke-width="2" cx="110.095" cy="162.121" r="24.751"/>
<polyline fill="none" stroke="#46B035" stroke-width="7" points="35.654,16.038 58.726,11.278 80.652,3.289 "/>

</svg>

Solution

  • False alarm! The problem was not actually where I thought it was, many steps further in the method calls chain, when I was trying to modify those transform values read from the SVG file. I was basically trying to get the dimensions of a JavaFX pane that hadn’t any dimensions yet, whose undefined values where then multiplied into the SVG transforms for display.

    So I was basically asking the wrong question.