]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/SVGNode.java
Editing of texts inside SVG elements
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / SVGNode.java
index ec85fd75c86e7893a8b7341bcfde6641e380d244..db491a3fda07e3145d91a38bdbbf8e693595debf 100644 (file)
@@ -24,6 +24,7 @@ import java.net.URL;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -64,16 +65,21 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
     protected Point           targetSize       = null;
     protected Boolean         useMipMap        = true;
     protected Rectangle2D     bounds           = null;
-    
+
     protected List<SVGNodeAssignment> assignments = new ArrayList<SVGNodeAssignment>();
 
-    transient BufferedImage buffer    = null;
-    transient String documentCache    = null;
-    transient SVGDiagram diagramCache = null;
-    transient String dataHash         = null;
+    protected transient BufferedImage buffer    = null;
+    protected transient String documentCache    = null;
+    protected transient SVGDiagram diagramCache = null;
+    protected transient String dataHash         = null;
 
     static transient Map<String, WeakReference<BufferedImage>> bufferCache = new HashMap<String, WeakReference<BufferedImage>>();
 
+    @Override
+    public void init() {
+        super.init();
+    }
+
     @Override
     public void cleanup() {
         cleanDiagramCache();
@@ -159,6 +165,10 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
             g2d.setTransform(ot);
     }
 
+    protected int dynamicHash() {
+        return 0;
+    }
+
     protected String parseSVG() {
         if (data == null)
             return null;
@@ -173,7 +183,6 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
                     diagramCache = null;
                 }
 
-                
                 // Lets check for rootAssignment that contributes the whole SVG 
                 SVGNodeAssignment rootAssignment = null;
                 if (!assignments.isEmpty()) {
@@ -191,7 +200,7 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
                     // NOTE: hard-coded to assume all SVG data is encoded in UTF-8
                     dataBytes = data.getBytes("UTF-8");
                 }
-                dataHash = digest(dataBytes, assignments);
+                dataHash = digest(dataBytes, assignments, dynamicHash());
                 URI uri = univ.loadSVG(new ByteArrayInputStream(dataBytes), dataHash);
                 diagramCache = univ.getDiagram(uri, false);
 
