summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkitfox2011-02-08 12:39:48 +0100
committerkitfox2011-02-08 12:39:48 +0100
commit83b6ddb437fd604cd68f1a6c19d3d72097861c9a (patch)
tree39a775a9363472b9722a3312305895c00c104b8d
parentFixing animation update for XML attributes. (diff)
downloadsvg-salamander-core-83b6ddb437fd604cd68f1a6c19d3d72097861c9a.tar.gz
svg-salamander-core-83b6ddb437fd604cd68f1a6c19d3d72097861c9a.tar.xz
svg-salamander-core-83b6ddb437fd604cd68f1a6c19d3d72097861c9a.zip
Added support for the SVG Marker tag.
git-svn-id: https://svn.java.net/svn/svgsalamander~svn/trunk/svg-core@88 7dc7fa77-23fb-e6ad-8e2e-c86bd48ed22b
-rwxr-xr-xnbproject/build-impl.xml7
-rwxr-xr-xnbproject/genfiles.properties4
-rwxr-xr-xnbproject/project.properties6
-rw-r--r--src/main/java/com/kitfox/svg/Marker.java263
-rw-r--r--src/main/java/com/kitfox/svg/SVGLoader.java1
-rw-r--r--src/main/java/com/kitfox/svg/ShapeElement.java57
-rw-r--r--src/main/java/com/kitfox/svg/Symbol.java3
7 files changed, 333 insertions, 8 deletions
diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml
index fafcef2..3a71c95 100755
--- a/nbproject/build-impl.xml
+++ b/nbproject/build-impl.xml
@@ -326,15 +326,18 @@ is divided into following sections:
<attribute default="${build.classes.dir}" name="destdir"/>
<sequential>
<fail unless="javac.includes">Must set javac.includes</fail>
- <pathconvert pathsep="," property="javac.includes.binary">
+ <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
<path>
<filelist dir="@{destdir}" files="${javac.includes}"/>
</path>
<globmapper from="*.java" to="*.class"/>
</pathconvert>
+ <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+ <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
<delete>
- <files includes="${javac.includes.binary}"/>
+ <files includesfile="${javac.includesfile.binary}"/>
</delete>
+ <delete file="${javac.includesfile.binary}"/>
</sequential>
</macrodef>
</target>
diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties
index f096182..49bff32 100755
--- a/nbproject/genfiles.properties
+++ b/nbproject/genfiles.properties
@@ -4,5 +4,5 @@ build.xml.stylesheet.CRC32=be360661
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=478066e1
-nbproject/build-impl.xml.script.CRC32=3700c371
-nbproject/build-impl.xml.stylesheet.CRC32=f33e10ff@1.38.2.45
+nbproject/build-impl.xml.script.CRC32=1ebb99f0
+nbproject/build-impl.xml.stylesheet.CRC32=229523de@1.38.3.45
diff --git a/nbproject/project.properties b/nbproject/project.properties
index 70220d9..406fd4c 100755
--- a/nbproject/project.properties
+++ b/nbproject/project.properties
@@ -1,3 +1,6 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.run.all.processors=true
application.title=svg-salamander-core
application.vendor=kitfox
build.classes.dir=${build.dir}/classes
@@ -18,6 +21,7 @@ debug.test.classpath=\
dist.dir=dist
dist.jar=${dist.dir}/svg-salamander-core.jar
dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
excludes=
file.reference.ant.jar=..\\libraries\\ant.jar
file.reference.javacc.jar=..\\libraries\\javacc.jar
@@ -34,6 +38,8 @@ javac.classpath=\
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
+javac.processorpath=\
+ ${javac.classpath}
javac.source=1.4
javac.target=1.4
javac.test.classpath=\
diff --git a/src/main/java/com/kitfox/svg/Marker.java b/src/main/java/com/kitfox/svg/Marker.java
new file mode 100644
index 0000000..e68a838
--- /dev/null
+++ b/src/main/java/com/kitfox/svg/Marker.java
@@ -0,0 +1,263 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.kitfox.svg;
+
+import com.kitfox.svg.xml.StyleAttribute;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+
+/**
+ *
+ * @author kitfox
+ */
+public class Marker extends Group
+{
+ AffineTransform viewXform;
+ AffineTransform markerXform;
+ Rectangle2D viewBox;
+
+ float refX;
+ float refY;
+ float markerWidth = 3;
+ float markerHeight = 3;
+ float orient = Float.NaN;
+
+ protected void build() throws SVGException
+ {
+ super.build();
+
+ StyleAttribute sty = new StyleAttribute();
+
+ if (getPres(sty.setName("refX"))) refX = sty.getFloatValueWithUnits();
+ if (getPres(sty.setName("refY"))) refY = sty.getFloatValueWithUnits();
+ if (getPres(sty.setName("markerWidth"))) markerWidth = sty.getFloatValueWithUnits();
+ if (getPres(sty.setName("markerHeight"))) markerHeight = sty.getFloatValueWithUnits();
+
+ if (getPres(sty.setName("orient")))
+ {
+ if ("auto".equals(sty.getStringValue()))
+ {
+ orient = Float.NaN;
+ }
+ else
+ {
+ orient = sty.getFloatValue();
+ }
+ }
+
+ if (getPres(sty.setName("viewBox")))
+ {
+ float[] dim = sty.getFloatList();
+ viewBox = new Rectangle2D.Float(dim[0], dim[1], dim[2], dim[3]);
+ }
+
+ if (viewBox == null)
+ {
+ viewBox = new Rectangle(0, 0, 1, 1);
+ }
+
+ //Transform pattern onto unit square
+ viewXform = new AffineTransform();
+ viewXform.scale(1.0 / viewBox.getWidth(), 1.0 / viewBox.getHeight());
+ viewXform.translate(-viewBox.getX(), -viewBox.getY());
+
+ markerXform = new AffineTransform();
+ markerXform.scale(markerWidth, markerHeight);
+ markerXform.concatenate(viewXform);
+ markerXform.translate(-refX, -refY);
+ }
+
+ protected boolean outsideClip(Graphics2D g) throws SVGException
+ {
+ g.getClipBounds(clipBounds);
+ Rectangle2D rect = super.getBoundingBox();
+ if (rect.intersects(clipBounds))
+ {
+ return false;
+ }
+
+ return true;
+
+ }
+
+ public void render(Graphics2D g) throws SVGException
+ {
+ AffineTransform oldXform = g.getTransform();
+ g.transform(markerXform);
+
+ super.render(g);
+
+ g.setTransform(oldXform);
+ }
+
+ public void render(Graphics2D g, MarkerPos pos, float strokeWidth) throws SVGException
+ {
+ AffineTransform cacheXform = g.getTransform();
+
+ g.translate(pos.x, pos.y);
+ g.scale(strokeWidth, strokeWidth);
+ g.rotate(Math.atan2(pos.dy, pos.dx));
+
+ g.transform(markerXform);
+
+ super.render(g);
+
+ g.setTransform(cacheXform);
+ }
+
+ public Shape getShape()
+ {
+ Shape shape = super.getShape();
+ return markerXform.createTransformedShape(shape);
+ }
+
+ public Rectangle2D getBoundingBox() throws SVGException
+ {
+ Rectangle2D rect = super.getBoundingBox();
+ return markerXform.createTransformedShape(rect).getBounds2D();
+ }
+
+ /**
+ * Updates all attributes in this diagram associated with a time event.
+ * Ie, all attributes with track information.
+ * @return - true if this node has changed state as a result of the time
+ * update
+ */
+ public boolean updateTime(double curTime) throws SVGException
+ {
+ boolean changeState = super.updateTime(curTime);
+
+ //Marker properties do not change
+ return changeState;
+ }
+
+ //--------------------------------
+ public static final int MARKER_START = 0;
+ public static final int MARKER_MID = 1;
+ public static final int MARKER_END = 2;
+
+ public static class MarkerPos
+ {
+ int type;
+ double x;
+ double y;
+ double dx;
+ double dy;
+
+ public MarkerPos(int type, double x, double y, double dx, double dy)
+ {
+ this.type = type;
+ this.x = x;
+ this.y = y;
+ this.dx = dx;
+ this.dy = dy;
+ }
+ }
+
+ public static class MarkerLayout
+ {
+ private ArrayList markerList = new ArrayList();
+ boolean started = false;
+
+ public void layout(Shape shape)
+ {
+ double px = 0;
+ double py = 0;
+ double[] coords = new double[6];
+ for (PathIterator it = shape.getPathIterator(null);
+ !it.isDone(); it.next())
+ {
+ switch (it.currentSegment(coords))
+ {
+ case PathIterator.SEG_MOVETO:
+ px = coords[0];
+ py = coords[1];
+ started = false;
+ break;
+ case PathIterator.SEG_CLOSE:
+ started = false;
+ break;
+ case PathIterator.SEG_LINETO:
+ {
+ double x = coords[0];
+ double y = coords[1];
+ markerIn(px, py, x - px, y - py);
+ markerOut(x, y, x - px, y - py);
+ px = x;
+ py = y;
+ break;
+ }
+ case PathIterator.SEG_QUADTO:
+ {
+ double k0x = coords[0];
+ double k0y = coords[1];
+ double x = coords[2];
+ double y = coords[3];
+ markerIn(px, py, k0x - px, k0y - py);
+ markerOut(x, y, x - k0x, y - k0y);
+ px = x;
+ py = y;
+ break;
+ }
+ case PathIterator.SEG_CUBICTO:
+ {
+ double k0x = coords[0];
+ double k0y = coords[1];
+ double k1x = coords[2];
+ double k1y = coords[3];
+ double x = coords[4];
+ double y = coords[5];
+ markerIn(px, py, k0x - px, k0y - py);
+ markerOut(x, y, x - k1x, y - k1y);
+ px = x;
+ py = y;
+ break;
+ }
+ }
+ }
+
+ for (int i = 1; i < markerList.size(); ++i)
+ {
+ MarkerPos prev = (MarkerPos)markerList.get(i - 1);
+ MarkerPos cur = (MarkerPos)markerList.get(i);
+
+ if (cur.type == MARKER_START)
+ {
+ prev.type = MARKER_END;
+ }
+ }
+ MarkerPos last = (MarkerPos)markerList.get(markerList.size() - 1);
+ last.type = MARKER_END;
+ }
+
+ private void markerIn(double x, double y, double dx, double dy)
+ {
+ if (started == false)
+ {
+ started = true;
+ markerList.add(new MarkerPos(MARKER_START, x, y, dx, dy));
+ }
+ }
+
+ private void markerOut(double x, double y, double dx, double dy)
+ {
+ markerList.add(new MarkerPos(MARKER_MID, x, y, dx, dy));
+ }
+
+ /**
+ * @return the markerList
+ */
+ public ArrayList getMarkerList()
+ {
+ return markerList;
+ }
+ }
+}
diff --git a/src/main/java/com/kitfox/svg/SVGLoader.java b/src/main/java/com/kitfox/svg/SVGLoader.java
index 9ba8527..ecace13 100644
--- a/src/main/java/com/kitfox/svg/SVGLoader.java
+++ b/src/main/java/com/kitfox/svg/SVGLoader.java
@@ -95,6 +95,7 @@ public class SVGLoader extends DefaultHandler
nodeClasses.put("image", ImageSVG.class);
nodeClasses.put("line", Line.class);
nodeClasses.put("lineargradient", LinearGradient.class);
+ nodeClasses.put("marker", Marker.class);
nodeClasses.put("metadata", Metadata.class);
nodeClasses.put("missing-glyph", MissingGlyph.class);
nodeClasses.put("path", Path.class);
diff --git a/src/main/java/com/kitfox/svg/ShapeElement.java b/src/main/java/com/kitfox/svg/ShapeElement.java
index 6446d11..f55ff15 100644
--- a/src/main/java/com/kitfox/svg/ShapeElement.java
+++ b/src/main/java/com/kitfox/svg/ShapeElement.java
@@ -27,6 +27,8 @@
package com.kitfox.svg;
+import com.kitfox.svg.Marker.MarkerLayout;
+import com.kitfox.svg.Marker.MarkerPos;
import com.kitfox.svg.xml.StyleAttribute;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
@@ -39,6 +41,7 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.net.URI;
+import java.util.ArrayList;
import java.util.List;
@@ -231,6 +234,26 @@ abstract public class ShapeElement extends RenderableElement
strokeWidth *= strokeWidthScalar;
// }
+ Marker markerStart = null;
+ if (getStyle(styleAttrib.setName("marker-start")))
+ {
+ URI uri = styleAttrib.getURIValue(getXMLBase());
+ markerStart = (Marker)diagram.getUniverse().getElement(uri);
+ }
+
+ Marker markerMid = null;
+ if (getStyle(styleAttrib.setName("marker-mid")))
+ {
+ URI uri = styleAttrib.getURIValue(getXMLBase());
+ markerMid = (Marker)diagram.getUniverse().getElement(uri);
+ }
+
+ Marker markerEnd = null;
+ if (getStyle(styleAttrib.setName("marker-end")))
+ {
+ URI uri = styleAttrib.getURIValue(getXMLBase());
+ markerEnd = (Marker)diagram.getUniverse().getElement(uri);
+ }
//Draw the shape
@@ -291,9 +314,41 @@ abstract public class ShapeElement extends RenderableElement
g.setPaint(strokePaint);
g.fill(strokeShape);
}
-
}
+ if (markerStart != null || markerMid != null || markerEnd != null)
+ {
+ MarkerLayout layout = new MarkerLayout();
+ layout.layout(shape);
+
+ ArrayList list = layout.getMarkerList();
+ for (int i = 0; i < list.size(); ++i)
+ {
+ MarkerPos pos = (MarkerPos)list.get(i);
+
+ switch (pos.type)
+ {
+ case Marker.MARKER_START:
+ if (markerStart != null)
+ {
+ markerStart.render(g, pos, strokeWidth);
+ }
+ break;
+ case Marker.MARKER_MID:
+ if (markerMid != null)
+ {
+ markerMid.render(g, pos, strokeWidth);
+ }
+ break;
+ case Marker.MARKER_END:
+ if (markerEnd != null)
+ {
+ markerEnd.render(g, pos, strokeWidth);
+ }
+ break;
+ }
+ }
+ }
}
abstract public Shape getShape();
diff --git a/src/main/java/com/kitfox/svg/Symbol.java b/src/main/java/com/kitfox/svg/Symbol.java
index 1a9f0b3..6d9e219 100644
--- a/src/main/java/com/kitfox/svg/Symbol.java
+++ b/src/main/java/com/kitfox/svg/Symbol.java
@@ -27,13 +27,10 @@
package com.kitfox.svg;
-import com.kitfox.svg.xml.StyleAttribute;
import java.awt.*;
import java.awt.geom.*;
-import java.util.*;
import com.kitfox.svg.xml.*;
-import org.xml.sax.*;
/**
* @author Mark McKay