From 2c8f0f5add687c236f091ad193ff43e492c7db1f Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Tue, 7 Apr 2015 11:05:14 +0200 Subject: [PATCH] TMI-125: Clean up after merge + fix Spi issue. --- .../imageio/plugins/svg/SVGImageReader.java | 127 +++++++++--------- .../plugins/svg/SVGImageReaderSpi.java | 33 +++-- .../plugins/svg/SVGImageReaderTestCase.java | 21 +-- 3 files changed, 93 insertions(+), 88 deletions(-) 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 90ddd370..3a1172d7 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 @@ -74,18 +74,19 @@ import java.util.Map; * @see batik-dev */ public class SVGImageReader extends ImageReaderBase { - private Rasterizer rasterizer = null; + private Rasterizer rasterizer; /** * Creates an {@code SVGImageReader}. * * @param pProvider the provider */ - public SVGImageReader(ImageReaderSpi pProvider) { + public SVGImageReader(final ImageReaderSpi pProvider) { super(pProvider); } protected void resetMembers() { + rasterizer = new Rasterizer(); } @Override @@ -100,7 +101,6 @@ public class SVGImageReader extends ImageReaderBase { if (imageInput != null) { TranscoderInput input = new TranscoderInput(IIOUtil.createStreamAdapter(imageInput)); - rasterizer = new Rasterizer(); rasterizer.setInput(input); } } @@ -135,7 +135,7 @@ public class SVGImageReader extends ImageReaderBase { try { processImageStarted(pIndex); - rasterizer.mTranscoderInput.setURI(baseURI); + rasterizer.transcoderInput.setURI(baseURI); BufferedImage image = rasterizer.getImage(); Graphics2D g = destination.createGraphics(); @@ -253,31 +253,29 @@ public class SVGImageReader extends ImageReaderBase { */ private class Rasterizer extends SVGAbstractTranscoder /*ImageTranscoder*/ { - BufferedImage mImage = null; - private TranscoderInput mTranscoderInput; - private float mDefaultWidth; - private float mDefaultHeight; - private boolean mInit = false; - private SVGOMDocument mDocument; - private String mURI; - private GraphicsNode mGVTRoot; - private TranscoderException mException; - private BridgeContext mContext; + BufferedImage image = null; + private TranscoderInput transcoderInput; + private float defaultWidth; + private float defaultHeight; + private boolean initialized = false; + private SVGOMDocument document; + private String uri; + private GraphicsNode gvtRoot; + private TranscoderException exception; + private BridgeContext context; - public BufferedImage createImage(int w, int h) { - return ImageUtil.createTransparent(w, h);//, BufferedImage.TYPE_INT_ARGB); + public BufferedImage createImage(final int width, final int height) { + return ImageUtil.createTransparent(width, height);//, BufferedImage.TYPE_INT_ARGB); } // This is cheating... We don't fully transcode after all - protected void transcode(Document document, String uri, TranscoderOutput output) throws TranscoderException { + protected void transcode(Document document, final String uri, final TranscoderOutput output) throws TranscoderException { // Sets up root, curTxf & curAoi // ---- - if ((document != null) && - !(document.getImplementation() instanceof SVGDOMImplementation)) { - DOMImplementation impl; - impl = (DOMImplementation) hints.get(KEY_DOM_IMPLEMENTATION); - // impl = ExtensibleSVGDOMImplementation.getDOMImplementation(); + if ((document != null) && !(document.getImplementation() instanceof SVGDOMImplementation)) { + DOMImplementation impl = (DOMImplementation) hints.get(KEY_DOM_IMPLEMENTATION); document = DOMUtilities.deepCloneDocument(document, impl); + if (uri != null) { try { URL url = new URL(uri); @@ -290,7 +288,6 @@ public class SVGImageReader extends ImageReaderBase { ctx = createBridgeContext(); SVGOMDocument svgDoc = (SVGOMDocument) document; - //SVGSVGElement root = svgDoc.getRootElement(); // build the GVT tree builder = new GVTBuilder(); @@ -298,7 +295,7 @@ public class SVGImageReader extends ImageReaderBase { boolean isDynamic = (hints.containsKey(KEY_EXECUTE_ONLOAD) && (Boolean) hints.get(KEY_EXECUTE_ONLOAD) && - BaseScriptingEnvironment.isDynamicDocument(ctx, svgDoc)); + BaseScriptingEnvironment.isDynamicDocument(ctx, svgDoc)); if (isDynamic) { ctx.setDynamicState(BridgeContext.DYNAMIC); @@ -312,8 +309,7 @@ public class SVGImageReader extends ImageReaderBase { catch (BridgeException ex) { // Note: This might fail, but we STILL have the dimensions we need // However, we need to reparse later... - //throw new TranscoderException(ex); - mException = new TranscoderException(ex); + exception = new TranscoderException(ex); } // ---- @@ -321,24 +317,23 @@ public class SVGImageReader extends ImageReaderBase { // get the 'width' and 'height' attributes of the SVG document Dimension2D docSize = ctx.getDocumentSize(); if (docSize != null) { - mDefaultWidth = (float) docSize.getWidth(); - mDefaultHeight = (float) docSize.getHeight(); + defaultWidth = (float) docSize.getWidth(); + defaultHeight = (float) docSize.getHeight(); } else { - mDefaultWidth = 200; - mDefaultHeight = 200; + defaultWidth = 200; + defaultHeight = 200; } // Hack to work around exception above if (root != null) { - mGVTRoot = root; + gvtRoot = root; } - mDocument = svgDoc; - mURI = uri; + this.document = svgDoc; + this.uri = uri; - //ctx.dispose(); // Hack to avoid the transcode method wacking my context... - mContext = ctx; + context = ctx; ctx = null; } @@ -353,24 +348,24 @@ public class SVGImageReader extends ImageReaderBase { // Hacky workaround below... - if (mGVTRoot == null) { + if (gvtRoot == null) { // Try to reparse, if we had no URI last time... - if (mURI != mTranscoderInput.getURI()) { + if (uri != transcoderInput.getURI()) { try { - mContext.dispose(); - mDocument.setURLObject(new URL(mTranscoderInput.getURI())); - transcode(mDocument, mTranscoderInput.getURI(), null); + context.dispose(); + document.setURLObject(new URL(transcoderInput.getURI())); + transcode(document, transcoderInput.getURI(), null); } catch (MalformedURLException ignore) { // Ignored } } - if (mGVTRoot == null) { - throw mException; + if (gvtRoot == null) { + throw exception; } } - ctx = mContext; + ctx = context; // /Hacky if (abortRequested()) { processReadAborted(); @@ -378,13 +373,13 @@ public class SVGImageReader extends ImageReaderBase { } processImageProgress(20f); - // -- -- - SVGSVGElement root = mDocument.getRootElement(); + // ---- + SVGSVGElement root = document.getRootElement(); // ---- // ---- - setImageSize(mDefaultWidth, mDefaultHeight); + setImageSize(defaultWidth, defaultHeight); if (abortRequested()) { processReadAborted(); @@ -394,7 +389,7 @@ public class SVGImageReader extends ImageReaderBase { // compute the preserveAspectRatio matrix AffineTransform Px; - String ref = new ParsedURL(mURI).getRef(); + String ref = new ParsedURL(uri).getRef(); try { Px = ViewBox.getViewTransform(ref, root, width, height); @@ -404,12 +399,12 @@ public class SVGImageReader extends ImageReaderBase { throw new TranscoderException(ex); } - if (Px.isIdentity() && (width != mDefaultWidth || height != mDefaultHeight)) { + if (Px.isIdentity() && (width != defaultWidth || height != defaultHeight)) { // The document has no viewBox, we need to resize it by hand. // we want to keep the document size ratio float xscale, yscale; - xscale = width / mDefaultWidth; - yscale = height / mDefaultHeight; + xscale = width / defaultWidth; + yscale = height / defaultHeight; float scale = Math.min(xscale, yscale); Px = AffineTransform.getScaleInstance(scale, scale); } @@ -440,7 +435,7 @@ public class SVGImageReader extends ImageReaderBase { } processImageProgress(50f); - CanvasGraphicsNode cgn = getCanvasGraphicsNode(mGVTRoot); + CanvasGraphicsNode cgn = getCanvasGraphicsNode(gvtRoot); if (cgn != null) { cgn.setViewingTransform(Px); curTxf = new AffineTransform(); @@ -462,7 +457,7 @@ public class SVGImageReader extends ImageReaderBase { throw new TranscoderException(ex); } - this.root = mGVTRoot; + this.root = gvtRoot; // ---- // NOTE: The code below is copied and pasted from the Batik @@ -510,6 +505,7 @@ public class SVGImageReader extends ImageReaderBase { g2d.setPaint(bgcolor); g2d.fillRect(0, 0, w, h); } + if (rend != null) { // might be null if the svg document is empty g2d.drawRenderedImage(rend, new AffineTransform()); } @@ -534,43 +530,44 @@ public class SVGImageReader extends ImageReaderBase { throw exception; } finally { - if (mContext != null) { - mContext.dispose(); + if (context != null) { + context.dispose(); } } } private synchronized void init() throws TranscoderException { - if (!mInit) { - if (mTranscoderInput == null) { + if (!initialized) { + if (transcoderInput == null) { throw new IllegalStateException("input == null"); } - mInit = true; + initialized = true; - super.transcode(mTranscoderInput, null); + super.transcode(transcoderInput, null); } } private BufferedImage getImage() throws TranscoderException { - if (mImage == null) { - mImage = readImage(); + if (image == null) { + image = readImage(); } - return mImage; + + return image; } protected int getDefaultWidth() throws TranscoderException { init(); - return (int) (mDefaultWidth + 0.5); + return (int) (defaultWidth + 0.5); } protected int getDefaultHeight() throws TranscoderException { init(); - return (int) (mDefaultHeight + 0.5); + return (int) (defaultHeight + 0.5); } - public void setInput(TranscoderInput pInput) { - mTranscoderInput = pInput; + public void setInput(final TranscoderInput pInput) { + transcoderInput = pInput; } } } diff --git a/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderSpi.java b/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderSpi.java index 3c1744d8..0d1d2a94 100755 --- a/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderSpi.java +++ b/imageio/imageio-batik/src/main/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderSpi.java @@ -29,8 +29,8 @@ package com.twelvemonkeys.imageio.plugins.svg; import com.twelvemonkeys.imageio.spi.ProviderInfo; -import com.twelvemonkeys.lang.SystemUtil; import com.twelvemonkeys.imageio.util.IIOUtil; +import com.twelvemonkeys.lang.SystemUtil; import javax.imageio.ImageReader; import javax.imageio.spi.ImageReaderSpi; @@ -80,18 +80,18 @@ public class SVGImageReaderSpi extends ImageReaderSpi { ); } - public boolean canDecodeInput(Object pSource) throws IOException { + public boolean canDecodeInput(final Object pSource) throws IOException { return pSource instanceof ImageInputStream && SVG_READER_AVAILABLE && canDecode((ImageInputStream) pSource); } - private static boolean canDecode(ImageInputStream pInput) throws IOException { + private static boolean canDecode(final ImageInputStream pInput) throws IOException { // NOTE: This test is quite quick as it does not involve any parsing, // however it requires the doctype to be "svg", which may not be correct // in all cases... try { pInput.mark(); - // TODO: This is may not be ok for non-UTF/iso-latin encodings... + // TODO: This is not ok for UTF-16 and other wide encodings // TODO: Use an XML (encoding) aware Reader instance instead // Need to figure out pretty fast if this is XML or not int b; @@ -111,9 +111,14 @@ public class SVGImageReaderSpi extends ImageReaderSpi { // Skip over, until begin tag } - // If this is not a comment, or the DOCTYPE declaration, the doc - // has no DOCTYPE and it can't be svg - if (pInput.read() != '!') { + if ((b = pInput.read()) != '!') { + if (b == 's' && pInput.read() == 'v' && pInput.read() == 'g' + && (Character.isWhitespace((char) (b = pInput.read())) || b == ':')) { + // TODO: Support svg with prefix + recognize namespace (http://www.w3.org/2000/svg)! + return true; + } + + // If this is not a comment, or the DOCTYPE declaration, the doc has no DOCTYPE and it can't be svg return false; } @@ -126,19 +131,19 @@ public class SVGImageReaderSpi extends ImageReaderSpi { } // If we are lucky, this is DOCTYPE declaration - if (b == 'D' && pInput.read() == 'O' && pInput.read() == 'C' - && pInput.read() == 'T' && pInput.read() == 'Y' && pInput.read() == 'P' - && pInput.read() == 'E') { + if (b == 'D' && pInput.read() == 'O' && pInput.read() == 'C' && pInput.read() == 'T' + && pInput.read() == 'Y' && pInput.read() == 'P' && pInput.read() == 'E') { docTypeFound = true; while (Character.isWhitespace((char) (b = pInput.read()))) { // Skip over WS } + if (b == 's' && pInput.read() == 'v' && pInput.read() == 'g') { - //System.out.println("It's svg!"); return true; } } } + return false; } finally { @@ -147,17 +152,17 @@ public class SVGImageReaderSpi extends ImageReaderSpi { } - public ImageReader createReaderInstance(Object extension) throws IOException { + public ImageReader createReaderInstance(final Object extension) throws IOException { return new SVGImageReader(this); } - public String getDescription(Locale locale) { + public String getDescription(final Locale locale) { return "Scaleable Vector Graphics (SVG) format image reader"; } @SuppressWarnings({"deprecation"}) @Override - public void onRegistration(ServiceRegistry registry, Class category) { + public void onRegistration(final ServiceRegistry registry, final Class category) { if (!SVG_READER_AVAILABLE) { try { // NOTE: This will break, but it gives us some useful debug info diff --git a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTestCase.java b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTestCase.java index e6738a11..40ebd140 100755 --- a/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTestCase.java +++ b/imageio/imageio-batik/src/test/java/com/twelvemonkeys/imageio/plugins/svg/SVGImageReaderTestCase.java @@ -31,7 +31,6 @@ package com.twelvemonkeys.imageio.plugins.svg; import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase; import org.junit.Ignore; import org.junit.Test; -import static org.junit.Assert.assertEquals; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; @@ -43,6 +42,8 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; +import static org.junit.Assert.assertEquals; + /** * SVGImageReaderTestCase * @@ -55,7 +56,9 @@ public class SVGImageReaderTestCase extends ImageReaderAbstractTestCase getTestData() { return Arrays.asList( - new TestData(getClassLoaderResource("/svg/batikLogo.svg"), new Dimension(450, 500)) + 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)) ); } @@ -114,19 +117,19 @@ public class SVGImageReaderTestCase extends ImageReaderAbstractTestCase