]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java
Support SVG generation from scenegraph.
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / SCLScenegraph.java
index 33d7f06290e109e69fdc4ceff7afb00c8b7cd00a..3fbfa2304a062f67983ad8a62199057fe360acb7 100644 (file)
@@ -1,10 +1,21 @@
 package org.simantics.modeling;
 
+import java.awt.Dimension;
+import java.awt.RenderingHints.Key;
+import java.awt.geom.Rectangle2D;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 
+import org.apache.batik.dom.GenericDOMImplementation;
+import org.apache.batik.svggen.SVGGraphics2D;
 import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.diagram.elements.DiagramNodeUtil;
@@ -19,6 +30,7 @@ import org.simantics.g2d.element.IElement;
 import org.simantics.g2d.scenegraph.ICanvasSceneGraphProvider;
 import org.simantics.g2d.utils.CanvasUtils;
 import org.simantics.scenegraph.ParentNode;
+import org.simantics.scenegraph.g2d.G2DHints;
 import org.simantics.scenegraph.g2d.G2DParentNode;
 import org.simantics.scenegraph.g2d.G2DSceneGraph;
 import org.simantics.scenegraph.g2d.events.command.Commands;
@@ -29,9 +41,13 @@ import org.simantics.scenegraph.g2d.nodes.DataNode;
 import org.simantics.scenegraph.g2d.nodes.DecorationSVGNode;
 import org.simantics.scenegraph.g2d.nodes.NavigationNode;
 import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
+import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
 import org.simantics.scenegraph.utils.NodeUtil;
 import org.simantics.trend.impl.ItemNode;
 import org.simantics.utils.threads.ThreadUtils;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 public class SCLScenegraph {
        
@@ -285,6 +301,128 @@ public class SCLScenegraph {
                }
                return true;
     }
+     
+   
+     
+     
+     static class Generator extends SVGGraphics2D {
+        
+        int elemLevel = 0;
+        String newElementId = null;
+        ArrayList<Element> elements = new ArrayList<Element>();
+
+        public static final String svgNS = "http://www.w3.org/2000/svg";
+        
+               public Generator(Document document) {
+                       super(document);
+               }
+               
+               @Override
+               public Element getRoot() {
+                       Element root = super.getRoot();
+                       for(Element e : elements) {
+                               root.appendChild(e);
+                       }
+                       return root;
+               }
+               
+               @Override
+               public void setRenderingHint(Key arg0, Object arg1) {
+                       if(G2DHints.KEY_BEGIN_ELEMENT == arg0) {
+                               elemLevel++;
+                       }
+                       if(G2DHints.KEY_ELEMENT_ID == arg0) {
+                               if(arg1 != null)
+                                       newElementId = arg1.toString();
+                               else
+                                       newElementId = UUID.randomUUID().toString();
+                       }
+                       if(G2DHints.KEY_END_ELEMENT == arg0) {
+                               elemLevel--;
+                               if(elemLevel == 0) {
+                                       Element group = getDOMFactory().createElementNS(SVG_NAMESPACE_URI, SVG_G_TAG);
+                                       group.setAttributeNS(null, "id", newElementId);
+                                       group.setAttributeNS(null, "class", arg1.toString());
+                                       getRoot(group);
+                                       elements.add(group);
+                               }
+                       }
+                       super.setRenderingHint(arg0, arg1);
+               }
+        
+     }
+     
+     public static String renderSVG(ICanvasContext ctx) {
+
+         // Get a DOMImplementation.
+         DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
+
+         // Create an instance of org.w3c.dom.Document.
+         String svgNS = "http://www.w3.org/2000/svg";
+         Document document = domImpl.createDocument(svgNS, "svg", null);
+         
+         // Create an instance of the SVG Generator.
+         SVGGraphics2D svgGenerator = new Generator(document);
+
+         try {
+                
+             G2DSceneGraph sg = ctx.getSceneGraph();
+             G2DParentNode root = (G2DParentNode) sg.getRootNode();
+             
+             // rtree is the actual content of the diagram
+             RTreeNode rtree = NodeUtil.getNearestChildByClass(root, RTreeNode.class);
+             Rectangle2D rtreeBounds = NodeUtil.getLocalBounds(rtree);
+             
+             // nav is a node that has zooming functionalities
+             NavigationNode nav = NodeUtil.getNearestChildByClass(root, NavigationNode.class);
+             nav.setZoomEnabled(true);
+             
+             // fit view with the contents of rtreeBounds
+             nav.zoomTo(rtreeBounds);
+             
+             // get the bounds of the content
+             Rectangle2D content = NodeUtil.getLocalBounds(nav);
+             
+             // translate svgGenerator to the x and y coordinates of current content
+             svgGenerator.translate(-1 * content.getX(), -1 * content.getY());
+
+             Rectangle2D destination = new Rectangle2D.Double(0,0,1000,1000);
+             double sx = destination.getWidth() / content.getWidth();
+             double sy = destination.getHeight() / content.getHeight();
+             double scale = sx < sy ? sx : sy;
+             
+             svgGenerator.scale(scale, scale);
+             
+             // Set svgCanvasSize to the given size parameters
+             svgGenerator.setSVGCanvasSize(new Dimension((int)(scale * content.getWidth()), (int)(scale * content.getHeight())));
+             svgGenerator.setClip(content);
+             
+             sg.render(svgGenerator);
+             
+         } finally {
+         }
+
+         String result = "";
+
+         // Finally, stream out SVG to the standard output using
+         // UTF-8 encoding.
+         boolean useCSS = true; // we want to use CSS style attributes
+         try {
+             ByteArrayOutputStream os = new ByteArrayOutputStream();
+             Writer out = new OutputStreamWriter(os, "UTF-8");
+             svgGenerator.stream(out, useCSS);
+             os.flush();
+             os.close();
+             result = new String(os.toByteArray());//Base64.encode(os.toByteArray());
+         } catch (UnsupportedEncodingException e) {
+             e.printStackTrace();
+         } catch (IOException e) {
+             e.printStackTrace();
+         }
+         
+         return result;
+        
+     }
 
 
 }
\ No newline at end of file