/* GeneralPath.java -- represents a shape built from subpaths
   Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt.geom;

import java.awt.Rectangle;
import java.awt.Shape;


/**
 * A general geometric path, consisting of any number of subpaths
 * constructed out of straight lines and cubic or quadratic Bezier
 * curves.
 *
 * <p>The inside of the curve is defined for drawing purposes by a winding
 * rule. Either the WIND_EVEN_ODD or WIND_NON_ZERO winding rule can be chosen.
 *
 * <p><img src="doc-files/GeneralPath-1.png" width="300" height="210"
 * alt="A drawing of a GeneralPath" />
 * <p>The EVEN_ODD winding rule defines a point as inside a path if:
 * A ray from the point towards infinity in an arbitrary direction
 * intersects the path an odd number of times. Points <b>A</b> and
 * <b>C</b> in the image are considered to be outside the path.
 * (both intersect twice)
 * Point <b>B</b> intersects once, and is inside.
 *
 * <p>The NON_ZERO winding rule defines a point as inside a path if:
 * The path intersects the ray in an equal number of opposite directions.
 * Point <b>A</b> in the image is outside (one intersection in the
 * &#x2019;up&#x2019;
 * direction, one in the &#x2019;down&#x2019; direction) Point <b>B</b> in
 * the image is inside (one intersection &#x2019;down&#x2019;)
 * Point <b>C</b> in the image is inside (two intersections in the
 * &#x2019;down&#x2019; direction)
 *
 * @see Line2D
 * @see CubicCurve2D
 * @see QuadCurve2D
 *
 * @author Sascha Brawer (brawer@dandelis.ch)
 * @author Sven de Marothy (sven@physto.se)
 *
 * @since 1.2
 */
public final class GeneralPath implements Shape, Cloneable
{
  /** Same constant as {@link PathIterator#WIND_EVEN_ODD}. */
  public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;

  /** Same constant as {@link PathIterator#WIND_NON_ZERO}. */
  public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;

  /** Initial size if not specified. */
  private static final int INIT_SIZE = 10;

  /** A big number, but not so big it can't survive a few float operations */
  private static final double BIG_VALUE = Double.MAX_VALUE / 10.0;

  /** The winding rule.
   * This is package-private to avoid an accessor method.
   */
  int rule;

  /**
   * The path type in points. Note that xpoints[index] and ypoints[index] maps
   * to types[index]; the control points of quad and cubic paths map as
   * well but are ignored.
   * This is package-private to avoid an accessor method.
   */
  byte[] types;

  /**
   * The list of all points seen. Since you can only append floats, it makes
   * sense for these to be float[]. I have no idea why Sun didn't choose to
   * allow a general path of double precision points.
   * Note: Storing x and y coords seperately makes for a slower transforms,
   * But it speeds up and simplifies box-intersection checking a lot.
   * These are package-private to avoid accessor methods.
   */
  float[] xpoints;
  float[] ypoints;

  /** The index of the most recent moveto point, or null. */
  private int subpath = -1;

  /** The next available index into points.
   * This is package-private to avoid an accessor method.
   */
  int index;

  /**
   * Constructs a GeneralPath with the default (NON_ZERO)
   * winding rule and initial capacity (20).
   */
  public GeneralPath()
  {
    this(WIND_NON_ZERO, INIT_SIZE);
  }

  /**
   * Constructs a GeneralPath with a specific winding rule
   * and the default initial capacity (20).
   * @param rule the winding rule ({@link #WIND_NON_ZERO} or
   *     {@link #WIND_EVEN_ODD})
   *
   * @throws IllegalArgumentException if <code>rule</code> is not one of the
   *     listed values.
   */
  public GeneralPath(int rule)
  {
    this(rule, INIT_SIZE);
  }

