diff --git a/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReader.java b/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReader.java index cb2121d5..c55012de 100755 --- a/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReader.java +++ b/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReader.java @@ -33,9 +33,11 @@ package com.twelvemonkeys.imageio.plugins.svg; import com.twelvemonkeys.image.ImageUtil; import com.twelvemonkeys.imageio.ImageReaderBase; import com.twelvemonkeys.imageio.util.IIOUtil; +import com.twelvemonkeys.lang.StringUtil; import org.apache.batik.anim.dom.SVGDOMImplementation; import org.apache.batik.anim.dom.SVGOMDocument; import org.apache.batik.bridge.*; +import org.apache.batik.css.parser.CSSLexicalUnit; import org.apache.batik.dom.util.DOMUtilities; import org.apache.batik.ext.awt.image.GraphicsUtil; import org.apache.batik.gvt.CanvasGraphicsNode; @@ -47,6 +49,7 @@ import org.apache.batik.transcoder.*; import org.apache.batik.transcoder.image.ImageTranscoder; import org.apache.batik.util.ParsedURL; import org.apache.batik.util.SVGConstants; +import org.apache.batik.xml.LexicalUnits; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.svg.SVGSVGElement; @@ -324,24 +327,54 @@ public class SVGImageReader extends ImageReaderBase { } // ---- + SVGSVGElement rootElement = svgDoc.getRootElement(); // get the 'width' and 'height' attributes of the SVG document - Dimension2D docSize = ctx.getDocumentSize(); - if (docSize != null) { - defaultWidth = (float) docSize.getWidth(); - defaultHeight = (float) docSize.getHeight(); + UnitProcessor.Context uctx + = UnitProcessor.createContext(ctx, rootElement); + String widthStr = rootElement.getAttributeNS(null, SVGConstants.SVG_WIDTH_ATTRIBUTE); + String heightStr = rootElement.getAttributeNS(null, SVGConstants.SVG_HEIGHT_ATTRIBUTE); + if (!StringUtil.isEmpty(widthStr)) { + defaultWidth = UnitProcessor.svgToUserSpace(widthStr, SVGConstants.SVG_WIDTH_ATTRIBUTE, UnitProcessor.HORIZONTAL_LENGTH, uctx); } - else { - defaultWidth = 200; - defaultHeight = 200; + if(!StringUtil.isEmpty(heightStr)){ + defaultHeight = UnitProcessor.svgToUserSpace(heightStr, SVGConstants.SVG_HEIGHT_ATTRIBUTE, UnitProcessor.VERTICAL_LENGTH, uctx); } - SVGSVGElement rootElement = svgDoc.getRootElement(); - String viewBoxStr = rootElement.getAttributeNS - (null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE); - if (viewBoxStr.length() != 0) { - float[] rect = ViewBox.parseViewBoxAttribute(rootElement, viewBoxStr, null); - defaultWidth = rect[2]; - defaultHeight = rect[3]; + + boolean hasWidth = defaultWidth > 0.0; + boolean hasHeight = defaultHeight > 0.0; + + if (!hasWidth || !hasHeight) { + String viewBoxStr = rootElement.getAttributeNS + (null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE); + if (viewBoxStr.length() != 0) { + float[] rect = ViewBox.parseViewBoxAttribute(rootElement, viewBoxStr, null); + // if one dimension is given, calculate other by aspect ratio in viewBox + // or use viewBox if no dimension is given + if (hasWidth) { + defaultHeight = defaultWidth * rect[3] / rect[2]; + } + else if (hasHeight) { + defaultWidth = defaultHeight * rect[2] / rect[3]; + } + else { + defaultWidth = rect[2]; + defaultHeight = rect[3]; + } + } + else { + if (hasHeight) { + defaultWidth = defaultHeight; + } + else if (hasWidth) { + defaultHeight = defaultWidth; + } + else { + // fallback to batik default sizes + defaultWidth = 400; + defaultHeight = 400; + } + } } // Hack to work around exception above diff --git a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java index 4860bd0f..21c30f3b 100755 --- a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java +++ b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTest.java @@ -74,7 +74,11 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest new TestData(getClassLoaderResource("/svg/batikLogo.svg"), new Dimension(450, 500)), new TestData(getClassLoaderResource("/svg/red-square.svg"), new Dimension(100, 100)), new TestData(getClassLoaderResource("/svg/blue-square.svg"), new Dimension(100, 100)), - new TestData(getClassLoaderResource("/svg/Android_robot.svg"), new Dimension(294, 345)) + new TestData(getClassLoaderResource("/svg/Android_robot.svg"), new Dimension(294, 345)), + new TestData(getClassLoaderResource("/svg/sizes/w50h50.svg"), new Dimension(50, 50)), + new TestData(getClassLoaderResource("/svg/sizes/w50_1to2.svg"), new Dimension(25, 50)), + new TestData(getClassLoaderResource("/svg/sizes/h50_1to2.svg"), new Dimension(50, 100)), + new TestData(getClassLoaderResource("/svg/sizes/w50noview.svg"), new Dimension(50, 50)) ); } diff --git a/imageio/imageio-batik/src/test/resources/svg/sizes/h50_1to2.svg b/imageio/imageio-batik/src/test/resources/svg/sizes/h50_1to2.svg new file mode 100644 index 00000000..2f29bfb1 --- /dev/null +++ b/imageio/imageio-batik/src/test/resources/svg/sizes/h50_1to2.svg @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/imageio/imageio-batik/src/test/resources/svg/sizes/w50_1to2.svg b/imageio/imageio-batik/src/test/resources/svg/sizes/w50_1to2.svg new file mode 100644 index 00000000..0b99c157 --- /dev/null +++ b/imageio/imageio-batik/src/test/resources/svg/sizes/w50_1to2.svg @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/imageio/imageio-batik/src/test/resources/svg/sizes/w50h50.svg b/imageio/imageio-batik/src/test/resources/svg/sizes/w50h50.svg new file mode 100644 index 00000000..bb34679d --- /dev/null +++ b/imageio/imageio-batik/src/test/resources/svg/sizes/w50h50.svg @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/imageio/imageio-batik/src/test/resources/svg/sizes/w50noview.svg b/imageio/imageio-batik/src/test/resources/svg/sizes/w50noview.svg new file mode 100644 index 00000000..888927a4 --- /dev/null +++ b/imageio/imageio-batik/src/test/resources/svg/sizes/w50noview.svg @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file