/*
* Copyright (c) 2016 Vivid Solutions.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.locationtech.jts.awt;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.util.Collection;
import java.util.Iterator;
/**
* A {@link PathIterator} which provides paths for a collection of {@link Shape}s.
*
* @author Martin Davis
*/
public class ShapeCollectionPathIterator implements PathIterator {
private Iterator shapeIterator;
// initialize with a no-op iterator
private PathIterator currentPathIterator = new PathIterator() {
public int getWindingRule() {
throw new UnsupportedOperationException();
}
public boolean isDone() {
return true;
}
public void next() {
}
public int currentSegment(float[] coords) {
throw new UnsupportedOperationException();
}
public int currentSegment(double[] coords) {
throw new UnsupportedOperationException();
}
};
private AffineTransform affineTransform;
private boolean done = false;
/**
* Creates a new path iterator for a collection of {@link Shape}s.
*
* @param shapes the Shapes in the collection
* @param affineTransform a optional transformation to be applied to the coordinates in the path (may be null)
*/
public ShapeCollectionPathIterator(Collection shapes,
AffineTransform affineTransform) {
shapeIterator = shapes.iterator();
this.affineTransform = affineTransform;
next();
}
public int getWindingRule() {
/**
* WIND_NON_ZERO is more accurate than WIND_EVEN_ODD, and can be comparable
* in speed. (See http://www.geometryalgorithms.com/Archive/algorithm_0103/algorithm_0103.htm#Winding%20Number)
* However, WIND_NON_ZERO requires that the
* shell and holes be oriented in a certain way.
* So use WIND_EVEN_ODD.
*/
return PathIterator.WIND_EVEN_ODD;
}
public boolean isDone() {
return done;
}
public void next() {
currentPathIterator.next();
if (currentPathIterator.isDone() && !shapeIterator.hasNext()) {
done = true;
return;
}
if (currentPathIterator.isDone()) {
currentPathIterator = ((Shape) shapeIterator.next()).getPathIterator(affineTransform);
}
}
public int currentSegment(float[] coords) {
return currentPathIterator.currentSegment(coords);
}
public int currentSegment(double[] coords) {
return currentPathIterator.currentSegment(coords);
}
}