Makefile.in: Rebuilt.
authorTom Tromey <tromey@redhat.com>
Fri, 11 May 2001 01:03:45 +0000 (01:03 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Fri, 11 May 2001 01:03:45 +0000 (01:03 +0000)
* Makefile.in: Rebuilt.
* Makefile.am (awt_java_source_files): Added Polygon.java.
* java/awt/Polygon.java: New file.

* java/awt/geom/AffineTransform.java
(setToRotation(double,double,double)): New method.
(AffineTransform): Set type to TYPE_GENERAL_TRANSFORM.
(setToShear): Likewise.

From-SVN: r41954

libjava/ChangeLog
libjava/java/awt/Polygon.java [new file with mode: 0644]
libjava/java/awt/geom/AffineTransform.java

index c803cd672b040c1ab35e0109a3428d357fe85668..bb2250185d095b5c414f5c20197d122c41442000 100644 (file)
@@ -1,3 +1,14 @@
+2001-05-10  Tom Tromey  <tromey@redhat.com>
+
+       * Makefile.in: Rebuilt.
+       * Makefile.am (awt_java_source_files): Added Polygon.java.
+       * java/awt/Polygon.java: New file.
+
+       * java/awt/geom/AffineTransform.java
+       (setToRotation(double,double,double)): New method.
+       (AffineTransform): Set type to TYPE_GENERAL_TRANSFORM.
+       (setToShear): Likewise.
+
 2001-05-10  Tom Tromey  <tromey@redhat.com>
 
        * java/util/GregorianCalendar.java: Imported from Classpath.
diff --git a/libjava/java/awt/Polygon.java b/libjava/java/awt/Polygon.java
new file mode 100644 (file)
index 0000000..ad4df2c
--- /dev/null
@@ -0,0 +1,422 @@
+/* Copyright (C) 2001  Free Software Foundation
+
+   This file is part of libjava.
+
+This software is copyrighted work licensed under the terms of the
+Libjava License.  Please consult the file "LIBJAVA_LICENSE" for
+details.  */
+
+package java.awt;
+
+import java.awt.geom.*;
+import java.io.Serializable;
+import java.util.Arrays;
+
+/**
+ * @author Tom Tromey <tromey@redhat.com>
+ * @date May 10, 2001
+ */
+
+/** The Polygon class represents a closed region whose boundary is
+    made of line segments.  The Polygon is defined by its vertices.  */
+public class Polygon implements Shape, Serializable
+{
+  /** The bounds of the polygon.  This is null until the bounds have
+   *  been computed for the first time; then it is correctly
+   *  maintained whenever it is modified.  */
+  protected Rectangle bounds;
+
+  /** The number of points in the polygon.  */
+  public int npoints;
+
+  /** The x coordinates of the points.  */
+  public int[] xpoints;
+
+  /** The y coordinates of the points.  */
+  public int[] ypoints;
+
+  /** Create a new, empty Polygon.  */
+  public Polygon ()
+  {
+    this.xpoints = new int[0];
+    this.ypoints = new int[0];
+    this.npoints = 0;
+  }
+
+  /** Create a new Polygon from the given vertices.
+   * @param xpoints The x coordinates
+   * @param ypoints The y coordinates
+   * @param npoints The number of points
+   */
+  public Polygon (int[] xpoints, int[] ypoints, int npoints)
+  {
+    // We make explicit copies instead of relying on clone so that we
+    // ensure the new arrays are the same size.
+    this.xpoints = new int[npoints];
+    this.ypoints = new int[npoints];
+    System.arraycopy (xpoints, 0, this.xpoints, 0, npoints);
+    System.arraycopy (ypoints, 0, this.ypoints, 0, npoints);
+  }
+
+  /** Append the specified point to this Polygon.
+   * @param x The x coordinate
+   * @param y The y coordinate
+   */
+  public void addPoint (int x, int y)
+  {
+    int[] newx = new int[npoints + 1];
+    System.arraycopy (xpoints, 0, newx, 0, npoints);
+    int[] newy = new int[npoints + 1];
+    System.arraycopy (ypoints, 0, newy, 0, npoints);
+    newx[npoints] = x;
+    newy[npoints] = y;
+    ++npoints;
+    xpoints = newx;
+    ypoints = newy;
+
+    // It is simpler to just recompute.
+    if (bounds != null)
+      computeBoundingBox ();
+  }
+
+  /** Return true if the indicated point is inside this Polygon.
+   * This uses an even-odd rule to determine insideness.
+   * @param x The x coordinate
+   * @param y The y coordinate
+   * @returns true if the point is contained by this Polygon.
+   */
+  public boolean contains (double x, double y)
+  {
+    // What we do is look at each line segment.  If the line segment
+    // crosses the "scan line" at y at a point x' < x, then we
+    // increment our counter.  At the end, an even number means the
+    // point is outside the polygon.  Instead of a number, though, we
+    // use a boolean.
+    boolean inside = false;
+    for (int i = 0; i < npoints; ++i)
+      {
+       // Handle the wrap case.
+       int x2 = (i == npoints) ? xpoints[0] : xpoints[i + 1];
+       int y2 = (i == npoints) ? ypoints[0] : ypoints[i + 1];
+
+       if (ypoints[i] == y2)
+         {
+           // We ignore horizontal lines.  This might give weird
+           // results in some situations -- ?
+           continue;
+         }
+
+       double t = (y - ypoints[i]) / (double) (y2 - ypoints[i]);
+       double x3 = xpoints[i] + t * (x2 - xpoints[i]);
+       if (x3 < x)
+         inside = ! inside;
+      }
+
+    return inside;
+  }
+
+  /** Return true if the indicated rectangle is entirely inside this
+   * Polygon.
+   * This uses an even-odd rule to determine insideness.
+   * @param x The x coordinate
+   * @param y The y coordinate
+   * @param w The width
+   * @param h The height
+   * @returns true if the rectangle is contained by this Polygon.
+   */
+  public boolean contains (double x, double y, double w, double h)
+  {
+    return intersectOrContains (x, y, w, h, false);
+  }
+
+  /** Return true if the indicated point is inside this Polygon.
+   * This uses an even-odd rule to determine insideness.
+   * @param x The x coordinate
+   * @param y The y coordinate
+   * @returns true if the point is contained by this Polygon.
+   */
+  public boolean contains (int x, int y)
+  {
+    return contains ((double) x, (double) y);
+  }
+
+  /** Return true if the indicated point is inside this Polygon.
+   * This uses an even-odd rule to determine insideness.
+   * @param p The point
+   * @returns true if the point is contained by this Polygon.
+   */
+  public boolean contains (Point p)
+  {
+    return contains (p.x, p.y);
+  }
+
+  /** Return true if the indicated point is inside this Polygon.
+   * This uses an even-odd rule to determine insideness.
+   * @param p The point
+   * @returns true if the point is contained by this Polygon.
+   */
+  public boolean contains (Point2D p)
+  {
+    return contains (p.getX (), p.getY ());
+  }
+
+  /** Return true if the indicated rectangle is entirely inside this
+   * Polygon.  This uses an even-odd rule to determine insideness.
+   * @param r The rectangle
+   * @returns true if the rectangle is contained by this Polygon.
+   */
+  public boolean contains (Rectangle2D r)
+  {
+    return contains (r.getX (), r.getY (), r.getWidth (), r.getHeight ());
+  }
+
+  /** Returns the bounds of this Polygon.
+   * @deprecated Use getBounds() instead.
+   */
+  public Rectangle getBoundingBox ()
+  {
+    if (bounds == null)
+      computeBoundingBox ();
+    return bounds;
+  }
+
+  /** Returns the bounds of this Polygon.  */
+  public Rectangle getBounds ()
+  {
+    if (bounds == null)
+      computeBoundingBox ();
+    return bounds;
+  }
+
+  /** Returns the bounds of this Polygon.  */
+  public Rectangle2D getBounds2D ()
+  {
+    if (bounds == null)
+      computeBoundingBox ();
+    return bounds;             // Why not?
+  }
+
+  /** Return an iterator for the boundary of this Polygon.
+   * @param at A transform to apply to the coordinates.
+   * @returns A path iterator for the Polygon's boundary.
+   */
+  public PathIterator getPathIterator (AffineTransform at)
+  {
+    return new Iterator (at);
+  }
+
+  /** Return an iterator for the boundary of this Polygon.
+   * @param at A transform to apply to the coordinates.
+   * @param flatness The flatness of the result; it is ignored by
+   *                 this class.
+   * @returns A path iterator for the Polygon's boundary.
+   */
+  public PathIterator getPathIterator (AffineTransform at, double flatness)
+  {
+    // We ignore the flatness.
+    return new Iterator (at);
+  }
+
+  /** @deprecated use contains(int,int).  */
+  public boolean inside (int x, int y)
+  {
+    return contains (x, y);
+  }
+
+  /** Return true if this Polygon's interior intersects the given
+   * rectangle's interior.
+   * @param x The x coordinate
+   * @param y The y coordinate
+   * @param w The width
+   * @param h The height
+   */
+  public boolean intersects (double x, double y, double w, double h)
+  {
+    return intersectOrContains (x, y, w, h, true);
+  }
+
+  /** Return true if this Polygon's interior intersects the given
+   * rectangle's interior.
+   * @param r The rectangle
+   */
+  public boolean intersects (Rectangle2D r)
+  {
+    return intersects (r.getX (), r.getY (), r.getWidth (), r.getHeight ());
+  }
+
+  // This tests for intersection with or containment of a rectangle,
+  // depending on the INTERSECT argument.
+  private boolean intersectOrContains (double x, double y, double w, double h,
+                                      boolean intersect)
+  {
+    // First compute the rectangle of possible intersection points.
+    Rectangle r = getBounds ();
+    int minx = Math.max (r.x, (int) x);
+    int maxx = Math.min (r.x + r.width, (int) (x + w));
+    int miny = Math.max (r.y, (int) y);
+    int maxy = Math.min (r.y + r.height, (int) (y + h));
+
+    if (miny > maxy)
+      return false;
+
+    double[] crosses = new double[npoints + 1];
+
+    for (; miny < maxy; ++miny)
+      {
+       // First compute every place where the polygon might intersect
+       // the scan line at Y.
+       int ins = 0;
+       for (int i = 0; i < npoints; ++i)
+         {
+           // Handle the wrap case.
+           int x2 = (i == npoints) ? xpoints[0] : xpoints[i + 1];
+           int y2 = (i == npoints) ? ypoints[0] : ypoints[i + 1];
+
+           if (ypoints[i] == y2)
+             {
+               // We ignore horizontal lines.  This might give weird
+               // results in some situations -- ?
+               continue;
+             }
+
+           double t = (((double) miny - ypoints[i])
+                       / (double) (y2 - ypoints[i]));
+           double x3 = xpoints[i] + t * (x2 - xpoints[i]);
+           crosses[ins++] = x3;
+         }
+
+       // Now we can sort into increasing order and look to see if
+       // any point in the rectangle is in the polygon.  We examine
+       // every other pair due to our even-odd rule.
+       Arrays.sort (crosses, 0, ins);
+       int i = intersect ? 0 : 1;
+       for (; i < ins - 1; i += 2)
+         {
+           // Pathological case.
+           if (crosses[i] == crosses[i + 1])
+             continue;
+
+           // Found a point on the inside.
+           if ((crosses[i] >= x && crosses[i] < x + w)
+               || (crosses[i + 1] >= x && crosses[i + 1] < x + w))
+             {
+               // If we're checking containment then we just lost.
+               // But if we're checking intersection then we just
+               // won.
+               return intersect;
+             }
+         }
+      }
+
+    return false;
+  }
+
+  /** Translates all the vertices of the polygon via a given vector.
+   * @param deltaX The X offset
+   * @param deltaY The Y offset
+   */
+  public void translate (int deltaX, int deltaY)
+  {
+    for (int i = 0; i < npoints; ++i)
+      {
+       xpoints[i] += deltaX;
+       ypoints[i] += deltaY;
+      }
+
+    if (bounds != null)
+      {
+       bounds.x += deltaX;
+       bounds.y += deltaY;
+      }
+  }
+
+  // This computes the bounding box if required.
+  private void computeBoundingBox ()
+  {
+    if (npoints == 0)
+      {
+       // This is wrong if the user adds a new point, but we
+       // account for that in addPoint().
+       bounds = new Rectangle (0, 0, 0, 0);
+      }
+    else
+      {
+       int maxx = xpoints[0];
+       int minx = xpoints[0];
+       int maxy = ypoints[0];
+       int miny = ypoints[0];
+
+       for (int i = 1; i < npoints; ++i)
+         {
+           maxx = Math.max (maxx, xpoints[i]);
+           minx = Math.min (minx, xpoints[i]);
+           maxy = Math.max (maxy, ypoints[i]);
+           miny = Math.min (miny, ypoints[i]);
+         }
+
+       bounds = new Rectangle (minx, miny, maxx - minx, maxy - miny);
+      }
+  }
+
+  private class Iterator implements PathIterator
+  {
+    public AffineTransform xform;
+    public int where;
+
+    public Iterator (AffineTransform xform)
+    {
+      this.xform = xform;
+      where = 0;
+    }
+
+    public int currentSegment (double[] coords)
+    {
+      int r;
+
+      if (where < npoints)
+       {
+         coords[0] = xpoints[where];
+         coords[1] = ypoints[where];
+         r = (where == 0) ? SEG_MOVETO : SEG_LINETO;
+         xform.transform (coords, 0, coords, 0, 1);
+         ++where;
+       }
+      else
+       r = SEG_CLOSE;
+
+      return r;
+    }
+
+    public int currentSegment (float[] coords)
+    {
+      int r;
+
+      if (where < npoints)
+       {
+         coords[0] = xpoints[where];
+         coords[1] = ypoints[where];
+         r = (where == 0) ? SEG_MOVETO : SEG_LINETO;
+         xform.transform (coords, 0, coords, 0, 1);
+       }
+      else
+       r = SEG_CLOSE;
+
+      return r;
+    }
+
+    public int getWindingRule ()
+    {
+      return WIND_EVEN_ODD;
+    }
+
+    public boolean isDone ()
+    {
+      return where == npoints + 1;
+    }
+
+    public void next ()
+    {
+      ++where;
+    }
+  }
+}
index 3e9bb8abb647a21b418d92b0e0d37461dd9a090c..8e9b8f04cfce20a211deaa543cc7d03035fff35b 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000  Free Software Foundation
+/* Copyright (C) 2000, 2001  Free Software Foundation
 
    This file is part of libjava.
 
@@ -51,7 +51,7 @@ public class AffineTransform implements Cloneable, Serializable
     this.m11 = m11;
     this.m02 = m02;
     this.m12 = m12;
-    this.type = 0; // fixme;
+    this.type = TYPE_GENERAL_TRANSFORM;
   }
 
   public AffineTransform (float[] flatmatrix)
@@ -260,6 +260,20 @@ public class AffineTransform implements Cloneable, Serializable
     type = TYPE_GENERAL_ROTATION;
   }
 
+  public void setToRotation (double theta, double x, double y)
+  {
+    double c = Math.cos (theta);
+    double s = Math.sin (theta);
+
+    m00 = c;
+    m01 = -s;
+    m02 = x - x * c + y * s;
+    m10 = s;
+    m11 = c;
+    m12 = y - x * s - y * c;
+    type = TYPE_GENERAL_TRANSFORM;
+  }
+
   public void setToScale (double sx, double sy)
   {
     m00 = sx;
@@ -274,7 +288,7 @@ public class AffineTransform implements Cloneable, Serializable
     m01 = shx;
     m10 = shy;
     m02 = m12 = 0;
-    type = 0;                  // FIXME
+    type = TYPE_GENERAL_TRANSFORM;
   }
 
   public void setTransform (AffineTransform tx)