/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package sec.sun.awt.geom;
import armyc2.c2sd.graphics2d.PathIterator;
/**
*
* @author Michael Deutch
*/
public class CrossingsObject {
public static final int CROSSINGS = 0;
public static final int NONZERO = 1;
public static final int EVENODD = 2;
public static final boolean debug = false;
int limit = 0;
double yranges[] = new double[10];
double xlo, ylo, xhi, yhi;
private int crosscounts[] = null;
private EvenOdd evenOdd = null;
private Crossings crossings = null;
private NonZero nonZero = null;
int type = -1;
public CrossingsObject(double xlo, double ylo, double xhi, double yhi, int type) {
//super(xlo, ylo, xhi, yhi);
this.xlo = xlo;
this.ylo = ylo;
this.xhi = xhi;
this.yhi = yhi;
this.type = type;
//crosscounts = new int[yranges.length / 2];
switch (type) {
case CROSSINGS:
crossings = new Crossings(xlo, ylo, xhi, yhi);
break;
case NONZERO:
nonZero = new NonZero(xlo, ylo, xhi, yhi);
crosscounts = new int[yranges.length / 2];
break;
case EVENODD:
evenOdd = new EvenOdd(xlo, ylo, xhi, yhi);
break;
}
}
public double getXLo() {
switch (type) {
case CROSSINGS:
return crossings.getXLo();
case EVENODD:
return evenOdd.getXLo();
case NONZERO:
return nonZero.getXLo();
default:
return -1;
}
}
public double getYLo() {
switch (type) {
case CROSSINGS:
return crossings.getYLo();
case EVENODD:
return evenOdd.getYLo();
case NONZERO:
return nonZero.getYLo();
default:
return -1;
}
}
public double getXHi() {
//return xhi;
switch (type) {
case CROSSINGS:
return crossings.getXHi();
case EVENODD:
return evenOdd.getXHi();
case NONZERO:
return nonZero.getXHi();
default:
return -1;
}
}
public double getYHi() {
//return yhi;
switch (type) {
case CROSSINGS:
return crossings.getYHi();
case EVENODD:
return evenOdd.getYHi();
case NONZERO:
return nonZero.getYHi();
default:
return -1;
}
}
public boolean isEmpty() {
//return (limit == 0);
switch (type) {
case CROSSINGS:
return crossings.isEmpty();
case EVENODD:
return evenOdd.isEmpty();
case NONZERO:
return nonZero.isEmpty();
default:
return true;
}
}
public void record(double ystart, double yend, int direction) {
switch (type) {
case CROSSINGS:
crossings.record(ystart, yend, direction);
case EVENODD:
evenOdd.record(ystart, yend, direction);
case NONZERO:
nonZero.record(ystart, yend, direction);
default:
return;
}
}
public static CrossingsObject findCrossings(Vector curves,
double xlo, double ylo,
double xhi, double yhi) {
//Crossings cross = new EvenOdd(xlo, ylo, xhi, yhi);
CrossingsObject cross = new CrossingsObject(xlo, ylo, xhi, yhi, CrossingsObject.EVENODD);
Enumeration enum_ = curves.elements();
while (enum_.hasMoreElements()) {
CurveObject c = (CurveObject) enum_.nextElement();
if (c.accumulateCrossings(cross)) {
return null;
}
}
return cross;
}
public CrossingsObject findCrossings2(PathIterator pi,
double xlo, double ylo,
double xhi, double yhi) {
CrossingsObject cross;
if (pi.getWindingRule() == pi.WIND_EVEN_ODD) {
cross = new CrossingsObject(xlo, ylo, xhi, yhi, EVENODD);
} else {
cross = new CrossingsObject(xlo, ylo, xhi, yhi, NONZERO);
}
// coords array is big enough for holding:
// coordinates returned from currentSegment (6)
// OR
// two subdivided quadratic curves (2+4+4=10)
// AND
// 0-1 horizontal splitting parameters
// OR
// 2 parametric equation derivative coefficients
// OR
// three subdivided cubic curves (2+6+6+6=20)
// AND
// 0-2 horizontal splitting parameters
// OR
// 3 parametric equation derivative coefficients
double coords[] = new double[23];
double movx = 0;
double movy = 0;
double curx = 0;
double cury = 0;
double newx, newy;
while (!pi.isDone()) {
int type = pi.currentSegment(coords);
switch (type) {
case PathIterator.SEG_MOVETO:
if (movy != cury
&& cross.accumulateLine(curx, cury, movx, movy)) {
return null;
}
movx = curx = coords[0];
movy = cury = coords[1];
break;
case PathIterator.SEG_LINETO:
newx = coords[0];
newy = coords[1];
if (cross.accumulateLine(curx, cury, newx, newy)) {
return null;
}
curx = newx;
cury = newy;
break;
case PathIterator.SEG_QUADTO:
newx = coords[2];
newy = coords[3];
if (cross.accumulateQuad(curx, cury, coords)) {
return null;
}
curx = newx;
cury = newy;
break;
case PathIterator.SEG_CUBICTO:
newx = coords[4];
newy = coords[5];
if (cross.accumulateCubic(curx, cury, coords)) {
return null;
}
curx = newx;
cury = newy;
break;
case PathIterator.SEG_CLOSE:
if (movy != cury
&& cross.accumulateLine(curx, cury, movx, movy)) {
return null;
}
curx = movx;
cury = movy;
break;
}
pi.next();
}
if (movy != cury) {
if (cross.accumulateLine(curx, cury, movx, movy)) {
return null;
}
}
return cross;
}
public boolean accumulateLine(double x0, double y0,
double x1, double y1) {
switch (this.type) {
case CROSSINGS:
return crossings.accumulateLine(x0, y0, x1, y1);
case EVENODD:
return evenOdd.accumulateLine(x0, y0, x1, y1);
case NONZERO:
return nonZero.accumulateLine(x0, y0, x1, y1);
default:
return false;
}
}
public boolean accumulateLine2(double x0, double y0,
double x1, double y1,
int direction) {
switch (this.type) {
case CROSSINGS:
return crossings.accumulateLine2(x0, y0, x1, y1, direction);
case EVENODD:
return evenOdd.accumulateLine2(x0, y0, x1, y1, direction);
case NONZERO:
return nonZero.accumulateLine2(x0, y0, x1, y1, direction);
default:
return false;
}
}
private Vector tmp = new Vector();
public boolean accumulateQuad(double x0, double y0, double coords[]) {
if (y0 < ylo && coords[1] < ylo && coords[3] < ylo) {
return false;
}
if (y0 > yhi && coords[1] > yhi && coords[3] > yhi) {
return false;
}
if (x0 > xhi && coords[0] > xhi && coords[2] > xhi) {
return false;
}
if (x0 < xlo && coords[0] < xlo && coords[2] < xlo) {
if (y0 < coords[3]) {
record(Math.max(y0, ylo), Math.min(coords[3], yhi), 1);
} else if (y0 > coords[3]) {
record(Math.max(coords[3], ylo), Math.min(y0, yhi), -1);
}
return false;
}
Curve.insertQuad(tmp, x0, y0, coords);
Enumeration enum_ = tmp.elements();
while (enum_.hasMoreElements()) {
CurveObject c = (CurveObject) enum_.nextElement();
if (c.accumulateCrossings(this)) {
return true;
}
}
tmp.clear();
return false;
}
public boolean accumulateCubic(double x0, double y0, double coords[]) {
if (y0 < ylo && coords[1] < ylo
&& coords[3] < ylo && coords[5] < ylo) {
return false;
}
if (y0 > yhi && coords[1] > yhi
&& coords[3] > yhi && coords[5] > yhi) {
return false;
}
if (x0 > xhi && coords[0] > xhi
&& coords[2] > xhi && coords[4] > xhi) {
return false;
}
if (x0 < xlo && coords[0] < xlo
&& coords[2] < xlo && coords[4] < xlo) {
if (y0 <= coords[5]) {
record(Math.max(y0, ylo), Math.min(coords[5], yhi), 1);
} else {
record(Math.max(coords[5], ylo), Math.min(y0, yhi), -1);
}
return false;
}
Curve.insertCubic(tmp, x0, y0, coords);
Enumeration enum_ = tmp.elements();
while (enum_.hasMoreElements()) {
CurveObject c = (CurveObject) enum_.nextElement();
if (c.accumulateCrossings(this)) {
return true;
}
}
tmp.clear();
return false;
}
}