  /**
   * Constructs a GeneralPath with a specific winding rule
   * and the initial capacity. The initial capacity should be
   * the approximate number of path segments to be used.
   * @param rule the winding rule ({@link #WIND_NON_ZERO} or
   *     {@link #WIND_EVEN_ODD})
   * @param capacity the inital capacity, in path segments
   *
   * @throws IllegalArgumentException if <code>rule</code> is not one of the
   *     listed values.
   */
  public GeneralPath(int rule, int capacity)
  {
    if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO)
      throw new IllegalArgumentException();
    this.rule = rule;
    if (capacity < INIT_SIZE)
      capacity = INIT_SIZE;
    types = new byte[capacity];
    xpoints = new float[capacity];
    ypoints = new float[capacity];
  }

  /**
   * Constructs a GeneralPath from an arbitrary shape object.
   * The Shapes PathIterator path and winding rule will be used.
   *
   * @param s the shape (<code>null</code> not permitted).
   *
   * @throws NullPointerException if <code>shape</code> is <code>null</code>.
   */
  public GeneralPath(Shape s)
  {
    types = new byte[INIT_SIZE];
    xpoints = new float[INIT_SIZE];
    ypoints = new float[INIT_SIZE];
    PathIterator pi = s.getPathIterator(null);
    setWindingRule(pi.getWindingRule());
    append(pi, false);
  }

  /**
   * Adds a new point to a path.
   *
   * @param x  the x-coordinate.
   * @param y  the y-coordinate.
   */
  public void moveTo(float x, float y)
  {
    subpath = index;
    ensureSize(index + 1);
    types[index] = PathIterator.SEG_MOVETO;
    xpoints[index] = x;
    ypoints[index++] = y;
  }

  /**
   * Appends a straight line to the current path.
   * @param x x coordinate of the line endpoint.
   * @param y y coordinate of the line endpoint.
   */
  public void lineTo(float x, float y)
  {
    ensureSize(index + 1);
    types[index] = PathIterator.SEG_LINETO;
    xpoints[index] = x;
    ypoints[index++] = y;
  }

  /**
   * Appends a quadratic Bezier curve to the current path.
   * @param x1 x coordinate of the control point
   * @param y1 y coordinate of the control point
   * @param x2 x coordinate of the curve endpoint.
   * @param y2 y coordinate of the curve endpoint.
   */
  public void quadTo(float x1, float y1, float x2, float y2)
  {
    ensureSize(index + 2);
    types[index] = PathIterator.SEG_QUADTO;
    xpoints[index] = x1;
    ypoints[index++] = y1;
    xpoints[index] = x2;
    ypoints[index++] = y2;
  }

  /**
   * Appends a cubic Bezier curve to the current path.
   * @param x1 x coordinate of the first control point
   * @param y1 y coordinate of the first control point
   * @param x2 x coordinate of the second control point
   * @param y2 y coordinate of the second control point
   * @param x3 x coordinate of the curve endpoint.
   * @param y3 y coordinate of the curve endpoint.
   */
  public void curveTo(float x1, float y1, float x2, float y2, float x3,
                      float y3)
  {
    ensureSize(index + 3);
    types[index] = PathIterator.SEG_CUBICTO;
    xpoints[index] = x1;
    ypoints[index++] = y1;
    xpoints[index] = x2;
    ypoints[index++] = y2;
    xpoints[index] = x3;
    ypoints[index++] = y3;
  }

  /**
   * Closes the current subpath by drawing a line
   * back to the point of the last moveTo, unless the path is already closed.
   */
  public void closePath()
  {
    if (index >= 1 && types[index - 1] == PathIterator.SEG_CLOSE)
      return;
    ensureSize(index + 1);
    types[index] = PathIterator.SEG_CLOSE;
    xpoints[index] = xpoints[subpath];
    ypoints[index++] = ypoints[subpath];
  }

  /**
   * Appends the segments of a Shape to the path. If <code>connect</code> is
   * true, the new path segments are connected to the existing one with a line.
   * The winding rule of the Shape is ignored.
   *
   * @param s  the shape (<code>null</code> not permitted).
   * @param connect  whether to connect the new shape to the existing path.
   *
   * @throws NullPointerException if <code>s</code> is <code>null</code>.
   */
  public void append(Shape s, boolean connect)
  {
    append(s.getPathIterator(null), connect);
  }

  /**
   * Appends the segments of a PathIterator to this GeneralPath.
   * Optionally, the initial {@link PathIterator#SEG_MOVETO} segment
   * of the appended path is changed into a {@link
   * PathIterator#SEG_LINETO} segment.
   *
   * @param iter the PathIterator specifying which segments shall be
   *     appended (<code>null</code> not permitted).
   *
   * @param connect <code>true</code> for substituting the initial
   * {@link PathIterator#SEG_MOVETO} segment by a {@link
   * PathIterator#SEG_LINETO}, or <code>false</code> for not
   * performing any substitution. If this GeneralPath is currently
   * empty, <code>connect</code> is assumed to be <code>false</code>,
   * thus leaving the initial {@link PathIterator#SEG_MOVETO}
   * unchanged.
   */
  public void append(PathIterator iter, boolean connect)
  {
    // A bad implementation of this method had caused Classpath bug #6076.
    float[] f = new float[6];
    while (! iter.isDone())
      {
        switch (iter.currentSegment(f))
          {
          case PathIterator.SEG_MOVETO:
            if (! connect || (index == 0))
              {
                moveTo(f[0], f[1]);
                break;
              }
            if ((index >= 1) && (types[index - 1] == PathIterator.SEG_CLOSE)
                && (f[0] == xpoints[index - 1])
                && (f[1] == ypoints[index - 1]))
              break;

          // Fall through.
          case PathIterator.SEG_LINETO:
            lineTo(f[0], f[1]);
            break;
          case PathIterator.SEG_QUADTO:
            quadTo(f[0], f[1], f[2], f[3]);
            break;
          case PathIterator.SEG_CUBICTO:
            curveTo(f[0], f[1], f[2], f[3], f[4], f[5]);
            break;
          case PathIterator.SEG_CLOSE:
            closePath();
            break;
          }

        connect = false;
        iter.next();
      }
  }

  /**
   * Returns the path&#x2019;s current winding rule.
   *
   * @return {@link #WIND_EVEN_ODD} or {@link #WIND_NON_ZERO}.
   */
  public int getWindingRule()
  {
    return rule;
  }

  /**
   * Sets the path&#x2019;s winding rule, which controls which areas are
   * considered &#x2019;inside&#x2019; or &#x2019;outside&#x2019; the path
   * on drawing. Valid rules are WIND_EVEN_ODD for an even-odd winding rule,
   * or WIND_NON_ZERO for a non-zero winding rule.
   *
   * @param rule  the rule ({@link #WIND_EVEN_ODD} or {@link #WIND_NON_ZERO}).
   */
  public void setWindingRule(int rule)
  {
    if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO)
      throw new IllegalArgumentException();
    this.rule = rule;
  }

  /**
   * Returns the current appending point of the path.
   *
   * @return The point.
   */
  public Point2D getCurrentPoint()
  {
    if (subpath < 0)
      return null;
    return new Point2D.Float(xpoints[index - 1], ypoints[index - 1]);
  }

  /**
   * Resets the path. All points and segments are destroyed.
   */
  public void reset()
  {
    subpath = -1;
    index = 0;
  }

  /**
   * Applies a transform to the path.
   *
   * @param xform  the transform (<code>null</code> not permitted).
   */
  public void transform(AffineTransform xform)
  {
    double nx;
    double ny;
    double[] m = new double[6];
    xform.getMatrix(m);
    for (int i = 0; i < index; i++)
      {
        nx = m[0] * xpoints[i] + m[2] * ypoints[i] + m[4];
        ny = m[1] * xpoints[i] + m[3] * ypoints[i] + m[5];
        xpoints[i] = (float) nx;
        ypoints[i] = (float) ny;
      }
  }

  /**
   * Creates a transformed version of the path.
   * @param xform the transform to apply
   * @return a new transformed GeneralPath
   */
  public Shape createTransformedShape(AffineTransform xform)
  {
    GeneralPath p = new GeneralPath(this);
    p.transform(xform);
    return p;
  }

  /**
   * Returns the path&#x2019;s bounding box.
   */
  public Rectangle getBounds()
  {
    return getBounds2D().getBounds();
  }

  /**
   * Returns the path&#x2019;s bounding box, in <code>float</code> precision
   */
  public Rectangle2D getBounds2D()
  {
    float x1;
    float y1;
    float x2;
    float y2;

    if (index > 0)
      {
        x1 = x2 = xpoints[0];
        y1 = y2 = ypoints[0];
      }
    else
      x1 = x2 = y1 = y2 = 0.0f;

    for (int i = 0; i < index; i++)
      {
        x1 = Math.min(xpoints[i], x1);
        y1 = Math.min(ypoints[i], y1);
        x2 = Math.max(xpoints[i], x2);
        y2 = Math.max(ypoints[i], y2);
      }
    return (new Rectangle2D.Float(x1, y1, x2 - x1, y2 - y1));
  }

  /**
   * Evaluates if a point is within the GeneralPath,
   * The NON_ZERO winding rule is used, regardless of the
   * set winding rule.
   * @param x x coordinate of the point to evaluate
   * @param y y coordinate of the point to evaluate
   * @return true if the point is within the path, false otherwise
   */
  public boolean contains(double x, double y)
  {
    return (getWindingNumber(x, y) != 0);
  }

  /**
   * Evaluates if a Point2D is within the GeneralPath,
   * The NON_ZERO winding rule is used, regardless of the
   * set winding rule.
   * @param p The Point2D to evaluate
   * @return true if the point is within the path, false otherwise
   */
  public boolean contains(Point2D p)
  {
    return contains(p.getX(), p.getY());
  }

  /**
   * Evaluates if a rectangle is completely contained within the path.
   * This method will return false in the cases when the box
   * intersects an inner segment of the path.
   * (i.e.: The method is accurate for the EVEN_ODD winding rule)
   */
  public boolean contains(double x, double y, double w, double h)
  {
    if (! getBounds2D().intersects(x, y, w, h))
      return false;

    /* Does any edge intersect? */
    if (getAxisIntersections(x, y, false, w) != 0 /* top */
        || getAxisIntersections(x, y + h, false, w) != 0 /* bottom */
        || getAxisIntersections(x + w, y, true, h) != 0 /* right */
        || getAxisIntersections(x, y, true, h) != 0) /* left */
      return false;

    /* No intersections, is any point inside? */
    if (getWindingNumber(x, y) != 0)
      return true;

    return false;
  }

  /**
   * Evaluates if a rectangle is completely contained within the path.
   * This method will return false in the cases when the box
   * intersects an inner segment of the path.
   * (i.e.: The method is accurate for the EVEN_ODD winding rule)
   * @param r the rectangle
   * @return <code>true</code> if the rectangle is completely contained
   * within the path, <code>false</code> otherwise
   */
  public boolean contains(Rectangle2D r)
  {
    return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
  }

  /**
   * Evaluates if a rectangle intersects the path.
   * @param x x coordinate of the rectangle
   * @param y y coordinate of the rectangle
   * @param w width of the rectangle
   * @param h height of the rectangle
   * @return <code>true</code> if the rectangle intersects the path,
   * <code>false</code> otherwise
   */
  public boolean intersects(double x, double y, double w, double h)
  {
    /* Does any edge intersect? */
    if (getAxisIntersections(x, y, false, w) != 0 /* top */
        || getAxisIntersections(x, y + h, false, w) != 0 /* bottom */
        || getAxisIntersections(x + w, y, true, h) != 0 /* right */
        || getAxisIntersections(x, y, true, h) != 0) /* left */
      return true;

    /* No intersections, is any point inside? */
    if (getWindingNumber(x, y) != 0)
      return true;

    return false;
  }

  /**
   * Evaluates if a Rectangle2D intersects the path.
   * @param r The rectangle
   * @return <code>true</code> if the rectangle intersects the path,
   * <code>false</code> otherwise
   */
  public boolean intersects(Rectangle2D r)
  {
    return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
  }

  /**
   * A PathIterator that iterates over the segments of a GeneralPath.
   *
   * @author Sascha Brawer (brawer@dandelis.ch)
   */
  private static class GeneralPathIterator implements PathIterator
  {
    /**
     * The number of coordinate values for each segment type.
     */
    private static final int[] NUM_COORDS = {
                                            /* 0: SEG_MOVETO */ 1,
                                            /* 1: SEG_LINETO */ 1,
                                            /* 2: SEG_QUADTO */ 2,
                                            /* 3: SEG_CUBICTO */ 3,
                                            /* 4: SEG_CLOSE */ 0};

    /**
     * The GeneralPath whose segments are being iterated.
     * This is package-private to avoid an accessor method.
     */
    final GeneralPath path;

    /**
     * The affine transformation used to transform coordinates.
     */
    private final AffineTransform transform;

    /**
     * The current position of the iterator.
     */
    private int pos;

    /**
     * Constructs a new iterator for enumerating the segments of a
     * GeneralPath.
     *
     * @param path the path to enumerate
     * @param transform an affine transformation for projecting the returned
     * points, or <code>null</code> to return the original points
     * without any mapping.
     */
    GeneralPathIterator(GeneralPath path, AffineTransform transform)
    {
      this.path = path;
      this.transform = transform;
    }

    /**
     * Returns the current winding rule of the GeneralPath.
     */
    public int getWindingRule()
    {
      return path.rule;
    }

    /**
     * Determines whether the iterator has reached the last segment in
     * the path.
     */
    public boolean isDone()
    {
      return pos >= path.index;
    }

    /**
     * Advances the iterator position by one segment.
     */
    public void next()
    {
      int seg;

      /*
       * Increment pos by the number of coordinate pairs.
       */
      seg = path.types[pos];
      if (seg == SEG_CLOSE)
        pos++;
      else
        pos += NUM_COORDS[seg];
    }

    /**
     * Returns the current segment in float coordinates.
     */
    public int currentSegment(float[] coords)
    {
      int seg;
      int numCoords;

      seg = path.types[pos];
      numCoords = NUM_COORDS[seg];
      if (numCoords > 0)
        {
          for (int i = 0; i < numCoords; i++)
            {
              coords[i << 1] = path.xpoints[pos + i];
              coords[(i << 1) + 1] = path.ypoints[pos + i];
            }

          if (transform != null)
            transform.transform( /* src */
            coords, /* srcOffset */
            0, /* dest */ coords, /* destOffset */
            0, /* numPoints */ numCoords);
        }
      return seg;
    }

    /**
     * Returns the current segment in double coordinates.
     */
    public int currentSegment(double[] coords)
    {
      int seg;
      int numCoords;

      seg = path.types[pos];
      numCoords = NUM_COORDS[seg];
      if (numCoords > 0)
        {
          for (int i = 0; i < numCoords; i++)
            {
              coords[i << 1] = (double) path.xpoints[pos + i];
              coords[(i << 1) + 1] = (double) path.ypoints[pos + i];
            }
          if (transform != null)
            transform.transform( /* src */
            coords, /* srcOffset */
            0, /* dest */ coords, /* destOffset */
            0, /* numPoints */ numCoords);
        }
      return seg;
    }
  }

  /**
   * Creates a PathIterator for iterating along the segments of the path.
   *
   * @param at an affine transformation for projecting the returned
   * points, or <code>null</code> to let the created iterator return
   * the original points without any mapping.
   */
  public PathIterator getPathIterator(AffineTransform at)
  {
    return new GeneralPathIterator(this, at);
  }

  /**
   * Creates a new FlatteningPathIterator for the path
   */
  public PathIterator getPathIterator(AffineTransform at, double flatness)
  {
    return new FlatteningPathIterator(getPathIterator(at), flatness);
  }

  /**
   * Creates a new shape of the same run-time type with the same contents
   * as this one.
   *
   * @return the clone
   *
   * @exception OutOfMemoryError If there is not enough memory available.
   *
   * @since 1.2
   */
  public Object clone()
  {
    // This class is final; no need to use super.clone().
    return new GeneralPath(this);
  }

  /**
   * Helper method - ensure the size of the data arrays,
   * otherwise, reallocate new ones twice the size
   *
   * @param size  the minimum array size.
   */
  private void ensureSize(int size)
  {
    if (subpath < 0)
      throw new IllegalPathStateException("need initial moveto");
    if (size <= xpoints.length)
      return;
    byte[] b = new byte[types.length << 1];
    System.arraycopy(types, 0, b, 0, index);
    types = b;
    float[] f = new float[xpoints.length << 1];
    System.arraycopy(xpoints, 0, f, 0, index);
    xpoints = f;
    f = new float[ypoints.length << 1];
    System.arraycopy(ypoints, 0, f, 0, index);
    ypoints = f;
  }

  /**
   * Helper method - Get the total number of intersections from (x,y) along
   * a given axis, within a given distance.
   */
  private int getAxisIntersections(double x, double y, boolean useYaxis,
                                   double distance)
  {
    return (evaluateCrossings(x, y, false, useYaxis, distance));
  }

  /**
   * Helper method - returns the winding number of a point.
   */
  private int getWindingNumber(double x, double y)
  {
    /* Evaluate the crossings from x,y to infinity on the y axis (arbitrary
       choice). Note that we don't actually use Double.INFINITY, since that's
       slower, and may cause problems. */
    return (evaluateCrossings(x, y, true, true, BIG_VALUE));
  }

  /**
   * Helper method - evaluates the number of intersections on an axis from
   * the point (x,y) to the point (x,y+distance) or (x+distance,y).
   * @param x x coordinate.
   * @param y y coordinate.
   * @param neg True if opposite-directed intersections should cancel,
   * false to sum all intersections.
   * @param useYaxis Use the Y axis, false uses the X axis.
   * @param distance Interval from (x,y) on the selected axis to find
   * intersections.
   */
  private int evaluateCrossings(double x, double y, boolean neg,
                                boolean useYaxis, double distance)
  {
    float cx = 0.0f;
    float cy = 0.0f;
    float firstx = 0.0f;
    float firsty = 0.0f;

    int negative = (neg) ? -1 : 1;
    double x0;
    double x1;
    double x2;
    double x3;
    double y0;
    double y1;
    double y2;
    double y3;
    double[] r = new double[4];
    int nRoots;
    double epsilon = 0.0;
    int pos = 0;
    int windingNumber = 0;
    boolean pathStarted = false;

    if (index == 0)
      return (0);
    if (useYaxis)
      {
        float[] swap1;
        swap1 = ypoints;
        ypoints = xpoints;
        xpoints = swap1;
        double swap2;
        swap2 = y;
        y = x;
        x = swap2;
      }

    /* Get a value which is hopefully small but not insignificant relative
     the path. */
    epsilon = ypoints[0] * 1E-7;

    if(epsilon == 0)
      epsilon = 1E-7;

    pos = 0;
    while (pos < index)
      {
        switch (types[pos])
          {
          case PathIterator.SEG_MOVETO:
            if (pathStarted) // close old path
              {
                x0 = cx;
                y0 = cy;
                x1 = firstx;
                y1 = firsty;

                if (y0 == 0.0)
                  y0 -= epsilon;
                if (y1 == 0.0)
                  y1 -= epsilon;
                if (Line2D.linesIntersect(x0, y0, x1, y1,
                                          epsilon, 0.0, distance, 0.0))
                  windingNumber += (y1 < y0) ? 1 : negative;

                cx = firstx;
                cy = firsty;
              }
            cx = firstx = xpoints[pos] - (float) x;
            cy = firsty = ypoints[pos++] - (float) y;
            pathStarted = true;
            break;
          case PathIterator.SEG_CLOSE:
            x0 = cx;
            y0 = cy;
            x1 = firstx;
            y1 = firsty;

            if (y0 == 0.0)
              y0 -= epsilon;
            if (y1 == 0.0)
              y1 -= epsilon;
            if (Line2D.linesIntersect(x0, y0, x1, y1,
                                      epsilon, 0.0, distance, 0.0))
              windingNumber += (y1 < y0) ? 1 : negative;

            cx = firstx;
            cy = firsty;
            pos++;
            pathStarted = false;
            break;
          case PathIterator.SEG_LINETO:
            x0 = cx;
            y0 = cy;
            x1 = xpoints[pos] - (float) x;
            y1 = ypoints[pos++] - (float) y;

            if (y0 == 0.0)
              y0 -= epsilon;
            if (y1 == 0.0)
              y1 -= epsilon;
            if (Line2D.linesIntersect(x0, y0, x1, y1,
                                      epsilon, 0.0, distance, 0.0))
              windingNumber += (y1 < y0) ? 1 : negative;

            cx = xpoints[pos - 1] - (float) x;
            cy = ypoints[pos - 1] - (float) y;
            break;
          case PathIterator.SEG_QUADTO:
            x0 = cx;
            y0 = cy;
            x1 = xpoints[pos] - x;
            y1 = ypoints[pos++] - y;
            x2 = xpoints[pos] - x;
            y2 = ypoints[pos++] - y;

            /* check if curve may intersect X+ axis. */
            if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0)
                && (y0 * y1 <= 0 || y1 * y2 <= 0))
              {
                if (y0 == 0.0)
                  y0 -= epsilon;
                if (y2 == 0.0)
                  y2 -= epsilon;

                r[0] = y0;
                r[1] = 2 * (y1 - y0);
                r[2] = (y2 - 2 * y1 + y0);

                /* degenerate roots (=tangent points) do not
                   contribute to the winding number. */
                if ((nRoots = QuadCurve2D.solveQuadratic(r)) == 2)
                  for (int i = 0; i < nRoots; i++)
                    {
                      float t = (float) r[i];
                      if (t > 0.0f && t < 1.0f)
                        {
                          double crossing = t * t * (x2 - 2 * x1 + x0)
                                            + 2 * t * (x1 - x0) + x0;
                          if (crossing >= 0.0 && crossing <= distance)
                            windingNumber += (2 * t * (y2 - 2 * y1 + y0)
                                           + 2 * (y1 - y0) < 0) ? 1 : negative;
                        }
                    }
              }

            cx = xpoints[pos - 1] - (float) x;
            cy = ypoints[pos - 1] - (float) y;
            break;
          case PathIterator.SEG_CUBICTO:
            x0 = cx;
            y0 = cy;
            x1 = xpoints[pos] - x;
            y1 = ypoints[pos++] - y;
            x2 = xpoints[pos] - x;
            y2 = ypoints[pos++] - y;
            x3 = xpoints[pos] - x;
            y3 = ypoints[pos++] - y;

            /* check if curve may intersect X+ axis. */
            if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0 || x3 > 0.0)
                && (y0 * y1 <= 0 || y1 * y2 <= 0 || y2 * y3 <= 0))
              {
                if (y0 == 0.0)
                  y0 -= epsilon;
                if (y3 == 0.0)
                  y3 -= epsilon;

                r[0] = y0;
                r[1] = 3 * (y1 - y0);
                r[2] = 3 * (y2 + y0 - 2 * y1);
                r[3] = y3 - 3 * y2 + 3 * y1 - y0;

                if ((nRoots = CubicCurve2D.solveCubic(r)) != 0)
                  for (int i = 0; i < nRoots; i++)
                    {
                      float t = (float) r[i];
                      if (t > 0.0 && t < 1.0)
                        {
                          double crossing = -(t * t * t) * (x0 - 3 * x1
                                            + 3 * x2 - x3)
                                            + 3 * t * t * (x0 - 2 * x1 + x2)
                                            + 3 * t * (x1 - x0) + x0;
                          if (crossing >= 0 && crossing <= distance)
                            windingNumber += (3 * t * t * (y3 + 3 * y1
                                             - 3 * y2 - y0)
                                             + 6 * t * (y0 - 2 * y1 + y2)
                                           + 3 * (y1 - y0) < 0) ? 1 : negative;
                        }
                    }
              }

            cx = xpoints[pos - 1] - (float) x;
            cy = ypoints[pos - 1] - (float) y;
            break;
          }
      }

    // swap coordinates back
    if (useYaxis)
      {
        float[] swap;
        swap = ypoints;
        ypoints = xpoints;
        xpoints = swap;
      }
    return (windingNumber);
  }
} // class GeneralPath
