package org.geotools.renderer.lite;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.fail;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import org.junit.Test;
import com.vividsolutions.jts.awt.ShapeReader;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
public class DashedShapeTest {
static final float EPS = 1e-3f;
@Test
public void testHorizontalLine() {
Line2D line = new Line2D.Double(0, 0, 30, 0);
Shape stroked = new DashedShape(line, new float[] { 10, 10 }, 0);
checkExpected(stroked, new float[] { 0, 0, 0 }, new float[] { 1, 10, 0 }, //
new float[] { 0, 20, 0 }, new float[] { 1, 30, 0 });
}
@Test
public void testShortLine() {
Line2D line = new Line2D.Double(0, 0, 5, 0);
Shape stroked = new DashedShape(line, new float[] { 10, 10 }, 0);
checkExpected(stroked, new float[] { 0, 0, 0 }, new float[] { 1, 5, 0 });
}
@Test
public void testMidLine() {
Line2D line = new Line2D.Double(0, 0, 25, 0);
Shape stroked = new DashedShape(line, new float[] { 10, 10 }, 0);
checkExpected(stroked, new float[] { 0, 0, 0 }, new float[] { 1, 10, 0 }, //
new float[] { 0, 20, 0 }, new float[] { 1, 25, 0 });
}
@Test
public void testPhase() {
Line2D line = new Line2D.Double(0, 0, 25, 0);
Shape stroked = new DashedShape(line, new float[] { 10, 10 }, 5);
checkExpected(stroked, new float[] { 0, 0, 0 }, new float[] { 1, 5, 0 }, //
new float[] { 0, 15, 0 }, new float[] { 1, 25, 0 });
}
@Test
public void testVerticalLine() {
Line2D line = new Line2D.Double(0, 0, 0, 30);
Shape stroked = new DashedShape(line, new float[] { 10, 10 }, 0);
checkExpected(stroked, new float[] { 0, 0, 0 }, new float[] { 1, 0, 10 }, //
new float[] { 0, 0, 20 }, new float[] { 1, 0, 30 });
}
@Test
public void testLShape() {
GeneralPath gp = new GeneralPath();
gp.moveTo(0, 0);
gp.lineTo(0, 5);
gp.lineTo(5, 5);
Shape stroked = new DashedShape(gp, new float[] {2, 2}, 0);
checkExpected(stroked, new float[] { 0, 0, 0 }, new float[] { 1, 0, 2 }, //
new float[] { 0, 0, 4 }, new float[] { 1, 0, 5 }, new float[] { 1, 1, 5 },
new float[] { 0, 3, 5 }, new float[] { 1, 5, 5 });
}
@Test
public void testDisconnected() {
GeneralPath gp = new GeneralPath();
gp.moveTo(0, 0);
gp.lineTo(5, 0);
gp.moveTo(10, 5);
gp.lineTo(15, 5);
Shape stroked = new DashedShape(gp, new float[] {2, 2}, 0);
checkExpected(stroked, new float[] { 0, 0, 0 }, new float[] { 1, 2, 0 }, //
new float[] { 0, 4, 0 }, new float[] { 1, 5, 0 },
new float[] { 0, 10, 5 }, new float[] { 1, 12, 5 },
new float[] { 0, 14, 5 }, new float[] { 1, 15, 5 });
}
@Test
public void testRectangle() {
// checks the SEG_CLOSE termination
Rectangle2D r = new Rectangle2D.Double(0, 0, 4, 4);
Shape stroked = new DashedShape(r, new float[] {2, 2}, 0);
checkExpected(stroked, new float[] { 0, 0, 0 }, new float[] { 1, 2, 0 }, //
new float[] { 0, 4, 0 }, new float[] { 1, 4, 2 }, new float[] { 0, 4, 4 },
new float[] { 1, 2, 4 }, new float[] { 0, 0, 4 }, new float[] { 1, 0, 2 },
new float[] { 0, 0, 0 }, new float[] { 4, 0, 0 });
}
void checkExpected(Shape stroked, float[]... segments) {
PathIterator pi = stroked.getPathIterator(new AffineTransform());
String errorMessage = errorMessage(stroked);
float[] piSegment = new float[2];
for (float[] segment : segments) {
if (pi.isDone()) {
fail("The iterator has less segments than expected. " + errorMessage);
}
int type = pi.currentSegment(piSegment);
assertEquals(errorMessage, type, (int) segment[0]);
assertEquals(errorMessage, segment[1], piSegment[0], EPS);
assertEquals(errorMessage, segment[2], piSegment[1], EPS);
pi.next();
}
if (!pi.isDone()) {
fail("The iterator has more segments than expected. " + errorMessage);
}
}
String errorMessage(Shape shape) {
PathIterator pi = shape.getPathIterator(new AffineTransform());
StringBuffer sb = new StringBuffer("The iterator sequence differs from what expected: \n");
float[] piSegment = new float[2];
while(!pi.isDone()) {
int type = pi.currentSegment(piSegment);
sb.append("{").append(type).append(", ").append(piSegment[0])
.append(", ").append(piSegment[1]).append("} ");
pi.next();
}
return sb.toString();
}
}