diff options
author | kitfox | 2011-02-08 12:39:48 +0100 |
---|---|---|
committer | kitfox | 2011-02-08 12:39:48 +0100 |
commit | 83b6ddb437fd604cd68f1a6c19d3d72097861c9a (patch) | |
tree | 39a775a9363472b9722a3312305895c00c104b8d | |
parent | Fixing animation update for XML attributes. (diff) | |
download | svg-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-x | nbproject/build-impl.xml | 7 | ||||
-rwxr-xr-x | nbproject/genfiles.properties | 4 | ||||
-rwxr-xr-x | nbproject/project.properties | 6 | ||||
-rw-r--r-- | src/main/java/com/kitfox/svg/Marker.java | 263 | ||||
-rw-r--r-- | src/main/java/com/kitfox/svg/SVGLoader.java | 1 | ||||
-rw-r--r-- | src/main/java/com/kitfox/svg/ShapeElement.java | 57 | ||||
-rw-r--r-- | src/main/java/com/kitfox/svg/Symbol.java | 3 |
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
|