@@ -208,7 +217,7 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
                         bbox = root.getBoundingBox();
                         if (bbox.isEmpty()) {
                             // Lets check if this should be visible or not
-                            Set presentationAttributes = root.getPresentationAttributes();
+                            Set<?> presentationAttributes = root.getPresentationAttributes();
                             if (!presentationAttributes.contains("display")) {
                                 // TODO: fix this - How can one read values of attributes in SVG salamander???
                                 univ.decRefCount(diagramCache.getXMLBase());
@@ -246,14 +255,13 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
         return dataHash;
     }
 
-    private static boolean applyAssignments(SVGDiagram diagram, List<SVGNodeAssignment> assignments) throws SVGException {
+    protected boolean applyAssignments(SVGDiagram diagram, List<SVGNodeAssignment> assignments) throws SVGException {
         if (assignments.isEmpty())
             return false;
+
         boolean changed = false;
+
         for (SVGNodeAssignment ass : assignments) {
-//             System.err.println("assign: " + ass.elementId + " " + ass.attributeNameOrId + " " + ass.value);
-//             if("opacity".equals(ass.attributeNameOrId))
-//                     System.err.println("faaf");
             SVGElement e = diagram.getElement(ass.elementId);
             if (e != null) {
                 if ("$text".equals(ass.attributeNameOrId)) {
@@ -269,21 +277,28 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
                             ((Text) parent).rebuild();
                         changed = true;
                     }
+                } else if (ass.attributeNameOrId.startsWith("#")) {
+                    e.setAttribute(ass.attributeNameOrId.substring(1), AnimationElement.AT_CSS, ass.value);
+                    changed = true;
                 } else {
                     e.setAttribute(ass.attributeNameOrId, AnimationElement.AT_AUTO, ass.value);
                     changed = true;
                 }
             }
         }
-        diagram.updateTime(0);
+
         return changed;
     }
 
     public static Rectangle2D getBounds(String data) {
-        return getBounds(data, null);
+        return getBounds(data, 0);
+    }
+
+    public static Rectangle2D getBounds(String data, int dynamicHash) {
+        return getBounds(data, Collections.emptyList(), dynamicHash);
     }
 
-    public static Rectangle2D getBounds(String data, List<SVGNodeAssignment> assignments) {
+    public static Rectangle2D getBounds(String data, List<SVGNodeAssignment> assignments, int dynamicHash) {
         if (data == null) {
             new Exception("null SVG data").printStackTrace();
             return null;
@@ -293,7 +308,7 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
         try {
             // NOTE: hard-coded to assume all SVG data is encoded in UTF-8
             byte[] dataBytes = data.getBytes("UTF-8");
-            String digest = digest(dataBytes, assignments);
+            String digest = digest(dataBytes, assignments, dynamicHash);
 
             SVGUniverse univ = SVGCache.getSVGUniverse();
             // TODO: this completely removes any parallel processing from the SVG loading which would be nice to have.
@@ -327,10 +342,10 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
     }
 
     public static Rectangle2D getRealBounds(String data) {
-       return getRealBounds(data, null);
+        return getRealBounds(data, Collections.emptyList(), 0);
     }
 
-    public static Rectangle2D getRealBounds(String data, List<SVGNodeAssignment> assignments) {
+    public static Rectangle2D getRealBounds(String data, List<SVGNodeAssignment> assignments, int dynamicHash) {
         if (data == null) {
             new Exception("null SVG data").printStackTrace();
             return null;
@@ -340,7 +355,7 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
         try {
             // NOTE: hard-coded to assume all SVG data is encoded in UTF-8
             byte[] dataBytes = data.getBytes("UTF-8");
-            String digest = digest(dataBytes, assignments);
+            String digest = digest(dataBytes, assignments, dynamicHash);
 
             SVGUniverse univ = SVGCache.getSVGUniverse();
             // TODO: this completely removes any parallel processing from the SVG loading which would be nice to have.
@@ -362,13 +377,12 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
     }
 
     protected void initBuffer(Graphics2D g2d) {
-       
         if (!data.equals(documentCache) || diagramCache == null) {
-               dataHash = parseSVG();
-               if (diagramCache == null) {
-                       System.err.println("UNABLE TO PARSE SVG:\n" + data);
-                       return;
-               }
+            dataHash = parseSVG();
+            if (diagramCache == null) {
+                System.err.println("UNABLE TO PARSE SVG:\n" + data);
+                return;
+            }
         }
 
         if (buffer != null) {
@@ -380,14 +394,14 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
         } else if(diagramCache.getViewRect().getWidth()==0 || diagramCache.getViewRect().getHeight()==0) {
             buffer = null;
         } else if(useMipMap) {
-               if(G2DUtils.isAccelerated(g2d)) {
+            if(G2DUtils.isAccelerated(g2d)) {
                 buffer = new MipMapVRamBufferedImage(diagramCache, bounds, targetSize);
             } else {
                 buffer = new MipMapBufferedImage(diagramCache, bounds, targetSize);
             }
             bufferCache.put(dataHash, new WeakReference<BufferedImage>(buffer));
         } else {
-               if(G2DUtils.isAccelerated(g2d)) {
+            if(G2DUtils.isAccelerated(g2d)) {
                 buffer = new VRamBufferedImage(diagramCache, bounds, targetSize);
             } else {
                 buffer = new BufferedImage(diagramCache, bounds, targetSize);
@@ -419,13 +433,13 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
     }
 
     static WeakHashMap<String, String> digestCache = new WeakHashMap<String, String>();
-    
-    static String digest(byte[] dataBytes, List<SVGNodeAssignment> assignments) {
+
+    static String digest(byte[] dataBytes, List<SVGNodeAssignment> assignments, int dynamicHash) {
         try {
             MessageDigest md = MessageDigest.getInstance("MD5");
             byte[] messageDigest = md.digest(dataBytes);
             BigInteger number = new BigInteger(1, messageDigest);
-            String dataHash = number.toString(16) + (assignments != null ? assignments.hashCode() : 0);
+            String dataHash = number.toString(16) + (assignments != null ? assignments.hashCode() : 0) + 31 * dynamicHash;
             String result = digestCache.get(dataHash);
             if(result == null) {
                result = dataHash;
@@ -462,12 +476,12 @@ public class SVGNode extends G2DNode implements InitValueSupport, LoaderNode {
        public void synchronizeTransform(double[] data) {
                this.setTransform(new AffineTransform(data));
        }
-       
+
        public String getSVGText() {
                String ret = data.replace("<svg", "<g").replaceAll("svg>", "g>");
                //return diagramCache.toString();
                //return data.replace("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"><svg xmlns=\"http://www.w3.org/2000/svg\" overflow=\"visible\" version=\"1.1\"", "<g").replaceAll("svg>", "/g>");
                return ret;
        }
-       
+
 }