/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g2d.svg; import java.awt.Point; import java.awt.Shape; import java.awt.geom.Rectangle2D; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.EnumSet; import org.simantics.g2d.image.Image; import org.simantics.scenegraph.Node; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.scenegraph.g2d.nodes.SVGNode; import org.simantics.utils.datastructures.cache.IFactory; import org.simantics.utils.datastructures.cache.ProvisionException; /** * This is a SVG implementation to the PaintableSymbol interface. */ public class SVGImage implements Image { static EnumSet caps = EnumSet.of(Feature.Vector); private Rectangle2D bounds; protected final String nodeIdentifier; protected final String svgDocument; protected Point targetSize; public static SVGImage loadFromURL(String nodeIdentifier, URL url) throws IOException { try (InputStream in = url.openStream()) { return new SVGImage(nodeIdentifier, in); } } public static IFactory createFactoryFromString(String nodeIdentifier, String svgDocument) { return createFactoryFromString(svgDocument, null); } public static IFactory createFactoryFromString(String nodeIdentifier, String svgDocument, Point targetSize) { return new SVGFactory(nodeIdentifier, svgDocument, targetSize); } static class SVGFactory implements IFactory { String nodeIdentifier; String document; Point targetSize; public SVGFactory(String nodeIdentifier, String document) { this(nodeIdentifier, document, null); } public SVGFactory(String nodeIdentifier, String document, Point referenceSize) { if (nodeIdentifier == null) throw new NullPointerException("nodeIdentifier is null"); if (document == null) throw new NullPointerException("document is null"); this.nodeIdentifier = nodeIdentifier; this.document = document; this.targetSize = referenceSize; } @Override public Image get() throws ProvisionException { return new SVGImage(nodeIdentifier, document, targetSize); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!obj.getClass().equals(getClass())) return false; SVGFactory other = (SVGFactory)obj; if (!nodeIdentifier.equals(other.nodeIdentifier)) return false; if (targetSize != null) { if (!targetSize.equals(other.targetSize)) return false; } else { if (other.targetSize != null) return false; } return document.equals(other.document); } @Override public int hashCode() { return nodeIdentifier.hashCode() * 31 + document.hashCode() + 123; } } public SVGImage(String nodeIdentifier, String svgDocument) { this(nodeIdentifier, svgDocument, null); } public SVGImage(String nodeIdentifier, String svgDocument, Point targetSize) { if (nodeIdentifier == null) throw new NullPointerException("nodeIdentifier is null"); if (svgDocument == null) throw new NullPointerException("svgDocument is null"); this.nodeIdentifier = nodeIdentifier; this.svgDocument = svgDocument; this.targetSize = targetSize; //this.bounds = SVGNode.getBounds(svgDocument); } public SVGImage(String nodeIdentifier, InputStream svgInput) { if (nodeIdentifier == null) throw new NullPointerException("nodeIdentifier is null"); String data = ""; try { BufferedReader reader = new BufferedReader(new InputStreamReader(svgInput, "UTF-8")); String line = ""; while((line = reader.readLine()) != null) { data += line+"\n"; } } catch(IOException e) { } this.nodeIdentifier = nodeIdentifier; this.bounds = SVGNode.getBounds(data); this.svgDocument = data; } @Override public Node init(G2DParentNode parent) { // FIXME: mipmaps enabled here by default, since some apps just don't work without them. // Figure out a way to pass the mipmap argument from above SVGNode node = parent.getOrCreateNode(nodeIdentifier, SVGNode.class); node.setData(svgDocument); node.setTargetSize(targetSize); node.useMipMap(true); return node; } @Override public Rectangle2D getBounds() { if(bounds == null) bounds = SVGNode.getBounds(svgDocument); return bounds; } @Override public Shape getOutline() { return getBounds(); } @Override public void addImageListener(ImageListener listener) { } @Override public EnumSet getFeatures() { return caps; } @Override public void removeImageListener(ImageListener listener) { } }