aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/java/awt/geom
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2016-09-30 16:24:48 +0000
committerAndrew Haley <aph@gcc.gnu.org>2016-09-30 16:24:48 +0000
commit07b78716af6a9d7c9fd1e94d9baf94a52c873947 (patch)
tree3f22b3241c513ad168c8353805614ae1249410f4 /libjava/classpath/java/awt/geom
parenteae993948bae8b788c53772bcb9217c063716f93 (diff)
downloadgcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.zip
gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.gz
gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.bz2
Makefile.def: Remove libjava.
2016-09-30 Andrew Haley <aph@redhat.com> * Makefile.def: Remove libjava. * Makefile.tpl: Likewise. * Makefile.in: Regenerate. * configure.ac: Likewise. * configure: Likewise. * gcc/java: Remove. * libjava: Likewise. From-SVN: r240662
Diffstat (limited to 'libjava/classpath/java/awt/geom')
-rw-r--r--libjava/classpath/java/awt/geom/AffineTransform.java1489
-rw-r--r--libjava/classpath/java/awt/geom/Arc2D.java1413
-rw-r--r--libjava/classpath/java/awt/geom/Area.java3298
-rw-r--r--libjava/classpath/java/awt/geom/CubicCurve2D.java1724
-rw-r--r--libjava/classpath/java/awt/geom/Dimension2D.java118
-rw-r--r--libjava/classpath/java/awt/geom/Ellipse2D.java413
-rw-r--r--libjava/classpath/java/awt/geom/FlatteningPathIterator.java579
-rw-r--r--libjava/classpath/java/awt/geom/GeneralPath.java992
-rw-r--r--libjava/classpath/java/awt/geom/IllegalPathStateException.java71
-rw-r--r--libjava/classpath/java/awt/geom/Line2D.java1182
-rw-r--r--libjava/classpath/java/awt/geom/NoninvertibleTransformException.java65
-rw-r--r--libjava/classpath/java/awt/geom/PathIterator.java189
-rw-r--r--libjava/classpath/java/awt/geom/Point2D.java396
-rw-r--r--libjava/classpath/java/awt/geom/QuadCurve2D.java1467
-rw-r--r--libjava/classpath/java/awt/geom/Rectangle2D.java992
-rw-r--r--libjava/classpath/java/awt/geom/RectangularShape.java382
-rw-r--r--libjava/classpath/java/awt/geom/RoundRectangle2D.java584
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/Area-1.pngbin21447 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-1.pngbin6280 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-2.pngbin5791 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-3.pngbin13168 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-4.pngbin7839 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-5.pngbin5112 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/Ellipse-1.pngbin19426 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/FlatteningPathIterator-1.html481
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/GeneralPath-1.pngbin13111 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-1.pngbin6363 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-2.pngbin5872 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-3.pngbin12334 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-4.pngbin7797 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-5.pngbin4757 -> 0 bytes
-rw-r--r--libjava/classpath/java/awt/geom/package.html46
32 files changed, 0 insertions, 15881 deletions
diff --git a/libjava/classpath/java/awt/geom/AffineTransform.java b/libjava/classpath/java/awt/geom/AffineTransform.java
deleted file mode 100644
index 42590ef..0000000
--- a/libjava/classpath/java/awt/geom/AffineTransform.java
+++ /dev/null
@@ -1,1489 +0,0 @@
-/* AffineTransform.java -- transform coordinates between two 2-D spaces
- Copyright (C) 2000, 2001, 2002, 2004 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.Shape;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-
-/**
- * This class represents an affine transformation between two coordinate
- * spaces in 2 dimensions. Such a transform preserves the "straightness"
- * and "parallelness" of lines. The transform is built from a sequence of
- * translations, scales, flips, rotations, and shears.
- *
- * <p>The transformation can be represented using matrix math on a 3x3 array.
- * Given (x,y), the transformation (x',y') can be found by:
- * <pre>
- * [ x'] [ m00 m01 m02 ] [ x ] [ m00*x + m01*y + m02 ]
- * [ y'] = [ m10 m11 m12 ] [ y ] = [ m10*x + m11*y + m12 ]
- * [ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
- * </pre>
- * The bottom row of the matrix is constant, so a transform can be uniquely
- * represented (as in {@link #toString()}) by
- * "[[m00, m01, m02], [m10, m11, m12]]".
- *
- * @author Tom Tromey (tromey@cygnus.com)
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status partially updated to 1.4, still has some problems
- */
-public class AffineTransform implements Cloneable, Serializable
-{
- /**
- * Compatible with JDK 1.2+.
- */
- private static final long serialVersionUID = 1330973210523860834L;
-
- /**
- * The transformation is the identity (x' = x, y' = y). All other transforms
- * have either a combination of the appropriate transform flag bits for
- * their type, or the type GENERAL_TRANSFORM.
- *
- * @see #TYPE_TRANSLATION
- * @see #TYPE_UNIFORM_SCALE
- * @see #TYPE_GENERAL_SCALE
- * @see #TYPE_FLIP
- * @see #TYPE_QUADRANT_ROTATION
- * @see #TYPE_GENERAL_ROTATION
- * @see #TYPE_GENERAL_TRANSFORM
- * @see #getType()
- */
- public static final int TYPE_IDENTITY = 0;
-
- /**
- * The transformation includes a translation - shifting in the x or y
- * direction without changing length or angles.
- *
- * @see #TYPE_IDENTITY
- * @see #TYPE_UNIFORM_SCALE
- * @see #TYPE_GENERAL_SCALE
- * @see #TYPE_FLIP
- * @see #TYPE_QUADRANT_ROTATION
- * @see #TYPE_GENERAL_ROTATION
- * @see #TYPE_GENERAL_TRANSFORM
- * @see #getType()
- */
- public static final int TYPE_TRANSLATION = 1;
-
- /**
- * The transformation includes a uniform scale - length is scaled in both
- * the x and y directions by the same amount, without affecting angles.
- * This is mutually exclusive with TYPE_GENERAL_SCALE.
- *
- * @see #TYPE_IDENTITY
- * @see #TYPE_TRANSLATION
- * @see #TYPE_GENERAL_SCALE
- * @see #TYPE_FLIP
- * @see #TYPE_QUADRANT_ROTATION
- * @see #TYPE_GENERAL_ROTATION
- * @see #TYPE_GENERAL_TRANSFORM
- * @see #TYPE_MASK_SCALE
- * @see #getType()
- */
- public static final int TYPE_UNIFORM_SCALE = 2;
-
- /**
- * The transformation includes a general scale - length is scaled in either
- * or both the x and y directions, but by different amounts; without
- * affecting angles. This is mutually exclusive with TYPE_UNIFORM_SCALE.
- *
- * @see #TYPE_IDENTITY
- * @see #TYPE_TRANSLATION
- * @see #TYPE_UNIFORM_SCALE
- * @see #TYPE_FLIP
- * @see #TYPE_QUADRANT_ROTATION
- * @see #TYPE_GENERAL_ROTATION
- * @see #TYPE_GENERAL_TRANSFORM
- * @see #TYPE_MASK_SCALE
- * @see #getType()
- */
- public static final int TYPE_GENERAL_SCALE = 4;
-
- /**
- * This constant checks if either variety of scale transform is performed.
- *
- * @see #TYPE_UNIFORM_SCALE
- * @see #TYPE_GENERAL_SCALE
- */
- public static final int TYPE_MASK_SCALE = 6;
-
- /**
- * The transformation includes a flip about an axis, swapping between
- * right-handed and left-handed coordinate systems. In a right-handed
- * system, the positive x-axis rotates counter-clockwise to the positive
- * y-axis; in a left-handed system it rotates clockwise.
- *
- * @see #TYPE_IDENTITY
- * @see #TYPE_TRANSLATION
- * @see #TYPE_UNIFORM_SCALE
- * @see #TYPE_GENERAL_SCALE
- * @see #TYPE_QUADRANT_ROTATION
- * @see #TYPE_GENERAL_ROTATION
- * @see #TYPE_GENERAL_TRANSFORM
- * @see #getType()
- */
- public static final int TYPE_FLIP = 64;
-
- /**
- * The transformation includes a rotation of a multiple of 90 degrees (PI/2
- * radians). Angles are rotated, but length is preserved. This is mutually
- * exclusive with TYPE_GENERAL_ROTATION.
- *
- * @see #TYPE_IDENTITY
- * @see #TYPE_TRANSLATION
- * @see #TYPE_UNIFORM_SCALE
- * @see #TYPE_GENERAL_SCALE
- * @see #TYPE_FLIP
- * @see #TYPE_GENERAL_ROTATION
- * @see #TYPE_GENERAL_TRANSFORM
- * @see #TYPE_MASK_ROTATION
- * @see #getType()
- */
- public static final int TYPE_QUADRANT_ROTATION = 8;
-
- /**
- * The transformation includes a rotation by an arbitrary angle. Angles are
- * rotated, but length is preserved. This is mutually exclusive with
- * TYPE_QUADRANT_ROTATION.
- *
- * @see #TYPE_IDENTITY
- * @see #TYPE_TRANSLATION
- * @see #TYPE_UNIFORM_SCALE
- * @see #TYPE_GENERAL_SCALE
- * @see #TYPE_FLIP
- * @see #TYPE_QUADRANT_ROTATION
- * @see #TYPE_GENERAL_TRANSFORM
- * @see #TYPE_MASK_ROTATION
- * @see #getType()
- */
- public static final int TYPE_GENERAL_ROTATION = 16;
-
- /**
- * This constant checks if either variety of rotation is performed.
- *
- * @see #TYPE_QUADRANT_ROTATION
- * @see #TYPE_GENERAL_ROTATION
- */
- public static final int TYPE_MASK_ROTATION = 24;
-
- /**
- * The transformation is an arbitrary conversion of coordinates which
- * could not be decomposed into the other TYPEs.
- *
- * @see #TYPE_IDENTITY
- * @see #TYPE_TRANSLATION
- * @see #TYPE_UNIFORM_SCALE
- * @see #TYPE_GENERAL_SCALE
- * @see #TYPE_FLIP
- * @see #TYPE_QUADRANT_ROTATION
- * @see #TYPE_GENERAL_ROTATION
- * @see #getType()
- */
- public static final int TYPE_GENERAL_TRANSFORM = 32;
-
- /**
- * The X coordinate scaling element of the transform matrix.
- *
- * @serial matrix[0,0]
- */
- private double m00;
-
- /**
- * The Y coordinate shearing element of the transform matrix.
- *
- * @serial matrix[1,0]
- */
- private double m10;
-
- /**
- * The X coordinate shearing element of the transform matrix.
- *
- * @serial matrix[0,1]
- */
- private double m01;
-
- /**
- * The Y coordinate scaling element of the transform matrix.
- *
- * @serial matrix[1,1]
- */
- private double m11;
-
- /**
- * The X coordinate translation element of the transform matrix.
- *
- * @serial matrix[0,2]
- */
- private double m02;
-
- /**
- * The Y coordinate translation element of the transform matrix.
- *
- * @serial matrix[1,2]
- */
- private double m12;
-
- /** The type of this transform. */
- private transient int type;
-
- /**
- * Construct a new identity transform:
- * <pre>
- * [ 1 0 0 ]
- * [ 0 1 0 ]
- * [ 0 0 1 ]
- * </pre>
- */
- public AffineTransform()
- {
- m00 = m11 = 1;
- }
-
- /**
- * Create a new transform which copies the given one.
- *
- * @param tx the transform to copy
- * @throws NullPointerException if tx is null
- */
- public AffineTransform(AffineTransform tx)
- {
- setTransform(tx);
- }
-
- /**
- * Construct a transform with the given matrix entries:
- * <pre>
- * [ m00 m01 m02 ]
- * [ m10 m11 m12 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param m00 the x scaling component
- * @param m10 the y shearing component
- * @param m01 the x shearing component
- * @param m11 the y scaling component
- * @param m02 the x translation component
- * @param m12 the y translation component
- */
- public AffineTransform(float m00, float m10,
- float m01, float m11,
- float m02, float m12)
- {
- this.m00 = m00;
- this.m10 = m10;
- this.m01 = m01;
- this.m11 = m11;
- this.m02 = m02;
- this.m12 = m12;
- updateType();
- }
-
- /**
- * Construct a transform from a sequence of float entries. The array must
- * have at least 4 entries, which has a translation factor of 0; or 6
- * entries, for specifying all parameters:
- * <pre>
- * [ f[0] f[2] (f[4]) ]
- * [ f[1] f[3] (f[5]) ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param f the matrix to copy from, with at least 4 (6) entries
- * @throws NullPointerException if f is null
- * @throws ArrayIndexOutOfBoundsException if f is too small
- */
- public AffineTransform(float[] f)
- {
- m00 = f[0];
- m10 = f[1];
- m01 = f[2];
- m11 = f[3];
- if (f.length >= 6)
- {
- m02 = f[4];
- m12 = f[5];
- }
- updateType();
- }
-
- /**
- * Construct a transform with the given matrix entries:
- * <pre>
- * [ m00 m01 m02 ]
- * [ m10 m11 m12 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param m00 the x scaling component
- * @param m10 the y shearing component
- * @param m01 the x shearing component
- * @param m11 the y scaling component
- * @param m02 the x translation component
- * @param m12 the y translation component
- */
- public AffineTransform(double m00, double m10, double m01,
- double m11, double m02, double m12)
- {
- this.m00 = m00;
- this.m10 = m10;
- this.m01 = m01;
- this.m11 = m11;
- this.m02 = m02;
- this.m12 = m12;
- updateType();
- }
-
- /**
- * Construct a transform from a sequence of double entries. The array must
- * have at least 4 entries, which has a translation factor of 0; or 6
- * entries, for specifying all parameters:
- * <pre>
- * [ d[0] d[2] (d[4]) ]
- * [ d[1] d[3] (d[5]) ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param d the matrix to copy from, with at least 4 (6) entries
- * @throws NullPointerException if d is null
- * @throws ArrayIndexOutOfBoundsException if d is too small
- */
- public AffineTransform(double[] d)
- {
- m00 = d[0];
- m10 = d[1];
- m01 = d[2];
- m11 = d[3];
- if (d.length >= 6)
- {
- m02 = d[4];
- m12 = d[5];
- }
- updateType();
- }
-
- /**
- * Returns a translation transform:
- * <pre>
- * [ 1 0 tx ]
- * [ 0 1 ty ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param tx the x translation distance
- * @param ty the y translation distance
- * @return the translating transform
- */
- public static AffineTransform getTranslateInstance(double tx, double ty)
- {
- AffineTransform t = new AffineTransform();
- t.m02 = tx;
- t.m12 = ty;
- t.type = (tx == 0 && ty == 0) ? TYPE_UNIFORM_SCALE : TYPE_TRANSLATION;
- return t;
- }
-
- /**
- * Returns a rotation transform. A positive angle (in radians) rotates
- * the positive x-axis to the positive y-axis:
- * <pre>
- * [ cos(theta) -sin(theta) 0 ]
- * [ sin(theta) cos(theta) 0 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param theta the rotation angle
- * @return the rotating transform
- */
- public static AffineTransform getRotateInstance(double theta)
- {
- AffineTransform t = new AffineTransform();
- t.setToRotation(theta);
- return t;
- }
-
- /**
- * Returns a rotation transform about a point. A positive angle (in radians)
- * rotates the positive x-axis to the positive y-axis. This is the same
- * as calling:
- * <pre>
- * AffineTransform tx = new AffineTransform();
- * tx.setToTranslation(x, y);
- * tx.rotate(theta);
- * tx.translate(-x, -y);
- * </pre>
- *
- * <p>The resulting matrix is:
- * <pre>
- * [ cos(theta) -sin(theta) x-x*cos+y*sin ]
- * [ sin(theta) cos(theta) y-x*sin-y*cos ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param theta the rotation angle
- * @param x the x coordinate of the pivot point
- * @param y the y coordinate of the pivot point
- * @return the rotating transform
- */
- public static AffineTransform getRotateInstance(double theta,
- double x, double y)
- {
- AffineTransform t = new AffineTransform();
- t.setToTranslation(x, y);
- t.rotate(theta);
- t.translate(-x, -y);
- return t;
- }
-
- /**
- * Returns a scaling transform:
- * <pre>
- * [ sx 0 0 ]
- * [ 0 sy 0 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param sx the x scaling factor
- * @param sy the y scaling factor
- * @return the scaling transform
- */
- public static AffineTransform getScaleInstance(double sx, double sy)
- {
- AffineTransform t = new AffineTransform();
- t.setToScale(sx, sy);
- return t;
- }
-
- /**
- * Returns a shearing transform (points are shifted in the x direction based
- * on a factor of their y coordinate, and in the y direction as a factor of
- * their x coordinate):
- * <pre>
- * [ 1 shx 0 ]
- * [ shy 1 0 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param shx the x shearing factor
- * @param shy the y shearing factor
- * @return the shearing transform
- */
- public static AffineTransform getShearInstance(double shx, double shy)
- {
- AffineTransform t = new AffineTransform();
- t.setToShear(shx, shy);
- return t;
- }
-
- /**
- * Returns the type of this transform. The result is always valid, although
- * it may not be the simplest interpretation (in other words, there are
- * sequences of transforms which reduce to something simpler, which this
- * does not always detect). The result is either TYPE_GENERAL_TRANSFORM,
- * or a bit-wise combination of TYPE_TRANSLATION, the mutually exclusive
- * TYPE_*_ROTATIONs, and the mutually exclusive TYPE_*_SCALEs.
- *
- * @return The type.
- *
- * @see #TYPE_IDENTITY
- * @see #TYPE_TRANSLATION
- * @see #TYPE_UNIFORM_SCALE
- * @see #TYPE_GENERAL_SCALE
- * @see #TYPE_QUADRANT_ROTATION
- * @see #TYPE_GENERAL_ROTATION
- * @see #TYPE_GENERAL_TRANSFORM
- */
- public int getType()
- {
- return type;
- }
-
- /**
- * Return the determinant of this transform matrix. If the determinant is
- * non-zero, the transform is invertible; otherwise operations which require
- * an inverse throw a NoninvertibleTransformException. A result very near
- * zero, due to rounding errors, may indicate that inversion results do not
- * carry enough precision to be meaningful.
- *
- * <p>If this is a uniform scale transformation, the determinant also
- * represents the squared value of the scale. Otherwise, it carries little
- * additional meaning. The determinant is calculated as:
- * <pre>
- * | m00 m01 m02 |
- * | m10 m11 m12 | = m00 * m11 - m01 * m10
- * | 0 0 1 |
- * </pre>
- *
- * @return the determinant
- * @see #createInverse()
- */
- public double getDeterminant()
- {
- return m00 * m11 - m01 * m10;
- }
-
- /**
- * Return the matrix of values used in this transform. If the matrix has
- * fewer than 6 entries, only the scale and shear factors are returned;
- * otherwise the translation factors are copied as well. The resulting
- * values are:
- * <pre>
- * [ d[0] d[2] (d[4]) ]
- * [ d[1] d[3] (d[5]) ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param d the matrix to store the results into; with 4 (6) entries
- * @throws NullPointerException if d is null
- * @throws ArrayIndexOutOfBoundsException if d is too small
- */
- public void getMatrix(double[] d)
- {
- d[0] = m00;
- d[1] = m10;
- d[2] = m01;
- d[3] = m11;
- if (d.length >= 6)
- {
- d[4] = m02;
- d[5] = m12;
- }
- }
-
- /**
- * Returns the X coordinate scaling factor of the matrix.
- *
- * @return m00
- * @see #getMatrix(double[])
- */
- public double getScaleX()
- {
- return m00;
- }
-
- /**
- * Returns the Y coordinate scaling factor of the matrix.
- *
- * @return m11
- * @see #getMatrix(double[])
- */
- public double getScaleY()
- {
- return m11;
- }
-
- /**
- * Returns the X coordinate shearing factor of the matrix.
- *
- * @return m01
- * @see #getMatrix(double[])
- */
- public double getShearX()
- {
- return m01;
- }
-
- /**
- * Returns the Y coordinate shearing factor of the matrix.
- *
- * @return m10
- * @see #getMatrix(double[])
- */
- public double getShearY()
- {
- return m10;
- }
-
- /**
- * Returns the X coordinate translation factor of the matrix.
- *
- * @return m02
- * @see #getMatrix(double[])
- */
- public double getTranslateX()
- {
- return m02;
- }
-
- /**
- * Returns the Y coordinate translation factor of the matrix.
- *
- * @return m12
- * @see #getMatrix(double[])
- */
- public double getTranslateY()
- {
- return m12;
- }
-
- /**
- * Concatenate a translation onto this transform. This is equivalent, but
- * more efficient than
- * <code>concatenate(AffineTransform.getTranslateInstance(tx, ty))</code>.
- *
- * @param tx the x translation distance
- * @param ty the y translation distance
- * @see #getTranslateInstance(double, double)
- * @see #concatenate(AffineTransform)
- */
- public void translate(double tx, double ty)
- {
- m02 += tx * m00 + ty * m01;
- m12 += tx * m10 + ty * m11;
- updateType();
- }
-
- /**
- * Concatenate a rotation onto this transform. This is equivalent, but
- * more efficient than
- * <code>concatenate(AffineTransform.getRotateInstance(theta))</code>.
- *
- * @param theta the rotation angle
- * @see #getRotateInstance(double)
- * @see #concatenate(AffineTransform)
- */
- public void rotate(double theta)
- {
- double c = Math.cos(theta);
- double s = Math.sin(theta);
- double n00 = m00 * c + m01 * s;
- double n01 = m00 * -s + m01 * c;
- double n10 = m10 * c + m11 * s;
- double n11 = m10 * -s + m11 * c;
- m00 = n00;
- m01 = n01;
- m10 = n10;
- m11 = n11;
- updateType();
- }
-
- /**
- * Concatenate a rotation about a point onto this transform. This is
- * equivalent, but more efficient than
- * <code>concatenate(AffineTransform.getRotateInstance(theta, x, y))</code>.
- *
- * @param theta the rotation angle
- * @param x the x coordinate of the pivot point
- * @param y the y coordinate of the pivot point
- * @see #getRotateInstance(double, double, double)
- * @see #concatenate(AffineTransform)
- */
- public void rotate(double theta, double x, double y)
- {
- translate(x, y);
- rotate(theta);
- translate(-x, -y);
- }
-
- /**
- * Concatenate a scale onto this transform. This is equivalent, but more
- * efficient than
- * <code>concatenate(AffineTransform.getScaleInstance(sx, sy))</code>.
- *
- * @param sx the x scaling factor
- * @param sy the y scaling factor
- * @see #getScaleInstance(double, double)
- * @see #concatenate(AffineTransform)
- */
- public void scale(double sx, double sy)
- {
- m00 *= sx;
- m01 *= sy;
- m10 *= sx;
- m11 *= sy;
- updateType();
- }
-
- /**
- * Concatenate a shearing onto this transform. This is equivalent, but more
- * efficient than
- * <code>concatenate(AffineTransform.getShearInstance(sx, sy))</code>.
- *
- * @param shx the x shearing factor
- * @param shy the y shearing factor
- * @see #getShearInstance(double, double)
- * @see #concatenate(AffineTransform)
- */
- public void shear(double shx, double shy)
- {
- double n00 = m00 + (shy * m01);
- double n01 = m01 + (shx * m00);
- double n10 = m10 + (shy * m11);
- double n11 = m11 + (shx * m10);
- m00 = n00;
- m01 = n01;
- m10 = n10;
- m11 = n11;
- updateType();
- }
-
- /**
- * Reset this transform to the identity (no transformation):
- * <pre>
- * [ 1 0 0 ]
- * [ 0 1 0 ]
- * [ 0 0 1 ]
- * </pre>
- */
- public void setToIdentity()
- {
- m00 = m11 = 1;
- m01 = m02 = m10 = m12 = 0;
- type = TYPE_IDENTITY;
- }
-
- /**
- * Set this transform to a translation:
- * <pre>
- * [ 1 0 tx ]
- * [ 0 1 ty ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param tx the x translation distance
- * @param ty the y translation distance
- */
- public void setToTranslation(double tx, double ty)
- {
- m00 = m11 = 1;
- m01 = m10 = 0;
- m02 = tx;
- m12 = ty;
- type = (tx == 0 && ty == 0) ? TYPE_UNIFORM_SCALE : TYPE_TRANSLATION;
- }
-
- /**
- * Set this transform to a rotation. A positive angle (in radians) rotates
- * the positive x-axis to the positive y-axis:
- * <pre>
- * [ cos(theta) -sin(theta) 0 ]
- * [ sin(theta) cos(theta) 0 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param theta the rotation angle
- */
- public void setToRotation(double theta)
- {
- double c = Math.cos(theta);
- double s = Math.sin(theta);
- m00 = c;
- m01 = -s;
- m02 = 0;
- m10 = s;
- m11 = c;
- m12 = 0;
- type = (c == 1 ? TYPE_IDENTITY
- : c == 0 || c == -1 ? TYPE_QUADRANT_ROTATION
- : TYPE_GENERAL_ROTATION);
- }
-
- /**
- * Set this transform to a rotation about a point. A positive angle (in
- * radians) rotates the positive x-axis to the positive y-axis. This is the
- * same as calling:
- * <pre>
- * tx.setToTranslation(x, y);
- * tx.rotate(theta);
- * tx.translate(-x, -y);
- * </pre>
- *
- * <p>The resulting matrix is:
- * <pre>
- * [ cos(theta) -sin(theta) x-x*cos+y*sin ]
- * [ sin(theta) cos(theta) y-x*sin-y*cos ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param theta the rotation angle
- * @param x the x coordinate of the pivot point
- * @param y the y coordinate of the pivot point
- */
- 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;
- updateType();
- }
-
- /**
- * Set this transform to a scale:
- * <pre>
- * [ sx 0 0 ]
- * [ 0 sy 0 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param sx the x scaling factor
- * @param sy the y scaling factor
- */
- public void setToScale(double sx, double sy)
- {
- m00 = sx;
- m01 = m02 = m10 = m12 = 0;
- m11 = sy;
- type = (sx != sy ? TYPE_GENERAL_SCALE
- : sx == 1 ? TYPE_IDENTITY : TYPE_UNIFORM_SCALE);
- }
-
- /**
- * Set this transform to a shear (points are shifted in the x direction based
- * on a factor of their y coordinate, and in the y direction as a factor of
- * their x coordinate):
- * <pre>
- * [ 1 shx 0 ]
- * [ shy 1 0 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param shx the x shearing factor
- * @param shy the y shearing factor
- */
- public void setToShear(double shx, double shy)
- {
- m00 = m11 = 1;
- m01 = shx;
- m10 = shy;
- m02 = m12 = 0;
- updateType();
- }
-
- /**
- * Set this transform to a copy of the given one.
- *
- * @param tx the transform to copy
- * @throws NullPointerException if tx is null
- */
- public void setTransform(AffineTransform tx)
- {
- m00 = tx.m00;
- m01 = tx.m01;
- m02 = tx.m02;
- m10 = tx.m10;
- m11 = tx.m11;
- m12 = tx.m12;
- type = tx.type;
- }
-
- /**
- * Set this transform to the given values:
- * <pre>
- * [ m00 m01 m02 ]
- * [ m10 m11 m12 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @param m00 the x scaling component
- * @param m10 the y shearing component
- * @param m01 the x shearing component
- * @param m11 the y scaling component
- * @param m02 the x translation component
- * @param m12 the y translation component
- */
- public void setTransform(double m00, double m10, double m01,
- double m11, double m02, double m12)
- {
- this.m00 = m00;
- this.m10 = m10;
- this.m01 = m01;
- this.m11 = m11;
- this.m02 = m02;
- this.m12 = m12;
- updateType();
- }
-
- /**
- * Set this transform to the result of performing the original version of
- * this followed by tx. This is commonly used when chaining transformations
- * from one space to another. In matrix form:
- * <pre>
- * [ this ] = [ this ] x [ tx ]
- * </pre>
- *
- * @param tx the transform to concatenate
- * @throws NullPointerException if tx is null
- * @see #preConcatenate(AffineTransform)
- */
- public void concatenate(AffineTransform tx)
- {
- double n00 = m00 * tx.m00 + m01 * tx.m10;
- double n01 = m00 * tx.m01 + m01 * tx.m11;
- double n02 = m00 * tx.m02 + m01 * tx.m12 + m02;
- double n10 = m10 * tx.m00 + m11 * tx.m10;
- double n11 = m10 * tx.m01 + m11 * tx.m11;
- double n12 = m10 * tx.m02 + m11 * tx.m12 + m12;
- m00 = n00;
- m01 = n01;
- m02 = n02;
- m10 = n10;
- m11 = n11;
- m12 = n12;
- updateType();
- }
-
- /**
- * Set this transform to the result of performing tx followed by the
- * original version of this. This is less common than normal concatenation,
- * but can still be used to chain transformations from one space to another.
- * In matrix form:
- * <pre>
- * [ this ] = [ tx ] x [ this ]
- * </pre>
- *
- * @param tx the transform to concatenate
- * @throws NullPointerException if tx is null
- * @see #concatenate(AffineTransform)
- */
- public void preConcatenate(AffineTransform tx)
- {
- double n00 = tx.m00 * m00 + tx.m01 * m10;
- double n01 = tx.m00 * m01 + tx.m01 * m11;
- double n02 = tx.m00 * m02 + tx.m01 * m12 + tx.m02;
- double n10 = tx.m10 * m00 + tx.m11 * m10;
- double n11 = tx.m10 * m01 + tx.m11 * m11;
- double n12 = tx.m10 * m02 + tx.m11 * m12 + tx.m12;
- m00 = n00;
- m01 = n01;
- m02 = n02;
- m10 = n10;
- m11 = n11;
- m12 = n12;
- updateType();
- }
-
- /**
- * Returns a transform, which if concatenated to this one, will result in
- * the identity transform. This is useful for undoing transformations, but
- * is only possible if the original transform has an inverse (ie. does not
- * map multiple points to the same line or point). A transform exists only
- * if getDeterminant() has a non-zero value.
- *
- * The inverse is calculated as:
- *
- * <pre>
- *
- * Let A be the matrix for which we want to find the inverse:
- *
- * A = [ m00 m01 m02 ]
- * [ m10 m11 m12 ]
- * [ 0 0 1 ]
- *
- *
- * 1
- * inverse (A) = --- x adjoint(A)
- * det
- *
- *
- *
- * = 1 [ m11 -m01 m01*m12-m02*m11 ]
- * --- x [ -m10 m00 -m00*m12+m10*m02 ]
- * det [ 0 0 m00*m11-m10*m01 ]
- *
- *
- *
- * = [ m11/det -m01/det m01*m12-m02*m11/det ]
- * [ -m10/det m00/det -m00*m12+m10*m02/det ]
- * [ 0 0 1 ]
- *
- *
- * </pre>
- *
- *
- *
- * @return a new inverse transform
- * @throws NoninvertibleTransformException if inversion is not possible
- * @see #getDeterminant()
- */
- public AffineTransform createInverse()
- throws NoninvertibleTransformException
- {
- double det = getDeterminant();
- if (det == 0)
- throw new NoninvertibleTransformException("can't invert transform");
-
- double im00 = m11 / det;
- double im10 = -m10 / det;
- double im01 = -m01 / det;
- double im11 = m00 / det;
- double im02 = (m01 * m12 - m02 * m11) / det;
- double im12 = (-m00 * m12 + m10 * m02) / det;
-
- return new AffineTransform (im00, im10, im01, im11, im02, im12);
- }
-
- /**
- * Perform this transformation on the given source point, and store the
- * result in the destination (creating it if necessary). It is safe for
- * src and dst to be the same.
- *
- * @param src the source point
- * @param dst the destination, or null
- * @return the transformation of src, in dst if it was non-null
- * @throws NullPointerException if src is null
- */
- public Point2D transform(Point2D src, Point2D dst)
- {
- if (dst == null)
- dst = new Point2D.Double();
- double x = src.getX();
- double y = src.getY();
- double nx = m00 * x + m01 * y + m02;
- double ny = m10 * x + m11 * y + m12;
- dst.setLocation(nx, ny);
- return dst;
- }
-
- /**
- * Perform this transformation on an array of points, storing the results
- * in another (possibly same) array. This will not create a destination
- * array, but will create points for the null entries of the destination.
- * The transformation is done sequentially. While having a single source
- * and destination point be the same is safe, you should be aware that
- * duplicate references to the same point in the source, and having the
- * source overlap the destination, may result in your source points changing
- * from a previous transform before it is their turn to be evaluated.
- *
- * @param src the array of source points
- * @param srcOff the starting offset into src
- * @param dst the array of destination points (may have null entries)
- * @param dstOff the starting offset into dst
- * @param num the number of points to transform
- * @throws NullPointerException if src or dst is null, or src has null
- * entries
- * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
- * @throws ArrayStoreException if new points are incompatible with dst
- */
- public void transform(Point2D[] src, int srcOff,
- Point2D[] dst, int dstOff, int num)
- {
- while (--num >= 0)
- dst[dstOff] = transform(src[srcOff++], dst[dstOff++]);
- }
-
- /**
- * Perform this transformation on an array of points, in (x,y) pairs,
- * storing the results in another (possibly same) array. This will not
- * create a destination array. All sources are copied before the
- * transformation, so that no result will overwrite a point that has not yet
- * been evaluated.
- *
- * @param srcPts the array of source points
- * @param srcOff the starting offset into src
- * @param dstPts the array of destination points
- * @param dstOff the starting offset into dst
- * @param num the number of points to transform
- * @throws NullPointerException if src or dst is null
- * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
- */
- public void transform(float[] srcPts, int srcOff,
- float[] dstPts, int dstOff, int num)
- {
- if (srcPts == dstPts && dstOff > srcOff
- && num > 1 && srcOff + 2 * num > dstOff)
- {
- float[] f = new float[2 * num];
- System.arraycopy(srcPts, srcOff, f, 0, 2 * num);
- srcPts = f;
- }
- while (--num >= 0)
- {
- float x = srcPts[srcOff++];
- float y = srcPts[srcOff++];
- dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02);
- dstPts[dstOff++] = (float) (m10 * x + m11 * y + m12);
- }
- }
-
- /**
- * Perform this transformation on an array of points, in (x,y) pairs,
- * storing the results in another (possibly same) array. This will not
- * create a destination array. All sources are copied before the
- * transformation, so that no result will overwrite a point that has not yet
- * been evaluated.
- *
- * @param srcPts the array of source points
- * @param srcOff the starting offset into src
- * @param dstPts the array of destination points
- * @param dstOff the starting offset into dst
- * @param num the number of points to transform
- * @throws NullPointerException if src or dst is null
- * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
- */
- public void transform(double[] srcPts, int srcOff,
- double[] dstPts, int dstOff, int num)
- {
- if (srcPts == dstPts && dstOff > srcOff
- && num > 1 && srcOff + 2 * num > dstOff)
- {
- double[] d = new double[2 * num];
- System.arraycopy(srcPts, srcOff, d, 0, 2 * num);
- srcPts = d;
- }
- while (--num >= 0)
- {
- double x = srcPts[srcOff++];
- double y = srcPts[srcOff++];
- dstPts[dstOff++] = m00 * x + m01 * y + m02;
- dstPts[dstOff++] = m10 * x + m11 * y + m12;
- }
- }
-
- /**
- * Perform this transformation on an array of points, in (x,y) pairs,
- * storing the results in another array. This will not create a destination
- * array.
- *
- * @param srcPts the array of source points
- * @param srcOff the starting offset into src
- * @param dstPts the array of destination points
- * @param dstOff the starting offset into dst
- * @param num the number of points to transform
- * @throws NullPointerException if src or dst is null
- * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
- */
- public void transform(float[] srcPts, int srcOff,
- double[] dstPts, int dstOff, int num)
- {
- while (--num >= 0)
- {
- float x = srcPts[srcOff++];
- float y = srcPts[srcOff++];
- dstPts[dstOff++] = m00 * x + m01 * y + m02;
- dstPts[dstOff++] = m10 * x + m11 * y + m12;
- }
- }
-
- /**
- * Perform this transformation on an array of points, in (x,y) pairs,
- * storing the results in another array. This will not create a destination
- * array.
- *
- * @param srcPts the array of source points
- * @param srcOff the starting offset into src
- * @param dstPts the array of destination points
- * @param dstOff the starting offset into dst
- * @param num the number of points to transform
- * @throws NullPointerException if src or dst is null
- * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
- */
- public void transform(double[] srcPts, int srcOff,
- float[] dstPts, int dstOff, int num)
- {
- while (--num >= 0)
- {
- double x = srcPts[srcOff++];
- double y = srcPts[srcOff++];
- dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02);
- dstPts[dstOff++] = (float) (m10 * x + m11 * y + m12);
- }
- }
-
- /**
- * Perform the inverse of this transformation on the given source point,
- * and store the result in the destination (creating it if necessary). It
- * is safe for src and dst to be the same.
- *
- * @param src the source point
- * @param dst the destination, or null
- * @return the inverse transformation of src, in dst if it was non-null
- * @throws NullPointerException if src is null
- * @throws NoninvertibleTransformException if the inverse does not exist
- * @see #getDeterminant()
- */
- public Point2D inverseTransform(Point2D src, Point2D dst)
- throws NoninvertibleTransformException
- {
- return createInverse().transform(src, dst);
- }
-
- /**
- * Perform the inverse of this transformation on an array of points, in
- * (x,y) pairs, storing the results in another (possibly same) array. This
- * will not create a destination array. All sources are copied before the
- * transformation, so that no result will overwrite a point that has not yet
- * been evaluated.
- *
- * @param srcPts the array of source points
- * @param srcOff the starting offset into src
- * @param dstPts the array of destination points
- * @param dstOff the starting offset into dst
- * @param num the number of points to transform
- * @throws NullPointerException if src or dst is null
- * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
- * @throws NoninvertibleTransformException if the inverse does not exist
- * @see #getDeterminant()
- */
- public void inverseTransform(double[] srcPts, int srcOff,
- double[] dstPts, int dstOff, int num)
- throws NoninvertibleTransformException
- {
- createInverse().transform(srcPts, srcOff, dstPts, dstOff, num);
- }
-
- /**
- * Perform this transformation, less any translation, on the given source
- * point, and store the result in the destination (creating it if
- * necessary). It is safe for src and dst to be the same. The reduced
- * transform is equivalent to:
- * <pre>
- * [ x' ] = [ m00 m01 ] [ x ] = [ m00 * x + m01 * y ]
- * [ y' ] [ m10 m11 ] [ y ] = [ m10 * x + m11 * y ]
- * </pre>
- *
- * @param src the source point
- * @param dst the destination, or null
- * @return the delta transformation of src, in dst if it was non-null
- * @throws NullPointerException if src is null
- */
- public Point2D deltaTransform(Point2D src, Point2D dst)
- {
- if (dst == null)
- dst = new Point2D.Double();
- double x = src.getX();
- double y = src.getY();
- double nx = m00 * x + m01 * y;
- double ny = m10 * x + m11 * y;
- dst.setLocation(nx, ny);
- return dst;
- }
-
- /**
- * Perform this transformation, less any translation, on an array of points,
- * in (x,y) pairs, storing the results in another (possibly same) array.
- * This will not create a destination array. All sources are copied before
- * the transformation, so that no result will overwrite a point that has
- * not yet been evaluated. The reduced transform is equivalent to:
- * <pre>
- * [ x' ] = [ m00 m01 ] [ x ] = [ m00 * x + m01 * y ]
- * [ y' ] [ m10 m11 ] [ y ] = [ m10 * x + m11 * y ]
- * </pre>
- *
- * @param srcPts the array of source points
- * @param srcOff the starting offset into src
- * @param dstPts the array of destination points
- * @param dstOff the starting offset into dst
- * @param num the number of points to transform
- * @throws NullPointerException if src or dst is null
- * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
- */
- public void deltaTransform(double[] srcPts, int srcOff,
- double[] dstPts, int dstOff,
- int num)
- {
- if (srcPts == dstPts && dstOff > srcOff
- && num > 1 && srcOff + 2 * num > dstOff)
- {
- double[] d = new double[2 * num];
- System.arraycopy(srcPts, srcOff, d, 0, 2 * num);
- srcPts = d;
- }
- while (--num >= 0)
- {
- double x = srcPts[srcOff++];
- double y = srcPts[srcOff++];
- dstPts[dstOff++] = m00 * x + m01 * y;
- dstPts[dstOff++] = m10 * x + m11 * y;
- }
- }
-
- /**
- * Return a new Shape, based on the given one, where the path of the shape
- * has been transformed by this transform. Notice that this uses GeneralPath,
- * which only stores points in float precision.
- *
- * @param src the shape source to transform
- * @return the shape, transformed by this, <code>null</code> if src is
- * <code>null</code>.
- * @see GeneralPath#transform(AffineTransform)
- */
- public Shape createTransformedShape(Shape src)
- {
- if(src == null)
- return null;
- GeneralPath p = new GeneralPath(src);
- p.transform(this);
- return p;
- }
-
- /**
- * Returns a string representation of the transform, in the format:
- * <code>"AffineTransform[[" + m00 + ", " + m01 + ", " + m02 + "], ["
- * + m10 + ", " + m11 + ", " + m12 + "]]"</code>.
- *
- * @return the string representation
- */
- public String toString()
- {
- return "AffineTransform[[" + m00 + ", " + m01 + ", " + m02 + "], ["
- + m10 + ", " + m11 + ", " + m12 + "]]";
- }
-
- /**
- * Tests if this transformation is the identity:
- * <pre>
- * [ 1 0 0 ]
- * [ 0 1 0 ]
- * [ 0 0 1 ]
- * </pre>
- *
- * @return true if this is the identity transform
- */
- public boolean isIdentity()
- {
- // Rather than rely on type, check explicitly.
- return (m00 == 1 && m01 == 0 && m02 == 0
- && m10 == 0 && m11 == 1 && m12 == 0);
- }
-
- /**
- * Create a new transform of the same run-time type, with the same
- * transforming properties as this one.
- *
- * @return the clone
- */
- public Object clone()
- {
- try
- {
- return super.clone();
- }
- catch (CloneNotSupportedException e)
- {
- throw (Error) new InternalError().initCause(e); // Impossible
- }
- }
-
- /**
- * Return the hashcode for this transformation. The formula is not
- * documented, but appears to be the same as:
- * <pre>
- * long l = Double.doubleToLongBits(getScaleX());
- * l = l * 31 + Double.doubleToLongBits(getShearX());
- * l = l * 31 + Double.doubleToLongBits(getTranslateX());
- * l = l * 31 + Double.doubleToLongBits(getShearY());
- * l = l * 31 + Double.doubleToLongBits(getScaleY());
- * l = l * 31 + Double.doubleToLongBits(getTranslateY());
- * return (int) ((l >> 32) ^ l);
- * </pre>
- *
- * @return the hashcode
- */
- public int hashCode()
- {
- long l = Double.doubleToLongBits(m00);
- l = l * 31 + Double.doubleToLongBits(m01);
- l = l * 31 + Double.doubleToLongBits(m02);
- l = l * 31 + Double.doubleToLongBits(m10);
- l = l * 31 + Double.doubleToLongBits(m11);
- l = l * 31 + Double.doubleToLongBits(m12);
- return (int) ((l >> 32) ^ l);
- }
-
- /**
- * Compares two transforms for equality. This returns true if they have the
- * same matrix values.
- *
- * @param obj the transform to compare
- * @return true if it is equal
- */
- public boolean equals(Object obj)
- {
- if (! (obj instanceof AffineTransform))
- return false;
- AffineTransform t = (AffineTransform) obj;
- return (m00 == t.m00 && m01 == t.m01 && m02 == t.m02
- && m10 == t.m10 && m11 == t.m11 && m12 == t.m12);
- }
-
- /**
- * Helper to decode the type from the matrix. This is not guaranteed
- * to find the optimal type, but at least it will be valid.
- */
- private void updateType()
- {
- double det = getDeterminant();
- if (det == 0)
- {
- type = TYPE_GENERAL_TRANSFORM;
- return;
- }
- // Scale (includes rotation by PI) or translation.
- if (m01 == 0 && m10 == 0)
- {
- if (m00 == m11)
- type = m00 == 1 ? TYPE_IDENTITY : TYPE_UNIFORM_SCALE;
- else
- type = TYPE_GENERAL_SCALE;
- if (m02 != 0 || m12 != 0)
- type |= TYPE_TRANSLATION;
- }
- // Rotation.
- else if (m00 == m11 && m01 == -m10)
- {
- type = m00 == 0 ? TYPE_QUADRANT_ROTATION : TYPE_GENERAL_ROTATION;
- if (det != 1)
- type |= TYPE_UNIFORM_SCALE;
- if (m02 != 0 || m12 != 0)
- type |= TYPE_TRANSLATION;
- }
- else
- type = TYPE_GENERAL_TRANSFORM;
- }
-
- /**
- * Reads a transform from an object stream.
- *
- * @param s the stream to read from
- * @throws ClassNotFoundException if there is a problem deserializing
- * @throws IOException if there is a problem deserializing
- */
- private void readObject(ObjectInputStream s)
- throws ClassNotFoundException, IOException
- {
- s.defaultReadObject();
- updateType();
- }
-} // class AffineTransform
diff --git a/libjava/classpath/java/awt/geom/Arc2D.java b/libjava/classpath/java/awt/geom/Arc2D.java
deleted file mode 100644
index 928c5cf..0000000
--- a/libjava/classpath/java/awt/geom/Arc2D.java
+++ /dev/null
@@ -1,1413 +0,0 @@
-/* Arc2D.java -- represents an arc in 2-D space
- Copyright (C) 2002, 2003, 2004 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.util.NoSuchElementException;
-
-
-/**
- * This class represents all arcs (segments of an ellipse in 2-D space). The
- * arcs are defined by starting angle and extent (arc length) in degrees, as
- * opposed to radians (like the rest of Java), and can be open, chorded, or
- * wedge shaped. The angles are skewed according to the ellipse, so that 45
- * degrees always points to the upper right corner (positive x, negative y)
- * of the bounding rectangle. A positive extent draws a counterclockwise arc,
- * and while the angle can be any value, the path iterator only traverses the
- * first 360 degrees. Storage is up to the subclasses.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @author Sven de Marothy (sven@physto.se)
- * @since 1.2
- */
-public abstract class Arc2D extends RectangularShape
-{
- /**
- * An open arc, with no segment connecting the endpoints. This type of
- * arc still contains the same points as a chorded version.
- */
- public static final int OPEN = 0;
-
- /**
- * A closed arc with a single segment connecting the endpoints (a chord).
- */
- public static final int CHORD = 1;
-
- /**
- * A closed arc with two segments, one from each endpoint, meeting at the
- * center of the ellipse.
- */
- public static final int PIE = 2;
-
- /** The closure type of this arc. This is package-private to avoid an
- * accessor method. */
- int type;
-
- /**
- * Create a new arc, with the specified closure type.
- *
- * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
- * @throws IllegalArgumentException if type is invalid
- */
- protected Arc2D(int type)
- {
- if (type < OPEN || type > PIE)
- throw new IllegalArgumentException();
- this.type = type;
- }
-
- /**
- * Get the starting angle of the arc in degrees.
- *
- * @return the starting angle
- * @see #setAngleStart(double)
- */
- public abstract double getAngleStart();
-
- /**
- * Get the extent angle of the arc in degrees.
- *
- * @return the extent angle
- * @see #setAngleExtent(double)
- */
- public abstract double getAngleExtent();
-
- /**
- * Return the closure type of the arc.
- *
- * @return the closure type
- * @see #OPEN
- * @see #CHORD
- * @see #PIE
- * @see #setArcType(int)
- */
- public int getArcType()
- {
- return type;
- }
-
- /**
- * Returns the starting point of the arc.
- *
- * @return the start point
- */
- public Point2D getStartPoint()
- {
- double angle = Math.toRadians(getAngleStart());
- double rx = getWidth() / 2;
- double ry = getHeight() / 2;
- double x = getX() + rx + rx * Math.cos(angle);
- double y = getY() + ry - ry * Math.sin(angle);
- return new Point2D.Double(x, y);
- }
-
- /**
- * Returns the ending point of the arc.
- *
- * @return the end point
- */
- public Point2D getEndPoint()
- {
- double angle = Math.toRadians(getAngleStart() + getAngleExtent());
- double rx = getWidth() / 2;
- double ry = getHeight() / 2;
- double x = getX() + rx + rx * Math.cos(angle);
- double y = getY() + ry - ry * Math.sin(angle);
- return new Point2D.Double(x, y);
- }
-
- /**
- * Set the parameters of the arc. The angles are in degrees, and a positive
- * extent sweeps counterclockwise (from the positive x-axis to the negative
- * y-axis).
- *
- * @param x the new x coordinate of the upper left of the bounding box
- * @param y the new y coordinate of the upper left of the bounding box
- * @param w the new width of the bounding box
- * @param h the new height of the bounding box
- * @param start the start angle, in degrees
- * @param extent the arc extent, in degrees
- * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- */
- public abstract void setArc(double x, double y, double w, double h,
- double start, double extent, int type);
-
- /**
- * Set the parameters of the arc. The angles are in degrees, and a positive
- * extent sweeps counterclockwise (from the positive x-axis to the negative
- * y-axis).
- *
- * @param p the upper left point of the bounding box
- * @param d the dimensions of the bounding box
- * @param start the start angle, in degrees
- * @param extent the arc extent, in degrees
- * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- * @throws NullPointerException if p or d is null
- */
- public void setArc(Point2D p, Dimension2D d, double start, double extent,
- int type)
- {
- setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(), start, extent, type);
- }
-
- /**
- * Set the parameters of the arc. The angles are in degrees, and a positive
- * extent sweeps counterclockwise (from the positive x-axis to the negative
- * y-axis).
- *
- * @param r the new bounding box
- * @param start the start angle, in degrees
- * @param extent the arc extent, in degrees
- * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- * @throws NullPointerException if r is null
- */
- public void setArc(Rectangle2D r, double start, double extent, int type)
- {
- setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(), start, extent, type);
- }
-
- /**
- * Set the parameters of the arc from the given one.
- *
- * @param a the arc to copy
- * @throws NullPointerException if a is null
- */
- public void setArc(Arc2D a)
- {
- setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(), a.getAngleStart(),
- a.getAngleExtent(), a.getArcType());
- }
-
- /**
- * Set the parameters of the arc. The angles are in degrees, and a positive
- * extent sweeps counterclockwise (from the positive x-axis to the negative
- * y-axis). This controls the center point and radius, so the arc will be
- * circular.
- *
- * @param x the x coordinate of the center of the circle
- * @param y the y coordinate of the center of the circle
- * @param r the radius of the circle
- * @param start the start angle, in degrees
- * @param extent the arc extent, in degrees
- * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- */
- public void setArcByCenter(double x, double y, double r, double start,
- double extent, int type)
- {
- setArc(x - r, y - r, r + r, r + r, start, extent, type);
- }
-
- /**
- * Sets the parameters of the arc by finding the tangents of two lines, and
- * using the specified radius. The arc will be circular, will begin on the
- * tangent point of the line extending from p1 to p2, and will end on the
- * tangent point of the line extending from p2 to p3.
- *
- * XXX What happens if the points are colinear, or the radius negative?
- *
- * @param p1 the first point
- * @param p2 the tangent line intersection point
- * @param p3 the third point
- * @param r the radius of the arc
- * @throws NullPointerException if any point is null
- */
- public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double r)
- {
- if ((p2.getX() - p1.getX()) * (p3.getY() - p1.getY())
- - (p3.getX() - p1.getX()) * (p2.getY() - p1.getY()) > 0)
- {
- Point2D p = p3;
- p3 = p1;
- p1 = p;
- }
-
- // normalized tangent vectors
- double dx1 = (p1.getX() - p2.getX()) / p1.distance(p2);
- double dy1 = (p1.getY() - p2.getY()) / p1.distance(p2);
- double dx2 = (p2.getX() - p3.getX()) / p3.distance(p2);
- double dy2 = (p2.getY() - p3.getY()) / p3.distance(p2);
- double theta1 = Math.atan2(dx1, dy1);
- double theta2 = Math.atan2(dx2, dy2);
-
- double dx = r * Math.cos(theta2) - r * Math.cos(theta1);
- double dy = -r * Math.sin(theta2) + r * Math.sin(theta1);
-
- if (theta1 < 0)
- theta1 += 2 * Math.PI;
- if (theta2 < 0)
- theta2 += 2 * Math.PI;
- if (theta2 < theta1)
- theta2 += 2 * Math.PI;
-
- // Vectors of the lines, not normalized, note we change
- // the direction of line 2.
- dx1 = p1.getX() - p2.getX();
- dy1 = p1.getY() - p2.getY();
- dx2 = p3.getX() - p2.getX();
- dy2 = p3.getY() - p2.getY();
-
- // Calculate the tangent point to the second line
- double t2 = -(dx1 * dy - dy1 * dx) / (dx2 * dy1 - dx1 * dy2);
- double x2 = t2 * (p3.getX() - p2.getX()) + p2.getX();
- double y2 = t2 * (p3.getY() - p2.getY()) + p2.getY();
-
- // calculate the center point
- double x = x2 - r * Math.cos(theta2);
- double y = y2 + r * Math.sin(theta2);
-
- setArc(x - r, y - r, 2 * r, 2 * r, Math.toDegrees(theta1),
- Math.toDegrees(theta2 - theta1), getArcType());
- }
-
- /**
- * Set the start, in degrees.
- *
- * @param start the new start angle
- * @see #getAngleStart()
- */
- public abstract void setAngleStart(double start);
-
- /**
- * Set the extent, in degrees.
- *
- * @param extent the new extent angle
- * @see #getAngleExtent()
- */
- public abstract void setAngleExtent(double extent);
-
- /**
- * Sets the starting angle to the angle of the given point relative to
- * the center of the arc. The extent remains constant; in other words,
- * this rotates the arc.
- *
- * @param p the new start point
- * @throws NullPointerException if p is null
- * @see #getStartPoint()
- * @see #getAngleStart()
- */
- public void setAngleStart(Point2D p)
- {
- // Normalize.
- double x = p.getX() - (getX() + getWidth() / 2);
- double y = p.getY() - (getY() + getHeight() / 2);
- setAngleStart(Math.toDegrees(Math.atan2(-y, x)));
- }
-
- /**
- * Sets the starting and extent angles to those of the given points
- * relative to the center of the arc. The arc will be non-empty, and will
- * extend counterclockwise.
- *
- * @param x1 the first x coordinate
- * @param y1 the first y coordinate
- * @param x2 the second x coordinate
- * @param y2 the second y coordinate
- * @see #setAngleStart(Point2D)
- */
- public void setAngles(double x1, double y1, double x2, double y2)
- {
- // Normalize the points.
- double mx = getX();
- double my = getY();
- double mw = getWidth();
- double mh = getHeight();
- x1 = x1 - (mx + mw / 2);
- y1 = y1 - (my + mh / 2);
- x2 = x2 - (mx + mw / 2);
- y2 = y2 - (my + mh / 2);
- double start = Math.toDegrees(Math.atan2(-y1, x1));
- double extent = Math.toDegrees(Math.atan2(-y2, x2)) - start;
- if (extent < 0)
- extent += 360;
- setAngleStart(start);
- setAngleExtent(extent);
- }
-
- /**
- * Sets the starting and extent angles to those of the given points
- * relative to the center of the arc. The arc will be non-empty, and will
- * extend counterclockwise.
- *
- * @param p1 the first point
- * @param p2 the second point
- * @throws NullPointerException if either point is null
- * @see #setAngleStart(Point2D)
- */
- public void setAngles(Point2D p1, Point2D p2)
- {
- setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
- }
-
- /**
- * Set the closure type of this arc.
- *
- * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- * @see #getArcType()
- */
- public void setArcType(int type)
- {
- if (type < OPEN || type > PIE)
- throw new IllegalArgumentException();
- this.type = type;
- }
-
- /**
- * Sets the location and bounds of the ellipse of which this arc is a part.
- *
- * @param x the new x coordinate
- * @param y the new y coordinate
- * @param w the new width
- * @param h the new height
- * @see #getFrame()
- */
- public void setFrame(double x, double y, double w, double h)
- {
- setArc(x, y, w, h, getAngleStart(), getAngleExtent(), type);
- }
-
- /**
- * Gets the bounds of the arc. This is much tighter than
- * <code>getBounds</code>, as it takes into consideration the start and
- * end angles, and the center point of a pie wedge, rather than just the
- * overall ellipse.
- *
- * @return the bounds of the arc
- * @see #getBounds()
- */
- public Rectangle2D getBounds2D()
- {
- double extent = getAngleExtent();
- if (Math.abs(extent) >= 360)
- return makeBounds(getX(), getY(), getWidth(), getHeight());
-
- // Find the minimal bounding box. This determined by its extrema,
- // which are the center, the endpoints of the arc, and any local
- // maximum contained by the arc.
- double rX = getWidth() / 2;
- double rY = getHeight() / 2;
- double centerX = getX() + rX;
- double centerY = getY() + rY;
-
- Point2D p1 = getStartPoint();
- Rectangle2D result = makeBounds(p1.getX(), p1.getY(), 0, 0);
- result.add(getEndPoint());
-
- if (type == PIE)
- result.add(centerX, centerY);
- if (containsAngle(0))
- result.add(centerX + rX, centerY);
- if (containsAngle(90))
- result.add(centerX, centerY - rY);
- if (containsAngle(180))
- result.add(centerX - rX, centerY);
- if (containsAngle(270))
- result.add(centerX, centerY + rY);
-
- return result;
- }
-
- /**
- * Construct a bounding box in a precision appropriate for the subclass.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- * @return the rectangle for use in getBounds2D
- */
- protected abstract Rectangle2D makeBounds(double x, double y, double w,
- double h);
-
- /**
- * Tests if the given angle, in degrees, is included in the arc.
- * All angles are normalized to be between 0 and 360 degrees.
- *
- * @param a the angle to test
- * @return true if it is contained
- */
- public boolean containsAngle(double a)
- {
- double start = getAngleStart();
- double extent = getAngleExtent();
- double end = start + extent;
-
- if (extent == 0)
- return false;
-
- if (extent >= 360 || extent <= -360)
- return true;
-
- if (extent < 0)
- {
- end = start;
- start += extent;
- }
-
- start %= 360;
- while (start < 0)
- start += 360;
-
- end %= 360;
- while (end < start)
- end += 360;
-
- a %= 360;
- while (a < start)
- a += 360;
-
- return a >= start && a < end; // starting angle included, ending angle not
- }
-
- /**
- * Determines if the arc contains the given point. If the bounding box
- * is empty, then this will return false.
- *
- * The area considered 'inside' an arc of type OPEN is the same as the
- * area inside an equivalent filled CHORD-type arc. The area considered
- * 'inside' a CHORD-type arc is the same as the filled area.
- *
- * @param x the x coordinate to test
- * @param y the y coordinate to test
- * @return true if the point is inside the arc
- */
- public boolean contains(double x, double y)
- {
- double w = getWidth();
- double h = getHeight();
- double extent = getAngleExtent();
- if (w <= 0 || h <= 0 || extent == 0)
- return false;
-
- double mx = getX() + w / 2;
- double my = getY() + h / 2;
- double dx = (x - mx) * 2 / w;
- double dy = (y - my) * 2 / h;
- if ((dx * dx + dy * dy) >= 1.0)
- return false;
-
- double angle = Math.toDegrees(Math.atan2(-dy, dx));
- if (getArcType() == PIE)
- return containsAngle(angle);
-
- double a1 = Math.toRadians(getAngleStart());
- double a2 = Math.toRadians(getAngleStart() + extent);
- double x1 = mx + getWidth() * Math.cos(a1) / 2;
- double y1 = my - getHeight() * Math.sin(a1) / 2;
- double x2 = mx + getWidth() * Math.cos(a2) / 2;
- double y2 = my - getHeight() * Math.sin(a2) / 2;
- double sgn = ((x2 - x1) * (my - y1) - (mx - x1) * (y2 - y1)) * ((x2 - x1) * (y
- - y1) - (x - x1) * (y2 - y1));
-
- if (Math.abs(extent) > 180)
- {
- if (containsAngle(angle))
- return true;
- return sgn > 0;
- }
- else
- {
- if (! containsAngle(angle))
- return false;
- return sgn < 0;
- }
- }
-
- /**
- * Tests if a given rectangle intersects the area of the arc.
- *
- * For a definition of the 'inside' area, see the contains() method.
- * @see #contains(double, double)
- *
- * @param x the x coordinate of the rectangle
- * @param y the y coordinate of the rectangle
- * @param w the width of the rectangle
- * @param h the height of the rectangle
- * @return true if the two shapes share common points
- */
- public boolean intersects(double x, double y, double w, double h)
- {
- double extent = getAngleExtent();
- if (extent == 0)
- return false;
-
- if (contains(x, y) || contains(x, y + h) || contains(x + w, y)
- || contains(x + w, y + h))
- return true;
-
- Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
-
- double a = getWidth() / 2.0;
- double b = getHeight() / 2.0;
-
- double mx = getX() + a;
- double my = getY() + b;
- double x1 = mx + a * Math.cos(Math.toRadians(getAngleStart()));
- double y1 = my - b * Math.sin(Math.toRadians(getAngleStart()));
- double x2 = mx + a * Math.cos(Math.toRadians(getAngleStart() + extent));
- double y2 = my - b * Math.sin(Math.toRadians(getAngleStart() + extent));
-
- if (getArcType() != CHORD)
- {
- // check intersections against the pie radii
- if (rect.intersectsLine(mx, my, x1, y1))
- return true;
- if (rect.intersectsLine(mx, my, x2, y2))
- return true;
- }
- else// check the chord
- if (rect.intersectsLine(x1, y1, x2, y2))
- return true;
-
- // Check the Arc segment against the four edges
- double dx;
-
- // Check the Arc segment against the four edges
- double dy;
- dy = y - my;
- dx = a * Math.sqrt(1 - ((dy * dy) / (b * b)));
- if (! java.lang.Double.isNaN(dx))
- {
- if (mx + dx >= x && mx + dx <= x + w
- && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
- return true;
- if (mx - dx >= x && mx - dx <= x + w
- && containsAngle(Math.toDegrees(Math.atan2(-dy, -dx))))
- return true;
- }
- dy = (y + h) - my;
- dx = a * Math.sqrt(1 - ((dy * dy) / (b * b)));
- if (! java.lang.Double.isNaN(dx))
- {
- if (mx + dx >= x && mx + dx <= x + w
- && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
- return true;
- if (mx - dx >= x && mx - dx <= x + w
- && containsAngle(Math.toDegrees(Math.atan2(-dy, -dx))))
- return true;
- }
- dx = x - mx;
- dy = b * Math.sqrt(1 - ((dx * dx) / (a * a)));
- if (! java.lang.Double.isNaN(dy))
- {
- if (my + dy >= y && my + dy <= y + h
- && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
- return true;
- if (my - dy >= y && my - dy <= y + h
- && containsAngle(Math.toDegrees(Math.atan2(dy, dx))))
- return true;
- }
-
- dx = (x + w) - mx;
- dy = b * Math.sqrt(1 - ((dx * dx) / (a * a)));
- if (! java.lang.Double.isNaN(dy))
- {
- if (my + dy >= y && my + dy <= y + h
- && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
- return true;
- if (my - dy >= y && my - dy <= y + h
- && containsAngle(Math.toDegrees(Math.atan2(dy, dx))))
- return true;
- }
-
- // Check whether the arc is contained within the box
- if (rect.contains(mx, my))
- return true;
-
- return false;
- }
-
- /**
- * Tests if a given rectangle is contained in the area of the arc.
- *
- * @param x the x coordinate of the rectangle
- * @param y the y coordinate of the rectangle
- * @param w the width of the rectangle
- * @param h the height of the rectangle
- * @return true if the arc contains the rectangle
- */
- public boolean contains(double x, double y, double w, double h)
- {
- double extent = getAngleExtent();
- if (extent == 0)
- return false;
-
- if (! (contains(x, y) && contains(x, y + h) && contains(x + w, y)
- && contains(x + w, y + h)))
- return false;
-
- Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
-
- double a = getWidth() / 2.0;
- double b = getHeight() / 2.0;
-
- double mx = getX() + a;
- double my = getY() + b;
- double x1 = mx + a * Math.cos(Math.toRadians(getAngleStart()));
- double y1 = my - b * Math.sin(Math.toRadians(getAngleStart()));
- double x2 = mx + a * Math.cos(Math.toRadians(getAngleStart() + extent));
- double y2 = my - b * Math.sin(Math.toRadians(getAngleStart() + extent));
- if (getArcType() != CHORD)
- {
- // check intersections against the pie radii
- if (rect.intersectsLine(mx, my, x1, y1))
- return false;
-
- if (rect.intersectsLine(mx, my, x2, y2))
- return false;
- }
- else if (rect.intersectsLine(x1, y1, x2, y2))
- return false;
- return true;
- }
-
- /**
- * Tests if a given rectangle is contained in the area of the arc.
- *
- * @param r the rectangle
- * @return true if the arc contains the rectangle
- */
- public boolean contains(Rectangle2D r)
- {
- return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Returns an iterator over this arc, with an optional transformation.
- * This iterator is threadsafe, so future modifications to the arc do not
- * affect the iteration.
- *
- * @param at the transformation, or null
- * @return a path iterator
- */
- public PathIterator getPathIterator(AffineTransform at)
- {
- return new ArcIterator(this, at);
- }
-
- /**
- * This class is used to iterate over an arc. Since ellipses are a subclass
- * of arcs, this is used by Ellipse2D as well.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- */
- static final class ArcIterator implements PathIterator
- {
- /** The current iteration. */
- private int current;
-
- /** The last iteration. */
- private final int limit;
-
- /** The optional transformation. */
- private final AffineTransform xform;
-
- /** The x coordinate of the bounding box. */
- private final double x;
-
- /** The y coordinate of the bounding box. */
- private final double y;
-
- /** The width of the bounding box. */
- private final double w;
-
- /** The height of the bounding box. */
- private final double h;
-
- /** The start angle, in radians (not degrees). */
- private final double start;
-
- /** The extent angle, in radians (not degrees). */
- private final double extent;
-
- /** The arc closure type. */
- private final int type;
-
- /**
- * Construct a new iterator over an arc.
- *
- * @param a the arc
- * @param xform the transform
- */
- public ArcIterator(Arc2D a, AffineTransform xform)
- {
- this.xform = xform;
- x = a.getX();
- y = a.getY();
- w = a.getWidth();
- h = a.getHeight();
- double start = Math.toRadians(a.getAngleStart());
- double extent = Math.toRadians(a.getAngleExtent());
-
- this.start = start;
- this.extent = extent;
-
- type = a.type;
- if (w < 0 || h < 0)
- limit = -1;
- else if (extent == 0)
- limit = type;
- else if (Math.abs(extent) <= Math.PI / 2.0)
- limit = type + 1;
- else if (Math.abs(extent) <= Math.PI)
- limit = type + 2;
- else if (Math.abs(extent) <= 3.0 * (Math.PI / 2.0))
- limit = type + 3;
- else
- limit = type + 4;
- }
-
- /**
- * Construct a new iterator over an ellipse.
- *
- * @param e the ellipse
- * @param xform the transform
- */
- public ArcIterator(Ellipse2D e, AffineTransform xform)
- {
- this.xform = xform;
- x = e.getX();
- y = e.getY();
- w = e.getWidth();
- h = e.getHeight();
- start = 0;
- extent = 2 * Math.PI;
- type = CHORD;
- limit = (w < 0 || h < 0) ? -1 : 5;
- }
-
- /**
- * Return the winding rule.
- *
- * @return {@link PathIterator#WIND_NON_ZERO}
- */
- public int getWindingRule()
- {
- return WIND_NON_ZERO;
- }
-
- /**
- * Test if the iteration is complete.
- *
- * @return true if more segments exist
- */
- public boolean isDone()
- {
- return current > limit;
- }
-
- /**
- * Advance the iterator.
- */
- public void next()
- {
- current++;
- }
-
- /**
- * Put the current segment into the array, and return the segment type.
- *
- * @param coords an array of 6 elements
- * @return the segment type
- * @throws NullPointerException if coords is null
- * @throws ArrayIndexOutOfBoundsException if coords is too small
- */
- public int currentSegment(float[] coords)
- {
- double[] double_coords = new double[6];
- int code = currentSegment(double_coords);
- for (int i = 0; i < 6; ++i)
- coords[i] = (float) double_coords[i];
- return code;
- }
-
- /**
- * Put the current segment into the array, and return the segment type.
- *
- * @param coords an array of 6 elements
- * @return the segment type
- * @throws NullPointerException if coords is null
- * @throws ArrayIndexOutOfBoundsException if coords is too small
- */
- public int currentSegment(double[] coords)
- {
- double rx = w / 2;
- double ry = h / 2;
- double xmid = x + rx;
- double ymid = y + ry;
-
- if (current > limit)
- throw new NoSuchElementException("arc iterator out of bounds");
-
- if (current == 0)
- {
- coords[0] = xmid + rx * Math.cos(start);
- coords[1] = ymid - ry * Math.sin(start);
- if (xform != null)
- xform.transform(coords, 0, coords, 0, 1);
- return SEG_MOVETO;
- }
-
- if (type != OPEN && current == limit)
- return SEG_CLOSE;
-
- if ((current == limit - 1) && (type == PIE))
- {
- coords[0] = xmid;
- coords[1] = ymid;
- if (xform != null)
- xform.transform(coords, 0, coords, 0, 1);
- return SEG_LINETO;
- }
-
- // note that this produces a cubic approximation of the arc segment,
- // not a true ellipsoid. there's no ellipsoid path segment code,
- // unfortunately. the cubic approximation looks about right, though.
- double kappa = (Math.sqrt(2.0) - 1.0) * (4.0 / 3.0);
- double quad = (Math.PI / 2.0);
-
- double curr_begin;
- double curr_extent;
- if (extent > 0)
- {
- curr_begin = start + (current - 1) * quad;
- curr_extent = Math.min((start + extent) - curr_begin, quad);
- }
- else
- {
- curr_begin = start - (current - 1) * quad;
- curr_extent = Math.max((start + extent) - curr_begin, -quad);
- }
-
- double portion_of_a_quadrant = Math.abs(curr_extent / quad);
-
- double x0 = xmid + rx * Math.cos(curr_begin);
- double y0 = ymid - ry * Math.sin(curr_begin);
-
- double x1 = xmid + rx * Math.cos(curr_begin + curr_extent);
- double y1 = ymid - ry * Math.sin(curr_begin + curr_extent);
-
- AffineTransform trans = new AffineTransform();
- double[] cvec = new double[2];
- double len = kappa * portion_of_a_quadrant;
- double angle = curr_begin;
-
- // in a hypothetical "first quadrant" setting, our first control
- // vector would be sticking up, from [1,0] to [1,kappa].
- //
- // let us recall however that in java2d, y coords are upside down
- // from what one would consider "normal" first quadrant rules, so we
- // will *subtract* the y value of this control vector from our first
- // point.
- cvec[0] = 0;
- if (extent > 0)
- cvec[1] = len;
- else
- cvec[1] = -len;
-
- trans.scale(rx, ry);
- trans.rotate(angle);
- trans.transform(cvec, 0, cvec, 0, 1);
- coords[0] = x0 + cvec[0];
- coords[1] = y0 - cvec[1];
-
- // control vector #2 would, ideally, be sticking out and to the
- // right, in a first quadrant arc segment. again, subtraction of y.
- cvec[0] = 0;
- if (extent > 0)
- cvec[1] = -len;
- else
- cvec[1] = len;
-
- trans.rotate(curr_extent);
- trans.transform(cvec, 0, cvec, 0, 1);
- coords[2] = x1 + cvec[0];
- coords[3] = y1 - cvec[1];
-
- // end point
- coords[4] = x1;
- coords[5] = y1;
-
- if (xform != null)
- xform.transform(coords, 0, coords, 0, 3);
-
- return SEG_CUBICTO;
- }
- } // class ArcIterator
-
- /**
- * This class implements an arc in double precision.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- */
- public static class Double extends Arc2D
- {
- /** The x coordinate of the box bounding the ellipse of this arc. */
- public double x;
-
- /** The y coordinate of the box bounding the ellipse of this arc. */
- public double y;
-
- /** The width of the box bounding the ellipse of this arc. */
- public double width;
-
- /** The height of the box bounding the ellipse of this arc. */
- public double height;
-
- /** The start angle of this arc, in degrees. */
- public double start;
-
- /** The extent angle of this arc, in degrees. */
- public double extent;
-
- /**
- * Create a new, open arc at (0,0) with 0 extent.
- */
- public Double()
- {
- super(OPEN);
- }
-
- /**
- * Create a new arc of the given type at (0,0) with 0 extent.
- *
- * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- */
- public Double(int type)
- {
- super(type);
- }
-
- /**
- * Create a new arc with the given dimensions.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- * @param start the start angle, in degrees
- * @param extent the extent, in degrees
- * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- */
- public Double(double x, double y, double w, double h, double start,
- double extent, int type)
- {
- super(type);
- this.x = x;
- this.y = y;
- width = w;
- height = h;
- this.start = start;
- this.extent = extent;
- }
-
- /**
- * Create a new arc with the given dimensions.
- *
- * @param r the bounding box
- * @param start the start angle, in degrees
- * @param extent the extent, in degrees
- * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- * @throws NullPointerException if r is null
- */
- public Double(Rectangle2D r, double start, double extent, int type)
- {
- super(type);
- x = r.getX();
- y = r.getY();
- width = r.getWidth();
- height = r.getHeight();
- this.start = start;
- this.extent = extent;
- }
-
- /**
- * Return the x coordinate of the bounding box.
- *
- * @return the value of x
- */
- public double getX()
- {
- return x;
- }
-
- /**
- * Return the y coordinate of the bounding box.
- *
- * @return the value of y
- */
- public double getY()
- {
- return y;
- }
-
- /**
- * Return the width of the bounding box.
- *
- * @return the value of width
- */
- public double getWidth()
- {
- return width;
- }
-
- /**
- * Return the height of the bounding box.
- *
- * @return the value of height
- */
- public double getHeight()
- {
- return height;
- }
-
- /**
- * Return the start angle of the arc, in degrees.
- *
- * @return the value of start
- */
- public double getAngleStart()
- {
- return start;
- }
-
- /**
- * Return the extent of the arc, in degrees.
- *
- * @return the value of extent
- */
- public double getAngleExtent()
- {
- return extent;
- }
-
- /**
- * Tests if the arc contains points.
- *
- * @return true if the arc has no interior
- */
- public boolean isEmpty()
- {
- return width <= 0 || height <= 0;
- }
-
- /**
- * Sets the arc to the given dimensions.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- * @param start the start angle, in degrees
- * @param extent the extent, in degrees
- * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- */
- public void setArc(double x, double y, double w, double h, double start,
- double extent, int type)
- {
- this.x = x;
- this.y = y;
- width = w;
- height = h;
- this.start = start;
- this.extent = extent;
- setArcType(type);
- }
-
- /**
- * Sets the start angle of the arc.
- *
- * @param start the new start angle
- */
- public void setAngleStart(double start)
- {
- this.start = start;
- }
-
- /**
- * Sets the extent angle of the arc.
- *
- * @param extent the new extent angle
- */
- public void setAngleExtent(double extent)
- {
- this.extent = extent;
- }
-
- /**
- * Creates a tight bounding box given dimensions that more precise than
- * the bounding box of the ellipse.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- */
- protected Rectangle2D makeBounds(double x, double y, double w, double h)
- {
- return new Rectangle2D.Double(x, y, w, h);
- }
- } // class Double
-
- /**
- * This class implements an arc in float precision.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- */
- public static class Float extends Arc2D
- {
- /** The x coordinate of the box bounding the ellipse of this arc. */
- public float x;
-
- /** The y coordinate of the box bounding the ellipse of this arc. */
- public float y;
-
- /** The width of the box bounding the ellipse of this arc. */
- public float width;
-
- /** The height of the box bounding the ellipse of this arc. */
- public float height;
-
- /** The start angle of this arc, in degrees. */
- public float start;
-
- /** The extent angle of this arc, in degrees. */
- public float extent;
-
- /**
- * Create a new, open arc at (0,0) with 0 extent.
- */
- public Float()
- {
- super(OPEN);
- }
-
- /**
- * Create a new arc of the given type at (0,0) with 0 extent.
- *
- * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- */
- public Float(int type)
- {
- super(type);
- }
-
- /**
- * Create a new arc with the given dimensions.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- * @param start the start angle, in degrees
- * @param extent the extent, in degrees
- * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- */
- public Float(float x, float y, float w, float h, float start,
- float extent, int type)
- {
- super(type);
- this.x = x;
- this.y = y;
- width = w;
- height = h;
- this.start = start;
- this.extent = extent;
- }
-
- /**
- * Create a new arc with the given dimensions.
- *
- * @param r the bounding box
- * @param start the start angle, in degrees
- * @param extent the extent, in degrees
- * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- * @throws NullPointerException if r is null
- */
- public Float(Rectangle2D r, float start, float extent, int type)
- {
- super(type);
- x = (float) r.getX();
- y = (float) r.getY();
- width = (float) r.getWidth();
- height = (float) r.getHeight();
- this.start = start;
- this.extent = extent;
- }
-
- /**
- * Return the x coordinate of the bounding box.
- *
- * @return the value of x
- */
- public double getX()
- {
- return x;
- }
-
- /**
- * Return the y coordinate of the bounding box.
- *
- * @return the value of y
- */
- public double getY()
- {
- return y;
- }
-
- /**
- * Return the width of the bounding box.
- *
- * @return the value of width
- */
- public double getWidth()
- {
- return width;
- }
-
- /**
- * Return the height of the bounding box.
- *
- * @return the value of height
- */
- public double getHeight()
- {
- return height;
- }
-
- /**
- * Return the start angle of the arc, in degrees.
- *
- * @return the value of start
- */
- public double getAngleStart()
- {
- return start;
- }
-
- /**
- * Return the extent of the arc, in degrees.
- *
- * @return the value of extent
- */
- public double getAngleExtent()
- {
- return extent;
- }
-
- /**
- * Tests if the arc contains points.
- *
- * @return true if the arc has no interior
- */
- public boolean isEmpty()
- {
- return width <= 0 || height <= 0;
- }
-
- /**
- * Sets the arc to the given dimensions.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- * @param start the start angle, in degrees
- * @param extent the extent, in degrees
- * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
- * @throws IllegalArgumentException if type is invalid
- */
- public void setArc(double x, double y, double w, double h, double start,
- double extent, int type)
- {
- this.x = (float) x;
- this.y = (float) y;
- width = (float) w;
- height = (float) h;
- this.start = (float) start;
- this.extent = (float) extent;
- setArcType(type);
- }
-
- /**
- * Sets the start angle of the arc.
- *
- * @param start the new start angle
- */
- public void setAngleStart(double start)
- {
- this.start = (float) start;
- }
-
- /**
- * Sets the extent angle of the arc.
- *
- * @param extent the new extent angle
- */
- public void setAngleExtent(double extent)
- {
- this.extent = (float) extent;
- }
-
- /**
- * Creates a tight bounding box given dimensions that more precise than
- * the bounding box of the ellipse.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- */
- protected Rectangle2D makeBounds(double x, double y, double w, double h)
- {
- return new Rectangle2D.Float((float) x, (float) y, (float) w, (float) h);
- }
- } // class Float
-} // class Arc2D
diff --git a/libjava/classpath/java/awt/geom/Area.java b/libjava/classpath/java/awt/geom/Area.java
deleted file mode 100644
index 51f914f..0000000
--- a/libjava/classpath/java/awt/geom/Area.java
+++ /dev/null
@@ -1,3298 +0,0 @@
-/* Area.java -- represents a shape built by constructive area geometry
- Copyright (C) 2002, 2004 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;
-import java.util.Vector;
-
-
-/**
- * The Area class represents any area for the purpose of
- * Constructive Area Geometry (CAG) manipulations. CAG manipulations
- * work as an area-wise form of boolean logic, where the basic operations are:
- * <P><li>Add (in boolean algebra: A <B>or</B> B)<BR>
- * <li>Subtract (in boolean algebra: A <B>and</B> (<B>not</B> B) )<BR>
- * <li>Intersect (in boolean algebra: A <B>and</B> B)<BR>
- * <li>Exclusive Or <BR>
- * <img src="doc-files/Area-1.png" width="342" height="302"
- * alt="Illustration of CAG operations" /><BR>
- * Above is an illustration of the CAG operations on two ring shapes.<P>
- *
- * The contains and intersects() methods are also more accurate than the
- * specification of #Shape requires.<P>
- *
- * Please note that constructing an Area can be slow
- * (Self-intersection resolving is proportional to the square of
- * the number of segments).<P>
- * @see #add(Area)
- * @see #subtract(Area)
- * @see #intersect(Area)
- * @see #exclusiveOr(Area)
- *
- * @author Sven de Marothy (sven@physto.se)
- *
- * @since 1.2
- * @status Works, but could be faster and more reliable.
- */
-public class Area implements Shape, Cloneable
-{
- /**
- * General numerical precision
- */
- private static final double EPSILON = 1E-11;
-
- /**
- * recursive subdivision epsilon - (see getRecursionDepth)
- */
- private static final double RS_EPSILON = 1E-13;
-
- /**
- * Snap distance - points within this distance are considered equal
- */
- private static final double PE_EPSILON = 1E-11;
-
- /**
- * Segment vectors containing solid areas and holes
- * This is package-private to avoid an accessor method.
- */
- Vector<Segment> solids;
-
- /**
- * Segment vectors containing solid areas and holes
- * This is package-private to avoid an accessor method.
- */
- Vector<Segment> holes;
-
- /**
- * Vector (temporary) storing curve-curve intersections
- */
- private Vector<double[]> ccIntersections;
-
- /**
- * Winding rule WIND_NON_ZERO used, after construction,
- * this is irrelevant.
- */
- private int windingRule;
-
- /**
- * Constructs an empty Area
- */
- public Area()
- {
- solids = new Vector<Segment>();
- holes = new Vector<Segment>();
- }
-
- /**
- * Constructs an Area from any given Shape. <P>
- *
- * If the Shape is self-intersecting, the created Area will consist
- * of non-self-intersecting subpaths, and any inner paths which
- * are found redundant in accordance with the Shape's winding rule
- * will not be included.
- *
- * @param s the shape (<code>null</code> not permitted).
- *
- * @throws NullPointerException if <code>s</code> is <code>null</code>.
- */
- public Area(Shape s)
- {
- this();
-
- Vector<Segment> p = makeSegment(s);
-
- // empty path
- if (p == null)
- return;
-
- // delete empty paths
- for (int i = 0; i < p.size(); i++)
- if (p.elementAt(i).getSignedArea() == 0.0)
- p.remove(i--);
-
- /*
- * Resolve self intersecting paths into non-intersecting
- * solids and holes.
- * Algorithm is as follows:
- * 1: Create nodes at all self intersections
- * 2: Put all segments into a list
- * 3: Grab a segment, follow it, change direction at each node,
- * removing segments from the list in the process
- * 4: Repeat (3) until no segments remain in the list
- * 5: Remove redundant paths and sort into solids and holes
- */
- Segment v;
-
- for (int i = 0; i < p.size(); i++)
- {
- Segment path = p.elementAt(i);
- createNodesSelf(path);
- }
-
- if (p.size() > 1)
- {
- for (int i = 0; i < p.size() - 1; i++)
- for (int j = i + 1; j < p.size(); j++)
- {
- Segment path1 = p.elementAt(i);
- Segment path2 = p.elementAt(j);
- createNodes(path1, path2);
- }
- }
-
- // we have intersecting points.
- Vector<Segment> segments = new Vector<Segment>();
-
- for (int i = 0; i < p.size(); i++)
- {
- Segment path = v = p.elementAt(i);
- do
- {
- segments.add(v);
- v = v.next;
- }
- while (v != path);
- }
-
- Vector<Segment> paths = weilerAtherton(segments);
- deleteRedundantPaths(paths);
- }
-
- /**
- * Performs an add (union) operation on this area with another Area.<BR>
- * @param area - the area to be unioned with this one
- */
- public void add(Area area)
- {
- if (equals(area))
- return;
- if (area.isEmpty())
- return;
-
- Area B = (Area) area.clone();
-
- Vector<Segment> pathA = new Vector<Segment>();
- Vector<Segment> pathB = new Vector<Segment>();
- pathA.addAll(solids);
- pathA.addAll(holes);
- pathB.addAll(B.solids);
- pathB.addAll(B.holes);
-
- for (int i = 0; i < pathA.size(); i++)
- {
- Segment a = pathA.elementAt(i);
- for (int j = 0; j < pathB.size(); j++)
- {
- Segment b = pathB.elementAt(j);
- createNodes(a, b);
- }
- }
-
- Vector<Segment> paths = new Vector<Segment>();
- Segment v;
-
- // we have intersecting points.
- Vector<Segment> segments = new Vector<Segment>();
-
- // In a union operation, we keep all
- // segments of A oustide B and all B outside A
- for (int i = 0; i < pathA.size(); i++)
- {
- v = pathA.elementAt(i);
- Segment path = v;
- do
- {
- if (v.isSegmentOutside(area))
- segments.add(v);
- v = v.next;
- }
- while (v != path);
- }
-
- for (int i = 0; i < pathB.size(); i++)
- {
- v = pathB.elementAt(i);
- Segment path = v;
- do
- {
- if (v.isSegmentOutside(this))
- segments.add(v);
- v = v.next;
- }
- while (v != path);
- }
-
- paths = weilerAtherton(segments);
- deleteRedundantPaths(paths);
- }
-
- /**
- * Performs a subtraction operation on this Area.<BR>
- * @param area the area to be subtracted from this area.
- * @throws NullPointerException if <code>area</code> is <code>null</code>.
- */
- public void subtract(Area area)
- {
- if (isEmpty() || area.isEmpty())
- return;
-
- if (equals(area))
- {
- reset();
- return;
- }
-
- Vector<Segment> pathA = new Vector<Segment>();
- Area B = (Area) area.clone();
- pathA.addAll(solids);
- pathA.addAll(holes);
-
- // reverse the directions of B paths.
- setDirection(B.holes, true);
- setDirection(B.solids, false);
-
- Vector<Segment> pathB = new Vector<Segment>();
- pathB.addAll(B.solids);
- pathB.addAll(B.holes);
-
- // create nodes
- for (int i = 0; i < pathA.size(); i++)
- {
- Segment a = pathA.elementAt(i);
- for (int j = 0; j < pathB.size(); j++)
- {
- Segment b = pathB.elementAt(j);
- createNodes(a, b);
- }
- }
-
- // we have intersecting points.
- Vector<Segment> segments = new Vector<Segment>();
-
- // In a subtraction operation, we keep all
- // segments of A oustide B and all B within A
- // We outsideness-test only one segment in each path
- // and the segments before and after any node
- for (int i = 0; i < pathA.size(); i++)
- {
- Segment v = pathA.elementAt(i);
- Segment path = v;
- if (v.isSegmentOutside(area) && v.node == null)
- segments.add(v);
- boolean node = false;
- do
- {
- if ((v.node != null || node))
- {
- node = (v.node != null);
- if (v.isSegmentOutside(area))
- segments.add(v);
- }
- v = v.next;
- }
- while (v != path);
- }
-
- for (int i = 0; i < pathB.size(); i++)
- {
- Segment v = (Segment) pathB.elementAt(i);
- Segment path = v;
- if (! v.isSegmentOutside(this) && v.node == null)
- segments.add(v);
- v = v.next;
- boolean node = false;
- do
- {
- if ((v.node != null || node))
- {
- node = (v.node != null);
- if (! v.isSegmentOutside(this))
- segments.add(v);
- }
- v = v.next;
- }
- while (v != path);
- }
-
- Vector<Segment> paths = weilerAtherton(segments);
- deleteRedundantPaths(paths);
- }
-
- /**
- * Performs an intersection operation on this Area.<BR>
- * @param area - the area to be intersected with this area.
- * @throws NullPointerException if <code>area</code> is <code>null</code>.
- */
- public void intersect(Area area)
- {
- if (isEmpty() || area.isEmpty())
- {
- reset();
- return;
- }
- if (equals(area))
- return;
-
- Vector<Segment> pathA = new Vector<Segment>();
- Area B = (Area) area.clone();
- pathA.addAll(solids);
- pathA.addAll(holes);
-
- Vector<Segment> pathB = new Vector<Segment>();
- pathB.addAll(B.solids);
- pathB.addAll(B.holes);
-
- // create nodes
- for (int i = 0; i < pathA.size(); i++)
- {
- Segment a = pathA.elementAt(i);
- for (int j = 0; j < pathB.size(); j++)
- {
- Segment b = pathB.elementAt(j);
- createNodes(a, b);
- }
- }
-
- // we have intersecting points.
- Vector<Segment> segments = new Vector<Segment>();
-
- // In an intersection operation, we keep all
- // segments of A within B and all B within A
- // (The rest must be redundant)
- // We outsideness-test only one segment in each path
- // and the segments before and after any node
- for (int i = 0; i < pathA.size(); i++)
- {
- Segment v = pathA.elementAt(i);
- Segment path = v;
- if (! v.isSegmentOutside(area) && v.node == null)
- segments.add(v);
- boolean node = false;
- do
- {
- if ((v.node != null || node))
- {
- node = (v.node != null);
- if (! v.isSegmentOutside(area))
- segments.add(v);
- }
- v = v.next;
- }
- while (v != path);
- }
-
- for (int i = 0; i < pathB.size(); i++)
- {
- Segment v = pathB.elementAt(i);
- Segment path = v;
- if (! v.isSegmentOutside(this) && v.node == null)
- segments.add(v);
- v = v.next;
- boolean node = false;
- do
- {
- if ((v.node != null || node))
- {
- node = (v.node != null);
- if (! v.isSegmentOutside(this))
- segments.add(v);
- }
- v = v.next;
- }
- while (v != path);
- }
-
- Vector<Segment> paths = weilerAtherton(segments);
- deleteRedundantPaths(paths);
- }
-
- /**
- * Performs an exclusive-or operation on this Area.<BR>
- * @param area - the area to be XORed with this area.
- * @throws NullPointerException if <code>area</code> is <code>null</code>.
- */
- public void exclusiveOr(Area area)
- {
- if (area.isEmpty())
- return;
-
- if (isEmpty())
- {
- Area B = (Area) area.clone();
- solids = B.solids;
- holes = B.holes;
- return;
- }
- if (equals(area))
- {
- reset();
- return;
- }
-
- Vector<Segment> pathA = new Vector<Segment>();
-
- Area B = (Area) area.clone();
- Vector<Segment> pathB = new Vector<Segment>();
- pathA.addAll(solids);
- pathA.addAll(holes);
-
- // reverse the directions of B paths.
- setDirection(B.holes, true);
- setDirection(B.solids, false);
- pathB.addAll(B.solids);
- pathB.addAll(B.holes);
-
- for (int i = 0; i < pathA.size(); i++)
- {
- Segment a = pathA.elementAt(i);
- for (int j = 0; j < pathB.size(); j++)
- {
- Segment b = pathB.elementAt(j);
- createNodes(a, b);
- }
- }
-
- Segment v;
-
- // we have intersecting points.
- Vector<Segment> segments = new Vector<Segment>();
-
- // In an XOR operation, we operate on all segments
- for (int i = 0; i < pathA.size(); i++)
- {
- v = pathA.elementAt(i);
- Segment path = v;
- do
- {
- segments.add(v);
- v = v.next;
- }
- while (v != path);
- }
-
- for (int i = 0; i < pathB.size(); i++)
- {
- v = pathB.elementAt(i);
- Segment path = v;
- do
- {
- segments.add(v);
- v = v.next;
- }
- while (v != path);
- }
-
- Vector<Segment> paths = weilerAtherton(segments);
- deleteRedundantPaths(paths);
- }
-
- /**
- * Clears the Area object, creating an empty area.
- */
- public void reset()
- {
- solids = new Vector<Segment>();
- holes = new Vector<Segment>();
- }
-
- /**
- * Returns whether this area encloses any area.
- * @return true if the object encloses any area.
- */
- public boolean isEmpty()
- {
- if (solids.size() == 0)
- return true;
-
- double totalArea = 0;
- for (int i = 0; i < solids.size(); i++)
- totalArea += Math.abs(solids.elementAt(i).getSignedArea());
- for (int i = 0; i < holes.size(); i++)
- totalArea -= Math.abs(holes.elementAt(i).getSignedArea());
- if (totalArea <= EPSILON)
- return true;
-
- return false;
- }
-
- /**
- * Determines whether the Area consists entirely of line segments
- * @return true if the Area lines-only, false otherwise
- */
- public boolean isPolygonal()
- {
- for (int i = 0; i < holes.size(); i++)
- if (!holes.elementAt(i).isPolygonal())
- return false;
- for (int i = 0; i < solids.size(); i++)
- if (!solids.elementAt(i).isPolygonal())
- return false;
- return true;
- }
-
- /**
- * Determines if the Area is rectangular.<P>
- *
- * This is strictly qualified. An area is considered rectangular if:<BR>
- * <li>It consists of a single polygonal path.<BR>
- * <li>It is oriented parallel/perpendicular to the xy axis<BR>
- * <li>It must be exactly rectangular, i.e. small errors induced by
- * transformations may cause a false result, although the area is
- * visibly rectangular.<P>
- * @return true if the above criteria are met, false otherwise
- */
- public boolean isRectangular()
- {
- if (isEmpty())
- return true;
-
- if (holes.size() != 0 || solids.size() != 1)
- return false;
-
- Segment path = solids.elementAt(0);
- if (! path.isPolygonal())
- return false;
-
- int nCorners = 0;
- Segment s = path;
- do
- {
- Segment s2 = s.next;
- double d1 = (s.P2.getX() - s.P1.getX())*(s2.P2.getX() - s2.P1.getX())/
- ((s.P1.distance(s.P2)) * (s2.P1.distance(s2.P2)));
- double d2 = (s.P2.getY() - s.P1.getY())*(s2.P2.getY() - s2.P1.getY())/
- ((s.P1.distance(s.P2)) * (s2.P1.distance(s2.P2)));
- double dotproduct = d1 + d2;
-
- // For some reason, only rectangles on the XY axis count.
- if (d1 != 0 && d2 != 0)
- return false;
-
- if (Math.abs(dotproduct) == 0) // 90 degree angle
- nCorners++;
- else if ((Math.abs(1.0 - dotproduct) > 0)) // 0 degree angle?
- return false; // if not, return false
-
- s = s.next;
- }
- while (s != path);
-
- return nCorners == 4;
- }
-
- /**
- * Returns whether the Area consists of more than one simple
- * (non self-intersecting) subpath.
- *
- * @return true if the Area consists of none or one simple subpath,
- * false otherwise.
- */
- public boolean isSingular()
- {
- return (holes.size() == 0 && solids.size() <= 1);
- }
-
- /**
- * Returns the bounding box of the Area.<P> Unlike the CubicCurve2D and
- * QuadraticCurve2D classes, this method will return the tightest possible
- * bounding box, evaluating the extreme points of each curved segment.<P>
- * @return the bounding box
- */
- public Rectangle2D getBounds2D()
- {
- if (solids.size() == 0)
- return new Rectangle2D.Double(0.0, 0.0, 0.0, 0.0);
-
- double xmin;
- double xmax;
- double ymin;
- double ymax;
- xmin = xmax = solids.elementAt(0).P1.getX();
- ymin = ymax = solids.elementAt(0).P1.getY();
-
- for (int path = 0; path < solids.size(); path++)
- {
- Rectangle2D r = solids.elementAt(path).getPathBounds();
- xmin = Math.min(r.getMinX(), xmin);
- ymin = Math.min(r.getMinY(), ymin);
- xmax = Math.max(r.getMaxX(), xmax);
- ymax = Math.max(r.getMaxY(), ymax);
- }
-
- return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
- }
-
- /**
- * Returns the bounds of this object in Rectangle format.
- * Please note that this may lead to loss of precision.
- *
- * @return The bounds.
- * @see #getBounds2D()
- */
- public Rectangle getBounds()
- {
- return getBounds2D().getBounds();
- }
-
- /**
- * Create a new area of the same run-time type with the same contents as
- * this one.
- *
- * @return the clone
- */
- public Object clone()
- {
- try
- {
- Area clone = new Area();
- for (int i = 0; i < solids.size(); i++)
- clone.solids.add(solids.elementAt(i).cloneSegmentList());
- for (int i = 0; i < holes.size(); i++)
- clone.holes.add(holes.elementAt(i).cloneSegmentList());
- return clone;
- }
- catch (CloneNotSupportedException e)
- {
- throw (Error) new InternalError().initCause(e); // Impossible
- }
- }
-
- /**
- * Compares two Areas.
- *
- * @param area the area to compare against this area (<code>null</code>
- * permitted).
- * @return <code>true</code> if the areas are equal, and <code>false</code>
- * otherwise.
- */
- public boolean equals(Area area)
- {
- if (area == null)
- return false;
-
- if (! getBounds2D().equals(area.getBounds2D()))
- return false;
-
- if (solids.size() != area.solids.size()
- || holes.size() != area.holes.size())
- return false;
-
- Vector<Segment> pathA = new Vector<Segment>();
- pathA.addAll(solids);
- pathA.addAll(holes);
- Vector<Segment> pathB = new Vector<Segment>();
- pathB.addAll(area.solids);
- pathB.addAll(area.holes);
-
- int nPaths = pathA.size();
- boolean[][] match = new boolean[2][nPaths];
-
- for (int i = 0; i < nPaths; i++)
- {
- for (int j = 0; j < nPaths; j++)
- {
- Segment p1 = pathA.elementAt(i);
- Segment p2 = pathB.elementAt(j);
- if (! match[0][i] && ! match[1][j])
- if (p1.pathEquals(p2))
- match[0][i] = match[1][j] = true;
- }
- }
-
- boolean result = true;
- for (int i = 0; i < nPaths; i++)
- result = result && match[0][i] && match[1][i];
- return result;
- }
-
- /**
- * Transforms this area by the AffineTransform at.
- *
- * @param at the transform.
- */
- public void transform(AffineTransform at)
- {
- for (int i = 0; i < solids.size(); i++)
- solids.elementAt(i).transformSegmentList(at);
- for (int i = 0; i < holes.size(); i++)
- holes.elementAt(i).transformSegmentList(at);
-
- // Note that the orientation is not invariant under inversion
- if ((at.getType() & AffineTransform.TYPE_FLIP) != 0)
- {
- setDirection(holes, false);
- setDirection(solids, true);
- }
- }
-
- /**
- * Returns a new Area equal to this one, transformed
- * by the AffineTransform at.
- * @param at the transform.
- * @return the transformed area
- * @throws NullPointerException if <code>at</code> is <code>null</code>.
- */
- public Area createTransformedArea(AffineTransform at)
- {
- Area a = (Area) clone();
- a.transform(at);
- return a;
- }
-
- /**
- * Determines if the point (x,y) is contained within this Area.
- *
- * @param x the x-coordinate of the point.
- * @param y the y-coordinate of the point.
- * @return true if the point is contained, false otherwise.
- */
- public boolean contains(double x, double y)
- {
- int n = 0;
- for (int i = 0; i < solids.size(); i++)
- if (solids.elementAt(i).contains(x, y))
- n++;
-
- for (int i = 0; i < holes.size(); i++)
- if (holes.elementAt(i).contains(x, y))
- n--;
-
- return (n != 0);
- }
-
- /**
- * Determines if the Point2D p is contained within this Area.
- *
- * @param p the point.
- * @return <code>true</code> if the point is contained, <code>false</code>
- * otherwise.
- * @throws NullPointerException if <code>p</code> is <code>null</code>.
- */
- public boolean contains(Point2D p)
- {
- return contains(p.getX(), p.getY());
- }
-
- /**
- * Determines if the rectangle specified by (x,y) as the upper-left
- * and with width w and height h is completely contained within this Area,
- * returns false otherwise.<P>
- *
- * This method should always produce the correct results, unlike for other
- * classes in geom.
- *
- * @param x the x-coordinate of the rectangle.
- * @param y the y-coordinate of the rectangle.
- * @param w the width of the the rectangle.
- * @param h the height of the rectangle.
- * @return <code>true</code> if the rectangle is considered contained
- */
- public boolean contains(double x, double y, double w, double h)
- {
- LineSegment[] l = new LineSegment[4];
- l[0] = new LineSegment(x, y, x + w, y);
- l[1] = new LineSegment(x, y + h, x + w, y + h);
- l[2] = new LineSegment(x, y, x, y + h);
- l[3] = new LineSegment(x + w, y, x + w, y + h);
-
- // Since every segment in the area must a contour
- // between inside/outside segments, ANY intersection
- // will mean the rectangle is not entirely contained.
- for (int i = 0; i < 4; i++)
- {
- for (int path = 0; path < solids.size(); path++)
- {
- Segment v;
- Segment start;
- start = v = solids.elementAt(path);
- do
- {
- if (l[i].hasIntersections(v))
- return false;
- v = v.next;
- }
- while (v != start);
- }
- for (int path = 0; path < holes.size(); path++)
- {
- Segment v;
- Segment start;
- start = v = holes.elementAt(path);
- do
- {
- if (l[i].hasIntersections(v))
- return false;
- v = v.next;
- }
- while (v != start);
- }
- }
-
- // Is any point inside?
- if (! contains(x, y))
- return false;
-
- // Final hoop: Is the rectangle non-intersecting and inside,
- // but encloses a hole?
- Rectangle2D r = new Rectangle2D.Double(x, y, w, h);
- for (int path = 0; path < holes.size(); path++)
- if (! holes.elementAt(path).isSegmentOutside(r))
- return false;
-
- return true;
- }
-
- /**
- * Determines if the Rectangle2D specified by r is completely contained
- * within this Area, returns false otherwise.<P>
- *
- * This method should always produce the correct results, unlike for other
- * classes in geom.
- *
- * @param r the rectangle.
- * @return <code>true</code> if the rectangle is considered contained
- *
- * @throws NullPointerException if <code>r</code> is <code>null</code>.
- */
- public boolean contains(Rectangle2D r)
- {
- return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Determines if the rectangle specified by (x,y) as the upper-left
- * and with width w and height h intersects any part of this Area.
- *
- * @param x the x-coordinate for the rectangle.
- * @param y the y-coordinate for the rectangle.
- * @param w the width of the rectangle.
- * @param h the height of the rectangle.
- * @return <code>true</code> if the rectangle intersects the area,
- * <code>false</code> otherwise.
- */
- public boolean intersects(double x, double y, double w, double h)
- {
- if (solids.size() == 0)
- return false;
-
- LineSegment[] l = new LineSegment[4];
- l[0] = new LineSegment(x, y, x + w, y);
- l[1] = new LineSegment(x, y + h, x + w, y + h);
- l[2] = new LineSegment(x, y, x, y + h);
- l[3] = new LineSegment(x + w, y, x + w, y + h);
-
- // Return true on any intersection
- for (int i = 0; i < 4; i++)
- {
- for (int path = 0; path < solids.size(); path++)
- {
- Segment v;
- Segment start;
- start = v = solids.elementAt(path);
- do
- {
- if (l[i].hasIntersections(v))
- return true;
- v = v.next;
- }
- while (v != start);
- }
- for (int path = 0; path < holes.size(); path++)
- {
- Segment v;
- Segment start;
- start = v = holes.elementAt(path);
- do
- {
- if (l[i].hasIntersections(v))
- return true;
- v = v.next;
- }
- while (v != start);
- }
- }
-
- // Non-intersecting, Is any point inside?
- if (contains(x + w * 0.5, y + h * 0.5))
- return true;
-
- // What if the rectangle encloses the whole shape?
- Point2D p = solids.elementAt(0).getMidPoint();
- if ((new Rectangle2D.Double(x, y, w, h)).contains(p))
- return true;
- return false;
- }
-
- /**
- * Determines if the Rectangle2D specified by r intersects any
- * part of this Area.
- * @param r the rectangle to test intersection with (<code>null</code>
- * not permitted).
- * @return <code>true</code> if the rectangle intersects the area,
- * <code>false</code> otherwise.
- * @throws NullPointerException if <code>r</code> is <code>null</code>.
- */
- public boolean intersects(Rectangle2D r)
- {
- return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Returns a PathIterator object defining the contour of this Area,
- * transformed by at.
- *
- * @param at the transform.
- * @return A path iterator.
- */
- public PathIterator getPathIterator(AffineTransform at)
- {
- return (new AreaIterator(at));
- }
-
- /**
- * Returns a flattened PathIterator object defining the contour of this
- * Area, transformed by at and with a defined flatness.
- *
- * @param at the transform.
- * @param flatness the flatness.
- * @return A path iterator.
- */
- public PathIterator getPathIterator(AffineTransform at, double flatness)
- {
- return new FlatteningPathIterator(getPathIterator(at), flatness);
- }
-
- //---------------------------------------------------------------------
- // Non-public methods and classes
-
- /**
- * Private pathiterator object.
- */
- private class AreaIterator implements PathIterator
- {
- private Vector<IteratorSegment> segments;
- private int index;
- private AffineTransform at;
-
- // Simple compound type for segments
- class IteratorSegment
- {
- int type;
- double[] coords;
-
- IteratorSegment()
- {
- coords = new double[6];
- }
- }
-
- /**
- * The contructor here does most of the work,
- * creates a vector of IteratorSegments, which can
- * readily be returned
- */
- public AreaIterator(AffineTransform at)
- {
- this.at = at;
- index = 0;
- segments = new Vector<IteratorSegment>();
- Vector<Segment> allpaths = new Vector<Segment>();
- allpaths.addAll(solids);
- allpaths.addAll(holes);
-
- for (int i = 0; i < allpaths.size(); i++)
- {
- Segment v = allpaths.elementAt(i);
- Segment start = v;
-
- IteratorSegment is = new IteratorSegment();
- is.type = SEG_MOVETO;
- is.coords[0] = start.P1.getX();
- is.coords[1] = start.P1.getY();
- segments.add(is);
-
- do
- {
- is = new IteratorSegment();
- is.type = v.pathIteratorFormat(is.coords);
- segments.add(is);
- v = v.next;
- }
- while (v != start);
-
- is = new IteratorSegment();
- is.type = SEG_CLOSE;
- segments.add(is);
- }
- }
-
- public int currentSegment(double[] coords)
- {
- IteratorSegment s = segments.elementAt(index);
- if (at != null)
- at.transform(s.coords, 0, coords, 0, 3);
- else
- for (int i = 0; i < 6; i++)
- coords[i] = s.coords[i];
- return (s.type);
- }
-
- public int currentSegment(float[] coords)
- {
- IteratorSegment s = segments.elementAt(index);
- double[] d = new double[6];
- if (at != null)
- {
- at.transform(s.coords, 0, d, 0, 3);
- for (int i = 0; i < 6; i++)
- coords[i] = (float) d[i];
- }
- else
- for (int i = 0; i < 6; i++)
- coords[i] = (float) s.coords[i];
- return (s.type);
- }
-
- // Note that the winding rule should not matter here,
- // EVEN_ODD is chosen because it renders faster.
- public int getWindingRule()
- {
- return (PathIterator.WIND_EVEN_ODD);
- }
-
- public boolean isDone()
- {
- return (index >= segments.size());
- }
-
- public void next()
- {
- index++;
- }
- }
-
- /**
- * Performs the fundamental task of the Weiler-Atherton algorithm,
- * traverse a list of segments, for each segment:
- * Follow it, removing segments from the list and switching paths
- * at each node. Do so until the starting segment is reached.
- *
- * Returns a Vector of the resulting paths.
- */
- private Vector<Segment> weilerAtherton(Vector<Segment> segments)
- {
- Vector<Segment> paths = new Vector<Segment>();
- while (segments.size() > 0)
- {
- // Iterate over the path
- Segment start = segments.elementAt(0);
- Segment s = start;
- do
- {
- segments.remove(s);
- if (s.node != null)
- { // switch over
- s.next = s.node;
- s.node = null;
- }
- s = s.next; // continue
- }
- while (s != start);
-
- paths.add(start);
- }
- return paths;
- }
-
- /**
- * A small wrapper class to store intersection points
- */
- private class Intersection
- {
- Point2D p; // the 2D point of intersection
- double ta; // the parametric value on a
- double tb; // the parametric value on b
- Segment seg; // segment placeholder for node setting
-
- public Intersection(Point2D p, double ta, double tb)
- {
- this.p = p;
- this.ta = ta;
- this.tb = tb;
- }
- }
-
- /**
- * Returns the recursion depth necessary to approximate the
- * curve by line segments within the error RS_EPSILON.
- *
- * This is done with Wang's formula:
- * L0 = max{0<=i<=N-2}(|xi - 2xi+1 + xi+2|,|yi - 2yi+1 + yi+2|)
- * r0 = log4(sqrt(2)*N*(N-1)*L0/8e)
- * Where e is the maximum distance error (RS_EPSILON)
- */
- private int getRecursionDepth(CubicSegment curve)
- {
- double x0 = curve.P1.getX();
- double y0 = curve.P1.getY();
-
- double x1 = curve.cp1.getX();
- double y1 = curve.cp1.getY();
-
- double x2 = curve.cp2.getX();
- double y2 = curve.cp2.getY();
-
- double x3 = curve.P2.getX();
- double y3 = curve.P2.getY();
-
- double L0 = Math.max(Math.max(Math.abs(x0 - 2 * x1 + x2),
- Math.abs(x1 - 2 * x2 + x3)),
- Math.max(Math.abs(y0 - 2 * y1 + y2),
- Math.abs(y1 - 2 * y2 + y3)));
-
- double f = Math.sqrt(2) * 6.0 * L0 / (8.0 * RS_EPSILON);
-
- int r0 = (int) Math.ceil(Math.log(f) / Math.log(4.0));
- return (r0);
- }
-
- /**
- * Performs recursive subdivision:
- * @param c1 - curve 1
- * @param c2 - curve 2
- * @param depth1 - recursion depth of curve 1
- * @param depth2 - recursion depth of curve 2
- * @param t1 - global parametric value of the first curve's starting point
- * @param t2 - global parametric value of the second curve's starting point
- * @param w1 - global parametric length of curve 1
- * @param w2 - global parametric length of curve 2
- *
- * The final four parameters are for keeping track of the parametric
- * value of the curve. For a full curve t = 0, w = 1, w is halved with
- * each subdivision.
- */
- private void recursiveSubdivide(CubicCurve2D c1, CubicCurve2D c2,
- int depth1, int depth2, double t1,
- double t2, double w1, double w2)
- {
- boolean flat1 = depth1 <= 0;
- boolean flat2 = depth2 <= 0;
-
- if (flat1 && flat2)
- {
- double xlk = c1.getP2().getX() - c1.getP1().getX();
- double ylk = c1.getP2().getY() - c1.getP1().getY();
-
- double xnm = c2.getP2().getX() - c2.getP1().getX();
- double ynm = c2.getP2().getY() - c2.getP1().getY();
-
- double xmk = c2.getP1().getX() - c1.getP1().getX();
- double ymk = c2.getP1().getY() - c1.getP1().getY();
- double det = xnm * ylk - ynm * xlk;
-
- if (det + 1.0 == 1.0)
- return;
-
- double detinv = 1.0 / det;
- double s = (xnm * ymk - ynm * xmk) * detinv;
- double t = (xlk * ymk - ylk * xmk) * detinv;
- if ((s < 0.0) || (s > 1.0) || (t < 0.0) || (t > 1.0))
- return;
-
- double[] temp = new double[2];
- temp[0] = t1 + s * w1;
- temp[1] = t2 + t * w1;
- ccIntersections.add(temp);
- return;
- }
-
- CubicCurve2D.Double c11 = new CubicCurve2D.Double();
- CubicCurve2D.Double c12 = new CubicCurve2D.Double();
- CubicCurve2D.Double c21 = new CubicCurve2D.Double();
- CubicCurve2D.Double c22 = new CubicCurve2D.Double();
-
- if (! flat1 && ! flat2)
- {
- depth1--;
- depth2--;
- w1 = w1 * 0.5;
- w2 = w2 * 0.5;
- c1.subdivide(c11, c12);
- c2.subdivide(c21, c22);
- if (c11.getBounds2D().intersects(c21.getBounds2D()))
- recursiveSubdivide(c11, c21, depth1, depth2, t1, t2, w1, w2);
- if (c11.getBounds2D().intersects(c22.getBounds2D()))
- recursiveSubdivide(c11, c22, depth1, depth2, t1, t2 + w2, w1, w2);
- if (c12.getBounds2D().intersects(c21.getBounds2D()))
- recursiveSubdivide(c12, c21, depth1, depth2, t1 + w1, t2, w1, w2);
- if (c12.getBounds2D().intersects(c22.getBounds2D()))
- recursiveSubdivide(c12, c22, depth1, depth2, t1 + w1, t2 + w2, w1, w2);
- return;
- }
-
- if (! flat1)
- {
- depth1--;
- c1.subdivide(c11, c12);
- w1 = w1 * 0.5;
- if (c11.getBounds2D().intersects(c2.getBounds2D()))
- recursiveSubdivide(c11, c2, depth1, depth2, t1, t2, w1, w2);
- if (c12.getBounds2D().intersects(c2.getBounds2D()))
- recursiveSubdivide(c12, c2, depth1, depth2, t1 + w1, t2, w1, w2);
- return;
- }
-
- depth2--;
- c2.subdivide(c21, c22);
- w2 = w2 * 0.5;
- if (c1.getBounds2D().intersects(c21.getBounds2D()))
- recursiveSubdivide(c1, c21, depth1, depth2, t1, t2, w1, w2);
- if (c1.getBounds2D().intersects(c22.getBounds2D()))
- recursiveSubdivide(c1, c22, depth1, depth2, t1, t2 + w2, w1, w2);
- }
-
- /**
- * Returns a set of interesections between two Cubic segments
- * Or null if no intersections were found.
- *
- * The method used to find the intersection is recursive midpoint
- * subdivision. Outline description:
- *
- * 1) Check if the bounding boxes of the curves intersect,
- * 2) If so, divide the curves in the middle and test the bounding
- * boxes again,
- * 3) Repeat until a maximum recursion depth has been reached, where
- * the intersecting curves can be approximated by line segments.
- *
- * This is a reasonably accurate method, although the recursion depth
- * is typically around 20, the bounding-box tests allow for significant
- * pruning of the subdivision tree.
- *
- * This is package-private to avoid an accessor method.
- */
- Intersection[] cubicCubicIntersect(CubicSegment curve1, CubicSegment curve2)
- {
- Rectangle2D r1 = curve1.getBounds();
- Rectangle2D r2 = curve2.getBounds();
-
- if (! r1.intersects(r2))
- return null;
-
- ccIntersections = new Vector<double[]>();
- recursiveSubdivide(curve1.getCubicCurve2D(), curve2.getCubicCurve2D(),
- getRecursionDepth(curve1), getRecursionDepth(curve2),
- 0.0, 0.0, 1.0, 1.0);
-
- if (ccIntersections.size() == 0)
- return null;
-
- Intersection[] results = new Intersection[ccIntersections.size()];
- for (int i = 0; i < ccIntersections.size(); i++)
- {
- double[] temp = ccIntersections.elementAt(i);
- results[i] = new Intersection(curve1.evaluatePoint(temp[0]), temp[0],
- temp[1]);
- }
- ccIntersections = null;
- return (results);
- }
-
- /**
- * Returns the intersections between a line and a quadratic bezier
- * Or null if no intersections are found.
- * This is done through combining the line's equation with the
- * parametric form of the Bezier and solving the resulting quadratic.
- * This is package-private to avoid an accessor method.
- */
- Intersection[] lineQuadIntersect(LineSegment l, QuadSegment c)
- {
- double[] y = new double[3];
- double[] x = new double[3];
- double[] r = new double[3];
- int nRoots;
- double x0 = c.P1.getX();
- double y0 = c.P1.getY();
- double x1 = c.cp.getX();
- double y1 = c.cp.getY();
- double x2 = c.P2.getX();
- double y2 = c.P2.getY();
-
- double lx0 = l.P1.getX();
- double ly0 = l.P1.getY();
- double lx1 = l.P2.getX();
- double ly1 = l.P2.getY();
- double dx = lx1 - lx0;
- double dy = ly1 - ly0;
-
- // form r(t) = y(t) - x(t) for the bezier
- y[0] = y0;
- y[1] = 2 * (y1 - y0);
- y[2] = (y2 - 2 * y1 + y0);
-
- x[0] = x0;
- x[1] = 2 * (x1 - x0);
- x[2] = (x2 - 2 * x1 + x0);
-
- // a point, not a line
- if (dy == 0 && dx == 0)
- return null;
-
- // line on y axis
- if (dx == 0 || (dy / dx) > 1.0)
- {
- double k = dx / dy;
- x[0] -= lx0;
- y[0] -= ly0;
- y[0] *= k;
- y[1] *= k;
- y[2] *= k;
- }
- else
- {
- double k = dy / dx;
- x[0] -= lx0;
- y[0] -= ly0;
- x[0] *= k;
- x[1] *= k;
- x[2] *= k;
- }
-
- for (int i = 0; i < 3; i++)
- r[i] = y[i] - x[i];
-
- if ((nRoots = QuadCurve2D.solveQuadratic(r)) > 0)
- {
- Intersection[] temp = new Intersection[nRoots];
- int intersections = 0;
- for (int i = 0; i < nRoots; i++)
- {
- double t = r[i];
- if (t >= 0.0 && t <= 1.0)
- {
- Point2D p = c.evaluatePoint(t);
-
- // if the line is on an axis, snap the point to that axis.
- if (dx == 0)
- p.setLocation(lx0, p.getY());
- if (dy == 0)
- p.setLocation(p.getX(), ly0);
-
- if (p.getX() <= Math.max(lx0, lx1)
- && p.getX() >= Math.min(lx0, lx1)
- && p.getY() <= Math.max(ly0, ly1)
- && p.getY() >= Math.min(ly0, ly1))
- {
- double lineparameter = p.distance(l.P1) / l.P2.distance(l.P1);
- temp[i] = new Intersection(p, lineparameter, t);
- intersections++;
- }
- }
- else
- temp[i] = null;
- }
- if (intersections == 0)
- return null;
-
- Intersection[] rValues = new Intersection[intersections];
-
- for (int i = 0; i < nRoots; i++)
- if (temp[i] != null)
- rValues[--intersections] = temp[i];
- return (rValues);
- }
- return null;
- }
-
- /**
- * Returns the intersections between a line and a cubic segment
- * This is done through combining the line's equation with the
- * parametric form of the Bezier and solving the resulting quadratic.
- * This is package-private to avoid an accessor method.
- */
- Intersection[] lineCubicIntersect(LineSegment l, CubicSegment c)
- {
- double[] y = new double[4];
- double[] x = new double[4];
- double[] r = new double[4];
- int nRoots;
- double x0 = c.P1.getX();
- double y0 = c.P1.getY();
- double x1 = c.cp1.getX();
- double y1 = c.cp1.getY();
- double x2 = c.cp2.getX();
- double y2 = c.cp2.getY();
- double x3 = c.P2.getX();
- double y3 = c.P2.getY();
-
- double lx0 = l.P1.getX();
- double ly0 = l.P1.getY();
- double lx1 = l.P2.getX();
- double ly1 = l.P2.getY();
- double dx = lx1 - lx0;
- double dy = ly1 - ly0;
-
- // form r(t) = y(t) - x(t) for the bezier
- y[0] = y0;
- y[1] = 3 * (y1 - y0);
- y[2] = 3 * (y2 + y0 - 2 * y1);
- y[3] = y3 - 3 * y2 + 3 * y1 - y0;
-
- x[0] = x0;
- x[1] = 3 * (x1 - x0);
- x[2] = 3 * (x2 + x0 - 2 * x1);
- x[3] = x3 - 3 * x2 + 3 * x1 - x0;
-
- // a point, not a line
- if (dy == 0 && dx == 0)
- return null;
-
- // line on y axis
- if (dx == 0 || (dy / dx) > 1.0)
- {
- double k = dx / dy;
- x[0] -= lx0;
- y[0] -= ly0;
- y[0] *= k;
- y[1] *= k;
- y[2] *= k;
- y[3] *= k;
- }
- else
- {
- double k = dy / dx;
- x[0] -= lx0;
- y[0] -= ly0;
- x[0] *= k;
- x[1] *= k;
- x[2] *= k;
- x[3] *= k;
- }
- for (int i = 0; i < 4; i++)
- r[i] = y[i] - x[i];
-
- if ((nRoots = CubicCurve2D.solveCubic(r)) > 0)
- {
- Intersection[] temp = new Intersection[nRoots];
- int intersections = 0;
- for (int i = 0; i < nRoots; i++)
- {
- double t = r[i];
- if (t >= 0.0 && t <= 1.0)
- {
- // if the line is on an axis, snap the point to that axis.
- Point2D p = c.evaluatePoint(t);
- if (dx == 0)
- p.setLocation(lx0, p.getY());
- if (dy == 0)
- p.setLocation(p.getX(), ly0);
-
- if (p.getX() <= Math.max(lx0, lx1)
- && p.getX() >= Math.min(lx0, lx1)
- && p.getY() <= Math.max(ly0, ly1)
- && p.getY() >= Math.min(ly0, ly1))
- {
- double lineparameter = p.distance(l.P1) / l.P2.distance(l.P1);
- temp[i] = new Intersection(p, lineparameter, t);
- intersections++;
- }
- }
- else
- temp[i] = null;
- }
-
- if (intersections == 0)
- return null;
-
- Intersection[] rValues = new Intersection[intersections];
- for (int i = 0; i < nRoots; i++)
- if (temp[i] != null)
- rValues[--intersections] = temp[i];
- return (rValues);
- }
- return null;
- }
-
- /**
- * Returns the intersection between two lines, or null if there is no
- * intersection.
- * This is package-private to avoid an accessor method.
- */
- Intersection linesIntersect(LineSegment a, LineSegment b)
- {
- Point2D P1 = a.P1;
- Point2D P2 = a.P2;
- Point2D P3 = b.P1;
- Point2D P4 = b.P2;
-
- if (! Line2D.linesIntersect(P1.getX(), P1.getY(), P2.getX(), P2.getY(),
- P3.getX(), P3.getY(), P4.getX(), P4.getY()))
- return null;
-
- double x1 = P1.getX();
- double y1 = P1.getY();
- double rx = P2.getX() - x1;
- double ry = P2.getY() - y1;
-
- double x2 = P3.getX();
- double y2 = P3.getY();
- double sx = P4.getX() - x2;
- double sy = P4.getY() - y2;
-
- double determinant = sx * ry - sy * rx;
- double nom = (sx * (y2 - y1) + sy * (x1 - x2));
-
- // Parallel lines don't intersect. At least we pretend they don't.
- if (Math.abs(determinant) < EPSILON)
- return null;
-
- nom = nom / determinant;
-
- if (nom == 0.0)
- return null;
- if (nom == 1.0)
- return null;
-
- Point2D p = new Point2D.Double(x1 + nom * rx, y1 + nom * ry);
-
- return new Intersection(p, p.distance(P1) / P1.distance(P2),
- p.distance(P3) / P3.distance(P4));
- }
-
- /**
- * Determines if two points are equal, within an error margin
- * 'snap distance'
- * This is package-private to avoid an accessor method.
- */
- boolean pointEquals(Point2D a, Point2D b)
- {
- return (a.equals(b) || a.distance(b) < PE_EPSILON);
- }
-
- /**
- * Helper method
- * Turns a shape into a Vector of Segments
- */
- private Vector<Segment> makeSegment(Shape s)
- {
- Vector<Segment> paths = new Vector<Segment>();
- PathIterator pi = s.getPathIterator(null);
- double[] coords = new double[6];
- Segment subpath = null;
- Segment current = null;
- double cx;
- double cy;
- double subpathx;
- double subpathy;
- cx = cy = subpathx = subpathy = 0.0;
-
- this.windingRule = pi.getWindingRule();
-
- while (! pi.isDone())
- {
- Segment v;
- switch (pi.currentSegment(coords))
- {
- case PathIterator.SEG_MOVETO:
- if (subpath != null)
- { // close existing open path
- current.next = new LineSegment(cx, cy, subpathx, subpathy);
- current = current.next;
- current.next = subpath;
- }
- subpath = null;
- subpathx = cx = coords[0];
- subpathy = cy = coords[1];
- break;
-
- // replace 'close' with a line-to.
- case PathIterator.SEG_CLOSE:
- if (subpath != null && (subpathx != cx || subpathy != cy))
- {
- current.next = new LineSegment(cx, cy, subpathx, subpathy);
- current = current.next;
- current.next = subpath;
- cx = subpathx;
- cy = subpathy;
- subpath = null;
- }
- else if (subpath != null)
- {
- current.next = subpath;
- subpath = null;
- }
- break;
- case PathIterator.SEG_LINETO:
- if (cx != coords[0] || cy != coords[1])
- {
- v = new LineSegment(cx, cy, coords[0], coords[1]);
- if (subpath == null)
- {
- subpath = current = v;
- paths.add(subpath);
- }
- else
- {
- current.next = v;
- current = current.next;
- }
- cx = coords[0];
- cy = coords[1];
- }
- break;
- case PathIterator.SEG_QUADTO:
- v = new QuadSegment(cx, cy, coords[0], coords[1], coords[2],
- coords[3]);
- if (subpath == null)
- {
- subpath = current = v;
- paths.add(subpath);
- }
- else
- {
- current.next = v;
- current = current.next;
- }
- cx = coords[2];
- cy = coords[3];
- break;
- case PathIterator.SEG_CUBICTO:
- v = new CubicSegment(cx, cy, coords[0], coords[1], coords[2],
- coords[3], coords[4], coords[5]);
- if (subpath == null)
- {
- subpath = current = v;
- paths.add(subpath);
- }
- else
- {
- current.next = v;
- current = current.next;
- }
-
- // check if the cubic is self-intersecting
- double[] lpts = ((CubicSegment) v).getLoop();
- if (lpts != null)
- {
- // if it is, break off the loop into its own path.
- v.subdivideInsert(lpts[0]);
- v.next.subdivideInsert((lpts[1] - lpts[0]) / (1.0 - lpts[0]));
-
- CubicSegment loop = (CubicSegment) v.next;
- v.next = loop.next;
- loop.next = loop;
-
- v.P2 = v.next.P1 = loop.P2 = loop.P1; // snap points
- paths.add(loop);
- current = v.next;
- }
-
- cx = coords[4];
- cy = coords[5];
- break;
- }
- pi.next();
- }
-
- if (subpath != null)
- { // close any open path
- if (subpathx != cx || subpathy != cy)
- {
- current.next = new LineSegment(cx, cy, subpathx, subpathy);
- current = current.next;
- current.next = subpath;
- }
- else
- current.next = subpath;
- }
-
- if (paths.size() == 0)
- return (null);
-
- return (paths);
- }
-
- /**
- * Find the intersections of two separate closed paths,
- * A and B, split the segments at the intersection points,
- * and create nodes pointing from one to the other
- */
- private int createNodes(Segment A, Segment B)
- {
- int nNodes = 0;
-
- Segment a = A;
- Segment b = B;
-
- do
- {
- do
- {
- nNodes += a.splitIntersections(b);
- b = b.next;
- }
- while (b != B);
-
- a = a.next; // move to the next segment
- }
- while (a != A); // until one wrap.
-
- return nNodes;
- }
-
- /**
- * Find the intersections of a path with itself.
- * Splits the segments at the intersection points,
- * and create nodes pointing from one to the other.
- */
- private int createNodesSelf(Segment A)
- {
- int nNodes = 0;
- Segment a = A;
-
- if (A.next == A)
- return 0;
-
- do
- {
- Segment b = a.next;
- do
- {
- if (b != a) // necessary
- nNodes += a.splitIntersections(b);
- b = b.next;
- }
- while (b != A);
- a = a.next; // move to the next segment
- }
- while (a != A); // until one wrap.
-
- return (nNodes);
- }
-
- /**
- * Deletes paths which are redundant from a list, (i.e. solid areas within
- * solid areas) Clears any nodes. Sorts the remaining paths into solids
- * and holes, sets their orientation and sets the solids and holes lists.
- */
- private void deleteRedundantPaths(Vector<Segment> paths)
- {
- int npaths = paths.size();
-
- int[][] contains = new int[npaths][npaths];
- int[][] windingNumbers = new int[npaths][2];
- int neg;
- Rectangle2D[] bb = new Rectangle2D[npaths]; // path bounding boxes
-
- neg = ((windingRule == PathIterator.WIND_NON_ZERO) ? -1 : 1);
-
- for (int i = 0; i < npaths; i++)
- bb[i] = paths.elementAt(i).getPathBounds();
-
- // Find which path contains which, assign winding numbers
- for (int i = 0; i < npaths; i++)
- {
- Segment pathA = paths.elementAt(i);
- pathA.nullNodes(); // remove any now-redundant nodes, in case.
- int windingA = pathA.hasClockwiseOrientation() ? 1 : neg;
-
- for (int j = 0; j < npaths; j++)
- if (i != j)
- {
- Segment pathB = paths.elementAt(j);
-
- // A contains B
- if (bb[i].intersects(bb[j]))
- {
- Segment s = pathB.next;
- while (s.P1.getY() == s.P2.getY() && s != pathB)
- s = s.next;
- Point2D p = s.getMidPoint();
- if (pathA.contains(p.getX(), p.getY()))
- contains[i][j] = windingA;
- }
- else
- // A does not contain B
- contains[i][j] = 0;
- }
- else
- contains[i][j] = windingA; // i == j
- }
-
- for (int i = 0; i < npaths; i++)
- {
- windingNumbers[i][0] = 0;
- for (int j = 0; j < npaths; j++)
- windingNumbers[i][0] += contains[j][i];
- windingNumbers[i][1] = contains[i][i];
- }
-
- Vector<Segment> solids = new Vector<Segment>();
- Vector<Segment> holes = new Vector<Segment>();
-
- if (windingRule == PathIterator.WIND_NON_ZERO)
- {
- for (int i = 0; i < npaths; i++)
- {
- if (windingNumbers[i][0] == 0)
- holes.add(paths.elementAt(i));
- else if (windingNumbers[i][0] - windingNumbers[i][1] == 0
- && Math.abs(windingNumbers[i][0]) == 1)
- solids.add(paths.elementAt(i));
- }
- }
- else
- {
- windingRule = PathIterator.WIND_NON_ZERO;
- for (int i = 0; i < npaths; i++)
- {
- if ((windingNumbers[i][0] & 1) == 0)
- holes.add(paths.elementAt(i));
- else if ((windingNumbers[i][0] & 1) == 1)
- solids.add(paths.elementAt(i));
- }
- }
-
- setDirection(holes, false);
- setDirection(solids, true);
- this.holes = holes;
- this.solids = solids;
- }
-
- /**
- * Sets the winding direction of a Vector of paths
- * @param clockwise gives the direction,
- * true = clockwise, false = counter-clockwise
- */
- private void setDirection(Vector<Segment> paths, boolean clockwise)
- {
- Segment v;
- for (int i = 0; i < paths.size(); i++)
- {
- v = paths.elementAt(i);
- if (clockwise != v.hasClockwiseOrientation())
- v.reverseAll();
- }
- }
-
- /**
- * Class representing a linked-list of vertices forming a closed polygon,
- * convex or concave, without holes.
- */
- private abstract class Segment implements Cloneable
- {
- // segment type, PathIterator segment types are used.
- Point2D P1;
- Point2D P2;
- Segment next;
- Segment node;
-
- Segment()
- {
- P1 = P2 = null;
- node = next = null;
- }
-
- /**
- * Reverses the direction of a single segment
- */
- abstract void reverseCoords();
-
- /**
- * Returns the segment's midpoint
- */
- abstract Point2D getMidPoint();
-
- /**
- * Returns the bounding box of this segment
- */
- abstract Rectangle2D getBounds();
-
- /**
- * Transforms a single segment
- */
- abstract void transform(AffineTransform at);
-
- /**
- * Returns the PathIterator type of a segment
- */
- abstract int getType();
-
- /**
- */
- abstract int splitIntersections(Segment b);
-
- /**
- * Returns the PathIterator coords of a segment
- */
- abstract int pathIteratorFormat(double[] coords);
-
- /**
- * Returns the number of intersections on the positive X axis,
- * with the origin at (x,y), used for contains()-testing
- *
- * (Although that could be done by the line-intersect methods,
- * a dedicated method is better to guarantee consitent handling
- * of endpoint-special-cases)
- */
- abstract int rayCrossing(double x, double y);
-
- /**
- * Subdivides the segment at parametric value t, inserting
- * the new segment into the linked list after this,
- * such that this becomes [0,t] and this.next becomes [t,1]
- */
- abstract void subdivideInsert(double t);
-
- /**
- * Returns twice the area of a curve, relative the P1-P2 line
- * Used for area calculations.
- */
- abstract double curveArea();
-
- /**
- * Compare two segments.
- */
- abstract boolean equals(Segment b);
-
- /**
- * Determines if this path of segments contains the point (x,y)
- */
- boolean contains(double x, double y)
- {
- Segment v = this;
- int crossings = 0;
- do
- {
- int n = v.rayCrossing(x, y);
- crossings += n;
- v = v.next;
- }
- while (v != this);
- return ((crossings & 1) == 1);
- }
-
- /**
- * Nulls all nodes of the path. Clean up any 'hairs'.
- */
- void nullNodes()
- {
- Segment v = this;
- do
- {
- v.node = null;
- v = v.next;
- }
- while (v != this);
- }
-
- /**
- * Transforms each segment in the closed path
- */
- void transformSegmentList(AffineTransform at)
- {
- Segment v = this;
- do
- {
- v.transform(at);
- v = v.next;
- }
- while (v != this);
- }
-
- /**
- * Determines the winding direction of the path
- * By the sign of the area.
- */
- boolean hasClockwiseOrientation()
- {
- return (getSignedArea() > 0.0);
- }
-
- /**
- * Returns the bounds of this path
- */
- public Rectangle2D getPathBounds()
- {
- double xmin;
- double xmax;
- double ymin;
- double ymax;
- xmin = xmax = P1.getX();
- ymin = ymax = P1.getY();
-
- Segment v = this;
- do
- {
- Rectangle2D r = v.getBounds();
- xmin = Math.min(r.getMinX(), xmin);
- ymin = Math.min(r.getMinY(), ymin);
- xmax = Math.max(r.getMaxX(), xmax);
- ymax = Math.max(r.getMaxY(), ymax);
- v = v.next;
- }
- while (v != this);
-
- return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
- }
-
- /**
- * Calculates twice the signed area of the path;
- */
- double getSignedArea()
- {
- Segment s;
- double area = 0.0;
-
- s = this;
- do
- {
- area += s.curveArea();
-
- area += s.P1.getX() * s.next.P1.getY()
- - s.P1.getY() * s.next.P1.getX();
- s = s.next;
- }
- while (s != this);
-
- return area;
- }
-
- /**
- * Reverses the orientation of the whole polygon
- */
- void reverseAll()
- {
- reverseCoords();
- Segment v = next;
- Segment former = this;
- while (v != this)
- {
- v.reverseCoords();
- Segment vnext = v.next;
- v.next = former;
- former = v;
- v = vnext;
- }
- next = former;
- }
-
- /**
- * Inserts a Segment after this one
- */
- void insert(Segment v)
- {
- Segment n = next;
- next = v;
- v.next = n;
- }
-
- /**
- * Returns if this segment path is polygonal
- */
- boolean isPolygonal()
- {
- Segment v = this;
- do
- {
- if (! (v instanceof LineSegment))
- return false;
- v = v.next;
- }
- while (v != this);
- return true;
- }
-
- /**
- * Clones this path
- */
- Segment cloneSegmentList() throws CloneNotSupportedException
- {
- Vector<Segment> list = new Vector<Segment>();
- Segment v = next;
-
- while (v != this)
- {
- list.add(v);
- v = v.next;
- }
-
- Segment clone = (Segment) this.clone();
- v = clone;
- for (int i = 0; i < list.size(); i++)
- {
- clone.next = (Segment) list.elementAt(i).clone();
- clone = clone.next;
- }
- clone.next = v;
- return v;
- }
-
- /**
- * Creates a node between this segment and segment b
- * at the given intersection
- * @return the number of nodes created (0 or 1)
- */
- int createNode(Segment b, Intersection i)
- {
- Point2D p = i.p;
- if ((pointEquals(P1, p) || pointEquals(P2, p))
- && (pointEquals(b.P1, p) || pointEquals(b.P2, p)))
- return 0;
-
- subdivideInsert(i.ta);
- b.subdivideInsert(i.tb);
-
- // snap points
- b.P2 = b.next.P1 = P2 = next.P1 = i.p;
-
- node = b.next;
- b.node = next;
- return 1;
- }
-
- /**
- * Creates multiple nodes from a list of intersections,
- * This must be done in the order of ascending parameters,
- * and the parameters must be recalculated in accordance
- * with each split.
- * @return the number of nodes created
- */
- protected int createNodes(Segment b, Intersection[] x)
- {
- Vector<Intersection> v = new Vector<Intersection>();
- for (int i = 0; i < x.length; i++)
- {
- Point2D p = x[i].p;
- if (! ((pointEquals(P1, p) || pointEquals(P2, p))
- && (pointEquals(b.P1, p) || pointEquals(b.P2, p))))
- v.add(x[i]);
- }
-
- int nNodes = v.size();
- Intersection[] A = new Intersection[nNodes];
- Intersection[] B = new Intersection[nNodes];
- for (int i = 0; i < nNodes; i++)
- A[i] = B[i] = v.elementAt(i);
-
- // Create two lists sorted by the parameter
- // Bubble sort, OK I suppose, since the number of intersections
- // cannot be larger than 9 (cubic-cubic worst case) anyway
- for (int i = 0; i < nNodes - 1; i++)
- {
- for (int j = i + 1; j < nNodes; j++)
- {
- if (A[i].ta > A[j].ta)
- {
- Intersection swap = A[i];
- A[i] = A[j];
- A[j] = swap;
- }
- if (B[i].tb > B[j].tb)
- {
- Intersection swap = B[i];
- B[i] = B[j];
- B[j] = swap;
- }
- }
- }
- // subdivide a
- Segment s = this;
- for (int i = 0; i < nNodes; i++)
- {
- s.subdivideInsert(A[i].ta);
-
- // renormalize the parameters
- for (int j = i + 1; j < nNodes; j++)
- A[j].ta = (A[j].ta - A[i].ta) / (1.0 - A[i].ta);
-
- A[i].seg = s;
- s = s.next;
- }
-
- // subdivide b, set nodes
- s = b;
- for (int i = 0; i < nNodes; i++)
- {
- s.subdivideInsert(B[i].tb);
-
- for (int j = i + 1; j < nNodes; j++)
- B[j].tb = (B[j].tb - B[i].tb) / (1.0 - B[i].tb);
-
- // set nodes
- B[i].seg.node = s.next; // node a -> b
- s.node = B[i].seg.next; // node b -> a
-
- // snap points
- B[i].seg.P2 = B[i].seg.next.P1 = s.P2 = s.next.P1 = B[i].p;
- s = s.next;
- }
- return nNodes;
- }
-
- /**
- * Determines if two paths are equal.
- * Colinear line segments are ignored in the comparison.
- */
- boolean pathEquals(Segment B)
- {
- if (! getPathBounds().equals(B.getPathBounds()))
- return false;
-
- Segment startA = getTopLeft();
- Segment startB = B.getTopLeft();
- Segment a = startA;
- Segment b = startB;
- do
- {
- if (! a.equals(b))
- return false;
-
- if (a instanceof LineSegment)
- a = ((LineSegment) a).lastCoLinear();
- if (b instanceof LineSegment)
- b = ((LineSegment) b).lastCoLinear();
-
- a = a.next;
- b = b.next;
- }
- while (a != startA && b != startB);
- return true;
- }
-
- /**
- * Return the segment with the top-leftmost first point
- */
- Segment getTopLeft()
- {
- Segment v = this;
- Segment tl = this;
- do
- {
- if (v.P1.getY() < tl.P1.getY())
- tl = v;
- else if (v.P1.getY() == tl.P1.getY())
- {
- if (v.P1.getX() < tl.P1.getX())
- tl = v;
- }
- v = v.next;
- }
- while (v != this);
- return tl;
- }
-
- /**
- * Returns if the path has a segment outside a shape
- */
- boolean isSegmentOutside(Shape shape)
- {
- return ! shape.contains(getMidPoint());
- }
- } // class Segment
-
- private class LineSegment extends Segment
- {
- public LineSegment(double x1, double y1, double x2, double y2)
- {
- super();
- P1 = new Point2D.Double(x1, y1);
- P2 = new Point2D.Double(x2, y2);
- }
-
- public LineSegment(Point2D p1, Point2D p2)
- {
- super();
- P1 = (Point2D) p1.clone();
- P2 = (Point2D) p2.clone();
- }
-
- /**
- * Clones this segment
- */
- public Object clone()
- {
- return new LineSegment(P1, P2);
- }
-
- /**
- * Transforms the segment
- */
- void transform(AffineTransform at)
- {
- P1 = at.transform(P1, null);
- P2 = at.transform(P2, null);
- }
-
- /**
- * Swap start and end points
- */
- void reverseCoords()
- {
- Point2D p = P1;
- P1 = P2;
- P2 = p;
- }
-
- /**
- * Returns the segment's midpoint
- */
- Point2D getMidPoint()
- {
- return (new Point2D.Double(0.5 * (P1.getX() + P2.getX()),
- 0.5 * (P1.getY() + P2.getY())));
- }
-
- /**
- * Returns twice the area of a curve, relative the P1-P2 line
- * Obviously, a line does not enclose any area besides the line
- */
- double curveArea()
- {
- return 0;
- }
-
- /**
- * Returns the PathIterator type of a segment
- */
- int getType()
- {
- return (PathIterator.SEG_LINETO);
- }
-
- /**
- * Subdivides the segment at parametric value t, inserting
- * the new segment into the linked list after this,
- * such that this becomes [0,t] and this.next becomes [t,1]
- */
- void subdivideInsert(double t)
- {
- Point2D p = new Point2D.Double((P2.getX() - P1.getX()) * t + P1.getX(),
- (P2.getY() - P1.getY()) * t + P1.getY());
- insert(new LineSegment(p, P2));
- P2 = p;
- next.node = node;
- node = null;
- }
-
- /**
- * Determines if two line segments are strictly colinear
- */
- boolean isCoLinear(LineSegment b)
- {
- double x1 = P1.getX();
- double y1 = P1.getY();
- double x2 = P2.getX();
- double y2 = P2.getY();
- double x3 = b.P1.getX();
- double y3 = b.P1.getY();
- double x4 = b.P2.getX();
- double y4 = b.P2.getY();
-
- if ((y1 - y3) * (x4 - x3) - (x1 - x3) * (y4 - y3) != 0.0)
- return false;
-
- return ((x2 - x1) * (y4 - y3) - (y2 - y1) * (x4 - x3) == 0.0);
- }
-
- /**
- * Return the last segment colinear with this one.
- * Used in comparing paths.
- */
- Segment lastCoLinear()
- {
- Segment prev = this;
- Segment v = next;
-
- while (v instanceof LineSegment)
- {
- if (isCoLinear((LineSegment) v))
- {
- prev = v;
- v = v.next;
- }
- else
- return prev;
- }
- return prev;
- }
-
- /**
- * Compare two segments.
- * We must take into account that the lines may be broken into colinear
- * subsegments and ignore them.
- */
- boolean equals(Segment b)
- {
- if (! (b instanceof LineSegment))
- return false;
- Point2D p1 = P1;
- Point2D p3 = b.P1;
-
- if (! p1.equals(p3))
- return false;
-
- Point2D p2 = lastCoLinear().P2;
- Point2D p4 = ((LineSegment) b).lastCoLinear().P2;
- return (p2.equals(p4));
- }
-
- /**
- * Returns a line segment
- */
- int pathIteratorFormat(double[] coords)
- {
- coords[0] = P2.getX();
- coords[1] = P2.getY();
- return (PathIterator.SEG_LINETO);
- }
-
- /**
- * Returns if the line has intersections.
- */
- boolean hasIntersections(Segment b)
- {
- if (b instanceof LineSegment)
- return (linesIntersect(this, (LineSegment) b) != null);
-
- if (b instanceof QuadSegment)
- return (lineQuadIntersect(this, (QuadSegment) b) != null);
-
- if (b instanceof CubicSegment)
- return (lineCubicIntersect(this, (CubicSegment) b) != null);
-
- return false;
- }
-
- /**
- * Splits intersections into nodes,
- * This one handles line-line, line-quadratic, line-cubic
- */
- int splitIntersections(Segment b)
- {
- if (b instanceof LineSegment)
- {
- Intersection i = linesIntersect(this, (LineSegment) b);
-
- if (i == null)
- return 0;
-
- return createNode(b, i);
- }
-
- Intersection[] x = null;
-
- if (b instanceof QuadSegment)
- x = lineQuadIntersect(this, (QuadSegment) b);
-
- if (b instanceof CubicSegment)
- x = lineCubicIntersect(this, (CubicSegment) b);
-
- if (x == null)
- return 0;
-
- if (x.length == 1)
- return createNode(b, (Intersection) x[0]);
-
- return createNodes(b, x);
- }
-
- /**
- * Returns the bounding box of this segment
- */
- Rectangle2D getBounds()
- {
- return (new Rectangle2D.Double(Math.min(P1.getX(), P2.getX()),
- Math.min(P1.getY(), P2.getY()),
- Math.abs(P1.getX() - P2.getX()),
- Math.abs(P1.getY() - P2.getY())));
- }
-
- /**
- * Returns the number of intersections on the positive X axis,
- * with the origin at (x,y), used for contains()-testing
- */
- int rayCrossing(double x, double y)
- {
- double x0 = P1.getX() - x;
- double y0 = P1.getY() - y;
- double x1 = P2.getX() - x;
- double y1 = P2.getY() - y;
-
- if (y0 * y1 > 0)
- return 0;
-
- if (x0 < 0 && x1 < 0)
- return 0;
-
- if (y0 == 0.0)
- y0 -= EPSILON;
-
- if (y1 == 0.0)
- y1 -= EPSILON;
-
- if (Line2D.linesIntersect(x0, y0, x1, y1,
- EPSILON, 0.0, Double.MAX_VALUE, 0.0))
- return 1;
- return 0;
- }
- } // class LineSegment
-
- /**
- * Quadratic Bezier curve segment
- *
- * Note: Most peers don't support quadratics directly, so it might make
- * sense to represent them as cubics internally and just be done with it.
- * I think we should be peer-agnostic, however, and stay faithful to the
- * input geometry types as far as possible.
- */
- private class QuadSegment extends Segment
- {
- Point2D cp; // control point
-
- /**
- * Constructor, takes the coordinates of the start, control,
- * and end point, respectively.
- */
- QuadSegment(double x1, double y1, double cx, double cy, double x2,
- double y2)
- {
- super();
- P1 = new Point2D.Double(x1, y1);
- P2 = new Point2D.Double(x2, y2);
- cp = new Point2D.Double(cx, cy);
- }
-
- /**
- * Clones this segment
- */
- public Object clone()
- {
- return new QuadSegment(P1.getX(), P1.getY(), cp.getX(), cp.getY(),
- P2.getX(), P2.getY());
- }
-
- /**
- * Returns twice the area of a curve, relative the P1-P2 line
- *
- * The area formula can be derived by using Green's formula in the
- * plane on the parametric form of the bezier.
- */
- double curveArea()
- {
- double x0 = P1.getX();
- double y0 = P1.getY();
- double x1 = cp.getX();
- double y1 = cp.getY();
- double x2 = P2.getX();
- double y2 = P2.getY();
-
- double P = (y2 - 2 * y1 + y0);
- double Q = 2 * (y1 - y0);
-
- double A = (x2 - 2 * x1 + x0);
- double B = 2 * (x1 - x0);
-
- double area = (B * P - A * Q) / 3.0;
- return (area);
- }
-
- /**
- * Compare two segments.
- */
- boolean equals(Segment b)
- {
- if (! (b instanceof QuadSegment))
- return false;
-
- return (P1.equals(b.P1) && cp.equals(((QuadSegment) b).cp)
- && P2.equals(b.P2));
- }
-
- /**
- * Returns a Point2D corresponding to the parametric value t
- * of the curve
- */
- Point2D evaluatePoint(double t)
- {
- double x0 = P1.getX();
- double y0 = P1.getY();
- double x1 = cp.getX();
- double y1 = cp.getY();
- double x2 = P2.getX();
- double y2 = P2.getY();
-
- return new Point2D.Double(t * t * (x2 - 2 * x1 + x0) + 2 * t * (x1 - x0)
- + x0,
- t * t * (y2 - 2 * y1 + y0) + 2 * t * (y1 - y0)
- + y0);
- }
-
- /**
- * Returns the bounding box of this segment
- */
- Rectangle2D getBounds()
- {
- double x0 = P1.getX();
- double y0 = P1.getY();
- double x1 = cp.getX();
- double y1 = cp.getY();
- double x2 = P2.getX();
- double y2 = P2.getY();
- double r0;
- double r1;
-
- double xmax = Math.max(x0, x2);
- double ymax = Math.max(y0, y2);
- double xmin = Math.min(x0, x2);
- double ymin = Math.min(y0, y2);
-
- r0 = 2 * (y1 - y0);
- r1 = 2 * (y2 - 2 * y1 + y0);
- if (r1 != 0.0)
- {
- double t = -r0 / r1;
- if (t > 0.0 && t < 1.0)
- {
- double y = evaluatePoint(t).getY();
- ymax = Math.max(y, ymax);
- ymin = Math.min(y, ymin);
- }
- }
- r0 = 2 * (x1 - x0);
- r1 = 2 * (x2 - 2 * x1 + x0);
- if (r1 != 0.0)
- {
- double t = -r0 / r1;
- if (t > 0.0 && t < 1.0)
- {
- double x = evaluatePoint(t).getY();
- xmax = Math.max(x, xmax);
- xmin = Math.min(x, xmin);
- }
- }
-
- return (new Rectangle2D.Double(xmin, ymin, xmax - xmin, ymax - ymin));
- }
-
- /**
- * Returns a cubic segment corresponding to this curve
- */
- CubicSegment getCubicSegment()
- {
- double x1 = P1.getX() + 2.0 * (cp.getX() - P1.getX()) / 3.0;
- double y1 = P1.getY() + 2.0 * (cp.getY() - P1.getY()) / 3.0;
- double x2 = cp.getX() + (P2.getX() - cp.getX()) / 3.0;
- double y2 = cp.getY() + (P2.getY() - cp.getY()) / 3.0;
-
- return new CubicSegment(P1.getX(), P1.getY(), x1, y1, x2, y2, P2.getX(),
- P2.getY());
- }
-
- /**
- * Returns the segment's midpoint
- */
- Point2D getMidPoint()
- {
- return evaluatePoint(0.5);
- }
-
- /**
- * Returns the PathIterator type of a segment
- */
- int getType()
- {
- return (PathIterator.SEG_QUADTO);
- }
-
- /**
- * Returns the PathIterator coords of a segment
- */
- int pathIteratorFormat(double[] coords)
- {
- coords[0] = cp.getX();
- coords[1] = cp.getY();
- coords[2] = P2.getX();
- coords[3] = P2.getY();
- return (PathIterator.SEG_QUADTO);
- }
-
- /**
- * Returns the number of intersections on the positive X axis,
- * with the origin at (x,y), used for contains()-testing
- */
- int rayCrossing(double x, double y)
- {
- double x0 = P1.getX() - x;
- double y0 = P1.getY() - y;
- double x1 = cp.getX() - x;
- double y1 = cp.getY() - y;
- double x2 = P2.getX() - x;
- double y2 = P2.getY() - y;
- double[] r = new double[3];
- int nRoots;
- int nCrossings = 0;
-
- /* 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);
-
- nRoots = QuadCurve2D.solveQuadratic(r);
- for (int i = 0; i < nRoots; i++)
- if (r[i] > 0.0f && r[i] < 1.0f)
- {
- double t = r[i];
- if (t * t * (x2 - 2 * x1 + x0) + 2 * t * (x1 - x0) + x0 > 0.0)
- nCrossings++;
- }
- }
- return nCrossings;
- }
-
- /**
- * Swap start and end points
- */
- void reverseCoords()
- {
- Point2D temp = P1;
- P1 = P2;
- P2 = temp;
- }
-
- /**
- * Splits intersections into nodes,
- * This one handles quadratic-quadratic only,
- * Quadratic-line is passed on to the LineSegment class,
- * Quadratic-cubic is passed on to the CubicSegment class
- */
- int splitIntersections(Segment b)
- {
- if (b instanceof LineSegment)
- return (b.splitIntersections(this));
-
- if (b instanceof CubicSegment)
- return (b.splitIntersections(this));
-
- if (b instanceof QuadSegment)
- {
- // Use the cubic-cubic intersection routine for quads as well,
- // Since a quadratic can be exactly described as a cubic, this
- // should not be a problem;
- // The recursion depth will be the same in any case.
- Intersection[] x = cubicCubicIntersect(getCubicSegment(),
- ((QuadSegment) b)
- .getCubicSegment());
- if (x == null)
- return 0;
-
- if (x.length == 1)
- return createNode(b, (Intersection) x[0]);
-
- return createNodes(b, x);
- }
- return 0;
- }
-
- /**
- * Subdivides the segment at parametric value t, inserting
- * the new segment into the linked list after this,
- * such that this becomes [0,t] and this.next becomes [t,1]
- */
- void subdivideInsert(double t)
- {
- double x0 = P1.getX();
- double y0 = P1.getY();
- double x1 = cp.getX();
- double y1 = cp.getY();
- double x2 = P2.getX();
- double y2 = P2.getY();
-
- double p10x = x0 + t * (x1 - x0);
- double p10y = y0 + t * (y1 - y0);
- double p11x = x1 + t * (x2 - x1);
- double p11y = y1 + t * (y2 - y1);
- double p20x = p10x + t * (p11x - p10x);
- double p20y = p10y + t * (p11y - p10y);
-
- insert(new QuadSegment(p20x, p20y, p11x, p11y, x2, y2));
- P2 = next.P1;
- cp.setLocation(p10x, p10y);
-
- next.node = node;
- node = null;
- }
-
- /**
- * Transforms the segment
- */
- void transform(AffineTransform at)
- {
- P1 = at.transform(P1, null);
- P2 = at.transform(P2, null);
- cp = at.transform(cp, null);
- }
- } // class QuadSegment
-
- /**
- * Cubic Bezier curve segment
- */
- private class CubicSegment extends Segment
- {
- Point2D cp1; // control points
- Point2D cp2; // control points
-
- /**
- * Constructor - takes coordinates of the starting point,
- * first control point, second control point and end point,
- * respecively.
- */
- public CubicSegment(double x1, double y1, double c1x, double c1y,
- double c2x, double c2y, double x2, double y2)
- {
- super();
- P1 = new Point2D.Double(x1, y1);
- P2 = new Point2D.Double(x2, y2);
- cp1 = new Point2D.Double(c1x, c1y);
- cp2 = new Point2D.Double(c2x, c2y);
- }
-
- /**
- * Clones this segment
- */
- public Object clone()
- {
- return new CubicSegment(P1.getX(), P1.getY(), cp1.getX(), cp1.getY(),
- cp2.getX(), cp2.getY(), P2.getX(), P2.getY());
- }
-
- /**
- * Returns twice the area of a curve, relative the P1-P2 line
- *
- * The area formula can be derived by using Green's formula in the
- * plane on the parametric form of the bezier.
- */
- double curveArea()
- {
- double x0 = P1.getX();
- double y0 = P1.getY();
- double x1 = cp1.getX();
- double y1 = cp1.getY();
- double x2 = cp2.getX();
- double y2 = cp2.getY();
- double x3 = P2.getX();
- double y3 = P2.getY();
-
- double P = y3 - 3 * y2 + 3 * y1 - y0;
- double Q = 3 * (y2 + y0 - 2 * y1);
- double R = 3 * (y1 - y0);
-
- double A = x3 - 3 * x2 + 3 * x1 - x0;
- double B = 3 * (x2 + x0 - 2 * x1);
- double C = 3 * (x1 - x0);
-
- double area = (B * P - A * Q) / 5.0 + (C * P - A * R) / 2.0
- + (C * Q - B * R) / 3.0;
-
- return (area);
- }
-
- /**
- * Compare two segments.
- */
- boolean equals(Segment b)
- {
- if (! (b instanceof CubicSegment))
- return false;
-
- return (P1.equals(b.P1) && cp1.equals(((CubicSegment) b).cp1)
- && cp2.equals(((CubicSegment) b).cp2) && P2.equals(b.P2));
- }
-
- /**
- * Returns a Point2D corresponding to the parametric value t
- * of the curve
- */
- Point2D evaluatePoint(double t)
- {
- double x0 = P1.getX();
- double y0 = P1.getY();
- double x1 = cp1.getX();
- double y1 = cp1.getY();
- double x2 = cp2.getX();
- double y2 = cp2.getY();
- double x3 = P2.getX();
- double y3 = P2.getY();
-
- return new Point2D.Double(-(t * t * t) * (x0 - 3 * x1 + 3 * x2 - x3)
- + 3 * t * t * (x0 - 2 * x1 + x2)
- + 3 * t * (x1 - x0) + x0,
- -(t * t * t) * (y0 - 3 * y1 + 3 * y2 - y3)
- + 3 * t * t * (y0 - 2 * y1 + y2)
- + 3 * t * (y1 - y0) + y0);
- }
-
- /**
- * Returns the bounding box of this segment
- */
- Rectangle2D getBounds()
- {
- double x0 = P1.getX();
- double y0 = P1.getY();
- double x1 = cp1.getX();
- double y1 = cp1.getY();
- double x2 = cp2.getX();
- double y2 = cp2.getY();
- double x3 = P2.getX();
- double y3 = P2.getY();
- double[] r = new double[3];
-
- double xmax = Math.max(x0, x3);
- double ymax = Math.max(y0, y3);
- double xmin = Math.min(x0, x3);
- double ymin = Math.min(y0, y3);
-
- r[0] = 3 * (y1 - y0);
- r[1] = 6.0 * (y2 + y0 - 2 * y1);
- r[2] = 3.0 * (y3 - 3 * y2 + 3 * y1 - y0);
-
- int n = QuadCurve2D.solveQuadratic(r);
- for (int i = 0; i < n; i++)
- {
- double t = r[i];
- if (t > 0 && t < 1.0)
- {
- double y = evaluatePoint(t).getY();
- ymax = Math.max(y, ymax);
- ymin = Math.min(y, ymin);
- }
- }
-
- r[0] = 3 * (x1 - x0);
- r[1] = 6.0 * (x2 + x0 - 2 * x1);
- r[2] = 3.0 * (x3 - 3 * x2 + 3 * x1 - x0);
- n = QuadCurve2D.solveQuadratic(r);
- for (int i = 0; i < n; i++)
- {
- double t = r[i];
- if (t > 0 && t < 1.0)
- {
- double x = evaluatePoint(t).getX();
- xmax = Math.max(x, xmax);
- xmin = Math.min(x, xmin);
- }
- }
- return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
- }
-
- /**
- * Returns a CubicCurve2D object corresponding to this segment.
- */
- CubicCurve2D getCubicCurve2D()
- {
- return new CubicCurve2D.Double(P1.getX(), P1.getY(), cp1.getX(),
- cp1.getY(), cp2.getX(), cp2.getY(),
- P2.getX(), P2.getY());
- }
-
- /**
- * Returns the parametric points of self-intersection if the cubic
- * is self-intersecting, null otherwise.
- */
- double[] getLoop()
- {
- double x0 = P1.getX();
- double y0 = P1.getY();
- double x1 = cp1.getX();
- double y1 = cp1.getY();
- double x2 = cp2.getX();
- double y2 = cp2.getY();
- double x3 = P2.getX();
- double y3 = P2.getY();
- double[] r = new double[4];
- double k;
- double R;
- double T;
- double A;
- double B;
- double[] results = new double[2];
-
- R = x3 - 3 * x2 + 3 * x1 - x0;
- T = y3 - 3 * y2 + 3 * y1 - y0;
-
- // A qudratic
- if (R == 0.0 && T == 0.0)
- return null;
-
- // true cubic
- if (R != 0.0 && T != 0.0)
- {
- A = 3 * (x2 + x0 - 2 * x1) / R;
- B = 3 * (x1 - x0) / R;
-
- double P = 3 * (y2 + y0 - 2 * y1) / T;
- double Q = 3 * (y1 - y0) / T;
-
- if (A == P || Q == B)
- return null;
-
- k = (Q - B) / (A - P);
- }
- else
- {
- if (R == 0.0)
- {
- // quadratic in x
- k = -(3 * (x1 - x0)) / (3 * (x2 + x0 - 2 * x1));
- A = 3 * (y2 + y0 - 2 * y1) / T;
- B = 3 * (y1 - y0) / T;
- }
- else
- {
- // quadratic in y
- k = -(3 * (y1 - y0)) / (3 * (y2 + y0 - 2 * y1));
- A = 3 * (x2 + x0 - 2 * x1) / R;
- B = 3 * (x1 - x0) / R;
- }
- }
-
- r[0] = -k * k * k - A * k * k - B * k;
- r[1] = 3 * k * k + 2 * k * A + 2 * B;
- r[2] = -3 * k;
- r[3] = 2;
-
- int n = CubicCurve2D.solveCubic(r);
- if (n != 3)
- return null;
-
- // sort r
- double t;
- for (int i = 0; i < 2; i++)
- for (int j = i + 1; j < 3; j++)
- if (r[j] < r[i])
- {
- t = r[i];
- r[i] = r[j];
- r[j] = t;
- }
-
- if (Math.abs(r[0] + r[2] - k) < 1E-13)
- if (r[0] >= 0.0 && r[0] <= 1.0 && r[2] >= 0.0 && r[2] <= 1.0)
- if (evaluatePoint(r[0]).distance(evaluatePoint(r[2])) < PE_EPSILON * 10)
- { // we snap the points anyway
- results[0] = r[0];
- results[1] = r[2];
- return (results);
- }
- return null;
- }
-
- /**
- * Returns the segment's midpoint
- */
- Point2D getMidPoint()
- {
- return evaluatePoint(0.5);
- }
-
- /**
- * Returns the PathIterator type of a segment
- */
- int getType()
- {
- return (PathIterator.SEG_CUBICTO);
- }
-
- /**
- * Returns the PathIterator coords of a segment
- */
- int pathIteratorFormat(double[] coords)
- {
- coords[0] = cp1.getX();
- coords[1] = cp1.getY();
- coords[2] = cp2.getX();
- coords[3] = cp2.getY();
- coords[4] = P2.getX();
- coords[5] = P2.getY();
- return (PathIterator.SEG_CUBICTO);
- }
-
- /**
- * Returns the number of intersections on the positive X axis,
- * with the origin at (x,y), used for contains()-testing
- */
- int rayCrossing(double x, double y)
- {
- double x0 = P1.getX() - x;
- double y0 = P1.getY() - y;
- double x1 = cp1.getX() - x;
- double y1 = cp1.getY() - y;
- double x2 = cp2.getX() - x;
- double y2 = cp2.getY() - y;
- double x3 = P2.getX() - x;
- double y3 = P2.getY() - y;
- double[] r = new double[4];
- int nRoots;
- int nCrossings = 0;
-
- /* 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++)
- {
- if (r[i] > 0.0 && r[i] < 1.0)
- {
- double t = r[i];
- if (-(t * t * t) * (x0 - 3 * x1 + 3 * x2 - x3)
- + 3 * t * t * (x0 - 2 * x1 + x2) + 3 * t * (x1 - x0)
- + x0 > 0.0)
- nCrossings++;
- }
- }
- }
- return nCrossings;
- }
-
- /**
- * Swap start and end points
- */
- void reverseCoords()
- {
- Point2D p = P1;
- P1 = P2;
- P2 = p;
- p = cp1; // swap control points
- cp1 = cp2;
- cp2 = p;
- }
-
- /**
- * Splits intersections into nodes,
- * This one handles cubic-cubic and cubic-quadratic intersections
- */
- int splitIntersections(Segment b)
- {
- if (b instanceof LineSegment)
- return (b.splitIntersections(this));
-
- Intersection[] x = null;
-
- if (b instanceof QuadSegment)
- x = cubicCubicIntersect(this, ((QuadSegment) b).getCubicSegment());
-
- if (b instanceof CubicSegment)
- x = cubicCubicIntersect(this, (CubicSegment) b);
-
- if (x == null)
- return 0;
-
- if (x.length == 1)
- return createNode(b, x[0]);
-
- return createNodes(b, x);
- }
-
- /**
- * Subdivides the segment at parametric value t, inserting
- * the new segment into the linked list after this,
- * such that this becomes [0,t] and this.next becomes [t,1]
- */
- void subdivideInsert(double t)
- {
- CubicSegment s = (CubicSegment) clone();
- double p1x = (s.cp1.getX() - s.P1.getX()) * t + s.P1.getX();
- double p1y = (s.cp1.getY() - s.P1.getY()) * t + s.P1.getY();
-
- double px = (s.cp2.getX() - s.cp1.getX()) * t + s.cp1.getX();
- double py = (s.cp2.getY() - s.cp1.getY()) * t + s.cp1.getY();
-
- s.cp2.setLocation((s.P2.getX() - s.cp2.getX()) * t + s.cp2.getX(),
- (s.P2.getY() - s.cp2.getY()) * t + s.cp2.getY());
-
- s.cp1.setLocation((s.cp2.getX() - px) * t + px,
- (s.cp2.getY() - py) * t + py);
-
- double p2x = (px - p1x) * t + p1x;
- double p2y = (py - p1y) * t + p1y;
-
- double p3x = (s.cp1.getX() - p2x) * t + p2x;
- double p3y = (s.cp1.getY() - p2y) * t + p2y;
- s.P1.setLocation(p3x, p3y);
-
- // insert new curve
- insert(s);
-
- // set this curve
- cp1.setLocation(p1x, p1y);
- cp2.setLocation(p2x, p2y);
- P2 = s.P1;
- next.node = node;
- node = null;
- }
-
- /**
- * Transforms the segment
- */
- void transform(AffineTransform at)
- {
- P1 = at.transform(P1, null);
- P2 = at.transform(P2, null);
- cp1 = at.transform(cp1, null);
- cp2 = at.transform(cp2, null);
- }
- } // class CubicSegment
-} // class Area
diff --git a/libjava/classpath/java/awt/geom/CubicCurve2D.java b/libjava/classpath/java/awt/geom/CubicCurve2D.java
deleted file mode 100644
index 5cb11fe..0000000
--- a/libjava/classpath/java/awt/geom/CubicCurve2D.java
+++ /dev/null
@@ -1,1724 +0,0 @@
-/* CubicCurve2D.java -- represents a parameterized cubic curve in 2-D space
- Copyright (C) 2002, 2003, 2004 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;
-import java.util.NoSuchElementException;
-
-
-/**
- * A two-dimensional curve that is parameterized with a cubic
- * function.
- *
- * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a CubicCurve2D" />
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @author Graydon Hoare (graydon@redhat.com)
- * @author Sascha Brawer (brawer@dandelis.ch)
- * @author Sven de Marothy (sven@physto.se)
- *
- * @since 1.2
- */
-public abstract class CubicCurve2D implements Shape, Cloneable
-{
- private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
- private static final double EPSILON = 1E-10;
-
- /**
- * Constructs a new CubicCurve2D. Typical users will want to
- * construct instances of a subclass, such as {@link
- * CubicCurve2D.Float} or {@link CubicCurve2D.Double}.
- */
- protected CubicCurve2D()
- {
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public abstract double getX1();
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public abstract double getY1();
-
- /**
- * Returns the curve&#x2019;s start point.
- */
- public abstract Point2D getP1();
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s first
- * control point.
- */
- public abstract double getCtrlX1();
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s first
- * control point.
- */
- public abstract double getCtrlY1();
-
- /**
- * Returns the curve&#x2019;s first control point.
- */
- public abstract Point2D getCtrlP1();
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s second
- * control point.
- */
- public abstract double getCtrlX2();
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s second
- * control point.
- */
- public abstract double getCtrlY2();
-
- /**
- * Returns the curve&#x2019;s second control point.
- */
- public abstract Point2D getCtrlP2();
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public abstract double getX2();
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public abstract double getY2();
-
- /**
- * Returns the curve&#x2019;s end point.
- */
- public abstract Point2D getP2();
-
- /**
- * Changes the curve geometry, separately specifying each coordinate
- * value.
- *
- * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a CubicCurve2D" />
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s new
- * first control point.
- *
- * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s new
- * first control point.
- *
- * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s new
- * second control point.
- *
- * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s new
- * second control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
- * point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
- * point.
- */
- public abstract void setCurve(double x1, double y1, double cx1, double cy1,
- double cx2, double cy2, double x2, double y2);
-
- /**
- * Changes the curve geometry, specifying coordinate values in an
- * array.
- *
- * @param coords an array containing the new coordinate values. The
- * <i>x</i> coordinate of the new start point is located at
- * <code>coords[offset]</code>, its <i>y</i> coordinate at
- * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
- * new first control point is located at <code>coords[offset +
- * 2]</code>, its <i>y</i> coordinate at <code>coords[offset +
- * 3]</code>. The <i>x</i> coordinate of the new second control
- * point is located at <code>coords[offset + 4]</code>, its <i>y</i>
- * coordinate at <code>coords[offset + 5]</code>. The <i>x</i>
- * coordinate of the new end point is located at <code>coords[offset
- * + 6]</code>, its <i>y</i> coordinate at <code>coords[offset +
- * 7]</code>.
- *
- * @param offset the offset of the first coordinate value in
- * <code>coords</code>.
- */
- public void setCurve(double[] coords, int offset)
- {
- setCurve(coords[offset++], coords[offset++], coords[offset++],
- coords[offset++], coords[offset++], coords[offset++],
- coords[offset++], coords[offset++]);
- }
-
- /**
- * Changes the curve geometry, specifying coordinate values in
- * separate Point objects.
- *
- * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a CubicCurve2D" />
- *
- * <p>The curve does not keep any reference to the passed point
- * objects. Therefore, a later change to <code>p1</code>,
- * <code>c1</code>, <code>c2</code> or <code>p2</code> will not
- * affect the curve geometry.
- *
- * @param p1 the new start point.
- * @param c1 the new first control point.
- * @param c2 the new second control point.
- * @param p2 the new end point.
- */
- public void setCurve(Point2D p1, Point2D c1, Point2D c2, Point2D p2)
- {
- setCurve(p1.getX(), p1.getY(), c1.getX(), c1.getY(), c2.getX(), c2.getY(),
- p2.getX(), p2.getY());
- }
-
- /**
- * Changes the curve geometry, specifying coordinate values in an
- * array of Point objects.
- *
- * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a CubicCurve2D" />
- *
- * <p>The curve does not keep references to the passed point
- * objects. Therefore, a later change to the <code>pts</code> array
- * or any of its elements will not affect the curve geometry.
- *
- * @param pts an array containing the points. The new start point
- * is located at <code>pts[offset]</code>, the new first control
- * point at <code>pts[offset + 1]</code>, the new second control
- * point at <code>pts[offset + 2]</code>, and the new end point
- * at <code>pts[offset + 3]</code>.
- *
- * @param offset the offset of the start point in <code>pts</code>.
- */
- public void setCurve(Point2D[] pts, int offset)
- {
- setCurve(pts[offset].getX(), pts[offset++].getY(), pts[offset].getX(),
- pts[offset++].getY(), pts[offset].getX(), pts[offset++].getY(),
- pts[offset].getX(), pts[offset++].getY());
- }
-
- /**
- * Changes the curve geometry to that of another curve.
- *
- * @param c the curve whose coordinates will be copied.
- */
- public void setCurve(CubicCurve2D c)
- {
- setCurve(c.getX1(), c.getY1(), c.getCtrlX1(), c.getCtrlY1(),
- c.getCtrlX2(), c.getCtrlY2(), c.getX2(), c.getY2());
- }
-
- /**
- * Calculates the squared flatness of a cubic curve, directly
- * specifying each coordinate value. The flatness is the maximal
- * distance of a control point to the line between start and end
- * point.
- *
- * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. In comparison to C1,
- * control point C2 is father away from the gray line. Therefore,
- * the result will be the square of the distance between C2 and the
- * gray line, i.e. the squared length of the red line.
- *
- * @param x1 the <i>x</i> coordinate of the start point P1.
- * @param y1 the <i>y</i> coordinate of the start point P1.
- * @param cx1 the <i>x</i> coordinate of the first control point C1.
- * @param cy1 the <i>y</i> coordinate of the first control point C1.
- * @param cx2 the <i>x</i> coordinate of the second control point C2.
- * @param cy2 the <i>y</i> coordinate of the second control point C2.
- * @param x2 the <i>x</i> coordinate of the end point P2.
- * @param y2 the <i>y</i> coordinate of the end point P2.
- */
- public static double getFlatnessSq(double x1, double y1, double cx1,
- double cy1, double cx2, double cy2,
- double x2, double y2)
- {
- return Math.max(Line2D.ptSegDistSq(x1, y1, x2, y2, cx1, cy1),
- Line2D.ptSegDistSq(x1, y1, x2, y2, cx2, cy2));
- }
-
- /**
- * Calculates the flatness of a cubic curve, directly specifying
- * each coordinate value. The flatness is the maximal distance of a
- * control point to the line between start and end point.
- *
- * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. In comparison to C1,
- * control point C2 is father away from the gray line. Therefore,
- * the result will be the distance between C2 and the gray line,
- * i.e. the length of the red line.
- *
- * @param x1 the <i>x</i> coordinate of the start point P1.
- * @param y1 the <i>y</i> coordinate of the start point P1.
- * @param cx1 the <i>x</i> coordinate of the first control point C1.
- * @param cy1 the <i>y</i> coordinate of the first control point C1.
- * @param cx2 the <i>x</i> coordinate of the second control point C2.
- * @param cy2 the <i>y</i> coordinate of the second control point C2.
- * @param x2 the <i>x</i> coordinate of the end point P2.
- * @param y2 the <i>y</i> coordinate of the end point P2.
- */
- public static double getFlatness(double x1, double y1, double cx1,
- double cy1, double cx2, double cy2,
- double x2, double y2)
- {
- return Math.sqrt(getFlatnessSq(x1, y1, cx1, cy1, cx2, cy2, x2, y2));
- }
-
- /**
- * Calculates the squared flatness of a cubic curve, specifying the
- * coordinate values in an array. The flatness is the maximal
- * distance of a control point to the line between start and end
- * point.
- *
- * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. In comparison to C1,
- * control point C2 is father away from the gray line. Therefore,
- * the result will be the square of the distance between C2 and the
- * gray line, i.e. the squared length of the red line.
- *
- * @param coords an array containing the coordinate values. The
- * <i>x</i> coordinate of the start point P1 is located at
- * <code>coords[offset]</code>, its <i>y</i> coordinate at
- * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
- * first control point C1 is located at <code>coords[offset +
- * 2]</code>, its <i>y</i> coordinate at <code>coords[offset +
- * 3]</code>. The <i>x</i> coordinate of the second control point C2
- * is located at <code>coords[offset + 4]</code>, its <i>y</i>
- * coordinate at <code>coords[offset + 5]</code>. The <i>x</i>
- * coordinate of the end point P2 is located at <code>coords[offset
- * + 6]</code>, its <i>y</i> coordinate at <code>coords[offset +
- * 7]</code>.
- *
- * @param offset the offset of the first coordinate value in
- * <code>coords</code>.
- */
- public static double getFlatnessSq(double[] coords, int offset)
- {
- return getFlatnessSq(coords[offset++], coords[offset++], coords[offset++],
- coords[offset++], coords[offset++], coords[offset++],
- coords[offset++], coords[offset++]);
- }
-
- /**
- * Calculates the flatness of a cubic curve, specifying the
- * coordinate values in an array. The flatness is the maximal
- * distance of a control point to the line between start and end
- * point.
- *
- * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. In comparison to C1,
- * control point C2 is father away from the gray line. Therefore,
- * the result will be the distance between C2 and the gray line,
- * i.e. the length of the red line.
- *
- * @param coords an array containing the coordinate values. The
- * <i>x</i> coordinate of the start point P1 is located at
- * <code>coords[offset]</code>, its <i>y</i> coordinate at
- * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
- * first control point C1 is located at <code>coords[offset +
- * 2]</code>, its <i>y</i> coordinate at <code>coords[offset +
- * 3]</code>. The <i>x</i> coordinate of the second control point C2
- * is located at <code>coords[offset + 4]</code>, its <i>y</i>
- * coordinate at <code>coords[offset + 5]</code>. The <i>x</i>
- * coordinate of the end point P2 is located at <code>coords[offset
- * + 6]</code>, its <i>y</i> coordinate at <code>coords[offset +
- * 7]</code>.
- *
- * @param offset the offset of the first coordinate value in
- * <code>coords</code>.
- */
- public static double getFlatness(double[] coords, int offset)
- {
- return Math.sqrt(getFlatnessSq(coords[offset++], coords[offset++],
- coords[offset++], coords[offset++],
- coords[offset++], coords[offset++],
- coords[offset++], coords[offset++]));
- }
-
- /**
- * Calculates the squared flatness of this curve. The flatness is
- * the maximal distance of a control point to the line between start
- * and end point.
- *
- * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. In comparison to C1,
- * control point C2 is father away from the gray line. Therefore,
- * the result will be the square of the distance between C2 and the
- * gray line, i.e. the squared length of the red line.
- */
- public double getFlatnessSq()
- {
- return getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(),
- getCtrlX2(), getCtrlY2(), getX2(), getY2());
- }
-
- /**
- * Calculates the flatness of this curve. The flatness is the
- * maximal distance of a control point to the line between start and
- * end point.
- *
- * <p><img src="doc-files/CubicCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. In comparison to C1,
- * control point C2 is father away from the gray line. Therefore,
- * the result will be the distance between C2 and the gray line,
- * i.e. the length of the red line.
- */
- public double getFlatness()
- {
- return Math.sqrt(getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(),
- getCtrlX2(), getCtrlY2(), getX2(), getY2()));
- }
-
- /**
- * Subdivides this curve into two halves.
- *
- * <p><img src="doc-files/CubicCurve2D-3.png" width="700"
- * height="180" alt="A drawing that illustrates the effects of
- * subdividing a CubicCurve2D" />
- *
- * @param left a curve whose geometry will be set to the left half
- * of this curve, or <code>null</code> if the caller is not
- * interested in the left half.
- *
- * @param right a curve whose geometry will be set to the right half
- * of this curve, or <code>null</code> if the caller is not
- * interested in the right half.
- */
- public void subdivide(CubicCurve2D left, CubicCurve2D right)
- {
- // Use empty slots at end to share single array.
- double[] d = new double[]
- {
- getX1(), getY1(), getCtrlX1(), getCtrlY1(), getCtrlX2(),
- getCtrlY2(), getX2(), getY2(), 0, 0, 0, 0, 0, 0
- };
- subdivide(d, 0, d, 0, d, 6);
- if (left != null)
- left.setCurve(d, 0);
- if (right != null)
- right.setCurve(d, 6);
- }
-
- /**
- * Subdivides a cubic curve into two halves.
- *
- * <p><img src="doc-files/CubicCurve2D-3.png" width="700"
- * height="180" alt="A drawing that illustrates the effects of
- * subdividing a CubicCurve2D" />
- *
- * @param src the curve to be subdivided.
- *
- * @param left a curve whose geometry will be set to the left half
- * of <code>src</code>, or <code>null</code> if the caller is not
- * interested in the left half.
- *
- * @param right a curve whose geometry will be set to the right half
- * of <code>src</code>, or <code>null</code> if the caller is not
- * interested in the right half.
- */
- public static void subdivide(CubicCurve2D src, CubicCurve2D left,
- CubicCurve2D right)
- {
- src.subdivide(left, right);
- }
-
- /**
- * Subdivides a cubic curve into two halves, passing all coordinates
- * in an array.
- *
- * <p><img src="doc-files/CubicCurve2D-3.png" width="700"
- * height="180" alt="A drawing that illustrates the effects of
- * subdividing a CubicCurve2D" />
- *
- * <p>The left end point and the right start point will always be
- * identical. Memory-concious programmers thus may want to pass the
- * same array for both <code>left</code> and <code>right</code>, and
- * set <code>rightOff</code> to <code>leftOff + 6</code>.
- *
- * @param src an array containing the coordinates of the curve to be
- * subdivided. The <i>x</i> coordinate of the start point P1 is
- * located at <code>src[srcOff]</code>, its <i>y</i> at
- * <code>src[srcOff + 1]</code>. The <i>x</i> coordinate of the
- * first control point C1 is located at <code>src[srcOff +
- * 2]</code>, its <i>y</i> at <code>src[srcOff + 3]</code>. The
- * <i>x</i> coordinate of the second control point C2 is located at
- * <code>src[srcOff + 4]</code>, its <i>y</i> at <code>src[srcOff +
- * 5]</code>. The <i>x</i> coordinate of the end point is located at
- * <code>src[srcOff + 6]</code>, its <i>y</i> at <code>src[srcOff +
- * 7]</code>.
- *
- * @param srcOff an offset into <code>src</code>, specifying
- * the index of the start point&#x2019;s <i>x</i> coordinate.
- *
- * @param left an array that will receive the coordinates of the
- * left half of <code>src</code>. It is acceptable to pass
- * <code>src</code>. A caller who is not interested in the left half
- * can pass <code>null</code>.
- *
- * @param leftOff an offset into <code>left</code>, specifying the
- * index where the start point&#x2019;s <i>x</i> coordinate will be
- * stored.
- *
- * @param right an array that will receive the coordinates of the
- * right half of <code>src</code>. It is acceptable to pass
- * <code>src</code> or <code>left</code>. A caller who is not
- * interested in the right half can pass <code>null</code>.
- *
- * @param rightOff an offset into <code>right</code>, specifying the
- * index where the start point&#x2019;s <i>x</i> coordinate will be
- * stored.
- */
- public static void subdivide(double[] src, int srcOff, double[] left,
- int leftOff, double[] right, int rightOff)
- {
- // To understand this code, please have a look at the image
- // "CubicCurve2D-3.png" in the sub-directory "doc-files".
- double src_C1_x;
- double src_C1_y;
- double src_C2_x;
- double src_C2_y;
- double left_P1_x;
- double left_P1_y;
- double left_C1_x;
- double left_C1_y;
- double left_C2_x;
- double left_C2_y;
- double right_C1_x;
- double right_C1_y;
- double right_C2_x;
- double right_C2_y;
- double right_P2_x;
- double right_P2_y;
- double Mid_x; // Mid = left.P2 = right.P1
- double Mid_y; // Mid = left.P2 = right.P1
-
- left_P1_x = src[srcOff];
- left_P1_y = src[srcOff + 1];
- src_C1_x = src[srcOff + 2];
- src_C1_y = src[srcOff + 3];
- src_C2_x = src[srcOff + 4];
- src_C2_y = src[srcOff + 5];
- right_P2_x = src[srcOff + 6];
- right_P2_y = src[srcOff + 7];
-
- left_C1_x = (left_P1_x + src_C1_x) / 2;
- left_C1_y = (left_P1_y + src_C1_y) / 2;
- right_C2_x = (right_P2_x + src_C2_x) / 2;
- right_C2_y = (right_P2_y + src_C2_y) / 2;
- Mid_x = (src_C1_x + src_C2_x) / 2;
- Mid_y = (src_C1_y + src_C2_y) / 2;
- left_C2_x = (left_C1_x + Mid_x) / 2;
- left_C2_y = (left_C1_y + Mid_y) / 2;
- right_C1_x = (Mid_x + right_C2_x) / 2;
- right_C1_y = (Mid_y + right_C2_y) / 2;
- Mid_x = (left_C2_x + right_C1_x) / 2;
- Mid_y = (left_C2_y + right_C1_y) / 2;
-
- if (left != null)
- {
- left[leftOff] = left_P1_x;
- left[leftOff + 1] = left_P1_y;
- left[leftOff + 2] = left_C1_x;
- left[leftOff + 3] = left_C1_y;
- left[leftOff + 4] = left_C2_x;
- left[leftOff + 5] = left_C2_y;
- left[leftOff + 6] = Mid_x;
- left[leftOff + 7] = Mid_y;
- }
-
- if (right != null)
- {
- right[rightOff] = Mid_x;
- right[rightOff + 1] = Mid_y;
- right[rightOff + 2] = right_C1_x;
- right[rightOff + 3] = right_C1_y;
- right[rightOff + 4] = right_C2_x;
- right[rightOff + 5] = right_C2_y;
- right[rightOff + 6] = right_P2_x;
- right[rightOff + 7] = right_P2_y;
- }
- }
-
- /**
- * Finds the non-complex roots of a cubic equation, placing the
- * results into the same array as the equation coefficients. The
- * following equation is being solved:
- *
- * <blockquote><code>eqn[3]</code> &#xb7; <i>x</i><sup>3</sup>
- * + <code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
- * + <code>eqn[1]</code> &#xb7; <i>x</i>
- * + <code>eqn[0]</code>
- * = 0
- * </blockquote>
- *
- * <p>For some background about solving cubic equations, see the
- * article <a
- * href="http://planetmath.org/encyclopedia/CubicFormula.html"
- * >&#x201c;Cubic Formula&#x201d;</a> in <a
- * href="http://planetmath.org/" >PlanetMath</a>. For an extensive
- * library of numerical algorithms written in the C programming
- * language, see the <a href= "http://www.gnu.org/software/gsl/">GNU
- * Scientific Library</a>, from which this implementation was
- * adapted.
- *
- * @param eqn an array with the coefficients of the equation. When
- * this procedure has returned, <code>eqn</code> will contain the
- * non-complex solutions of the equation, in no particular order.
- *
- * @return the number of non-complex solutions. A result of 0
- * indicates that the equation has no non-complex solutions. A
- * result of -1 indicates that the equation is constant (i.e.,
- * always or never zero).
- *
- * @see #solveCubic(double[], double[])
- * @see QuadCurve2D#solveQuadratic(double[],double[])
- *
- * @author Brian Gough (bjg@network-theory.com)
- * (original C implementation in the <a href=
- * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
- *
- * @author Sascha Brawer (brawer@dandelis.ch)
- * (adaptation to Java)
- */
- public static int solveCubic(double[] eqn)
- {
- return solveCubic(eqn, eqn);
- }
-
- /**
- * Finds the non-complex roots of a cubic equation. The following
- * equation is being solved:
- *
- * <blockquote><code>eqn[3]</code> &#xb7; <i>x</i><sup>3</sup>
- * + <code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
- * + <code>eqn[1]</code> &#xb7; <i>x</i>
- * + <code>eqn[0]</code>
- * = 0
- * </blockquote>
- *
- * <p>For some background about solving cubic equations, see the
- * article <a
- * href="http://planetmath.org/encyclopedia/CubicFormula.html"
- * >&#x201c;Cubic Formula&#x201d;</a> in <a
- * href="http://planetmath.org/" >PlanetMath</a>. For an extensive
- * library of numerical algorithms written in the C programming
- * language, see the <a href= "http://www.gnu.org/software/gsl/">GNU
- * Scientific Library</a>, from which this implementation was
- * adapted.
- *
- * @see QuadCurve2D#solveQuadratic(double[],double[])
- *
- * @param eqn an array with the coefficients of the equation.
- *
- * @param res an array into which the non-complex roots will be
- * stored. The results may be in an arbitrary order. It is safe to
- * pass the same array object reference for both <code>eqn</code>
- * and <code>res</code>.
- *
- * @return the number of non-complex solutions. A result of 0
- * indicates that the equation has no non-complex solutions. A
- * result of -1 indicates that the equation is constant (i.e.,
- * always or never zero).
- *
- * @author Brian Gough (bjg@network-theory.com)
- * (original C implementation in the <a href=
- * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
- *
- * @author Sascha Brawer (brawer@dandelis.ch)
- * (adaptation to Java)
- */
- public static int solveCubic(double[] eqn, double[] res)
- {
- // Adapted from poly/solve_cubic.c in the GNU Scientific Library
- // (GSL), revision 1.7 of 2003-07-26. For the original source, see
- // http://www.gnu.org/software/gsl/
- //
- // Brian Gough, the author of that code, has granted the
- // permission to use it in GNU Classpath under the GNU Classpath
- // license, and has assigned the copyright to the Free Software
- // Foundation.
- //
- // The Java implementation is very similar to the GSL code, but
- // not a strict one-to-one copy. For example, GSL would sort the
- // result.
-
- double a;
- double b;
- double c;
- double q;
- double r;
- double Q;
- double R;
- double c3;
- double Q3;
- double R2;
- double CR2;
- double CQ3;
-
- // If the cubic coefficient is zero, we have a quadratic equation.
- c3 = eqn[3];
- if (c3 == 0)
- return QuadCurve2D.solveQuadratic(eqn, res);
-
- // Divide the equation by the cubic coefficient.
- c = eqn[0] / c3;
- b = eqn[1] / c3;
- a = eqn[2] / c3;
-
- // We now need to solve x^3 + ax^2 + bx + c = 0.
- q = a * a - 3 * b;
- r = 2 * a * a * a - 9 * a * b + 27 * c;
-
- Q = q / 9;
- R = r / 54;
-
- Q3 = Q * Q * Q;
- R2 = R * R;
-
- CR2 = 729 * r * r;
- CQ3 = 2916 * q * q * q;
-
- if (R == 0 && Q == 0)
- {
- // The GNU Scientific Library would return three identical
- // solutions in this case.
- res[0] = -a / 3;
- return 1;
- }
-
- if (CR2 == CQ3)
- {
- /* this test is actually R2 == Q3, written in a form suitable
- for exact computation with integers */
- /* Due to finite precision some double roots may be missed, and
- considered to be a pair of complex roots z = x +/- epsilon i
- close to the real axis. */
- double sqrtQ = Math.sqrt(Q);
-
- if (R > 0)
- {
- res[0] = -2 * sqrtQ - a / 3;
- res[1] = sqrtQ - a / 3;
- }
- else
- {
- res[0] = -sqrtQ - a / 3;
- res[1] = 2 * sqrtQ - a / 3;
- }
- return 2;
- }
-
- if (CR2 < CQ3) /* equivalent to R2 < Q3 */
- {
- double sqrtQ = Math.sqrt(Q);
- double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
- double theta = Math.acos(R / sqrtQ3);
- double norm = -2 * sqrtQ;
- res[0] = norm * Math.cos(theta / 3) - a / 3;
- res[1] = norm * Math.cos((theta + 2.0 * Math.PI) / 3) - a / 3;
- res[2] = norm * Math.cos((theta - 2.0 * Math.PI) / 3) - a / 3;
-
- // The GNU Scientific Library sorts the results. We don't.
- return 3;
- }
-
- double sgnR = (R >= 0 ? 1 : -1);
- double A = -sgnR * Math.pow(Math.abs(R) + Math.sqrt(R2 - Q3), 1.0 / 3.0);
- double B = Q / A;
- res[0] = A + B - a / 3;
- return 1;
- }
-
- /**
- * Determines whether a position lies inside the area bounded
- * by the curve and the straight line connecting its end points.
- *
- * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
- * alt="A drawing of the area spanned by the curve" />
- *
- * <p>The above drawing illustrates in which area points are
- * considered &#x201c;inside&#x201d; a CubicCurve2D.
- */
- public boolean contains(double x, double y)
- {
- if (! getBounds2D().contains(x, y))
- return false;
-
- return ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0);
- }
-
- /**
- * Determines whether a point lies inside the area bounded
- * by the curve and the straight line connecting its end points.
- *
- * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
- * alt="A drawing of the area spanned by the curve" />
- *
- * <p>The above drawing illustrates in which area points are
- * considered &#x201c;inside&#x201d; a CubicCurve2D.
- */
- public boolean contains(Point2D p)
- {
- return contains(p.getX(), p.getY());
- }
-
- /**
- * Determines whether any part of a rectangle is inside the area bounded
- * by the curve and the straight line connecting its end points.
- *
- * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
- * alt="A drawing of the area spanned by the curve" />
- *
- * <p>The above drawing illustrates in which area points are
- * considered &#x201c;inside&#x201d; in a CubicCurve2D.
- * @see #contains(double, double)
- */
- public boolean intersects(double x, double y, double w, double h)
- {
- if (! getBounds2D().contains(x, y, w, h))
- return false;
-
- /* Does any edge intersect? */
- if (getAxisIntersections(x, y, true, w) != 0 /* top */
- || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
- || getAxisIntersections(x + w, y, false, h) != 0 /* right */
- || getAxisIntersections(x, y, false, h) != 0) /* left */
- return true;
-
- /* No intersections, is any point inside? */
- if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
- return true;
-
- return false;
- }
-
- /**
- * Determines whether any part of a Rectangle2D is inside the area bounded
- * by the curve and the straight line connecting its end points.
- * @see #intersects(double, double, double, double)
- */
- public boolean intersects(Rectangle2D r)
- {
- return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Determine whether a rectangle is entirely inside the area that is bounded
- * by the curve and the straight line connecting its end points.
- *
- * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
- * alt="A drawing of the area spanned by the curve" />
- *
- * <p>The above drawing illustrates in which area points are
- * considered &#x201c;inside&#x201d; a CubicCurve2D.
- * @see #contains(double, double)
- */
- 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, true, w) != 0 /* top */
- || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
- || getAxisIntersections(x + w, y, false, h) != 0 /* right */
- || getAxisIntersections(x, y, false, h) != 0) /* left */
- return false;
-
- /* No intersections, is any point inside? */
- if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
- return true;
-
- return false;
- }
-
- /**
- * Determine whether a Rectangle2D is entirely inside the area that is
- * bounded by the curve and the straight line connecting its end points.
- *
- * <p><img src="doc-files/CubicCurve2D-5.png" width="350" height="180"
- * alt="A drawing of the area spanned by the curve" />
- *
- * <p>The above drawing illustrates in which area points are
- * considered &#x201c;inside&#x201d; a CubicCurve2D.
- * @see #contains(double, double)
- */
- public boolean contains(Rectangle2D r)
- {
- return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Determines the smallest rectangle that encloses the
- * curve&#x2019;s start, end and control points.
- */
- public Rectangle getBounds()
- {
- return getBounds2D().getBounds();
- }
-
- public PathIterator getPathIterator(final AffineTransform at)
- {
- return new PathIterator()
- {
- /** Current coordinate. */
- private int current = 0;
-
- public int getWindingRule()
- {
- return WIND_NON_ZERO;
- }
-
- public boolean isDone()
- {
- return current >= 2;
- }
-
- public void next()
- {
- current++;
- }
-
- public int currentSegment(float[] coords)
- {
- int result;
- switch (current)
- {
- case 0:
- coords[0] = (float) getX1();
- coords[1] = (float) getY1();
- result = SEG_MOVETO;
- break;
- case 1:
- coords[0] = (float) getCtrlX1();
- coords[1] = (float) getCtrlY1();
- coords[2] = (float) getCtrlX2();
- coords[3] = (float) getCtrlY2();
- coords[4] = (float) getX2();
- coords[5] = (float) getY2();
- result = SEG_CUBICTO;
- break;
- default:
- throw new NoSuchElementException("cubic iterator out of bounds");
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 3);
- return result;
- }
-
- public int currentSegment(double[] coords)
- {
- int result;
- switch (current)
- {
- case 0:
- coords[0] = getX1();
- coords[1] = getY1();
- result = SEG_MOVETO;
- break;
- case 1:
- coords[0] = getCtrlX1();
- coords[1] = getCtrlY1();
- coords[2] = getCtrlX2();
- coords[3] = getCtrlY2();
- coords[4] = getX2();
- coords[5] = getY2();
- result = SEG_CUBICTO;
- break;
- default:
- throw new NoSuchElementException("cubic iterator out of bounds");
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 3);
- return result;
- }
- };
- }
-
- public PathIterator getPathIterator(AffineTransform at, double flatness)
- {
- return new FlatteningPathIterator(getPathIterator(at), flatness);
- }
-
- /**
- * Create a new curve with the same contents as this one.
- *
- * @return the clone.
- */
- public Object clone()
- {
- try
- {
- return super.clone();
- }
- catch (CloneNotSupportedException e)
- {
- throw (Error) new InternalError().initCause(e); // Impossible
- }
- }
-
- /**
- * Helper method used by contains() and intersects() methods, that
- * returns the number of curve/line intersections on a given axis
- * extending from a certain point.
- *
- * @param x x coordinate of the origin point
- * @param y y coordinate of the origin point
- * @param useYaxis axis used, if true the positive Y axis is used,
- * false uses the positive X axis.
- *
- * This is an implementation of the line-crossings algorithm,
- * Detailed in an article on Eric Haines' page:
- * http://www.acm.org/tog/editors/erich/ptinpoly/
- *
- * A special-case not adressed in this code is self-intersections
- * of the curve, e.g. if the axis intersects the self-itersection,
- * the degenerate roots of the polynomial will erroneously count as
- * a single intersection of the curve, and not two.
- */
- private int getAxisIntersections(double x, double y, boolean useYaxis,
- double distance)
- {
- int nCrossings = 0;
- double a0;
- double a1;
- double a2;
- double a3;
- double b0;
- double b1;
- double b2;
- double b3;
- double[] r = new double[4];
- int nRoots;
-
- a0 = a3 = 0.0;
-
- if (useYaxis)
- {
- a0 = getY1() - y;
- a1 = getCtrlY1() - y;
- a2 = getCtrlY2() - y;
- a3 = getY2() - y;
- b0 = getX1() - x;
- b1 = getCtrlX1() - x;
- b2 = getCtrlX2() - x;
- b3 = getX2() - x;
- }
- else
- {
- a0 = getX1() - x;
- a1 = getCtrlX1() - x;
- a2 = getCtrlX2() - x;
- a3 = getX2() - x;
- b0 = getY1() - y;
- b1 = getCtrlY1() - y;
- b2 = getCtrlY2() - y;
- b3 = getY2() - y;
- }
-
- /* If the axis intersects a start/endpoint, shift it up by some small
- amount to guarantee the line is 'inside'
- If this is not done, bad behaviour may result for points on that axis.*/
- if (a0 == 0.0 || a3 == 0.0)
- {
- double small = getFlatness() * EPSILON;
- if (a0 == 0.0)
- a0 -= small;
- if (a3 == 0.0)
- a3 -= small;
- }
-
- if (useYaxis)
- {
- if (Line2D.linesIntersect(b0, a0, b3, a3, EPSILON, 0.0, distance, 0.0))
- nCrossings++;
- }
- else
- {
- if (Line2D.linesIntersect(a0, b0, a3, b3, 0.0, EPSILON, 0.0, distance))
- nCrossings++;
- }
-
- r[0] = a0;
- r[1] = 3 * (a1 - a0);
- r[2] = 3 * (a2 + a0 - 2 * a1);
- r[3] = a3 - 3 * a2 + 3 * a1 - a0;
-
- if ((nRoots = solveCubic(r)) != 0)
- for (int i = 0; i < nRoots; i++)
- {
- double t = r[i];
- if (t >= 0.0 && t <= 1.0)
- {
- double crossing = -(t * t * t) * (b0 - 3 * b1 + 3 * b2 - b3)
- + 3 * t * t * (b0 - 2 * b1 + b2)
- + 3 * t * (b1 - b0) + b0;
- if (crossing > 0.0 && crossing <= distance)
- nCrossings++;
- }
- }
-
- return (nCrossings);
- }
-
- /**
- * A two-dimensional curve that is parameterized with a cubic
- * function and stores coordinate values in double-precision
- * floating-point format.
- *
- * @see CubicCurve2D.Float
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @author Sascha Brawer (brawer@dandelis.ch)
- */
- public static class Double extends CubicCurve2D
- {
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s start point.
- */
- public double x1;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s start point.
- */
- public double y1;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s first control point.
- */
- public double ctrlx1;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s first control point.
- */
- public double ctrly1;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s second control point.
- */
- public double ctrlx2;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s second control point.
- */
- public double ctrly2;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s end point.
- */
- public double x2;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s end point.
- */
- public double y2;
-
- /**
- * Constructs a new CubicCurve2D that stores its coordinate values
- * in double-precision floating-point format. All points are
- * initially at position (0, 0).
- */
- public Double()
- {
- }
-
- /**
- * Constructs a new CubicCurve2D that stores its coordinate values
- * in double-precision floating-point format, specifying the
- * initial position of each point.
- *
- * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a CubicCurve2D" />
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- *
- * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s first
- * control point.
- *
- * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s first
- * control point.
- *
- * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s second
- * control point.
- *
- * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s second
- * control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public Double(double x1, double y1, double cx1, double cy1, double cx2,
- double cy2, double x2, double y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- ctrlx1 = cx1;
- ctrly1 = cy1;
- ctrlx2 = cx2;
- ctrly2 = cy2;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public double getX1()
- {
- return x1;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public double getY1()
- {
- return y1;
- }
-
- /**
- * Returns the curve&#x2019;s start point.
- */
- public Point2D getP1()
- {
- return new Point2D.Double(x1, y1);
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s first
- * control point.
- */
- public double getCtrlX1()
- {
- return ctrlx1;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s first
- * control point.
- */
- public double getCtrlY1()
- {
- return ctrly1;
- }
-
- /**
- * Returns the curve&#x2019;s first control point.
- */
- public Point2D getCtrlP1()
- {
- return new Point2D.Double(ctrlx1, ctrly1);
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s second
- * control point.
- */
- public double getCtrlX2()
- {
- return ctrlx2;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s second
- * control point.
- */
- public double getCtrlY2()
- {
- return ctrly2;
- }
-
- /**
- * Returns the curve&#x2019;s second control point.
- */
- public Point2D getCtrlP2()
- {
- return new Point2D.Double(ctrlx2, ctrly2);
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public double getX2()
- {
- return x2;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public double getY2()
- {
- return y2;
- }
-
- /**
- * Returns the curve&#x2019;s end point.
- */
- public Point2D getP2()
- {
- return new Point2D.Double(x2, y2);
- }
-
- /**
- * Changes the curve geometry, separately specifying each coordinate
- * value.
- *
- * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a CubicCurve2D" />
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s new
- * first control point.
- *
- * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s new
- * first control point.
- *
- * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s new
- * second control point.
- *
- * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s new
- * second control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
- * point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
- * point.
- */
- public void setCurve(double x1, double y1, double cx1, double cy1,
- double cx2, double cy2, double x2, double y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- ctrlx1 = cx1;
- ctrly1 = cy1;
- ctrlx2 = cx2;
- ctrly2 = cy2;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Determines the smallest rectangle that encloses the
- * curve&#x2019;s start, end and control points. As the
- * illustration below shows, the invisible control points may cause
- * the bounds to be much larger than the area that is actually
- * covered by the curve.
- *
- * <p><img src="doc-files/CubicCurve2D-2.png" width="350" height="180"
- * alt="An illustration of the bounds of a CubicCurve2D" />
- */
- public Rectangle2D getBounds2D()
- {
- double nx1 = Math.min(Math.min(x1, ctrlx1), Math.min(ctrlx2, x2));
- double ny1 = Math.min(Math.min(y1, ctrly1), Math.min(ctrly2, y2));
- double nx2 = Math.max(Math.max(x1, ctrlx1), Math.max(ctrlx2, x2));
- double ny2 = Math.max(Math.max(y1, ctrly1), Math.max(ctrly2, y2));
- return new Rectangle2D.Double(nx1, ny1, nx2 - nx1, ny2 - ny1);
- }
- }
-
- /**
- * A two-dimensional curve that is parameterized with a cubic
- * function and stores coordinate values in single-precision
- * floating-point format.
- *
- * @see CubicCurve2D.Float
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @author Sascha Brawer (brawer@dandelis.ch)
- */
- public static class Float extends CubicCurve2D
- {
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s start point.
- */
- public float x1;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s start point.
- */
- public float y1;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s first control point.
- */
- public float ctrlx1;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s first control point.
- */
- public float ctrly1;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s second control point.
- */
- public float ctrlx2;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s second control point.
- */
- public float ctrly2;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s end point.
- */
- public float x2;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s end point.
- */
- public float y2;
-
- /**
- * Constructs a new CubicCurve2D that stores its coordinate values
- * in single-precision floating-point format. All points are
- * initially at position (0, 0).
- */
- public Float()
- {
- }
-
- /**
- * Constructs a new CubicCurve2D that stores its coordinate values
- * in single-precision floating-point format, specifying the
- * initial position of each point.
- *
- * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a CubicCurve2D" />
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- *
- * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s first
- * control point.
- *
- * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s first
- * control point.
- *
- * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s second
- * control point.
- *
- * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s second
- * control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public Float(float x1, float y1, float cx1, float cy1, float cx2,
- float cy2, float x2, float y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- ctrlx1 = cx1;
- ctrly1 = cy1;
- ctrlx2 = cx2;
- ctrly2 = cy2;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public double getX1()
- {
- return x1;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public double getY1()
- {
- return y1;
- }
-
- /**
- * Returns the curve&#x2019;s start point.
- */
- public Point2D getP1()
- {
- return new Point2D.Float(x1, y1);
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s first
- * control point.
- */
- public double getCtrlX1()
- {
- return ctrlx1;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s first
- * control point.
- */
- public double getCtrlY1()
- {
- return ctrly1;
- }
-
- /**
- * Returns the curve&#x2019;s first control point.
- */
- public Point2D getCtrlP1()
- {
- return new Point2D.Float(ctrlx1, ctrly1);
- }
-
- /**
- * Returns the <i>s</i> coordinate of the curve&#x2019;s second
- * control point.
- */
- public double getCtrlX2()
- {
- return ctrlx2;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s second
- * control point.
- */
- public double getCtrlY2()
- {
- return ctrly2;
- }
-
- /**
- * Returns the curve&#x2019;s second control point.
- */
- public Point2D getCtrlP2()
- {
- return new Point2D.Float(ctrlx2, ctrly2);
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public double getX2()
- {
- return x2;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public double getY2()
- {
- return y2;
- }
-
- /**
- * Returns the curve&#x2019;s end point.
- */
- public Point2D getP2()
- {
- return new Point2D.Float(x2, y2);
- }
-
- /**
- * Changes the curve geometry, separately specifying each coordinate
- * value as a double-precision floating-point number.
- *
- * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a CubicCurve2D" />
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s new
- * first control point.
- *
- * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s new
- * first control point.
- *
- * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s new
- * second control point.
- *
- * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s new
- * second control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
- * point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
- * point.
- */
- public void setCurve(double x1, double y1, double cx1, double cy1,
- double cx2, double cy2, double x2, double y2)
- {
- this.x1 = (float) x1;
- this.y1 = (float) y1;
- ctrlx1 = (float) cx1;
- ctrly1 = (float) cy1;
- ctrlx2 = (float) cx2;
- ctrly2 = (float) cy2;
- this.x2 = (float) x2;
- this.y2 = (float) y2;
- }
-
- /**
- * Changes the curve geometry, separately specifying each coordinate
- * value as a single-precision floating-point number.
- *
- * <p><img src="doc-files/CubicCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a CubicCurve2D" />
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param cx1 the <i>x</i> coordinate of the curve&#x2019;s new
- * first control point.
- *
- * @param cy1 the <i>y</i> coordinate of the curve&#x2019;s new
- * first control point.
- *
- * @param cx2 the <i>x</i> coordinate of the curve&#x2019;s new
- * second control point.
- *
- * @param cy2 the <i>y</i> coordinate of the curve&#x2019;s new
- * second control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
- * point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
- * point.
- */
- public void setCurve(float x1, float y1, float cx1, float cy1, float cx2,
- float cy2, float x2, float y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- ctrlx1 = cx1;
- ctrly1 = cy1;
- ctrlx2 = cx2;
- ctrly2 = cy2;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Determines the smallest rectangle that encloses the
- * curve&#x2019;s start, end and control points. As the
- * illustration below shows, the invisible control points may cause
- * the bounds to be much larger than the area that is actually
- * covered by the curve.
- *
- * <p><img src="doc-files/CubicCurve2D-2.png" width="350" height="180"
- * alt="An illustration of the bounds of a CubicCurve2D" />
- */
- public Rectangle2D getBounds2D()
- {
- float nx1 = Math.min(Math.min(x1, ctrlx1), Math.min(ctrlx2, x2));
- float ny1 = Math.min(Math.min(y1, ctrly1), Math.min(ctrly2, y2));
- float nx2 = Math.max(Math.max(x1, ctrlx1), Math.max(ctrlx2, x2));
- float ny2 = Math.max(Math.max(y1, ctrly1), Math.max(ctrly2, y2));
- return new Rectangle2D.Float(nx1, ny1, nx2 - nx1, ny2 - ny1);
- }
- }
-}
diff --git a/libjava/classpath/java/awt/geom/Dimension2D.java b/libjava/classpath/java/awt/geom/Dimension2D.java
deleted file mode 100644
index 6b5ce88..0000000
--- a/libjava/classpath/java/awt/geom/Dimension2D.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Dimension2D.java -- abstraction of a dimension
- Copyright (C) 1999, 2000, 2002 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;
-
-/**
- * This stores a dimension in 2-dimensional space - a width (along the x-axis)
- * and height (along the y-axis). The storage is left to subclasses.
- *
- * @author Per Bothner (bothner@cygnus.com)
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status updated to 1.4
- */
-public abstract class Dimension2D implements Cloneable
-{
- /**
- * The default constructor.
- */
- protected Dimension2D()
- {
- }
-
- /**
- * Get the width of this dimension. A negative result, while legal, is
- * undefined in meaning.
- *
- * @return the width
- */
- public abstract double getWidth();
-
- /**
- * Get the height of this dimension. A negative result, while legal, is
- * undefined in meaning.
- *
- * @return the height
- */
- public abstract double getHeight();
-
- /**
- * Set the size of this dimension to the requested values. Loss of precision
- * may occur.
- *
- * @param w the new width
- * @param h the new height
- */
- public abstract void setSize(double w, double h);
-
- /**
- * Set the size of this dimension to the requested value. Loss of precision
- * may occur.
- *
- * @param d the dimension containing the new values
- *
- * @throws NullPointerException if d is null
- */
- public void setSize(Dimension2D d)
- {
- setSize(d.getWidth(), d.getHeight());
- }
-
- /**
- * Create a new dimension 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()
- {
- try
- {
- return super.clone();
- }
- catch (CloneNotSupportedException e)
- {
- throw (Error) new InternalError().initCause(e); // Impossible
- }
- }
-} // class Dimension2D
diff --git a/libjava/classpath/java/awt/geom/Ellipse2D.java b/libjava/classpath/java/awt/geom/Ellipse2D.java
deleted file mode 100644
index 3bbf2f0..0000000
--- a/libjava/classpath/java/awt/geom/Ellipse2D.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/* Ellipse2D.java -- represents an ellipse in 2-D space
- Copyright (C) 2000, 2002, 2004 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;
-
-
-/**
- * Ellipse2D is the shape of an ellipse.
- * <BR>
- * <img src="doc-files/Ellipse-1.png" width="347" height="221"
- * alt="A drawing of an ellipse" /><BR>
- * The ellipse is defined by it's bounding box (shown in red),
- * and is defined by the implicit curve:<BR>
- * <blockquote>(<i>x</i>/<i>a</i>)<sup>2</sup> +
- * (<i>y</i>/<i>b</i>)<sup>2</sup> = 1<BR><BR></blockquote>
- *
- * @author Tom Tromey (tromey@cygnus.com)
- * @author Eric Blake (ebb9@email.byu.edu)
- *
- * @since 1.2
- */
-public abstract class Ellipse2D extends RectangularShape
-{
- /**
- * Ellipse2D is defined as abstract.
- * Implementing classes are Ellipse2D.Float and Ellipse2D.Double.
- */
- protected Ellipse2D()
- {
- }
-
- /**
- * Determines if a point is contained within the ellipse. <P>
- * @param x - x coordinate of the point.
- * @param y - y coordinate of the point.
- * @return true if the point is within the ellipse, false otherwise.
- */
- public boolean contains(double x, double y)
- {
- double rx = getWidth() / 2;
- double ry = getHeight() / 2;
- double tx = (x - (getX() + rx)) / rx;
- double ty = (y - (getY() + ry)) / ry;
- return tx * tx + ty * ty < 1.0;
- }
-
- /**
- * Determines if a rectangle is completely contained within the
- * ellipse. <P>
- * @param x - x coordinate of the upper-left corner of the rectangle
- * @param y - y coordinate of the upper-left corner of the rectangle
- * @param w - width of the rectangle
- * @param h - height of the rectangle
- * @return true if the rectangle is completely contained, false otherwise.
- */
- public boolean contains(double x, double y, double w, double h)
- {
- double x2 = x + w;
- double y2 = y + h;
- return (contains(x, y) && contains(x, y2) && contains(x2, y)
- && contains(x2, y2));
- }
-
- /**
- * Returns a PathIterator object corresponding to the ellipse.<P>
- *
- * Note: An ellipse cannot be represented exactly in PathIterator
- * segments, the outline is thefore approximated with cubic
- * Bezier segments.
- *
- * @param at an optional transform.
- * @return A path iterator.
- */
- public PathIterator getPathIterator(AffineTransform at)
- {
- // An ellipse is just a complete arc.
- return new Arc2D.ArcIterator(this, at);
- }
-
- /**
- * Determines if a rectangle intersects any part of the ellipse.<P>
- * @param x - x coordinate of the upper-left corner of the rectangle
- * @param y - y coordinate of the upper-left corner of the rectangle
- * @param w - width of the rectangle
- * @param h - height of the rectangle
- * @return true if the rectangle intersects the ellipse, false otherwise.
- */
- public boolean intersects(double x, double y, double w, double h)
- {
- Rectangle2D r = new Rectangle2D.Double(x, y, w, h);
- if (! r.intersects(getX(), getY(), getWidth(), getHeight()))
- return false;
-
- if (contains(x, y) || contains(x, y + h) || contains(x + w, y)
- || contains(x + w, y + h))
- return true;
-
- Line2D l1 = new Line2D.Double(getX(), getY() + (getHeight() / 2),
- getX() + getWidth(),
- getY() + (getHeight() / 2));
- Line2D l2 = new Line2D.Double(getX() + (getWidth() / 2), getY(),
- getX() + (getWidth() / 2),
- getY() + getHeight());
-
- if (l1.intersects(r) || l2.intersects(r))
- return true;
-
- return false;
- }
-
- /**
- * An {@link Ellipse2D} that stores its coordinates using <code>double</code>
- * primitives.
- */
- public static class Double extends Ellipse2D
- {
- /**
- * The height of the ellipse.
- */
- public double height;
-
- /**
- * The width of the ellipse.
- */
- public double width;
-
- /**
- * The upper-left x coordinate of the bounding-box
- */
- public double x;
-
- /**
- * The upper-left y coordinate of the bounding-box
- */
- public double y;
-
- /**
- * Creates a new Ellipse2D with an upper-left coordinate of (0,0)
- * and a zero size.
- */
- public Double()
- {
- }
-
- /**
- * Creates a new Ellipse2D within a given rectangle
- * using double-precision coordinates.<P>
- * @param x - x coordinate of the upper-left of the bounding rectangle
- * @param y - y coordinate of the upper-left of the bounding rectangle
- * @param w - width of the ellipse
- * @param h - height of the ellipse
- */
- public Double(double x, double y, double w, double h)
- {
- this.x = x;
- this.y = y;
- height = h;
- width = w;
- }
-
- /**
- * Returns the bounding-box of the ellipse.
- * @return The bounding box.
- */
- public Rectangle2D getBounds2D()
- {
- return new Rectangle2D.Double(x, y, width, height);
- }
-
- /**
- * Returns the height of the ellipse.
- * @return The height of the ellipse.
- */
- public double getHeight()
- {
- return height;
- }
-
- /**
- * Returns the width of the ellipse.
- * @return The width of the ellipse.
- */
- public double getWidth()
- {
- return width;
- }
-
- /**
- * Returns x coordinate of the upper-left corner of
- * the ellipse's bounding-box.
- * @return The x coordinate.
- */
- public double getX()
- {
- return x;
- }
-
- /**
- * Returns y coordinate of the upper-left corner of
- * the ellipse's bounding-box.
- * @return The y coordinate.
- */
- public double getY()
- {
- return y;
- }
-
- /**
- * Returns <code>true</code> if the ellipse encloses no area, and
- * <code>false</code> otherwise.
- *
- * @return A boolean.
- */
- public boolean isEmpty()
- {
- return height <= 0 || width <= 0;
- }
-
- /**
- * Sets the geometry of the ellipse's bounding box.<P>
- *
- * @param x - x coordinate of the upper-left of the bounding rectangle
- * @param y - y coordinate of the upper-left of the bounding rectangle
- * @param w - width of the ellipse
- * @param h - height of the ellipse
- */
- public void setFrame(double x, double y, double w, double h)
- {
- this.x = x;
- this.y = y;
- height = h;
- width = w;
- }
- } // class Double
-
- /**
- * An {@link Ellipse2D} that stores its coordinates using <code>float</code>
- * primitives.
- */
- public static class Float extends Ellipse2D
- {
- /**
- * The height of the ellipse.
- */
- public float height;
-
- /**
- * The width of the ellipse.
- */
- public float width;
-
- /**
- * The upper-left x coordinate of the bounding-box
- */
- public float x;
-
- /**
- * The upper-left y coordinate of the bounding-box
- */
- public float y;
-
- /**
- * Creates a new Ellipse2D with an upper-left coordinate of (0,0)
- * and a zero size.
- */
- public Float()
- {
- }
-
- /**
- * Creates a new Ellipse2D within a given rectangle
- * using floating-point precision.<P>
- * @param x - x coordinate of the upper-left of the bounding rectangle
- * @param y - y coordinate of the upper-left of the bounding rectangle
- * @param w - width of the ellipse
- * @param h - height of the ellipse
- *
- */
- public Float(float x, float y, float w, float h)
- {
- this.x = x;
- this.y = y;
- this.height = h;
- this.width = w;
- }
-
- /**
- * Returns the bounding-box of the ellipse.
- * @return The bounding box.
- */
- public Rectangle2D getBounds2D()
- {
- return new Rectangle2D.Float(x, y, width, height);
- }
-
- /**
- * Returns the height of the ellipse.
- * @return The height of the ellipse.
- */
- public double getHeight()
- {
- return height;
- }
-
- /**
- * Returns the width of the ellipse.
- * @return The width of the ellipse.
- */
- public double getWidth()
- {
- return width;
- }
-
- /**
- * Returns x coordinate of the upper-left corner of
- * the ellipse's bounding-box.
- * @return The x coordinate.
- */
- public double getX()
- {
- return x;
- }
-
- /**
- * Returns y coordinate of the upper-left corner of
- * the ellipse's bounding-box.
- * @return The y coordinate.
- */
- public double getY()
- {
- return y;
- }
-
- /**
- * Returns <code>true</code> if the ellipse encloses no area, and
- * <code>false</code> otherwise.
- *
- * @return A boolean.
- */
- public boolean isEmpty()
- {
- return height <= 0 || width <= 0;
- }
-
- /**
- * Sets the geometry of the ellipse's bounding box.<P>
- *
- * @param x - x coordinate of the upper-left of the bounding rectangle
- * @param y - y coordinate of the upper-left of the bounding rectangle
- * @param w - width of the ellipse
- * @param h - height of the ellipse
- */
- public void setFrame(float x, float y, float w, float h)
- {
- this.x = x;
- this.y = y;
- height = h;
- width = w;
- }
-
- /**
- * Sets the geometry of the ellipse's bounding box.
- *
- * Note: This leads to a loss of precision.<P>
- *
- * @param x - x coordinate of the upper-left of the bounding rectangle
- * @param y - y coordinate of the upper-left of the bounding rectangle
- * @param w - width of the ellipse
- * @param h - height of the ellipse
- */
- public void setFrame(double x, double y, double w, double h)
- {
- this.x = (float) x;
- this.y = (float) y;
- height = (float) h;
- width = (float) w;
- }
- } // class Float
-} // class Ellipse2D
diff --git a/libjava/classpath/java/awt/geom/FlatteningPathIterator.java b/libjava/classpath/java/awt/geom/FlatteningPathIterator.java
deleted file mode 100644
index 629936b..0000000
--- a/libjava/classpath/java/awt/geom/FlatteningPathIterator.java
+++ /dev/null
@@ -1,579 +0,0 @@
-/* FlatteningPathIterator.java -- Approximates curves by straight lines
- Copyright (C) 2003 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.util.NoSuchElementException;
-
-
-/**
- * A PathIterator for approximating curved path segments by sequences
- * of straight lines. Instances of this class will only return
- * segments of type {@link PathIterator#SEG_MOVETO}, {@link
- * PathIterator#SEG_LINETO}, and {@link PathIterator#SEG_CLOSE}.
- *
- * <p>The accuracy of the approximation is determined by two
- * parameters:
- *
- * <ul><li>The <i>flatness</i> is a threshold value for deciding when
- * a curved segment is consided flat enough for being approximated by
- * a single straight line. Flatness is defined as the maximal distance
- * of a curve control point to the straight line that connects the
- * curve start and end. A lower flatness threshold means a closer
- * approximation. See {@link QuadCurve2D#getFlatness()} and {@link
- * CubicCurve2D#getFlatness()} for drawings which illustrate the
- * meaning of flatness.</li>
- *
- * <li>The <i>recursion limit</i> imposes an upper bound for how often
- * a curved segment gets subdivided. A limit of <i>n</i> means that
- * for each individual quadratic and cubic B&#xe9;zier spline
- * segment, at most 2<sup><small><i>n</i></small></sup> {@link
- * PathIterator#SEG_LINETO} segments will be created.</li></ul>
- *
- * <p><b>Memory Efficiency:</b> The memory consumption grows linearly
- * with the recursion limit. Neither the <i>flatness</i> parameter nor
- * the number of segments in the flattened path will affect the memory
- * consumption.
- *
- * <p><b>Thread Safety:</b> Multiple threads can safely work on
- * separate instances of this class. However, multiple threads should
- * not concurrently access the same instance, as no synchronization is
- * performed.
- *
- * @see <a href="doc-files/FlatteningPathIterator-1.html"
- * >Implementation Note</a>
- *
- * @author Sascha Brawer (brawer@dandelis.ch)
- *
- * @since 1.2
- */
-public class FlatteningPathIterator
- implements PathIterator
-{
- /**
- * The PathIterator whose curved segments are being approximated.
- */
- private final PathIterator srcIter;
-
-
- /**
- * The square of the flatness threshold value, which determines when
- * a curve segment is considered flat enough that no further
- * subdivision is needed.
- *
- * <p>Calculating flatness actually produces the squared flatness
- * value. To avoid the relatively expensive calculation of a square
- * root for each curve segment, we perform all flatness comparisons
- * on squared values.
- *
- * @see QuadCurve2D#getFlatnessSq()
- * @see CubicCurve2D#getFlatnessSq()
- */
- private final double flatnessSq;
-
-
- /**
- * The maximal number of subdivions that are performed to
- * approximate a quadratic or cubic curve segment.
- */
- private final int recursionLimit;
-
-
- /**
- * A stack for holding the coordinates of subdivided segments.
- *
- * @see <a href="doc-files/FlatteningPathIterator-1.html"
- * >Implementation Note</a>
- */
- private double[] stack;
-
-
- /**
- * The current stack size.
- *
- * @see <a href="doc-files/FlatteningPathIterator-1.html"
- * >Implementation Note</a>
- */
- private int stackSize;
-
-
- /**
- * The number of recursions that were performed to arrive at
- * a segment on the stack.
- *
- * @see <a href="doc-files/FlatteningPathIterator-1.html"
- * >Implementation Note</a>
- */
- private int[] recLevel;
-
-
-
- private final double[] scratch = new double[6];
-
-
- /**
- * The segment type of the last segment that was returned by
- * the source iterator.
- */
- private int srcSegType;
-
-
- /**
- * The current <i>x</i> position of the source iterator.
- */
- private double srcPosX;
-
-
- /**
- * The current <i>y</i> position of the source iterator.
- */
- private double srcPosY;
-
-
- /**
- * A flag that indicates when this path iterator has finished its
- * iteration over path segments.
- */
- private boolean done;
-
-
- /**
- * Constructs a new PathIterator for approximating an input
- * PathIterator with straight lines. The approximation works by
- * recursive subdivisons, until the specified flatness threshold is
- * not exceeded.
- *
- * <p>There will not be more than 10 nested recursion steps, which
- * means that a single <code>SEG_QUADTO</code> or
- * <code>SEG_CUBICTO</code> segment is approximated by at most
- * 2<sup><small>10</small></sup> = 1024 straight lines.
- */
- public FlatteningPathIterator(PathIterator src, double flatness)
- {
- this(src, flatness, 10);
- }
-
-
- /**
- * Constructs a new PathIterator for approximating an input
- * PathIterator with straight lines. The approximation works by
- * recursive subdivisons, until the specified flatness threshold is
- * not exceeded. Additionally, the number of recursions is also
- * bound by the specified recursion limit.
- */
- public FlatteningPathIterator(PathIterator src, double flatness,
- int limit)
- {
- if (flatness < 0 || limit < 0)
- throw new IllegalArgumentException();
-
- srcIter = src;
- flatnessSq = flatness * flatness;
- recursionLimit = limit;
- fetchSegment();
- }
-
-
- /**
- * Returns the maximally acceptable flatness.
- *
- * @see QuadCurve2D#getFlatness()
- * @see CubicCurve2D#getFlatness()
- */
- public double getFlatness()
- {
- return Math.sqrt(flatnessSq);
- }
-
-
- /**
- * Returns the maximum number of recursive curve subdivisions.
- */
- public int getRecursionLimit()
- {
- return recursionLimit;
- }
-
-
- // Documentation will be copied from PathIterator.
- public int getWindingRule()
- {
- return srcIter.getWindingRule();
- }
-
-
- // Documentation will be copied from PathIterator.
- public boolean isDone()
- {
- return done;
- }
-
-
- // Documentation will be copied from PathIterator.
- public void next()
- {
- if (stackSize > 0)
- {
- --stackSize;
- if (stackSize > 0)
- {
- switch (srcSegType)
- {
- case PathIterator.SEG_QUADTO:
- subdivideQuadratic();
- return;
-
- case PathIterator.SEG_CUBICTO:
- subdivideCubic();
- return;
-
- default:
- throw new IllegalStateException();
- }
- }
- }
-
- srcIter.next();
- fetchSegment();
- }
-
-
- // Documentation will be copied from PathIterator.
- public int currentSegment(double[] coords)
- {
- if (done)
- throw new NoSuchElementException();
-
- switch (srcSegType)
- {
- case PathIterator.SEG_CLOSE:
- return srcSegType;
-
- case PathIterator.SEG_MOVETO:
- case PathIterator.SEG_LINETO:
- coords[0] = srcPosX;
- coords[1] = srcPosY;
- return srcSegType;
-
- case PathIterator.SEG_QUADTO:
- if (stackSize == 0)
- {
- coords[0] = srcPosX;
- coords[1] = srcPosY;
- }
- else
- {
- int sp = stack.length - 4 * stackSize;
- coords[0] = stack[sp + 2];
- coords[1] = stack[sp + 3];
- }
- return PathIterator.SEG_LINETO;
-
- case PathIterator.SEG_CUBICTO:
- if (stackSize == 0)
- {
- coords[0] = srcPosX;
- coords[1] = srcPosY;
- }
- else
- {
- int sp = stack.length - 6 * stackSize;
- coords[0] = stack[sp + 4];
- coords[1] = stack[sp + 5];
- }
- return PathIterator.SEG_LINETO;
- }
-
- throw new IllegalStateException();
- }
-
-
- // Documentation will be copied from PathIterator.
- public int currentSegment(float[] coords)
- {
- if (done)
- throw new NoSuchElementException();
-
- switch (srcSegType)
- {
- case PathIterator.SEG_CLOSE:
- return srcSegType;
-
- case PathIterator.SEG_MOVETO:
- case PathIterator.SEG_LINETO:
- coords[0] = (float) srcPosX;
- coords[1] = (float) srcPosY;
- return srcSegType;
-
- case PathIterator.SEG_QUADTO:
- if (stackSize == 0)
- {
- coords[0] = (float) srcPosX;
- coords[1] = (float) srcPosY;
- }
- else
- {
- int sp = stack.length - 4 * stackSize;
- coords[0] = (float) stack[sp + 2];
- coords[1] = (float) stack[sp + 3];
- }
- return PathIterator.SEG_LINETO;
-
- case PathIterator.SEG_CUBICTO:
- if (stackSize == 0)
- {
- coords[0] = (float) srcPosX;
- coords[1] = (float) srcPosY;
- }
- else
- {
- int sp = stack.length - 6 * stackSize;
- coords[0] = (float) stack[sp + 4];
- coords[1] = (float) stack[sp + 5];
- }
- return PathIterator.SEG_LINETO;
- }
-
- throw new IllegalStateException();
- }
-
-
- /**
- * Fetches the next segment from the source iterator.
- */
- private void fetchSegment()
- {
- int sp;
-
- if (srcIter.isDone())
- {
- done = true;
- return;
- }
-
- srcSegType = srcIter.currentSegment(scratch);
-
- switch (srcSegType)
- {
- case PathIterator.SEG_CLOSE:
- return;
-
- case PathIterator.SEG_MOVETO:
- case PathIterator.SEG_LINETO:
- srcPosX = scratch[0];
- srcPosY = scratch[1];
- return;
-
- case PathIterator.SEG_QUADTO:
- if (recursionLimit == 0)
- {
- srcPosX = scratch[2];
- srcPosY = scratch[3];
- stackSize = 0;
- return;
- }
- sp = 4 * recursionLimit;
- stackSize = 1;
- if (stack == null)
- {
- stack = new double[sp + /* 4 + 2 */ 6];
- recLevel = new int[recursionLimit + 1];
- }
- recLevel[0] = 0;
- stack[sp] = srcPosX; // P1.x
- stack[sp + 1] = srcPosY; // P1.y
- stack[sp + 2] = scratch[0]; // C.x
- stack[sp + 3] = scratch[1]; // C.y
- srcPosX = stack[sp + 4] = scratch[2]; // P2.x
- srcPosY = stack[sp + 5] = scratch[3]; // P2.y
- subdivideQuadratic();
- break;
-
- case PathIterator.SEG_CUBICTO:
- if (recursionLimit == 0)
- {
- srcPosX = scratch[4];
- srcPosY = scratch[5];
- stackSize = 0;
- return;
- }
- sp = 6 * recursionLimit;
- stackSize = 1;
- if ((stack == null) || (stack.length < sp + 8))
- {
- stack = new double[sp + /* 6 + 2 */ 8];
- recLevel = new int[recursionLimit + 1];
- }
- recLevel[0] = 0;
- stack[sp] = srcPosX; // P1.x
- stack[sp + 1] = srcPosY; // P1.y
- stack[sp + 2] = scratch[0]; // C1.x
- stack[sp + 3] = scratch[1]; // C1.y
- stack[sp + 4] = scratch[2]; // C2.x
- stack[sp + 5] = scratch[3]; // C2.y
- srcPosX = stack[sp + 6] = scratch[4]; // P2.x
- srcPosY = stack[sp + 7] = scratch[5]; // P2.y
- subdivideCubic();
- return;
- }
- }
-
-
- /**
- * Repeatedly subdivides the quadratic curve segment that is on top
- * of the stack. The iteration terminates when the recursion limit
- * has been reached, or when the resulting segment is flat enough.
- */
- private void subdivideQuadratic()
- {
- int sp;
- int level;
-
- sp = stack.length - 4 * stackSize - 2;
- level = recLevel[stackSize - 1];
- while ((level < recursionLimit)
- && (QuadCurve2D.getFlatnessSq(stack, sp) >= flatnessSq))
- {
- recLevel[stackSize] = recLevel[stackSize - 1] = ++level;
- QuadCurve2D.subdivide(stack, sp, stack, sp - 4, stack, sp);
- ++stackSize;
- sp -= 4;
- }
- }
-
-
- /**
- * Repeatedly subdivides the cubic curve segment that is on top
- * of the stack. The iteration terminates when the recursion limit
- * has been reached, or when the resulting segment is flat enough.
- */
- private void subdivideCubic()
- {
- int sp;
- int level;
-
- sp = stack.length - 6 * stackSize - 2;
- level = recLevel[stackSize - 1];
- while ((level < recursionLimit)
- && (CubicCurve2D.getFlatnessSq(stack, sp) >= flatnessSq))
- {
- recLevel[stackSize] = recLevel[stackSize - 1] = ++level;
-
- CubicCurve2D.subdivide(stack, sp, stack, sp - 6, stack, sp);
- ++stackSize;
- sp -= 6;
- }
- }
-
-
- /* These routines were useful for debugging. Since they would
- * just bloat the implementation, they are commented out.
- *
- *
-
- private static String segToString(int segType, double[] d, int offset)
- {
- String s;
-
- switch (segType)
- {
- case PathIterator.SEG_CLOSE:
- return "SEG_CLOSE";
-
- case PathIterator.SEG_MOVETO:
- return "SEG_MOVETO (" + d[offset] + ", " + d[offset + 1] + ")";
-
- case PathIterator.SEG_LINETO:
- return "SEG_LINETO (" + d[offset] + ", " + d[offset + 1] + ")";
-
- case PathIterator.SEG_QUADTO:
- return "SEG_QUADTO (" + d[offset] + ", " + d[offset + 1]
- + ") (" + d[offset + 2] + ", " + d[offset + 3] + ")";
-
- case PathIterator.SEG_CUBICTO:
- return "SEG_CUBICTO (" + d[offset] + ", " + d[offset + 1]
- + ") (" + d[offset + 2] + ", " + d[offset + 3]
- + ") (" + d[offset + 4] + ", " + d[offset + 5] + ")";
- }
-
- throw new IllegalStateException();
- }
-
-
- private void dumpQuadraticStack(String msg)
- {
- int sp = stack.length - 4 * stackSize - 2;
- int i = 0;
- System.err.print(" " + msg + ":");
- while (sp < stack.length)
- {
- System.err.print(" (" + stack[sp] + ", " + stack[sp+1] + ")");
- if (i < recLevel.length)
- System.out.print("/" + recLevel[i++]);
- if (sp + 3 < stack.length)
- System.err.print(" [" + stack[sp+2] + ", " + stack[sp+3] + "]");
- sp += 4;
- }
- System.err.println();
- }
-
-
- private void dumpCubicStack(String msg)
- {
- int sp = stack.length - 6 * stackSize - 2;
- int i = 0;
- System.err.print(" " + msg + ":");
- while (sp < stack.length)
- {
- System.err.print(" (" + stack[sp] + ", " + stack[sp+1] + ")");
- if (i < recLevel.length)
- System.out.print("/" + recLevel[i++]);
- if (sp + 3 < stack.length)
- {
- System.err.print(" [" + stack[sp+2] + ", " + stack[sp+3] + "]");
- System.err.print(" [" + stack[sp+4] + ", " + stack[sp+5] + "]");
- }
- sp += 6;
- }
- System.err.println();
- }
-
- *
- *
- */
-}
diff --git a/libjava/classpath/java/awt/geom/GeneralPath.java b/libjava/classpath/java/awt/geom/GeneralPath.java
deleted file mode 100644
index 99f1905..0000000
--- a/libjava/classpath/java/awt/geom/GeneralPath.java
+++ /dev/null
@@ -1,992 +0,0 @@
-/* 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
diff --git a/libjava/classpath/java/awt/geom/IllegalPathStateException.java b/libjava/classpath/java/awt/geom/IllegalPathStateException.java
deleted file mode 100644
index 4d190c7..0000000
--- a/libjava/classpath/java/awt/geom/IllegalPathStateException.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/* IllegalPathStateException.java -- an operation was in an illegal path state
- Copyright (C) 2000, 2002 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;
-
-/**
- * Thrown when an operation on a path is in an illegal state, such as appending
- * a segment to a <code>GeneralPath</code> without an initial moveto.
- *
- * @author Tom Tromey (tromey@cygnus.com)
- * @see GeneralPath
- * @status updated to 1.4
- */
-public class IllegalPathStateException extends RuntimeException
-{
- /**
- * Compatible with JDK 1.2+.
- */
- private static final long serialVersionUID = -5158084205220481094L;
-
- /**
- * Create an exception with no message.
- */
- public IllegalPathStateException()
- {
- }
-
- /**
- * Create an exception with a message.
- *
- * @param msg the message
- */
- public IllegalPathStateException(String msg)
- {
- super(msg);
- }
-}
diff --git a/libjava/classpath/java/awt/geom/Line2D.java b/libjava/classpath/java/awt/geom/Line2D.java
deleted file mode 100644
index c92aab0..0000000
--- a/libjava/classpath/java/awt/geom/Line2D.java
+++ /dev/null
@@ -1,1182 +0,0 @@
-/* Line2D.java -- represents a line in 2-D space, plus operations on a line
- Copyright (C) 2000, 2001, 2002 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;
-import java.util.NoSuchElementException;
-
-/**
- * Represents a directed line bewteen two points in (x,y) Cartesian space.
- * Remember, on-screen graphics have increasing x from left-to-right, and
- * increasing y from top-to-bottom. The storage is left to subclasses.
- *
- * @author Tom Tromey (tromey@cygnus.com)
- * @author Eric Blake (ebb9@email.byu.edu)
- * @author David Gilbert
- * @since 1.2
- * @status updated to 1.4
- */
-public abstract class Line2D implements Shape, Cloneable
-{
- /**
- * The default constructor.
- */
- protected Line2D()
- {
- }
-
- /**
- * Return the x coordinate of the first point.
- *
- * @return the starting x coordinate
- */
- public abstract double getX1();
-
- /**
- * Return the y coordinate of the first point.
- *
- * @return the starting y coordinate
- */
- public abstract double getY1();
-
- /**
- * Return the first point.
- *
- * @return the starting point
- */
- public abstract Point2D getP1();
-
- /**
- * Return the x coordinate of the second point.
- *
- * @return the ending x coordinate
- */
- public abstract double getX2();
-
- /**
- * Return the y coordinate of the second point.
- *
- * @return the ending y coordinate
- */
- public abstract double getY2();
-
- /**
- * Return the second point.
- *
- * @return the ending point
- */
- public abstract Point2D getP2();
-
- /**
- * Set the coordinates of the line to the given coordinates. Loss of
- * precision may occur due to rounding issues.
- *
- * @param x1 the first x coordinate
- * @param y1 the first y coordinate
- * @param x2 the second x coordinate
- * @param y2 the second y coordinate
- */
- public abstract void setLine(double x1, double y1, double x2, double y2);
-
- /**
- * Set the coordinates to the given points.
- *
- * @param p1 the first point
- * @param p2 the second point
- * @throws NullPointerException if either point is null
- */
- public void setLine(Point2D p1, Point2D p2)
- {
- setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
- }
-
- /**
- * Set the coordinates to those of the given line.
- *
- * @param l the line to copy
- * @throws NullPointerException if l is null
- */
- public void setLine(Line2D l)
- {
- setLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
- }
-
- /**
- * Computes the relative rotation direction needed to pivot the line about
- * the first point in order to have the second point colinear with point p.
- * Because of floating point rounding, don't expect this to be a perfect
- * measure of colinearity. The answer is 1 if the line has a shorter rotation
- * in the direction of the positive X axis to the negative Y axis
- * (counter-clockwise in the default Java coordinate system), or -1 if the
- * shortest rotation is in the opposite direction (clockwise). If p
- * is already colinear, the return value is -1 if it lies beyond the first
- * point, 0 if it lies in the segment, or 1 if it lies beyond the second
- * point. If the first and second point are coincident, this returns 0.
- *
- * @param x1 the first x coordinate
- * @param y1 the first y coordinate
- * @param x2 the second x coordinate
- * @param y2 the second y coordinate
- * @param px the reference x coordinate
- * @param py the reference y coordinate
- * @return the relative rotation direction
- */
- public static int relativeCCW(double x1, double y1, double x2, double y2,
- double px, double py)
- {
- if ((x1 == x2 && y1 == y2)
- || (x1 == px && y1 == py))
- return 0; // Coincident points.
- // Translate to the origin.
- x2 -= x1;
- y2 -= y1;
- px -= x1;
- py -= y1;
- double slope2 = y2 / x2;
- double slopep = py / px;
- if (slope2 == slopep || (x2 == 0 && px == 0))
- return y2 > 0 // Colinear.
- ? (py < 0 ? -1 : py > y2 ? 1 : 0)
- : (py > 0 ? -1 : py < y2 ? 1 : 0);
- if (x2 >= 0 && slope2 >= 0)
- return px >= 0 // Quadrant 1.
- ? (slope2 > slopep ? 1 : -1)
- : (slope2 < slopep ? 1 : -1);
- if (y2 > 0)
- return px < 0 // Quadrant 2.
- ? (slope2 > slopep ? 1 : -1)
- : (slope2 < slopep ? 1 : -1);
- if (slope2 >= 0.0)
- return px >= 0 // Quadrant 3.
- ? (slope2 < slopep ? 1 : -1)
- : (slope2 > slopep ? 1 : -1);
- return px < 0 // Quadrant 4.
- ? (slope2 < slopep ? 1 : -1)
- : (slope2 > slopep ? 1 : -1);
- }
-
- /**
- * Computes the relative rotation direction needed to pivot this line about
- * the first point in order to have the second point colinear with point p.
- * Because of floating point rounding, don't expect this to be a perfect
- * measure of colinearity. The answer is 1 if the line has a shorter rotation
- * in the direction of the positive X axis to the negative Y axis
- * (counter-clockwise in the default Java coordinate system), or -1 if the
- * shortest rotation is in the opposite direction (clockwise). If p
- * is already colinear, the return value is -1 if it lies beyond the first
- * point, 0 if it lies in the segment, or 1 if it lies beyond the second
- * point. If the first and second point are coincident, this returns 0.
- *
- * @param px the reference x coordinate
- * @param py the reference y coordinate
- * @return the relative rotation direction
- * @see #relativeCCW(double, double, double, double, double, double)
- */
- public int relativeCCW(double px, double py)
- {
- return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
- }
-
- /**
- * Computes the relative rotation direction needed to pivot this line about
- * the first point in order to have the second point colinear with point p.
- * Because of floating point rounding, don't expect this to be a perfect
- * measure of colinearity. The answer is 1 if the line has a shorter rotation
- * in the direction of the positive X axis to the negative Y axis
- * (counter-clockwise in the default Java coordinate system), or -1 if the
- * shortest rotation is in the opposite direction (clockwise). If p
- * is already colinear, the return value is -1 if it lies beyond the first
- * point, 0 if it lies in the segment, or 1 if it lies beyond the second
- * point. If the first and second point are coincident, this returns 0.
- *
- * @param p the reference point
- * @return the relative rotation direction
- * @throws NullPointerException if p is null
- * @see #relativeCCW(double, double, double, double, double, double)
- */
- public int relativeCCW(Point2D p)
- {
- return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
- }
-
- /**
- * Computes twice the (signed) area of the triangle defined by the three
- * points. This method is used for intersection testing.
- *
- * @param x1 the x-coordinate of the first point.
- * @param y1 the y-coordinate of the first point.
- * @param x2 the x-coordinate of the second point.
- * @param y2 the y-coordinate of the second point.
- * @param x3 the x-coordinate of the third point.
- * @param y3 the y-coordinate of the third point.
- *
- * @return Twice the area.
- */
- private static double area2(double x1, double y1,
- double x2, double y2,
- double x3, double y3)
- {
- return (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
- }
-
- /**
- * Returns <code>true</code> if (x3, y3) lies between (x1, y1) and (x2, y2),
- * and false otherwise, This test assumes that the three points are
- * collinear, and is used for intersection testing.
- *
- * @param x1 the x-coordinate of the first point.
- * @param y1 the y-coordinate of the first point.
- * @param x2 the x-coordinate of the second point.
- * @param y2 the y-coordinate of the second point.
- * @param x3 the x-coordinate of the third point.
- * @param y3 the y-coordinate of the third point.
- *
- * @return A boolean.
- */
- private static boolean between(double x1, double y1,
- double x2, double y2,
- double x3, double y3)
- {
- if (x1 != x2) {
- return (x1 <= x3 && x3 <= x2) || (x1 >= x3 && x3 >= x2);
- }
- else {
- return (y1 <= y3 && y3 <= y2) || (y1 >= y3 && y3 >= y2);
- }
- }
-
- /**
- * Test if the line segment (x1,y1)-&gt;(x2,y2) intersects the line segment
- * (x3,y3)-&gt;(x4,y4).
- *
- * @param x1 the first x coordinate of the first segment
- * @param y1 the first y coordinate of the first segment
- * @param x2 the second x coordinate of the first segment
- * @param y2 the second y coordinate of the first segment
- * @param x3 the first x coordinate of the second segment
- * @param y3 the first y coordinate of the second segment
- * @param x4 the second x coordinate of the second segment
- * @param y4 the second y coordinate of the second segment
- * @return true if the segments intersect
- */
- public static boolean linesIntersect(double x1, double y1,
- double x2, double y2,
- double x3, double y3,
- double x4, double y4)
- {
- double a1, a2, a3, a4;
-
- // deal with special cases
- if ((a1 = area2(x1, y1, x2, y2, x3, y3)) == 0.0)
- {
- // check if p3 is between p1 and p2 OR
- // p4 is collinear also AND either between p1 and p2 OR at opposite ends
- if (between(x1, y1, x2, y2, x3, y3))
- {
- return true;
- }
- else
- {
- if (area2(x1, y1, x2, y2, x4, y4) == 0.0)
- {
- return between(x3, y3, x4, y4, x1, y1)
- || between (x3, y3, x4, y4, x2, y2);
- }
- else {
- return false;
- }
- }
- }
- else if ((a2 = area2(x1, y1, x2, y2, x4, y4)) == 0.0)
- {
- // check if p4 is between p1 and p2 (we already know p3 is not
- // collinear)
- return between(x1, y1, x2, y2, x4, y4);
- }
-
- if ((a3 = area2(x3, y3, x4, y4, x1, y1)) == 0.0) {
- // check if p1 is between p3 and p4 OR
- // p2 is collinear also AND either between p1 and p2 OR at opposite ends
- if (between(x3, y3, x4, y4, x1, y1)) {
- return true;
- }
- else {
- if (area2(x3, y3, x4, y4, x2, y2) == 0.0) {
- return between(x1, y1, x2, y2, x3, y3)
- || between (x1, y1, x2, y2, x4, y4);
- }
- else {
- return false;
- }
- }
- }
- else if ((a4 = area2(x3, y3, x4, y4, x2, y2)) == 0.0) {
- // check if p2 is between p3 and p4 (we already know p1 is not
- // collinear)
- return between(x3, y3, x4, y4, x2, y2);
- }
- else { // test for regular intersection
- return ((a1 > 0.0) ^ (a2 > 0.0)) && ((a3 > 0.0) ^ (a4 > 0.0));
- }
- }
-
- /**
- * Test if this line intersects the line given by (x1,y1)-&gt;(x2,y2).
- *
- * @param x1 the first x coordinate of the other segment
- * @param y1 the first y coordinate of the other segment
- * @param x2 the second x coordinate of the other segment
- * @param y2 the second y coordinate of the other segment
- * @return true if the segments intersect
- * @see #linesIntersect(double, double, double, double,
- * double, double, double, double)
- */
- public boolean intersectsLine(double x1, double y1, double x2, double y2)
- {
- return linesIntersect(getX1(), getY1(), getX2(), getY2(),
- x1, y1, x2, y2);
- }
-
- /**
- * Test if this line intersects the given line.
- *
- * @param l the other segment
- * @return true if the segments intersect
- * @throws NullPointerException if l is null
- * @see #linesIntersect(double, double, double, double,
- * double, double, double, double)
- */
- public boolean intersectsLine(Line2D l)
- {
- return linesIntersect(getX1(), getY1(), getX2(), getY2(),
- l.getX1(), l.getY1(), l.getX2(), l.getY2());
- }
-
- /**
- * Measures the square of the shortest distance from the reference point
- * to a point on the line segment. If the point is on the segment, the
- * result will be 0.
- *
- * @param x1 the first x coordinate of the segment
- * @param y1 the first y coordinate of the segment
- * @param x2 the second x coordinate of the segment
- * @param y2 the second y coordinate of the segment
- * @param px the x coordinate of the point
- * @param py the y coordinate of the point
- * @return the square of the distance from the point to the segment
- * @see #ptSegDist(double, double, double, double, double, double)
- * @see #ptLineDistSq(double, double, double, double, double, double)
- */
- public static double ptSegDistSq(double x1, double y1, double x2, double y2,
- double px, double py)
- {
- double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
-
- double x, y;
- if (pd2 == 0)
- {
- // Points are coincident.
- x = x1;
- y = y2;
- }
- else
- {
- double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;
-
- if (u < 0)
- {
- // "Off the end"
- x = x1;
- y = y1;
- }
- else if (u > 1.0)
- {
- x = x2;
- y = y2;
- }
- else
- {
- x = x1 + u * (x2 - x1);
- y = y1 + u * (y2 - y1);
- }
- }
-
- return (x - px) * (x - px) + (y - py) * (y - py);
- }
-
- /**
- * Measures the shortest distance from the reference point to a point on
- * the line segment. If the point is on the segment, the result will be 0.
- *
- * @param x1 the first x coordinate of the segment
- * @param y1 the first y coordinate of the segment
- * @param x2 the second x coordinate of the segment
- * @param y2 the second y coordinate of the segment
- * @param px the x coordinate of the point
- * @param py the y coordinate of the point
- * @return the distance from the point to the segment
- * @see #ptSegDistSq(double, double, double, double, double, double)
- * @see #ptLineDist(double, double, double, double, double, double)
- */
- public static double ptSegDist(double x1, double y1, double x2, double y2,
- double px, double py)
- {
- return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
- }
-
- /**
- * Measures the square of the shortest distance from the reference point
- * to a point on this line segment. If the point is on the segment, the
- * result will be 0.
- *
- * @param px the x coordinate of the point
- * @param py the y coordinate of the point
- * @return the square of the distance from the point to the segment
- * @see #ptSegDistSq(double, double, double, double, double, double)
- */
- public double ptSegDistSq(double px, double py)
- {
- return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
- }
-
- /**
- * Measures the square of the shortest distance from the reference point
- * to a point on this line segment. If the point is on the segment, the
- * result will be 0.
- *
- * @param p the point
- * @return the square of the distance from the point to the segment
- * @throws NullPointerException if p is null
- * @see #ptSegDistSq(double, double, double, double, double, double)
- */
- public double ptSegDistSq(Point2D p)
- {
- return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
- }
-
- /**
- * Measures the shortest distance from the reference point to a point on
- * this line segment. If the point is on the segment, the result will be 0.
- *
- * @param px the x coordinate of the point
- * @param py the y coordinate of the point
- * @return the distance from the point to the segment
- * @see #ptSegDist(double, double, double, double, double, double)
- */
- public double ptSegDist(double px, double py)
- {
- return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
- }
-
- /**
- * Measures the shortest distance from the reference point to a point on
- * this line segment. If the point is on the segment, the result will be 0.
- *
- * @param p the point
- * @return the distance from the point to the segment
- * @throws NullPointerException if p is null
- * @see #ptSegDist(double, double, double, double, double, double)
- */
- public double ptSegDist(Point2D p)
- {
- return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
- }
-
- /**
- * Measures the square of the shortest distance from the reference point
- * to a point on the infinite line extended from the segment. If the point
- * is on the segment, the result will be 0. If the segment is length 0,
- * the distance is to the common endpoint.
- *
- * @param x1 the first x coordinate of the segment
- * @param y1 the first y coordinate of the segment
- * @param x2 the second x coordinate of the segment
- * @param y2 the second y coordinate of the segment
- * @param px the x coordinate of the point
- * @param py the y coordinate of the point
- * @return the square of the distance from the point to the extended line
- * @see #ptLineDist(double, double, double, double, double, double)
- * @see #ptSegDistSq(double, double, double, double, double, double)
- */
- public static double ptLineDistSq(double x1, double y1, double x2, double y2,
- double px, double py)
- {
- double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
-
- double x, y;
- if (pd2 == 0)
- {
- // Points are coincident.
- x = x1;
- y = y2;
- }
- else
- {
- double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;
- x = x1 + u * (x2 - x1);
- y = y1 + u * (y2 - y1);
- }
-
- return (x - px) * (x - px) + (y - py) * (y - py);
- }
-
- /**
- * Measures the shortest distance from the reference point to a point on
- * the infinite line extended from the segment. If the point is on the
- * segment, the result will be 0. If the segment is length 0, the distance
- * is to the common endpoint.
- *
- * @param x1 the first x coordinate of the segment
- * @param y1 the first y coordinate of the segment
- * @param x2 the second x coordinate of the segment
- * @param y2 the second y coordinate of the segment
- * @param px the x coordinate of the point
- * @param py the y coordinate of the point
- * @return the distance from the point to the extended line
- * @see #ptLineDistSq(double, double, double, double, double, double)
- * @see #ptSegDist(double, double, double, double, double, double)
- */
- public static double ptLineDist(double x1, double y1,
- double x2, double y2,
- double px, double py)
- {
- return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
- }
-
- /**
- * Measures the square of the shortest distance from the reference point
- * to a point on the infinite line extended from this segment. If the point
- * is on the segment, the result will be 0. If the segment is length 0,
- * the distance is to the common endpoint.
- *
- * @param px the x coordinate of the point
- * @param py the y coordinate of the point
- * @return the square of the distance from the point to the extended line
- * @see #ptLineDistSq(double, double, double, double, double, double)
- */
- public double ptLineDistSq(double px, double py)
- {
- return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
- }
-
- /**
- * Measures the square of the shortest distance from the reference point
- * to a point on the infinite line extended from this segment. If the point
- * is on the segment, the result will be 0. If the segment is length 0,
- * the distance is to the common endpoint.
- *
- * @param p the point
- * @return the square of the distance from the point to the extended line
- * @throws NullPointerException if p is null
- * @see #ptLineDistSq(double, double, double, double, double, double)
- */
- public double ptLineDistSq(Point2D p)
- {
- return ptLineDistSq(getX1(), getY1(), getX2(), getY2(),
- p.getX(), p.getY());
- }
-
- /**
- * Measures the shortest distance from the reference point to a point on
- * the infinite line extended from this segment. If the point is on the
- * segment, the result will be 0. If the segment is length 0, the distance
- * is to the common endpoint.
- *
- * @param px the x coordinate of the point
- * @param py the y coordinate of the point
- * @return the distance from the point to the extended line
- * @see #ptLineDist(double, double, double, double, double, double)
- */
- public double ptLineDist(double px, double py)
- {
- return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
- }
-
- /**
- * Measures the shortest distance from the reference point to a point on
- * the infinite line extended from this segment. If the point is on the
- * segment, the result will be 0. If the segment is length 0, the distance
- * is to the common endpoint.
- *
- * @param p the point
- * @return the distance from the point to the extended line
- * @throws NullPointerException if p is null
- * @see #ptLineDist(double, double, double, double, double, double)
- */
- public double ptLineDist(Point2D p)
- {
- return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
- }
-
- /**
- * Test if a point is contained inside the line. Since a line has no area,
- * this returns false.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @return false; the line does not contain points
- */
- public boolean contains(double x, double y)
- {
- return false;
- }
-
- /**
- * Test if a point is contained inside the line. Since a line has no area,
- * this returns false.
- *
- * @param p the point
- * @return false; the line does not contain points
- */
- public boolean contains(Point2D p)
- {
- return false;
- }
-
- /**
- * Tests if this line intersects the interior of the specified rectangle.
- *
- * @param x the x coordinate of the rectangle
- * @param y the y coordinate of the rectangle
- * @param w the width of the rectangle
- * @param h the height of the rectangle
- * @return true if the line intersects the rectangle
- */
- public boolean intersects(double x, double y, double w, double h)
- {
- if (w <= 0 || h <= 0)
- return false;
- double x1 = getX1();
- double y1 = getY1();
- double x2 = getX2();
- double y2 = getY2();
-
- if (x1 >= x && x1 <= x + w && y1 >= y && y1 <= y + h)
- return true;
- if (x2 >= x && x2 <= x + w && y2 >= y && y2 <= y + h)
- return true;
-
- double x3 = x + w;
- double y3 = y + h;
-
- return (linesIntersect(x1, y1, x2, y2, x, y, x, y3)
- || linesIntersect(x1, y1, x2, y2, x, y3, x3, y3)
- || linesIntersect(x1, y1, x2, y2, x3, y3, x3, y)
- || linesIntersect(x1, y1, x2, y2, x3, y, x, y));
- }
-
- /**
- * Tests if this line intersects the interior of the specified rectangle.
- *
- * @param r the rectangle
- * @return true if the line intersects the rectangle
- * @throws NullPointerException if r is null
- */
- public boolean intersects(Rectangle2D r)
- {
- return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Tests if the line contains a rectangle. Since lines have no area, this
- * always returns false.
- *
- * @param x the x coordinate of the rectangle
- * @param y the y coordinate of the rectangle
- * @param w the width of the rectangle
- * @param h the height of the rectangle
- * @return false; the line does not contain points
- */
- public boolean contains(double x, double y, double w, double h)
- {
- return false;
- }
-
- /**
- * Tests if the line contains a rectangle. Since lines have no area, this
- * always returns false.
- *
- * @param r the rectangle
- * @return false; the line does not contain points
- */
- public boolean contains(Rectangle2D r)
- {
- return false;
- }
-
- /**
- * Gets a bounding box (not necessarily minimal) for this line.
- *
- * @return the integer bounding box
- * @see #getBounds2D()
- */
- public Rectangle getBounds()
- {
- return getBounds2D().getBounds();
- }
-
- /**
- * Return a path iterator, possibly applying a transform on the result. This
- * iterator is not threadsafe.
- *
- * @param at the transform, or null
- * @return a new path iterator
- */
- public PathIterator getPathIterator(final AffineTransform at)
- {
- return new PathIterator()
- {
- /** Current coordinate. */
- private int current = 0;
-
- public int getWindingRule()
- {
- return WIND_NON_ZERO;
- }
-
- public boolean isDone()
- {
- return current >= 2;
- }
-
- public void next()
- {
- current++;
- }
-
- public int currentSegment(float[] coords)
- {
- int result;
- switch (current)
- {
- case 0:
- coords[0] = (float) getX1();
- coords[1] = (float) getY1();
- result = SEG_MOVETO;
- break;
- case 1:
- coords[0] = (float) getX2();
- coords[1] = (float) getY2();
- result = SEG_LINETO;
- break;
- default:
- throw new NoSuchElementException("line iterator out of bounds");
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 1);
- return result;
- }
-
- public int currentSegment(double[] coords)
- {
- int result;
- switch (current)
- {
- case 0:
- coords[0] = getX1();
- coords[1] = getY1();
- result = SEG_MOVETO;
- break;
- case 1:
- coords[0] = getX2();
- coords[1] = getY2();
- result = SEG_LINETO;
- break;
- default:
- throw new NoSuchElementException("line iterator out of bounds");
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 1);
- return result;
- }
- };
- }
-
- /**
- * Return a flat path iterator, possibly applying a transform on the result.
- * This iterator is not threadsafe.
- *
- * @param at the transform, or null
- * @param flatness ignored, since lines are already flat
- * @return a new path iterator
- * @see #getPathIterator(AffineTransform)
- */
- public PathIterator getPathIterator(AffineTransform at, double flatness)
- {
- return getPathIterator(at);
- }
-
- /**
- * Create a new line 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()
- {
- try
- {
- return super.clone();
- }
- catch (CloneNotSupportedException e)
- {
- throw (Error) new InternalError().initCause(e); // Impossible
- }
- }
-
- /**
- * This class defines a point in <code>double</code> precision.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status updated to 1.4
- */
- public static class Double extends Line2D
- {
- /** The x coordinate of the first point. */
- public double x1;
-
- /** The y coordinate of the first point. */
- public double y1;
-
- /** The x coordinate of the second point. */
- public double x2;
-
- /** The y coordinate of the second point. */
- public double y2;
-
- /**
- * Construct the line segment (0,0)-&gt;(0,0).
- */
- public Double()
- {
- }
-
- /**
- * Construct the line segment with the specified points.
- *
- * @param x1 the x coordinate of the first point
- * @param y1 the y coordinate of the first point
- * @param x2 the x coordinate of the second point
- * @param y2 the y coordinate of the second point
- */
- public Double(double x1, double y1, double x2, double y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Construct the line segment with the specified points.
- *
- * @param p1 the first point
- * @param p2 the second point
- * @throws NullPointerException if either point is null
- */
- public Double(Point2D p1, Point2D p2)
- {
- x1 = p1.getX();
- y1 = p1.getY();
- x2 = p2.getX();
- y2 = p2.getY();
- }
-
- /**
- * Return the x coordinate of the first point.
- *
- * @return the value of x1
- */
- public double getX1()
- {
- return x1;
- }
-
- /**
- * Return the y coordinate of the first point.
- *
- * @return the value of y1
- */
- public double getY1()
- {
- return y1;
- }
-
- /**
- * Return the first point.
- *
- * @return the point (x1,y1)
- */
- public Point2D getP1()
- {
- return new Point2D.Double(x1, y1);
- }
-
- /**
- * Return the x coordinate of the second point.
- *
- * @return the value of x2
- */
- public double getX2()
- {
- return x2;
- }
-
- /**
- * Return the y coordinate of the second point.
- *
- * @return the value of y2
- */
- public double getY2()
- {
- return y2;
- }
-
- /**
- * Return the second point.
- *
- * @return the point (x2,y2)
- */
- public Point2D getP2()
- {
- return new Point2D.Double(x2, y2);
- }
-
- /**
- * Set this line to the given points.
- *
- * @param x1 the new x coordinate of the first point
- * @param y1 the new y coordinate of the first point
- * @param x2 the new x coordinate of the second point
- * @param y2 the new y coordinate of the second point
- */
- public void setLine(double x1, double y1, double x2, double y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Return the exact bounds of this line segment.
- *
- * @return the bounding box
- */
- public Rectangle2D getBounds2D()
- {
- double x = Math.min(x1, x2);
- double y = Math.min(y1, y2);
- double w = Math.abs(x1 - x2);
- double h = Math.abs(y1 - y2);
- return new Rectangle2D.Double(x, y, w, h);
- }
- } // class Double
-
- /**
- * This class defines a point in <code>float</code> precision.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status updated to 1.4
- */
- public static class Float extends Line2D
- {
- /** The x coordinate of the first point. */
- public float x1;
-
- /** The y coordinate of the first point. */
- public float y1;
-
- /** The x coordinate of the second point. */
- public float x2;
-
- /** The y coordinate of the second point. */
- public float y2;
-
- /**
- * Construct the line segment (0,0)-&gt;(0,0).
- */
- public Float()
- {
- }
-
- /**
- * Construct the line segment with the specified points.
- *
- * @param x1 the x coordinate of the first point
- * @param y1 the y coordinate of the first point
- * @param x2 the x coordinate of the second point
- * @param y2 the y coordinate of the second point
- */
- public Float(float x1, float y1, float x2, float y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Construct the line segment with the specified points.
- *
- * @param p1 the first point
- * @param p2 the second point
- * @throws NullPointerException if either point is null
- */
- public Float(Point2D p1, Point2D p2)
- {
- x1 = (float) p1.getX();
- y1 = (float) p1.getY();
- x2 = (float) p2.getX();
- y2 = (float) p2.getY();
- }
-
- /**
- * Return the x coordinate of the first point.
- *
- * @return the value of x1
- */
- public double getX1()
- {
- return x1;
- }
-
- /**
- * Return the y coordinate of the first point.
- *
- * @return the value of y1
- */
- public double getY1()
- {
- return y1;
- }
-
- /**
- * Return the first point.
- *
- * @return the point (x1,y1)
- */
- public Point2D getP1()
- {
- return new Point2D.Float(x1, y1);
- }
-
- /**
- * Return the x coordinate of the second point.
- *
- * @return the value of x2
- */
- public double getX2()
- {
- return x2;
- }
-
- /**
- * Return the y coordinate of the second point.
- *
- * @return the value of y2
- */
- public double getY2()
- {
- return y2;
- }
-
- /**
- * Return the second point.
- *
- * @return the point (x2,y2)
- */
- public Point2D getP2()
- {
- return new Point2D.Float(x2, y2);
- }
-
- /**
- * Set this line to the given points.
- *
- * @param x1 the new x coordinate of the first point
- * @param y1 the new y coordinate of the first point
- * @param x2 the new x coordinate of the second point
- * @param y2 the new y coordinate of the second point
- */
- public void setLine(double x1, double y1, double x2, double y2)
- {
- this.x1 = (float) x1;
- this.y1 = (float) y1;
- this.x2 = (float) x2;
- this.y2 = (float) y2;
- }
-
- /**
- * Set this line to the given points.
- *
- * @param x1 the new x coordinate of the first point
- * @param y1 the new y coordinate of the first point
- * @param x2 the new x coordinate of the second point
- * @param y2 the new y coordinate of the second point
- */
- public void setLine(float x1, float y1, float x2, float y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Return the exact bounds of this line segment.
- *
- * @return the bounding box
- */
- public Rectangle2D getBounds2D()
- {
- float x = Math.min(x1, x2);
- float y = Math.min(y1, y2);
- float w = Math.abs(x1 - x2);
- float h = Math.abs(y1 - y2);
- return new Rectangle2D.Float(x, y, w, h);
- }
- } // class Float
-} // class Line2D
diff --git a/libjava/classpath/java/awt/geom/NoninvertibleTransformException.java b/libjava/classpath/java/awt/geom/NoninvertibleTransformException.java
deleted file mode 100644
index 7995a52..0000000
--- a/libjava/classpath/java/awt/geom/NoninvertibleTransformException.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/* NoninvertibleTransformException.java -- a transform can't be inverted
- Copyright (C) 2000, 2002 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;
-
-/**
- * Thrown if an operation requires an inverse of an
- * <code>AffineTransform</code>, but the transform is in a non-invertible
- * state.
- *
- * @author Tom Tromey (tromey@cygnus.com)
- * @see AffineTransform
- * @status updated to 1.4
- */
-public class NoninvertibleTransformException extends Exception
-{
- /**
- * Compatible with JDK 1.2+.
- */
- private static final long serialVersionUID = 6137225240503990466L;
-
- /**
- * Create an exception with a message.
- *
- * @param s the message
- */
- public NoninvertibleTransformException(String s)
- {
- super(s);
- }
-}
diff --git a/libjava/classpath/java/awt/geom/PathIterator.java b/libjava/classpath/java/awt/geom/PathIterator.java
deleted file mode 100644
index 2cd08b9..0000000
--- a/libjava/classpath/java/awt/geom/PathIterator.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/* PathIterator.java -- describes a shape by iterating over its vertices
- Copyright (C) 2000, 2002, 2003 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;
-
-/**
- * This interface provides a directed path over the boundary of a shape. The
- * path can contain 1st through 3rd order Bezier curves (lines, and quadratic
- * and cubic splines). A shape can have multiple disjoint paths via the
- * MOVETO directive, and can close a circular path back to the previos
- * MOVETO via the CLOSE directive.
- *
- * @author Tom Tromey (tromey@cygnus.com)
- * @author Eric Blake (ebb9@email.byu.edu)
- * @see java.awt.Shape
- * @see java.awt.Stroke
- * @see FlatteningPathIterator
- * @since 1.2
- * @status updated to 1.4
- */
-public interface PathIterator
-{
- /**
- * The even-odd winding mode: a point is internal to the shape if a ray
- * from the point to infinity (in any direction) crosses an odd number of
- * segments.
- */
- int WIND_EVEN_ODD = 0;
-
- /**
- * The non-zero winding mode: a point is internal to the shape if a ray
- * from the point to infinity (in any direction) crosses a different number
- * of segments headed clockwise than those headed counterclockwise.
- */
- int WIND_NON_ZERO = 1;
-
- /**
- * Starts a new subpath. There is no segment from the previous vertex.
- */
- int SEG_MOVETO = 0;
-
- /**
- * The current segment is a line.
- */
- int SEG_LINETO = 1;
-
- /**
- * The current segment is a quadratic parametric curve. It is interpolated
- * as t varies from 0 to 1 over the current point (CP), first control point
- * (P1), and final interpolated control point (P2):
- * <pre>
- * P(t) = B(2,0)*CP + B(2,1)*P1 + B(2,2)*P2
- * 0 &lt;= t &lt;= 1
- * B(n,m) = mth coefficient of nth degree Bernstein polynomial
- * = C(n,m) * t^(m) * (1 - t)^(n-m)
- * C(n,m) = Combinations of n things, taken m at a time
- * = n! / (m! * (n-m)!)
- * </pre>
- */
- int SEG_QUADTO = 2;
-
- /**
- * The current segment is a cubic parametric curve (more commonly known as
- * a Bezier curve). It is interpolated as t varies from 0 to 1 over the
- * current point (CP), first control point (P1), the second control point
- * (P2), and final interpolated control point (P3):
- * <pre>
- * P(t) = B(3,0)*CP + B(3,1)*P1 + B(3,2)*P2 + B(3,3)*P3
- * 0 &lt;= t &lt;= 1
- * B(n,m) = mth coefficient of nth degree Bernstein polynomial
- * = C(n,m) * t^(m) * (1 - t)^(n-m)
- * C(n,m) = Combinations of n things, taken m at a time
- * = n! / (m! * (n-m)!)
- * </pre>
- */
- int SEG_CUBICTO = 3;
-
- /**
- * The current segment closes a loop by an implicit line to the previous
- * SEG_MOVETO coordinate.
- */
- int SEG_CLOSE = 4;
-
- /**
- * Returns the winding rule to determine which points are inside this path.
- *
- * @return the winding rule
- * @see #WIND_EVEN_ODD
- * @see #WIND_NON_ZERO
- */
- int getWindingRule();
-
- /**
- * Tests if the iterator is exhausted. If this returns true, currentSegment
- * and next may throw a NoSuchElementException (although this is not
- * required).
- *
- * @return true if the iteration is complete
- */
- boolean isDone();
-
- /**
- * Advance to the next segment in the iteration. It is not specified what
- * this does if called when isDone() returns true.
- *
- * @throws java.util.NoSuchElementException optional when isDone() is true
- */
- void next();
-
- /**
- * Returns the coordinates of the next point(s), as well as the type of
- * line segment. The input array must be at least a float[6], to accomodate
- * up to three (x,y) point pairs (although if you know the iterator is
- * flat, you can probably get by with a float[2]). If the returned type is
- * SEG_MOVETO or SEG_LINETO, the first point in the array is modified; if
- * the returned type is SEG_QUADTO, the first two points are modified; if
- * the returned type is SEG_CUBICTO, all three points are modified; and if
- * the returned type is SEG_CLOSE, the array is untouched.
- *
- * @param coords the array to place the point coordinates in
- * @return the segment type
- * @throws NullPointerException if coords is null
- * @throws ArrayIndexOutOfBoundsException if coords is too small
- * @throws java.util.NoSuchElementException optional when isDone() is true
- * @see #SEG_MOVETO
- * @see #SEG_LINETO
- * @see #SEG_QUADTO
- * @see #SEG_CUBICTO
- * @see #SEG_CLOSE
- */
- int currentSegment(float[] coords);
-
- /**
- * Returns the coordinates of the next point(s), as well as the type of
- * line segment. The input array must be at least a double[6], to accomodate
- * up to three (x,y) point pairs (although if you know the iterator is
- * flat, you can probably get by with a double[2]). If the returned type is
- * SEG_MOVETO or SEG_LINETO, the first point in the array is modified; if
- * the returned type is SEG_QUADTO, the first two points are modified; if
- * the returned type is SEG_CUBICTO, all three points are modified; and if
- * the returned type is SEG_CLOSE, the array is untouched.
- *
- * @param coords the array to place the point coordinates in
- * @return the segment type
- * @throws NullPointerException if coords is null
- * @throws ArrayIndexOutOfBoundsException if coords is too small
- * @throws java.util.NoSuchElementException optional when isDone() is true
- * @see #SEG_MOVETO
- * @see #SEG_LINETO
- * @see #SEG_QUADTO
- * @see #SEG_CUBICTO
- * @see #SEG_CLOSE
- */
- int currentSegment(double[] coords);
-} // interface PathIterator
diff --git a/libjava/classpath/java/awt/geom/Point2D.java b/libjava/classpath/java/awt/geom/Point2D.java
deleted file mode 100644
index a2689ab..0000000
--- a/libjava/classpath/java/awt/geom/Point2D.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/* Point2D.java -- generic point in 2-D space
- Copyright (C) 1999, 2000, 2002, 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;
-
-/**
- * This class implements a generic point in 2D Cartesian space. The storage
- * representation is left up to the subclass. Point includes two useful
- * nested classes, for float and double storage respectively.
- *
- * @author Per Bothner (bothner@cygnus.com)
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status updated to 1.4
- */
-public abstract class Point2D implements Cloneable
-{
- /**
- * The default constructor.
- *
- * @see java.awt.Point
- * @see Point2D.Float
- * @see Point2D.Double
- */
- protected Point2D()
- {
- }
-
- /**
- * Get the X coordinate, in double precision.
- *
- * @return the x coordinate
- */
- public abstract double getX();
-
- /**
- * Get the Y coordinate, in double precision.
- *
- * @return the y coordinate
- */
- public abstract double getY();
-
- /**
- * Set the location of this point to the new coordinates. There may be a
- * loss of precision.
- *
- * @param x the new x coordinate
- * @param y the new y coordinate
- */
- public abstract void setLocation(double x, double y);
-
- /**
- * Set the location of this point to the new coordinates. There may be a
- * loss of precision.
- *
- * @param p the point to copy
- * @throws NullPointerException if p is null
- */
- public void setLocation(Point2D p)
- {
- setLocation(p.getX(), p.getY());
- }
-
- /**
- * Return the square of the distance between two points.
- *
- * @param x1 the x coordinate of point 1
- * @param y1 the y coordinate of point 1
- * @param x2 the x coordinate of point 2
- * @param y2 the y coordinate of point 2
- * @return (x2 - x1)^2 + (y2 - y1)^2
- */
- public static double distanceSq(double x1, double y1, double x2, double y2)
- {
- x2 -= x1;
- y2 -= y1;
- return x2 * x2 + y2 * y2;
- }
-
- /**
- * Return the distance between two points.
- *
- * @param x1 the x coordinate of point 1
- * @param y1 the y coordinate of point 1
- * @param x2 the x coordinate of point 2
- * @param y2 the y coordinate of point 2
- * @return the distance from (x1,y1) to (x2,y2)
- */
- public static double distance(double x1, double y1, double x2, double y2)
- {
- return Math.sqrt(distanceSq(x1, y1, x2, y2));
- }
-
- /**
- * Return the square of the distance from this point to the given one.
- *
- * @param x the x coordinate of the other point
- * @param y the y coordinate of the other point
- * @return the square of the distance
- */
- public double distanceSq(double x, double y)
- {
- return distanceSq(getX(), getY(), x, y);
- }
-
- /**
- * Return the square of the distance from this point to the given one.
- *
- * @param p the other point
- * @return the square of the distance
- * @throws NullPointerException if p is null
- */
- public double distanceSq(Point2D p)
- {
- return distanceSq(getX(), getY(), p.getX(), p.getY());
- }
-
- /**
- * Return the distance from this point to the given one.
- *
- * @param x the x coordinate of the other point
- * @param y the y coordinate of the other point
- * @return the distance
- */
- public double distance(double x, double y)
- {
- return distance(getX(), getY(), x, y);
- }
-
- /**
- * Return the distance from this point to the given one.
- *
- * @param p the other point
- * @return the distance
- * @throws NullPointerException if p is null
- */
- public double distance(Point2D p)
- {
- return distance(getX(), getY(), p.getX(), p.getY());
- }
-
- /**
- * Create a new point of the same run-time type with the same contents as
- * this one.
- *
- * @return the clone
- */
- public Object clone()
- {
- try
- {
- return super.clone();
- }
- catch (CloneNotSupportedException e)
- {
- throw (Error) new InternalError().initCause(e); // Impossible
- }
- }
-
- /**
- * Return the hashcode for this point. The formula is not documented, but
- * appears to be the same as:
- * <pre>
- * long l = Double.doubleToLongBits(getY());
- * l = l * 31 ^ Double.doubleToLongBits(getX());
- * return (int) ((l >> 32) ^ l);
- * </pre>
- *
- * @return the hashcode
- */
- public int hashCode()
- {
- // Talk about a fun time reverse engineering this one!
- long l = java.lang.Double.doubleToLongBits(getY());
- l = l * 31 ^ java.lang.Double.doubleToLongBits(getX());
- return (int) ((l >> 32) ^ l);
- }
-
- /**
- * Compares two points for equality. This returns true if they have the
- * same coordinates.
- *
- * @param o the point to compare
- * @return true if it is equal
- */
- public boolean equals(Object o)
- {
- if (! (o instanceof Point2D))
- return false;
- Point2D p = (Point2D) o;
- return getX() == p.getX() && getY() == p.getY();
- }
-
- /**
- * This class defines a point in <code>double</code> precision.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status updated to 1.4
- */
- public static class Double extends Point2D
- {
- /** The X coordinate. */
- public double x;
-
- /** The Y coordinate. */
- public double y;
-
- /**
- * Create a new point at (0,0).
- */
- public Double()
- {
- }
-
- /**
- * Create a new point at (x,y).
- *
- * @param x the x coordinate
- * @param y the y coordinate
- */
- public Double(double x, double y)
- {
- this.x = x;
- this.y = y;
- }
-
- /**
- * Return the x coordinate.
- *
- * @return the x coordinate
- */
- public double getX()
- {
- return x;
- }
-
- /**
- * Return the y coordinate.
- *
- * @return the y coordinate
- */
- public double getY()
- {
- return y;
- }
-
- /**
- * Sets the location of this point.
- *
- * @param x the new x coordinate
- * @param y the new y coordinate
- */
- public void setLocation(double x, double y)
- {
- this.x = x;
- this.y = y;
- }
-
- /**
- * Returns a string representation of this object. The format is:
- * <code>"Point2D.Double[" + x + ", " + y + ']'</code>.
- *
- * @return a string representation of this object
- */
- public String toString()
- {
- return "Point2D.Double[" + x + ", " + y + ']';
- }
- } // class Double
-
- /**
- * This class defines a point in <code>float</code> precision.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status updated to 1.4
- */
- public static class Float extends Point2D
- {
- /** The X coordinate. */
- public float x;
-
- /** The Y coordinate. */
- public float y;
-
- /**
- * Create a new point at (0,0).
- */
- public Float()
- {
- }
-
- /**
- * Create a new point at (x,y).
- *
- * @param x the x coordinate
- * @param y the y coordinate
- */
- public Float(float x, float y)
- {
- this.x = x;
- this.y = y;
- }
-
- /**
- * Return the x coordinate.
- *
- * @return the x coordinate
- */
- public double getX()
- {
- return x;
- }
-
- /**
- * Return the y coordinate.
- *
- * @return the y coordinate
- */
- public double getY()
- {
- return y;
- }
-
- /**
- * Sets the location of this point.
- *
- * @param x the new x coordinate
- * @param y the new y coordinate
- */
- public void setLocation(double x, double y)
- {
- this.x = (float) x;
- this.y = (float) y;
- }
-
- /**
- * Sets the location of this point.
- *
- * @param x the new x coordinate
- * @param y the new y coordinate
- */
- public void setLocation(float x, float y)
- {
- this.x = x;
- this.y = y;
- }
-
- /**
- * Returns a string representation of this object. The format is:
- * <code>"Point2D.Float[" + x + ", " + y + ']'</code>.
- *
- * @return a string representation of this object
- */
- public String toString()
- {
- return "Point2D.Float[" + x + ", " + y + ']';
- }
- } // class Float
-} // class Point2D
diff --git a/libjava/classpath/java/awt/geom/QuadCurve2D.java b/libjava/classpath/java/awt/geom/QuadCurve2D.java
deleted file mode 100644
index 62c829d..0000000
--- a/libjava/classpath/java/awt/geom/QuadCurve2D.java
+++ /dev/null
@@ -1,1467 +0,0 @@
-/* QuadCurve2D.java -- represents a parameterized quadratic curve in 2-D space
- Copyright (C) 2002, 2003, 2004 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;
-import java.util.NoSuchElementException;
-
-/**
- * A two-dimensional curve that is parameterized with a quadratic
- * function.
- *
- * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a QuadCurve2D" />
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @author Graydon Hoare (graydon@redhat.com)
- * @author Sascha Brawer (brawer@dandelis.ch)
- * @author Sven de Marothy (sven@physto.se)
- *
- * @since 1.2
- */
-public abstract class QuadCurve2D implements Shape, Cloneable
-{
- private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
- private static final double EPSILON = 1E-10;
-
- /**
- * Constructs a new QuadCurve2D. Typical users will want to
- * construct instances of a subclass, such as {@link
- * QuadCurve2D.Float} or {@link QuadCurve2D.Double}.
- */
- protected QuadCurve2D()
- {
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public abstract double getX1();
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public abstract double getY1();
-
- /**
- * Returns the curve&#x2019;s start point.
- */
- public abstract Point2D getP1();
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s control
- * point.
- */
- public abstract double getCtrlX();
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s control
- * point.
- */
- public abstract double getCtrlY();
-
- /**
- * Returns the curve&#x2019;s control point.
- */
- public abstract Point2D getCtrlPt();
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public abstract double getX2();
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public abstract double getY2();
-
- /**
- * Returns the curve&#x2019;s end point.
- */
- public abstract Point2D getP2();
-
- /**
- * Changes the curve geometry, separately specifying each coordinate
- * value.
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
- * point.
- *
- * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
- * control point.
- *
- * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
- * control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
- * point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
- * point.
- */
- public abstract void setCurve(double x1, double y1, double cx, double cy,
- double x2, double y2);
-
- /**
- * Changes the curve geometry, passing coordinate values in an
- * array.
- *
- * @param coords an array containing the new coordinate values. The
- * <i>x</i> coordinate of the new start point is located at
- * <code>coords[offset]</code>, its <i>y</i> coordinate at
- * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
- * new control point is located at <code>coords[offset + 2]</code>,
- * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The
- * <i>x</i> coordinate of the new end point is located at
- * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at
- * <code>coords[offset + 5]</code>.
- *
- * @param offset the offset of the first coordinate value in
- * <code>coords</code>.
- */
- public void setCurve(double[] coords, int offset)
- {
- setCurve(coords[offset++], coords[offset++], coords[offset++],
- coords[offset++], coords[offset++], coords[offset++]);
- }
-
- /**
- * Changes the curve geometry, specifying coordinate values in
- * separate Point objects.
- *
- * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a QuadCurve2D" />
- *
- * <p>The curve does not keep any reference to the passed point
- * objects. Therefore, a later change to <code>p1</code>,
- * <code>c</code> <code>p2</code> will not affect the curve
- * geometry.
- *
- * @param p1 the new start point.
- * @param c the new control point.
- * @param p2 the new end point.
- */
- public void setCurve(Point2D p1, Point2D c, Point2D p2)
- {
- setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(), p2.getX(), p2.getY());
- }
-
- /**
- * Changes the curve geometry, specifying coordinate values in an
- * array of Point objects.
- *
- * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180"
- * alt="A drawing of a QuadCurve2D" />
- *
- * <p>The curve does not keep references to the passed point
- * objects. Therefore, a later change to the <code>pts</code> array
- * or any of its elements will not affect the curve geometry.
- *
- * @param pts an array containing the points. The new start point
- * is located at <code>pts[offset]</code>, the new control
- * point at <code>pts[offset + 1]</code>, and the new end point
- * at <code>pts[offset + 2]</code>.
- *
- * @param offset the offset of the start point in <code>pts</code>.
- */
- public void setCurve(Point2D[] pts, int offset)
- {
- setCurve(pts[offset].getX(), pts[offset].getY(), pts[offset + 1].getX(),
- pts[offset + 1].getY(), pts[offset + 2].getX(),
- pts[offset + 2].getY());
- }
-
- /**
- * Changes the geometry of the curve to that of another curve.
- *
- * @param c the curve whose coordinates will be copied.
- */
- public void setCurve(QuadCurve2D c)
- {
- setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(), c.getX2(),
- c.getY2());
- }
-
- /**
- * Calculates the squared flatness of a quadratic curve, directly
- * specifying each coordinate value. The flatness is the distance of
- * the control point to the line between start and end point.
- *
- * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. The result will be the
- * the square of the distance between C and the gray line, i.e.
- * the squared length of the red line.
- *
- * @param x1 the <i>x</i> coordinate of the start point P1.
- * @param y1 the <i>y</i> coordinate of the start point P1.
- * @param cx the <i>x</i> coordinate of the control point C.
- * @param cy the <i>y</i> coordinate of the control point C.
- * @param x2 the <i>x</i> coordinate of the end point P2.
- * @param y2 the <i>y</i> coordinate of the end point P2.
- */
- public static double getFlatnessSq(double x1, double y1, double cx,
- double cy, double x2, double y2)
- {
- return Line2D.ptSegDistSq(x1, y1, x2, y2, cx, cy);
- }
-
- /**
- * Calculates the flatness of a quadratic curve, directly specifying
- * each coordinate value. The flatness is the distance of the
- * control point to the line between start and end point.
- *
- * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. The result will be the
- * the distance between C and the gray line, i.e. the length of
- * the red line.
- *
- * @param x1 the <i>x</i> coordinate of the start point P1.
- * @param y1 the <i>y</i> coordinate of the start point P1.
- * @param cx the <i>x</i> coordinate of the control point C.
- * @param cy the <i>y</i> coordinate of the control point C.
- * @param x2 the <i>x</i> coordinate of the end point P2.
- * @param y2 the <i>y</i> coordinate of the end point P2.
- */
- public static double getFlatness(double x1, double y1, double cx, double cy,
- double x2, double y2)
- {
- return Line2D.ptSegDist(x1, y1, x2, y2, cx, cy);
- }
-
- /**
- * Calculates the squared flatness of a quadratic curve, specifying
- * the coordinate values in an array. The flatness is the distance
- * of the control point to the line between start and end point.
- *
- * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. The result will be the
- * the square of the distance between C and the gray line, i.e.
- * the squared length of the red line.
- *
- * @param coords an array containing the coordinate values. The
- * <i>x</i> coordinate of the start point P1 is located at
- * <code>coords[offset]</code>, its <i>y</i> coordinate at
- * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
- * control point C is located at <code>coords[offset + 2]</code>,
- * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The
- * <i>x</i> coordinate of the end point P2 is located at
- * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at
- * <code>coords[offset + 5]</code>.
- *
- * @param offset the offset of the first coordinate value in
- * <code>coords</code>.
- */
- public static double getFlatnessSq(double[] coords, int offset)
- {
- return Line2D.ptSegDistSq(coords[offset], coords[offset + 1],
- coords[offset + 4], coords[offset + 5],
- coords[offset + 2], coords[offset + 3]);
- }
-
- /**
- * Calculates the flatness of a quadratic curve, specifying the
- * coordinate values in an array. The flatness is the distance of
- * the control point to the line between start and end point.
- *
- * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. The result will be the
- * the the distance between C and the gray line, i.e. the length of
- * the red line.
- *
- * @param coords an array containing the coordinate values. The
- * <i>x</i> coordinate of the start point P1 is located at
- * <code>coords[offset]</code>, its <i>y</i> coordinate at
- * <code>coords[offset + 1]</code>. The <i>x</i> coordinate of the
- * control point C is located at <code>coords[offset + 2]</code>,
- * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The
- * <i>x</i> coordinate of the end point P2 is located at
- * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at
- * <code>coords[offset + 5]</code>.
- *
- * @param offset the offset of the first coordinate value in
- * <code>coords</code>.
- */
- public static double getFlatness(double[] coords, int offset)
- {
- return Line2D.ptSegDist(coords[offset], coords[offset + 1],
- coords[offset + 4], coords[offset + 5],
- coords[offset + 2], coords[offset + 3]);
- }
-
- /**
- * Calculates the squared flatness of this curve. The flatness is
- * the distance of the control point to the line between start and
- * end point.
- *
- * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. The result will be the
- * the square of the distance between C and the gray line, i.e. the
- * squared length of the red line.
- */
- public double getFlatnessSq()
- {
- return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
- getCtrlY());
- }
-
- /**
- * Calculates the flatness of this curve. The flatness is the
- * distance of the control point to the line between start and end
- * point.
- *
- * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
- * alt="A drawing that illustrates the flatness" />
- *
- * <p>In the above drawing, the straight line connecting start point
- * P1 and end point P2 is depicted in gray. The result will be the
- * the distance between C and the gray line, i.e. the length of the
- * red line.
- */
- public double getFlatness()
- {
- return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
- getCtrlY());
- }
-
- /**
- * Subdivides this curve into two halves.
- *
- * <p><img src="doc-files/QuadCurve2D-3.png" width="700"
- * height="180" alt="A drawing that illustrates the effects of
- * subdividing a QuadCurve2D" />
- *
- * @param left a curve whose geometry will be set to the left half
- * of this curve, or <code>null</code> if the caller is not
- * interested in the left half.
- *
- * @param right a curve whose geometry will be set to the right half
- * of this curve, or <code>null</code> if the caller is not
- * interested in the right half.
- */
- public void subdivide(QuadCurve2D left, QuadCurve2D right)
- {
- // Use empty slots at end to share single array.
- double[] d = new double[]
- {
- getX1(), getY1(), getCtrlX(), getCtrlY(), getX2(), getY2(),
- 0, 0, 0, 0
- };
- subdivide(d, 0, d, 0, d, 4);
- if (left != null)
- left.setCurve(d, 0);
- if (right != null)
- right.setCurve(d, 4);
- }
-
- /**
- * Subdivides a quadratic curve into two halves.
- *
- * <p><img src="doc-files/QuadCurve2D-3.png" width="700"
- * height="180" alt="A drawing that illustrates the effects of
- * subdividing a QuadCurve2D" />
- *
- * @param src the curve to be subdivided.
- *
- * @param left a curve whose geometry will be set to the left half
- * of <code>src</code>, or <code>null</code> if the caller is not
- * interested in the left half.
- *
- * @param right a curve whose geometry will be set to the right half
- * of <code>src</code>, or <code>null</code> if the caller is not
- * interested in the right half.
- */
- public static void subdivide(QuadCurve2D src, QuadCurve2D left,
- QuadCurve2D right)
- {
- src.subdivide(left, right);
- }
-
- /**
- * Subdivides a quadratic curve into two halves, passing all
- * coordinates in an array.
- *
- * <p><img src="doc-files/QuadCurve2D-3.png" width="700"
- * height="180" alt="A drawing that illustrates the effects of
- * subdividing a QuadCurve2D" />
- *
- * <p>The left end point and the right start point will always be
- * identical. Memory-concious programmers thus may want to pass the
- * same array for both <code>left</code> and <code>right</code>, and
- * set <code>rightOff</code> to <code>leftOff + 4</code>.
- *
- * @param src an array containing the coordinates of the curve to be
- * subdivided. The <i>x</i> coordinate of the start point is
- * located at <code>src[srcOff]</code>, its <i>y</i> at
- * <code>src[srcOff + 1]</code>. The <i>x</i> coordinate of the
- * control point is located at <code>src[srcOff + 2]</code>, its
- * <i>y</i> at <code>src[srcOff + 3]</code>. The <i>x</i>
- * coordinate of the end point is located at <code>src[srcOff +
- * 4]</code>, its <i>y</i> at <code>src[srcOff + 5]</code>.
- *
- * @param srcOff an offset into <code>src</code>, specifying
- * the index of the start point&#x2019;s <i>x</i> coordinate.
- *
- * @param left an array that will receive the coordinates of the
- * left half of <code>src</code>. It is acceptable to pass
- * <code>src</code>. A caller who is not interested in the left half
- * can pass <code>null</code>.
- *
- * @param leftOff an offset into <code>left</code>, specifying the
- * index where the start point&#x2019;s <i>x</i> coordinate will be
- * stored.
- *
- * @param right an array that will receive the coordinates of the
- * right half of <code>src</code>. It is acceptable to pass
- * <code>src</code> or <code>left</code>. A caller who is not
- * interested in the right half can pass <code>null</code>.
- *
- * @param rightOff an offset into <code>right</code>, specifying the
- * index where the start point&#x2019;s <i>x</i> coordinate will be
- * stored.
- */
- public static void subdivide(double[] src, int srcOff, double[] left,
- int leftOff, double[] right, int rightOff)
- {
- double x1;
- double y1;
- double xc;
- double yc;
- double x2;
- double y2;
-
- x1 = src[srcOff];
- y1 = src[srcOff + 1];
- xc = src[srcOff + 2];
- yc = src[srcOff + 3];
- x2 = src[srcOff + 4];
- y2 = src[srcOff + 5];
-
- if (left != null)
- {
- left[leftOff] = x1;
- left[leftOff + 1] = y1;
- }
-
- if (right != null)
- {
- right[rightOff + 4] = x2;
- right[rightOff + 5] = y2;
- }
-
- x1 = (x1 + xc) / 2;
- x2 = (xc + x2) / 2;
- xc = (x1 + x2) / 2;
- y1 = (y1 + yc) / 2;
- y2 = (y2 + yc) / 2;
- yc = (y1 + y2) / 2;
-
- if (left != null)
- {
- left[leftOff + 2] = x1;
- left[leftOff + 3] = y1;
- left[leftOff + 4] = xc;
- left[leftOff + 5] = yc;
- }
-
- if (right != null)
- {
- right[rightOff] = xc;
- right[rightOff + 1] = yc;
- right[rightOff + 2] = x2;
- right[rightOff + 3] = y2;
- }
- }
-
- /**
- * Finds the non-complex roots of a quadratic equation, placing the
- * results into the same array as the equation coefficients. The
- * following equation is being solved:
- *
- * <blockquote><code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
- * + <code>eqn[1]</code> &#xb7; <i>x</i>
- * + <code>eqn[0]</code>
- * = 0
- * </blockquote>
- *
- * <p>For some background about solving quadratic equations, see the
- * article <a href=
- * "http://planetmath.org/encyclopedia/QuadraticFormula.html"
- * >&#x201c;Quadratic Formula&#x201d;</a> in <a href=
- * "http://planetmath.org/">PlanetMath</a>. For an extensive library
- * of numerical algorithms written in the C programming language,
- * see the <a href="http://www.gnu.org/software/gsl/">GNU Scientific
- * Library</a>.
- *
- * @see #solveQuadratic(double[], double[])
- * @see CubicCurve2D#solveCubic(double[], double[])
- *
- * @param eqn an array with the coefficients of the equation. When
- * this procedure has returned, <code>eqn</code> will contain the
- * non-complex solutions of the equation, in no particular order.
- *
- * @return the number of non-complex solutions. A result of 0
- * indicates that the equation has no non-complex solutions. A
- * result of -1 indicates that the equation is constant (i.e.,
- * always or never zero).
- *
- * @author Brian Gough (bjg@network-theory.com)
- * (original C implementation in the <a href=
- * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
- *
- * @author Sascha Brawer (brawer@dandelis.ch)
- * (adaptation to Java)
- */
- public static int solveQuadratic(double[] eqn)
- {
- return solveQuadratic(eqn, eqn);
- }
-
- /**
- * Finds the non-complex roots of a quadratic equation. The
- * following equation is being solved:
- *
- * <blockquote><code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
- * + <code>eqn[1]</code> &#xb7; <i>x</i>
- * + <code>eqn[0]</code>
- * = 0
- * </blockquote>
- *
- * <p>For some background about solving quadratic equations, see the
- * article <a href=
- * "http://planetmath.org/encyclopedia/QuadraticFormula.html"
- * >&#x201c;Quadratic Formula&#x201d;</a> in <a href=
- * "http://planetmath.org/">PlanetMath</a>. For an extensive library
- * of numerical algorithms written in the C programming language,
- * see the <a href="http://www.gnu.org/software/gsl/">GNU Scientific
- * Library</a>.
- *
- * @see CubicCurve2D#solveCubic(double[],double[])
- *
- * @param eqn an array with the coefficients of the equation.
- *
- * @param res an array into which the non-complex roots will be
- * stored. The results may be in an arbitrary order. It is safe to
- * pass the same array object reference for both <code>eqn</code>
- * and <code>res</code>.
- *
- * @return the number of non-complex solutions. A result of 0
- * indicates that the equation has no non-complex solutions. A
- * result of -1 indicates that the equation is constant (i.e.,
- * always or never zero).
- *
- * @author Brian Gough (bjg@network-theory.com)
- * (original C implementation in the <a href=
- * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
- *
- * @author Sascha Brawer (brawer@dandelis.ch)
- * (adaptation to Java)
- */
- public static int solveQuadratic(double[] eqn, double[] res)
- {
- // Taken from poly/solve_quadratic.c in the GNU Scientific Library
- // (GSL), cvs revision 1.7 of 2003-07-26. For the original source,
- // see http://www.gnu.org/software/gsl/
- //
- // Brian Gough, the author of that code, has granted the
- // permission to use it in GNU Classpath under the GNU Classpath
- // license, and has assigned the copyright to the Free Software
- // Foundation.
- //
- // The Java implementation is very similar to the GSL code, but
- // not a strict one-to-one copy. For example, GSL would sort the
- // result.
- double a;
- double b;
- double c;
- double disc;
-
- c = eqn[0];
- b = eqn[1];
- a = eqn[2];
-
- // Check for linear or constant functions. This is not done by the
- // GNU Scientific Library. Without this special check, we
- // wouldn't return -1 for constant functions, and 2 instead of 1
- // for linear functions.
- if (a == 0)
- {
- if (b == 0)
- return -1;
-
- res[0] = -c / b;
- return 1;
- }
-
- disc = b * b - 4 * a * c;
-
- if (disc < 0)
- return 0;
-
- if (disc == 0)
- {
- // The GNU Scientific Library returns two identical results here.
- // We just return one.
- res[0] = -0.5 * b / a;
- return 1;
- }
-
- // disc > 0
- if (b == 0)
- {
- double r;
-
- r = Math.abs(0.5 * Math.sqrt(disc) / a);
- res[0] = -r;
- res[1] = r;
- }
- else
- {
- double sgnb;
- double temp;
-
- sgnb = (b > 0 ? 1 : -1);
- temp = -0.5 * (b + sgnb * Math.sqrt(disc));
-
- // The GNU Scientific Library sorts the result here. We don't.
- res[0] = temp / a;
- res[1] = c / temp;
- }
- return 2;
- }
-
- /**
- * Determines whether a point is inside the area bounded
- * by the curve and the straight line connecting its end points.
- *
- * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
- * alt="A drawing of the area spanned by the curve" />
- *
- * <p>The above drawing illustrates in which area points are
- * considered &#x201c;inside&#x201d; a QuadCurve2D.
- */
- public boolean contains(double x, double y)
- {
- if (! getBounds2D().contains(x, y))
- return false;
-
- return ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0);
- }
-
- /**
- * Determines whether a point is inside the area bounded
- * by the curve and the straight line connecting its end points.
- *
- * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
- * alt="A drawing of the area spanned by the curve" />
- *
- * <p>The above drawing illustrates in which area points are
- * considered &#x201c;inside&#x201d; a QuadCurve2D.
- */
- public boolean contains(Point2D p)
- {
- return contains(p.getX(), p.getY());
- }
-
- /**
- * Determines whether any part of a rectangle is inside the area bounded
- * by the curve and the straight line connecting its end points.
- *
- * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
- * alt="A drawing of the area spanned by the curve" />
- *
- * <p>The above drawing illustrates in which area points are
- * considered &#x201c;inside&#x201d; in a CubicCurve2D.
- */
- public boolean intersects(double x, double y, double w, double h)
- {
- if (! getBounds2D().contains(x, y, w, h))
- return false;
-
- /* Does any edge intersect? */
- if (getAxisIntersections(x, y, true, w) != 0 /* top */
- || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
- || getAxisIntersections(x + w, y, false, h) != 0 /* right */
- || getAxisIntersections(x, y, false, h) != 0) /* left */
- return true;
-
- /* No intersections, is any point inside? */
- if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
- return true;
-
- return false;
- }
-
- /**
- * Determines whether any part of a Rectangle2D is inside the area bounded
- * by the curve and the straight line connecting its end points.
- * @see #intersects(double, double, double, double)
- */
- public boolean intersects(Rectangle2D r)
- {
- return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Determines whether a rectangle is entirely inside the area bounded
- * by the curve and the straight line connecting its end points.
- *
- * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
- * alt="A drawing of the area spanned by the curve" />
- *
- * <p>The above drawing illustrates in which area points are
- * considered &#x201c;inside&#x201d; a QuadCurve2D.
- * @see #contains(double, double)
- */
- 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, true, w) != 0 /* top */
- || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
- || getAxisIntersections(x + w, y, false, h) != 0 /* right */
- || getAxisIntersections(x, y, false, h) != 0) /* left */
- return false;
-
- /* No intersections, is any point inside? */
- if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
- return true;
-
- return false;
- }
-
- /**
- * Determines whether a Rectangle2D is entirely inside the area that is
- * bounded by the curve and the straight line connecting its end points.
- * @see #contains(double, double, double, double)
- */
- public boolean contains(Rectangle2D r)
- {
- return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Determines the smallest rectangle that encloses the
- * curve&#x2019;s start, end and control point. As the illustration
- * below shows, the invisible control point may cause the bounds to
- * be much larger than the area that is actually covered by the
- * curve.
- *
- * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180"
- * alt="An illustration of the bounds of a QuadCurve2D" />
- */
- public Rectangle getBounds()
- {
- return getBounds2D().getBounds();
- }
-
- public PathIterator getPathIterator(final AffineTransform at)
- {
- return new PathIterator()
- {
- /** Current coordinate. */
- private int current = 0;
-
- public int getWindingRule()
- {
- return WIND_NON_ZERO;
- }
-
- public boolean isDone()
- {
- return current >= 2;
- }
-
- public void next()
- {
- current++;
- }
-
- public int currentSegment(float[] coords)
- {
- int result;
- switch (current)
- {
- case 0:
- coords[0] = (float) getX1();
- coords[1] = (float) getY1();
- result = SEG_MOVETO;
- break;
- case 1:
- coords[0] = (float) getCtrlX();
- coords[1] = (float) getCtrlY();
- coords[2] = (float) getX2();
- coords[3] = (float) getY2();
- result = SEG_QUADTO;
- break;
- default:
- throw new NoSuchElementException("quad iterator out of bounds");
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 2);
- return result;
- }
-
- public int currentSegment(double[] coords)
- {
- int result;
- switch (current)
- {
- case 0:
- coords[0] = getX1();
- coords[1] = getY1();
- result = SEG_MOVETO;
- break;
- case 1:
- coords[0] = getCtrlX();
- coords[1] = getCtrlY();
- coords[2] = getX2();
- coords[3] = getY2();
- result = SEG_QUADTO;
- break;
- default:
- throw new NoSuchElementException("quad iterator out of bounds");
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 2);
- return result;
- }
- };
- }
-
- public PathIterator getPathIterator(AffineTransform at, double flatness)
- {
- return new FlatteningPathIterator(getPathIterator(at), flatness);
- }
-
- /**
- * Creates a new curve with the same contents as this one.
- *
- * @return the clone.
- */
- public Object clone()
- {
- try
- {
- return super.clone();
- }
- catch (CloneNotSupportedException e)
- {
- throw (Error) new InternalError().initCause(e); // Impossible
- }
- }
-
- /**
- * Helper method used by contains() and intersects() methods
- * Return the number of curve/line intersections on a given axis
- * extending from a certain point. useYaxis is true for using the Y axis,
- * @param x x coordinate of the origin point
- * @param y y coordinate of the origin point
- * @param useYaxis axis to follow, if true the positive Y axis is used,
- * false uses the positive X axis.
- *
- * This is an implementation of the line-crossings algorithm,
- * Detailed in an article on Eric Haines' page:
- * http://www.acm.org/tog/editors/erich/ptinpoly/
- */
- private int getAxisIntersections(double x, double y, boolean useYaxis,
- double distance)
- {
- int nCrossings = 0;
- double a0;
- double a1;
- double a2;
- double b0;
- double b1;
- double b2;
- double[] r = new double[3];
- int nRoots;
-
- a0 = a2 = 0.0;
-
- if (useYaxis)
- {
- a0 = getY1() - y;
- a1 = getCtrlY() - y;
- a2 = getY2() - y;
- b0 = getX1() - x;
- b1 = getCtrlX() - x;
- b2 = getX2() - x;
- }
- else
- {
- a0 = getX1() - x;
- a1 = getCtrlX() - x;
- a2 = getX2() - x;
- b0 = getY1() - y;
- b1 = getCtrlY() - y;
- b2 = getY2() - y;
- }
-
- /* If the axis intersects a start/endpoint, shift it up by some small
- amount to guarantee the line is 'inside'
- If this is not done,bad behaviour may result for points on that axis. */
- if (a0 == 0.0 || a2 == 0.0)
- {
- double small = getFlatness() * EPSILON;
- if (a0 == 0.0)
- a0 -= small;
-
- if (a2 == 0.0)
- a2 -= small;
- }
-
- r[0] = a0;
- r[1] = 2 * (a1 - a0);
- r[2] = (a2 - 2 * a1 + a0);
-
- nRoots = solveQuadratic(r);
- for (int i = 0; i < nRoots; i++)
- {
- double t = r[i];
- if (t >= 0.0 && t <= 1.0)
- {
- double crossing = t * t * (b2 - 2 * b1 + b0) + 2 * t * (b1 - b0)
- + b0;
- /* single root is always doubly degenerate in quads */
- if (crossing > 0 && crossing < distance)
- nCrossings += (nRoots == 1) ? 2 : 1;
- }
- }
-
- if (useYaxis)
- {
- if (Line2D.linesIntersect(b0, a0, b2, a2, EPSILON, 0.0, distance, 0.0))
- nCrossings++;
- }
- else
- {
- if (Line2D.linesIntersect(a0, b0, a2, b2, 0.0, EPSILON, 0.0, distance))
- nCrossings++;
- }
-
- return (nCrossings);
- }
-
- /**
- * A two-dimensional curve that is parameterized with a quadratic
- * function and stores coordinate values in double-precision
- * floating-point format.
- *
- * @see QuadCurve2D.Float
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @author Sascha Brawer (brawer@dandelis.ch)
- */
- public static class Double extends QuadCurve2D
- {
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s start point.
- */
- public double x1;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s start point.
- */
- public double y1;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s control point.
- */
- public double ctrlx;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s control point.
- */
- public double ctrly;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s end point.
- */
- public double x2;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s end point.
- */
- public double y2;
-
- /**
- * Constructs a new QuadCurve2D that stores its coordinate values
- * in double-precision floating-point format. All points are
- * initially at position (0, 0).
- */
- public Double()
- {
- }
-
- /**
- * Constructs a new QuadCurve2D that stores its coordinate values
- * in double-precision floating-point format, specifying the
- * initial position of each point.
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- *
- * @param cx the <i>x</i> coordinate of the curve&#x2019;s control
- * point.
- *
- * @param cy the <i>y</i> coordinate of the curve&#x2019;s control
- * point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public Double(double x1, double y1, double cx, double cy, double x2,
- double y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- ctrlx = cx;
- ctrly = cy;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public double getX1()
- {
- return x1;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public double getY1()
- {
- return y1;
- }
-
- /**
- * Returns the curve&#x2019;s start point.
- */
- public Point2D getP1()
- {
- return new Point2D.Double(x1, y1);
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s control
- * point.
- */
- public double getCtrlX()
- {
- return ctrlx;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s control
- * point.
- */
- public double getCtrlY()
- {
- return ctrly;
- }
-
- /**
- * Returns the curve&#x2019;s control point.
- */
- public Point2D getCtrlPt()
- {
- return new Point2D.Double(ctrlx, ctrly);
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public double getX2()
- {
- return x2;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public double getY2()
- {
- return y2;
- }
-
- /**
- * Returns the curve&#x2019;s end point.
- */
- public Point2D getP2()
- {
- return new Point2D.Double(x2, y2);
- }
-
- /**
- * Changes the geometry of the curve.
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new
- * start point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new
- * start point.
- *
- * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
- * control point.
- *
- * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
- * control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new
- * end point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
- * end point.
- */
- public void setCurve(double x1, double y1, double cx, double cy,
- double x2, double y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- ctrlx = cx;
- ctrly = cy;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Determines the smallest rectangle that encloses the
- * curve&#x2019;s start, end and control point. As the
- * illustration below shows, the invisible control point may cause
- * the bounds to be much larger than the area that is actually
- * covered by the curve.
- *
- * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180"
- * alt="An illustration of the bounds of a QuadCurve2D" />
- */
- public Rectangle2D getBounds2D()
- {
- double nx1 = Math.min(Math.min(x1, ctrlx), x2);
- double ny1 = Math.min(Math.min(y1, ctrly), y2);
- double nx2 = Math.max(Math.max(x1, ctrlx), x2);
- double ny2 = Math.max(Math.max(y1, ctrly), y2);
- return new Rectangle2D.Double(nx1, ny1, nx2 - nx1, ny2 - ny1);
- }
- }
-
- /**
- * A two-dimensional curve that is parameterized with a quadratic
- * function and stores coordinate values in single-precision
- * floating-point format.
- *
- * @see QuadCurve2D.Double
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @author Sascha Brawer (brawer@dandelis.ch)
- */
- public static class Float extends QuadCurve2D
- {
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s start point.
- */
- public float x1;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s start point.
- */
- public float y1;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s control point.
- */
- public float ctrlx;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s control point.
- */
- public float ctrly;
-
- /**
- * The <i>x</i> coordinate of the curve&#x2019;s end point.
- */
- public float x2;
-
- /**
- * The <i>y</i> coordinate of the curve&#x2019;s end point.
- */
- public float y2;
-
- /**
- * Constructs a new QuadCurve2D that stores its coordinate values
- * in single-precision floating-point format. All points are
- * initially at position (0, 0).
- */
- public Float()
- {
- }
-
- /**
- * Constructs a new QuadCurve2D that stores its coordinate values
- * in single-precision floating-point format, specifying the
- * initial position of each point.
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- *
- * @param cx the <i>x</i> coordinate of the curve&#x2019;s control
- * point.
- *
- * @param cy the <i>y</i> coordinate of the curve&#x2019;s control
- * point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public Float(float x1, float y1, float cx, float cy, float x2, float y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- ctrlx = cx;
- ctrly = cy;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public double getX1()
- {
- return x1;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s start
- * point.
- */
- public double getY1()
- {
- return y1;
- }
-
- /**
- * Returns the curve&#x2019;s start point.
- */
- public Point2D getP1()
- {
- return new Point2D.Float(x1, y1);
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s control
- * point.
- */
- public double getCtrlX()
- {
- return ctrlx;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s control
- * point.
- */
- public double getCtrlY()
- {
- return ctrly;
- }
-
- /**
- * Returns the curve&#x2019;s control point.
- */
- public Point2D getCtrlPt()
- {
- return new Point2D.Float(ctrlx, ctrly);
- }
-
- /**
- * Returns the <i>x</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public double getX2()
- {
- return x2;
- }
-
- /**
- * Returns the <i>y</i> coordinate of the curve&#x2019;s end
- * point.
- */
- public double getY2()
- {
- return y2;
- }
-
- /**
- * Returns the curve&#x2019;s end point.
- */
- public Point2D getP2()
- {
- return new Point2D.Float(x2, y2);
- }
-
- /**
- * Changes the geometry of the curve, specifying coordinate values
- * as double-precision floating-point numbers.
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new
- * start point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new
- * start point.
- *
- * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
- * control point.
- *
- * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
- * control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new
- * end point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
- * end point.
- */
- public void setCurve(double x1, double y1, double cx, double cy,
- double x2, double y2)
- {
- this.x1 = (float) x1;
- this.y1 = (float) y1;
- ctrlx = (float) cx;
- ctrly = (float) cy;
- this.x2 = (float) x2;
- this.y2 = (float) y2;
- }
-
- /**
- * Changes the geometry of the curve, specifying coordinate values
- * as single-precision floating-point numbers.
- *
- * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new
- * start point.
- *
- * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new
- * start point.
- *
- * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
- * control point.
- *
- * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
- * control point.
- *
- * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new
- * end point.
- *
- * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
- * end point.
- */
- public void setCurve(float x1, float y1, float cx, float cy, float x2,
- float y2)
- {
- this.x1 = x1;
- this.y1 = y1;
- ctrlx = cx;
- ctrly = cy;
- this.x2 = x2;
- this.y2 = y2;
- }
-
- /**
- * Determines the smallest rectangle that encloses the
- * curve&#x2019;s start, end and control point. As the
- * illustration below shows, the invisible control point may cause
- * the bounds to be much larger than the area that is actually
- * covered by the curve.
- *
- * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180"
- * alt="An illustration of the bounds of a QuadCurve2D" />
- */
- public Rectangle2D getBounds2D()
- {
- float nx1 = Math.min(Math.min(x1, ctrlx), x2);
- float ny1 = Math.min(Math.min(y1, ctrly), y2);
- float nx2 = Math.max(Math.max(x1, ctrlx), x2);
- float ny2 = Math.max(Math.max(y1, ctrly), y2);
- return new Rectangle2D.Float(nx1, ny1, nx2 - nx1, ny2 - ny1);
- }
- }
-}
diff --git a/libjava/classpath/java/awt/geom/Rectangle2D.java b/libjava/classpath/java/awt/geom/Rectangle2D.java
deleted file mode 100644
index 6a255f9..0000000
--- a/libjava/classpath/java/awt/geom/Rectangle2D.java
+++ /dev/null
@@ -1,992 +0,0 @@
-/* Rectangle2D.java -- generic rectangles in 2-D space
- Copyright (C) 2000, 2001, 2002, 2004 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.util.NoSuchElementException;
-
-/**
- * This class describes a rectangle by a point (x,y) and dimension (w x h).
- * The actual storage is left up to subclasses.
- *
- * <p>It is valid for a rectangle to have negative width or height; but it
- * is considered to have no area or internal points. Therefore, the behavior
- * in methods like <code>contains</code> or <code>intersects</code> is
- * undefined unless the rectangle has positive width and height.
- *
- * @author Tom Tromey (tromey@cygnus.com)
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status updated to 1.4
- */
-public abstract class Rectangle2D extends RectangularShape
-{
- /**
- * The point lies left of the rectangle (p.x &lt; r.x).
- *
- * @see #outcode(double, double)
- */
- public static final int OUT_LEFT = 1;
-
- /**
- * The point lies above the rectangle (p.y &lt; r.y).
- *
- * @see #outcode(double, double)
- */
- public static final int OUT_TOP = 2;
-
- /**
- * The point lies right of the rectangle (p.x &gt; r.maxX).
- *
- * @see #outcode(double, double)
- */
- public static final int OUT_RIGHT = 4;
-
- /**
- * The point lies below of the rectangle (p.y &gt; r.maxY).
- *
- * @see #outcode(double, double)
- */
- public static final int OUT_BOTTOM = 8;
-
- /**
- * Default constructor.
- */
- protected Rectangle2D()
- {
- }
-
- /**
- * Set the bounding box of this rectangle.
- *
- * @param x the new X coordinate
- * @param y the new Y coordinate
- * @param w the new width
- * @param h the new height
- */
- public abstract void setRect(double x, double y, double w, double h);
-
- /**
- * Set the bounding box of this rectangle from the given one.
- *
- * @param r rectangle to copy
- * @throws NullPointerException if r is null
- */
- public void setRect(Rectangle2D r)
- {
- setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Tests if the specified line intersects the interior of this rectangle.
- *
- * @param x1 the first x coordinate of line segment
- * @param y1 the first y coordinate of line segment
- * @param x2 the second x coordinate of line segment
- * @param y2 the second y coordinate of line segment
- * @return true if the line intersects the rectangle
- */
- public boolean intersectsLine(double x1, double y1, double x2, double y2)
- {
- double x = getX();
- double y = getY();
- double w = getWidth();
- double h = getHeight();
- if (w <= 0 || h <= 0)
- return false;
-
- if (x1 >= x && x1 <= x + w && y1 >= y && y1 <= y + h)
- return true;
- if (x2 >= x && x2 <= x + w && y2 >= y && y2 <= y + h)
- return true;
-
- double x3 = x + w;
- double y3 = y + h;
-
- return (Line2D.linesIntersect(x1, y1, x2, y2, x, y, x, y3)
- || Line2D.linesIntersect(x1, y1, x2, y2, x, y3, x3, y3)
- || Line2D.linesIntersect(x1, y1, x2, y2, x3, y3, x3, y)
- || Line2D.linesIntersect(x1, y1, x2, y2, x3, y, x, y));
- }
-
- /**
- * Tests if the specified line intersects the interior of this rectangle.
- *
- * @param l the line segment
- * @return true if the line intersects the rectangle
- * @throws NullPointerException if l is null
- */
- public boolean intersectsLine(Line2D l)
- {
- return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
- }
-
- /**
- * Determine where the point lies with respect to this rectangle. The
- * result will be the binary OR of the appropriate bit masks.
- *
- * @param x the x coordinate to check
- * @param y the y coordinate to check
- * @return the binary OR of the result
- * @see #OUT_LEFT
- * @see #OUT_TOP
- * @see #OUT_RIGHT
- * @see #OUT_BOTTOM
- */
- public abstract int outcode(double x, double y);
-
- /**
- * Determine where the point lies with respect to this rectangle. The
- * result will be the binary OR of the appropriate bit masks.
- *
- * @param p the point to check
- * @return the binary OR of the result
- * @throws NullPointerException if p is null
- * @see #OUT_LEFT
- * @see #OUT_TOP
- * @see #OUT_RIGHT
- * @see #OUT_BOTTOM
- */
- public int outcode(Point2D p)
- {
- return outcode(p.getX(), p.getY());
- }
-
- /**
- * Set the bounding box of this rectangle.
- *
- * @param x the new X coordinate
- * @param y the new Y coordinate
- * @param w the new width
- * @param h the new height
- */
- public void setFrame(double x, double y, double w, double h)
- {
- setRect(x, y, w, h);
- }
-
- /**
- * Returns the bounds of this rectangle. A pretty useless method, as this
- * is already a rectangle.
- *
- * @return a copy of this rectangle
- */
- public Rectangle2D getBounds2D()
- {
- return (Rectangle2D) clone();
- }
-
- /**
- * Test if the given point is contained in the rectangle.
- *
- * @param x the x coordinate of the point
- * @param y the y coordinate of the point
- * @return true if (x,y) is in the rectangle
- */
- public boolean contains(double x, double y)
- {
- double mx = getX();
- double my = getY();
- double w = getWidth();
- double h = getHeight();
- return w > 0 && h > 0 && x >= mx && x < mx + w && y >= my && y < my + h;
- }
-
- /**
- * Tests if the given rectangle intersects this one. In other words, test if
- * the two rectangles share at least one internal point.
- *
- * @param x the x coordinate of the other rectangle
- * @param y the y coordinate of the other rectangle
- * @param w the width of the other rectangle
- * @param h the height of the other rectangle
- * @return true if the rectangles intersect
- */
- public boolean intersects(double x, double y, double w, double h)
- {
- double mx = getX();
- double my = getY();
- double mw = getWidth();
- double mh = getHeight();
- return w > 0 && h > 0 && mw > 0 && mh > 0
- && x < mx + mw && x + w > mx && y < my + mh && y + h > my;
- }
-
- /**
- * Tests if this rectangle contains the given one. In other words, test if
- * this rectangle contains all points in the given one.
- *
- * @param x the x coordinate of the other rectangle
- * @param y the y coordinate of the other rectangle
- * @param w the width of the other rectangle
- * @param h the height of the other rectangle
- * @return true if this rectangle contains the other
- */
- public boolean contains(double x, double y, double w, double h)
- {
- double mx = getX();
- double my = getY();
- double mw = getWidth();
- double mh = getHeight();
- return w > 0 && h > 0 && mw > 0 && mh > 0
- && x >= mx && x + w <= mx + mw && y >= my && y + h <= my + mh;
- }
-
- /**
- * Return a new rectangle which is the intersection of this and the given
- * one. The result will be empty if there is no intersection.
- *
- * @param r the rectangle to be intersected
- * @return the intersection
- * @throws NullPointerException if r is null
- */
- public abstract Rectangle2D createIntersection(Rectangle2D r);
-
- /**
- * Intersects a pair of rectangles, and places the result in the
- * destination; this can be used to avoid object creation. This method
- * even works when the destination is also a source, although you stand
- * to lose the original data.
- *
- * @param src1 the first source
- * @param src2 the second source
- * @param dest the destination for the intersection
- * @throws NullPointerException if any rectangle is null
- */
- public static void intersect(Rectangle2D src1, Rectangle2D src2,
- Rectangle2D dest)
- {
- double x = Math.max(src1.getX(), src2.getX());
- double y = Math.max(src1.getY(), src2.getY());
- double maxx = Math.min(src1.getMaxX(), src2.getMaxX());
- double maxy = Math.min(src1.getMaxY(), src2.getMaxY());
- dest.setRect(x, y, maxx - x, maxy - y);
- }
-
- /**
- * Return a new rectangle which is the union of this and the given one.
- *
- * @param r the rectangle to be merged
- * @return the union
- * @throws NullPointerException if r is null
- */
- public abstract Rectangle2D createUnion(Rectangle2D r);
-
- /**
- * Joins a pair of rectangles, and places the result in the destination;
- * this can be used to avoid object creation. This method even works when
- * the destination is also a source, although you stand to lose the
- * original data.
- *
- * @param src1 the first source
- * @param src2 the second source
- * @param dest the destination for the union
- * @throws NullPointerException if any rectangle is null
- */
- public static void union(Rectangle2D src1, Rectangle2D src2,
- Rectangle2D dest)
- {
- double x = Math.min(src1.getX(), src2.getX());
- double y = Math.min(src1.getY(), src2.getY());
- double maxx = Math.max(src1.getMaxX(), src2.getMaxX());
- double maxy = Math.max(src1.getMaxY(), src2.getMaxY());
- dest.setRect(x, y, maxx - x, maxy - y);
- }
-
- /**
- * Modifies this rectangle so that it represents the smallest rectangle
- * that contains both the existing rectangle and the specified point.
- * However, if the point falls on one of the two borders which are not
- * inside the rectangle, a subsequent call to <code>contains</code> may
- * return false.
- *
- * @param newx the X coordinate of the point to add to this rectangle
- * @param newy the Y coordinate of the point to add to this rectangle
- */
- public void add(double newx, double newy)
- {
- double minx = Math.min(getX(), newx);
- double maxx = Math.max(getMaxX(), newx);
- double miny = Math.min(getY(), newy);
- double maxy = Math.max(getMaxY(), newy);
- setRect(minx, miny, maxx - minx, maxy - miny);
- }
-
- /**
- * Modifies this rectangle so that it represents the smallest rectangle
- * that contains both the existing rectangle and the specified point.
- * However, if the point falls on one of the two borders which are not
- * inside the rectangle, a subsequent call to <code>contains</code> may
- * return false.
- *
- * @param p the point to add to this rectangle
- * @throws NullPointerException if p is null
- */
- public void add(Point2D p)
- {
- add(p.getX(), p.getY());
- }
-
- /**
- * Modifies this rectangle so that it represents the smallest rectangle
- * that contains both the existing rectangle and the specified rectangle.
- *
- * @param r the rectangle to add to this rectangle
- * @throws NullPointerException if r is null
- * @see #union(Rectangle2D, Rectangle2D, Rectangle2D)
- */
- public void add(Rectangle2D r)
- {
- union(this, r, this);
- }
-
- /**
- * Return an iterator along the shape boundary. If the optional transform
- * is provided, the iterator is transformed accordingly. Each call returns
- * a new object, independent from others in use. This iterator is thread
- * safe; modifications to the rectangle do not affect the results of this
- * path instance.
- *
- * @param at an optional transform to apply to the iterator
- * @return a new iterator over the boundary
- * @since 1.2
- */
- public PathIterator getPathIterator(final AffineTransform at)
- {
- final double minx = getX();
- final double miny = getY();
- final double maxx = minx + getWidth();
- final double maxy = miny + getHeight();
- return new PathIterator()
- {
- /** Current coordinate. */
- private int current = (maxx <= minx && maxy <= miny) ? 6 : 0;
-
- public int getWindingRule()
- {
- // A test program showed that Sun J2SE 1.3.1 and 1.4.1_01
- // return WIND_NON_ZERO paths. While this does not really
- // make any difference for rectangles (because they are not
- // self-intersecting), it seems appropriate to behave
- // identically.
-
- return WIND_NON_ZERO;
- }
-
- public boolean isDone()
- {
- return current > 5;
- }
-
- public void next()
- {
- current++;
- }
-
- public int currentSegment(float[] coords)
- {
- switch (current)
- {
- case 1:
- coords[0] = (float) maxx;
- coords[1] = (float) miny;
- break;
- case 2:
- coords[0] = (float) maxx;
- coords[1] = (float) maxy;
- break;
- case 3:
- coords[0] = (float) minx;
- coords[1] = (float) maxy;
- break;
- case 0:
- case 4:
- coords[0] = (float) minx;
- coords[1] = (float) miny;
- break;
- case 5:
- return SEG_CLOSE;
- default:
- throw new NoSuchElementException("rect iterator out of bounds");
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 1);
- return current == 0 ? SEG_MOVETO : SEG_LINETO;
- }
-
- public int currentSegment(double[] coords)
- {
- switch (current)
- {
- case 1:
- coords[0] = maxx;
- coords[1] = miny;
- break;
- case 2:
- coords[0] = maxx;
- coords[1] = maxy;
- break;
- case 3:
- coords[0] = minx;
- coords[1] = maxy;
- break;
- case 0:
- case 4:
- coords[0] = minx;
- coords[1] = miny;
- break;
- case 5:
- return SEG_CLOSE;
- default:
- throw new NoSuchElementException("rect iterator out of bounds");
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 1);
- return current == 0 ? SEG_MOVETO : SEG_LINETO;
- }
- };
- }
-
- /**
- * Return an iterator along the shape boundary. If the optional transform
- * is provided, the iterator is transformed accordingly. Each call returns
- * a new object, independent from others in use. This iterator is thread
- * safe; modifications to the rectangle do not affect the results of this
- * path instance. As the rectangle is already flat, the flatness parameter
- * is ignored.
- *
- * @param at an optional transform to apply to the iterator
- * @param flatness the maximum distance for deviation from the real boundary
- * @return a new iterator over the boundary
- * @since 1.2
- */
- public PathIterator getPathIterator(AffineTransform at, double flatness)
- {
- return getPathIterator(at);
- }
-
- /**
- * Return the hashcode for this rectangle. The formula is not documented, but
- * appears to be the same as:
- * <pre>
- * long l = Double.doubleToLongBits(getX())
- * + 37 * Double.doubleToLongBits(getY())
- * + 43 * Double.doubleToLongBits(getWidth())
- * + 47 * Double.doubleToLongBits(getHeight());
- * return (int) ((l &gt;&gt; 32) ^ l);
- * </pre>
- *
- * @return the hashcode
- */
- public int hashCode()
- {
- // Talk about a fun time reverse engineering this one!
- long l = java.lang.Double.doubleToLongBits(getX())
- + 37 * java.lang.Double.doubleToLongBits(getY())
- + 43 * java.lang.Double.doubleToLongBits(getWidth())
- + 47 * java.lang.Double.doubleToLongBits(getHeight());
- return (int) ((l >> 32) ^ l);
- }
-
- /**
- * Tests this rectangle for equality against the specified object. This
- * will be true if an only if the specified object is an instance of
- * Rectangle2D with the same coordinates and dimensions.
- *
- * @param obj the object to test against for equality
- * @return true if the specified object is equal to this one
- */
- public boolean equals(Object obj)
- {
- if (! (obj instanceof Rectangle2D))
- return false;
- Rectangle2D r = (Rectangle2D) obj;
- return r.getX() == getX() && r.getY() == getY()
- && r.getWidth() == getWidth() && r.getHeight() == getHeight();
- }
-
- /**
- * This class defines a rectangle in <code>double</code> precision.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status updated to 1.4
- */
- public static class Double extends Rectangle2D
- {
- /** The x coordinate of the lower left corner. */
- public double x;
-
- /** The y coordinate of the lower left corner. */
- public double y;
-
- /** The width of the rectangle. */
- public double width;
-
- /** The height of the rectangle. */
- public double height;
-
- /**
- * Create a rectangle at (0,0) with width 0 and height 0.
- */
- public Double()
- {
- }
-
- /**
- * Create a rectangle with the given values.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- */
- public Double(double x, double y, double w, double h)
- {
- this.x = x;
- this.y = y;
- width = w;
- height = h;
- }
-
- /**
- * Return the X coordinate.
- *
- * @return the value of x
- */
- public double getX()
- {
- return x;
- }
-
- /**
- * Return the Y coordinate.
- *
- * @return the value of y
- */
- public double getY()
- {
- return y;
- }
-
- /**
- * Return the width.
- *
- * @return the value of width
- */
- public double getWidth()
- {
- return width;
- }
-
- /**
- * Return the height.
- *
- * @return the value of height
- */
- public double getHeight()
- {
- return height;
- }
-
- /**
- * Test if the rectangle is empty.
- *
- * @return true if width or height is not positive
- */
- public boolean isEmpty()
- {
- return width <= 0 || height <= 0;
- }
-
- /**
- * Set the contents of this rectangle to those specified.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- */
- public void setRect(double x, double y, double w, double h)
- {
- this.x = x;
- this.y = y;
- width = w;
- height = h;
- }
-
- /**
- * Set the contents of this rectangle to those specified.
- *
- * @param r the rectangle to copy
- * @throws NullPointerException if r is null
- */
- public void setRect(Rectangle2D r)
- {
- x = r.getX();
- y = r.getY();
- width = r.getWidth();
- height = r.getHeight();
- }
-
- /**
- * Determine where the point lies with respect to this rectangle. The
- * result will be the binary OR of the appropriate bit masks.
- *
- * @param x the x coordinate to check
- * @param y the y coordinate to check
- * @return the binary OR of the result
- * @see #OUT_LEFT
- * @see #OUT_TOP
- * @see #OUT_RIGHT
- * @see #OUT_BOTTOM
- * @since 1.2
- */
- public int outcode(double x, double y)
- {
- int result = 0;
- if (width <= 0)
- result |= OUT_LEFT | OUT_RIGHT;
- else if (x < this.x)
- result |= OUT_LEFT;
- else if (x > this.x + width)
- result |= OUT_RIGHT;
- if (height <= 0)
- result |= OUT_BOTTOM | OUT_TOP;
- else if (y < this.y) // Remember that +y heads top-to-bottom.
- result |= OUT_TOP;
- else if (y > this.y + height)
- result |= OUT_BOTTOM;
- return result;
- }
-
- /**
- * Returns the bounds of this rectangle. A pretty useless method, as this
- * is already a rectangle.
- *
- * @return a copy of this rectangle
- */
- public Rectangle2D getBounds2D()
- {
- return new Double(x, y, width, height);
- }
-
- /**
- * Return a new rectangle which is the intersection of this and the given
- * one. The result will be empty if there is no intersection.
- *
- * @param r the rectangle to be intersected
- * @return the intersection
- * @throws NullPointerException if r is null
- */
- public Rectangle2D createIntersection(Rectangle2D r)
- {
- Double res = new Double();
- intersect(this, r, res);
- return res;
- }
-
- /**
- * Return a new rectangle which is the union of this and the given one.
- *
- * @param r the rectangle to be merged
- * @return the union
- * @throws NullPointerException if r is null
- */
- public Rectangle2D createUnion(Rectangle2D r)
- {
- Double res = new Double();
- union(this, r, res);
- return res;
- }
-
- /**
- * Returns a string representation of this rectangle. This is in the form
- * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
- * + ",h=" + height + ']'</code>.
- *
- * @return a string representation of this rectangle
- */
- public String toString()
- {
- return getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
- + ",h=" + height + ']';
- }
- }
-
- /**
- * This class defines a rectangle in <code>float</code> precision.
- *
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @status updated to 1.4
- */
- public static class Float extends Rectangle2D
- {
- /** The x coordinate of the lower left corner. */
- public float x;
-
- /** The y coordinate of the lower left corner. */
- public float y;
-
- /** The width of the rectangle. */
- public float width;
-
- /** The height of the rectangle. */
- public float height;
-
- /**
- * Create a rectangle at (0,0) with width 0 and height 0.
- */
- public Float()
- {
- }
-
- /**
- * Create a rectangle with the given values.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- */
- public Float(float x, float y, float w, float h)
- {
- this.x = x;
- this.y = y;
- width = w;
- height = h;
- }
-
- /**
- * Create a rectangle with the given values.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- */
- Float(double x, double y, double w, double h)
- {
- this.x = (float) x;
- this.y = (float) y;
- width = (float) w;
- height = (float) h;
- }
-
- /**
- * Return the X coordinate.
- *
- * @return the value of x
- */
- public double getX()
- {
- return x;
- }
-
- /**
- * Return the Y coordinate.
- *
- * @return the value of y
- */
- public double getY()
- {
- return y;
- }
-
- /**
- * Return the width.
- *
- * @return the value of width
- */
- public double getWidth()
- {
- return width;
- }
-
- /**
- * Return the height.
- *
- * @return the value of height
- */
- public double getHeight()
- {
- return height;
- }
-
- /**
- * Test if the rectangle is empty.
- *
- * @return true if width or height is not positive
- */
- public boolean isEmpty()
- {
- return width <= 0 || height <= 0;
- }
-
- /**
- * Set the contents of this rectangle to those specified.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- */
- public void setRect(float x, float y, float w, float h)
- {
- this.x = x;
- this.y = y;
- width = w;
- height = h;
- }
-
- /**
- * Set the contents of this rectangle to those specified.
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param w the width
- * @param h the height
- */
- public void setRect(double x, double y, double w, double h)
- {
- this.x = (float) x;
- this.y = (float) y;
- width = (float) w;
- height = (float) h;
- }
-
- /**
- * Set the contents of this rectangle to those specified.
- *
- * @param r the rectangle to copy
- * @throws NullPointerException if r is null
- */
- public void setRect(Rectangle2D r)
- {
- x = (float) r.getX();
- y = (float) r.getY();
- width = (float) r.getWidth();
- height = (float) r.getHeight();
- }
-
- /**
- * Determine where the point lies with respect to this rectangle. The
- * result will be the binary OR of the appropriate bit masks.
- *
- * @param x the x coordinate to check
- * @param y the y coordinate to check
- * @return the binary OR of the result
- * @see #OUT_LEFT
- * @see #OUT_TOP
- * @see #OUT_RIGHT
- * @see #OUT_BOTTOM
- * @since 1.2
- */
- public int outcode(double x, double y)
- {
- int result = 0;
- if (width <= 0)
- result |= OUT_LEFT | OUT_RIGHT;
- else if (x < this.x)
- result |= OUT_LEFT;
- else if (x > this.x + width)
- result |= OUT_RIGHT;
- if (height <= 0)
- result |= OUT_BOTTOM | OUT_TOP;
- else if (y < this.y) // Remember that +y heads top-to-bottom.
- result |= OUT_TOP;
- else if (y > this.y + height)
- result |= OUT_BOTTOM;
- return result;
- }
-
- /**
- * Returns the bounds of this rectangle. A pretty useless method, as this
- * is already a rectangle.
- *
- * @return a copy of this rectangle
- */
- public Rectangle2D getBounds2D()
- {
- return new Float(x, y, width, height);
- }
-
- /**
- * Return a new rectangle which is the intersection of this and the given
- * one. The result will be empty if there is no intersection.
- *
- * @param r the rectangle to be intersected
- * @return the intersection
- * @throws NullPointerException if r is null
- */
- public Rectangle2D createIntersection(Rectangle2D r)
- {
- Float res = new Float();
- intersect(this, r, res);
- return res;
- }
-
- /**
- * Return a new rectangle which is the union of this and the given one.
- *
- * @param r the rectangle to be merged
- * @return the union
- * @throws NullPointerException if r is null
- */
- public Rectangle2D createUnion(Rectangle2D r)
- {
- Float res = new Float();
- union(this, r, res);
- return res;
- }
-
- /**
- * Returns a string representation of this rectangle. This is in the form
- * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
- * + ",h=" + height + ']'</code>.
- *
- * @return a string representation of this rectangle
- */
- public String toString()
- {
- return getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
- + ",h=" + height + ']';
- }
- }
-}
diff --git a/libjava/classpath/java/awt/geom/RectangularShape.java b/libjava/classpath/java/awt/geom/RectangularShape.java
deleted file mode 100644
index 68bc451..0000000
--- a/libjava/classpath/java/awt/geom/RectangularShape.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/* RectangularShape.java -- a rectangular frame for several generic shapes
- Copyright (C) 2000, 2002 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;
-
-/**
- * This class provides a generic framework, and several helper methods, for
- * subclasses which represent geometric objects inside a rectangular frame.
- * This does not specify any geometry except for the bounding box.
- *
- * @author Tom Tromey (tromey@cygnus.com)
- * @author Eric Blake (ebb9@email.byu.edu)
- * @since 1.2
- * @see Arc2D
- * @see Ellipse2D
- * @see Rectangle2D
- * @see RoundRectangle2D
- * @status updated to 1.4
- */
-public abstract class RectangularShape implements Shape, Cloneable
-{
- /**
- * Default constructor.
- */
- protected RectangularShape()
- {
- }
-
- /**
- * Get the x coordinate of the upper-left corner of the framing rectangle.
- *
- * @return the x coordinate
- */
- public abstract double getX();
-
- /**
- * Get the y coordinate of the upper-left corner of the framing rectangle.
- *
- * @return the y coordinate
- */
- public abstract double getY();
-
- /**
- * Get the width of the framing rectangle.
- *
- * @return the width
- */
- public abstract double getWidth();
-
- /**
- * Get the height of the framing rectangle.
- *
- * @return the height
- */
- public abstract double getHeight();
-
- /**
- * Get the minimum x coordinate in the frame. This is misnamed, or else
- * Sun has a bug, because the implementation returns getX() even when
- * getWidth() is negative.
- *
- * @return the minimum x coordinate
- */
- public double getMinX()
- {
- return getX();
- }
-
- /**
- * Get the minimum y coordinate in the frame. This is misnamed, or else
- * Sun has a bug, because the implementation returns getY() even when
- * getHeight() is negative.
- *
- * @return the minimum y coordinate
- */
- public double getMinY()
- {
- return getY();
- }
-
- /**
- * Get the maximum x coordinate in the frame. This is misnamed, or else
- * Sun has a bug, because the implementation returns getX()+getWidth() even
- * when getWidth() is negative.
- *
- * @return the maximum x coordinate
- */
- public double getMaxX()
- {
- return getX() + getWidth();
- }
-
- /**
- * Get the maximum y coordinate in the frame. This is misnamed, or else
- * Sun has a bug, because the implementation returns getY()+getHeight() even
- * when getHeight() is negative.
- *
- * @return the maximum y coordinate
- */
- public double getMaxY()
- {
- return getY() + getHeight();
- }
-
- /**
- * Return the x coordinate of the center point of the framing rectangle.
- *
- * @return the central x coordinate
- */
- public double getCenterX()
- {
- return getX() + getWidth() / 2;
- }
-
- /**
- * Return the y coordinate of the center point of the framing rectangle.
- *
- * @return the central y coordinate
- */
- public double getCenterY()
- {
- return getY() + getHeight() / 2;
- }
-
- /**
- * Return the frame around this object. Note that this may be a looser
- * bounding box than getBounds2D.
- *
- * @return the frame, in double precision
- * @see #setFrame(double, double, double, double)
- */
- public Rectangle2D getFrame()
- {
- return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
- }
-
- /**
- * Test if the shape is empty, meaning that no points are inside it.
- *
- * @return true if the shape is empty
- */
- public abstract boolean isEmpty();
-
- /**
- * Set the framing rectangle of this shape to the given coordinate and size.
- *
- * @param x the new x coordinate
- * @param y the new y coordinate
- * @param w the new width
- * @param h the new height
- * @see #getFrame()
- */
- public abstract void setFrame(double x, double y, double w, double h);
-
- /**
- * Set the framing rectangle of this shape to the given coordinate and size.
- *
- * @param p the new point
- * @param d the new dimension
- * @throws NullPointerException if p or d is null
- * @see #getFrame()
- */
- public void setFrame(Point2D p, Dimension2D d)
- {
- setFrame(p.getX(), p.getY(), d.getWidth(), d.getHeight());
- }
-
- /**
- * Set the framing rectangle of this shape to the given rectangle.
- *
- * @param r the new framing rectangle
- * @throws NullPointerException if r is null
- * @see #getFrame()
- */
- public void setFrame(Rectangle2D r)
- {
- setFrame(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Set the framing rectangle of this shape using two points on a diagonal.
- * The area will be positive.
- *
- * @param x1 the first x coordinate
- * @param y1 the first y coordinate
- * @param x2 the second x coordinate
- * @param y2 the second y coordinate
- */
- public void setFrameFromDiagonal(double x1, double y1, double x2, double y2)
- {
- if (x1 > x2)
- {
- double t = x2;
- x2 = x1;
- x1 = t;
- }
- if (y1 > y2)
- {
- double t = y2;
- y2 = y1;
- y1 = t;
- }
- setFrame(x1, y1, x2 - x1, y2 - y1);
- }
-
- /**
- * Set the framing rectangle of this shape using two points on a diagonal.
- * The area will be positive.
- *
- * @param p1 the first point
- * @param p2 the second point
- * @throws NullPointerException if either point is null
- */
- public void setFrameFromDiagonal(Point2D p1, Point2D p2)
- {
- setFrameFromDiagonal(p1.getX(), p1.getY(), p2.getX(), p2.getY());
- }
-
- /**
- * Set the framing rectangle of this shape using the center of the frame,
- * and one of the four corners. The area will be positive.
- *
- * @param centerX the x coordinate at the center
- * @param centerY the y coordinate at the center
- * @param cornerX the x coordinate at a corner
- * @param cornerY the y coordinate at a corner
- */
- public void setFrameFromCenter(double centerX, double centerY,
- double cornerX, double cornerY)
- {
- double halfw = Math.abs(cornerX - centerX);
- double halfh = Math.abs(cornerY - centerY);
- setFrame(centerX - halfw, centerY - halfh, halfw + halfw, halfh + halfh);
- }
-
- /**
- * Set the framing rectangle of this shape using the center of the frame,
- * and one of the four corners. The area will be positive.
- *
- * @param center the center point
- * @param corner a corner point
- * @throws NullPointerException if either point is null
- */
- public void setFrameFromCenter(Point2D center, Point2D corner)
- {
- setFrameFromCenter(center.getX(), center.getY(),
- corner.getX(), corner.getY());
- }
-
- /**
- * Tests if a point is inside the boundary of the shape.
- *
- * @param p the point to test
- * @return true if the point is inside the shape
- * @throws NullPointerException if p is null
- * @see #contains(double, double)
- */
- public boolean contains(Point2D p)
- {
- return contains(p.getX(), p.getY());
- }
-
- /**
- * Tests if a rectangle and this shape share common internal points.
- *
- * @param r the rectangle to test
- * @return true if the rectangle intersects this shpae
- * @throws NullPointerException if r is null
- * @see #intersects(double, double, double, double)
- */
- public boolean intersects(Rectangle2D r)
- {
- return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Tests if the shape completely contains the given rectangle.
- *
- * @param r the rectangle to test
- * @return true if r is contained in this shape
- * @throws NullPointerException if r is null
- * @see #contains(double, double, double, double)
- */
- public boolean contains(Rectangle2D r)
- {
- return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
- }
-
- /**
- * Returns a bounding box for this shape, in integer format. Notice that you
- * may get a tighter bound with getBounds2D.
- *
- * @return a bounding box
- */
- public Rectangle getBounds()
- {
- double x = getX();
- double y = getY();
- double maxx = Math.ceil(x + getWidth());
- double maxy = Math.ceil(y + getHeight());
- x = Math.floor(x);
- y = Math.floor(y);
- return new Rectangle((int) x, (int) y, (int) (maxx - x), (int) (maxy - y));
- }
-
- /**
- * Return an iterator along the shape boundary. If the optional transform
- * is provided, the iterator is transformed accordingly. The path is
- * flattened until all segments differ from the curve by at most the value
- * of the flatness parameter, within the limits of the default interpolation
- * recursion limit of 1024 segments between actual points. Each call
- * returns a new object, independent from others in use. The result is
- * threadsafe if and only if the iterator returned by
- * {@link #getPathIterator(AffineTransform)} is as well.
- *
- * @param at an optional transform to apply to the iterator
- * @param flatness the desired flatness
- * @return a new iterator over the boundary
- * @throws IllegalArgumentException if flatness is invalid
- * @since 1.2
- */
- public PathIterator getPathIterator(AffineTransform at, double flatness)
- {
- return new FlatteningPathIterator(getPathIterator(at), flatness);
- }
-
- /**
- * Create a new shape of the same run-time type with the same contents as
- * this one.
- *
- * @return the clone
- */
- public Object clone()
- {
- try
- {
- return super.clone();
- }
- catch (CloneNotSupportedException e)
- {
- throw (Error) new InternalError().initCause(e); // Impossible
- }
- }
-} // class RectangularShape
diff --git a/libjava/classpath/java/awt/geom/RoundRectangle2D.java b/libjava/classpath/java/awt/geom/RoundRectangle2D.java
deleted file mode 100644
index 19a7b42..0000000
--- a/libjava/classpath/java/awt/geom/RoundRectangle2D.java
+++ /dev/null
@@ -1,584 +0,0 @@
-/* RoundRectangle2D.java -- represents a rectangle with rounded corners
- Copyright (C) 2000, 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;
-
-
-
-/** This class implements a rectangle with rounded corners.
- * @author Tom Tromey (tromey@cygnus.com)
- * @date December 3, 2000
- */
-public abstract class RoundRectangle2D extends RectangularShape
-{
- /**
- * Return the arc height of this round rectangle. The arc height and width
- * control the roundness of the corners of the rectangle.
- *
- * @return The arc height.
- *
- * @see #getArcWidth()
- */
- public abstract double getArcHeight();
-
- /**
- * Return the arc width of this round rectangle. The arc width and height
- * control the roundness of the corners of the rectangle.
- *
- * @return The arc width.
- *
- * @see #getArcHeight()
- */
- public abstract double getArcWidth();
-
- /**
- * Set the values of this round rectangle.
- *
- * @param x The x coordinate
- * @param y The y coordinate
- * @param w The width
- * @param h The height
- * @param arcWidth The arc width
- * @param arcHeight The arc height
- */
- public abstract void setRoundRect(double x, double y, double w, double h,
- double arcWidth, double arcHeight);
-
- /**
- * Create a RoundRectangle2D. This is protected because this class
- * is abstract and cannot be instantiated.
- */
- protected RoundRectangle2D()
- {
- }
-
- /**
- * Return true if this object contains the specified point.
- * @param x The x coordinate
- * @param y The y coordinate
- */
- public boolean contains(double x, double y)
- {
- double mx = getX();
- double mw = getWidth();
- if (x < mx || x >= mx + mw)
- return false;
- double my = getY();
- double mh = getHeight();
- if (y < my || y >= my + mh)
- return false;
-
- // Now check to see if the point is in range of an arc.
- double dy = Math.min(Math.abs(my - y), Math.abs(my + mh - y));
- double dx = Math.min(Math.abs(mx - x), Math.abs(mx + mw - x));
-
- // The arc dimensions are that of the corresponding ellipse
- // thus a 90 degree segment is half of that.
- double aw = getArcWidth() / 2.0;
- double ah = getArcHeight() / 2.0;
- if (dx > aw || dy > ah)
- return true;
-
- // At this point DX represents the distance from the nearest edge
- // of the rectangle. But we want to transform it to represent the
- // scaled distance from the center of the ellipse that forms the
- // arc. Hence this code:
- dy = (ah - dy) / ah;
- dx = (aw - dx) / aw;
-
- return dx * dx + dy * dy <= 1.0;
- }
-
- /**
- * Return true if this object contains the specified rectangle
- * @param x The x coordinate
- * @param y The y coordinate
- * @param w The width
- * @param h The height
- */
- public boolean contains(double x, double y, double w, double h)
- {
- // We have to check all four points here (for ordinary rectangles
- // we can just check opposing corners).
- return (contains(x, y) && contains(x, y + h) && contains(x + w, y + h)
- && contains(x + w, y));
- }
-
- /**
- * Return a new path iterator which iterates over this rectangle.
- *
- * @param at An affine transform to apply to the object
- */
- public PathIterator getPathIterator(final AffineTransform at)
- {
- double arcW = Math.min(getArcWidth(), getWidth());
- double arcH = Math.min(getArcHeight(), getHeight());
-
- // check for special cases...
- if (arcW <= 0 || arcH <= 0)
- {
- Rectangle2D r = new Rectangle2D.Double(getX(), getY(), getWidth(),
- getHeight());
- return r.getPathIterator(at);
- }
- else if (arcW >= getWidth() && arcH >= getHeight())
- {
- Ellipse2D e = new Ellipse2D.Double(getX(), getY(), getWidth(),
- getHeight());
- return e.getPathIterator(at);
- }
-
- // otherwise return the standard case...
- return new PathIterator()
- {
- double x = getX();
- double y = getY();
- double w = getWidth();
- double h = getHeight();
- double arcW = Math.min(getArcWidth(), w);
- double arcH = Math.min(getArcHeight(), h);
- Arc2D.Double arc = new Arc2D.Double();
- PathIterator corner;
- int step = -1;
-
- public int currentSegment(double[] coords)
- {
- if (corner != null) // steps 1, 3, 5 and 7
- {
- int r = corner.currentSegment(coords);
- if (r == SEG_MOVETO)
- r = SEG_LINETO;
- return r;
- }
- if (step == -1)
- {
- // move to the start position
- coords[0] = x + w - arcW / 2;
- coords[1] = y;
- }
- else if (step == 0)
- {
- // top line
- coords[0] = x + arcW / 2;
- coords[1] = y;
- }
- else if (step == 2)
- {
- // left line
- coords[0] = x;
- coords[1] = y + h - arcH / 2;
- }
- else if (step == 4)
- {
- // bottom line
- coords[0] = x + w - arcW / 2;
- coords[1] = y + h;
- }
- else if (step == 6)
- {
- // right line
- coords[0] = x + w;
- coords[1] = y + arcH / 2;
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 1);
- return step == -1 ? SEG_MOVETO : SEG_LINETO;
- }
-
- public int currentSegment(float[] coords) {
- if (corner != null) // steps 1, 3, 5 and 7
- {
- int r = corner.currentSegment(coords);
- if (r == SEG_MOVETO)
- r = SEG_LINETO;
- return r;
- }
- if (step == -1)
- {
- // move to the start position
- coords[0] = (float) (x + w - arcW / 2);
- coords[1] = (float) y;
- }
- else if (step == 0)
- {
- // top line
- coords[0] = (float) (x + arcW / 2);
- coords[1] = (float) y;
- }
- else if (step == 2)
- {
- // left line
- coords[0] = (float) x;
- coords[1] = (float) (y + h - arcH / 2);
- }
- else if (step == 4)
- {
- // bottom line
- coords[0] = (float) (x + w - arcW / 2);
- coords[1] = (float) (y + h);
- }
- else if (step == 6)
- {
- // right line
- coords[0] = (float) (x + w);
- coords[1] = (float) (y + arcH / 2);
- }
- if (at != null)
- at.transform(coords, 0, coords, 0, 1);
- return step == -1 ? SEG_MOVETO : SEG_LINETO;
- }
-
- public int getWindingRule() {
- return WIND_NON_ZERO;
- }
-
- public boolean isDone() {
- return step >= 8;
- }
-
- public void next()
- {
- if (corner != null)
- {
- corner.next();
- if (corner.isDone())
- {
- corner = null;
- step++;
- }
- }
- else
- {
- step++;
- if (step == 1)
- {
- // create top left corner
- arc.setArc(x, y, arcW, arcH, 90, 90, Arc2D.OPEN);
- corner = arc.getPathIterator(at);
- }
- else if (step == 3)
- {
- // create bottom left corner
- arc.setArc(x, y + h - arcH, arcW, arcH, 180, 90,
- Arc2D.OPEN);
- corner = arc.getPathIterator(at);
- }
- else if (step == 5)
- {
- // create bottom right corner
- arc.setArc(x + w - arcW, y + h - arcH, arcW, arcH, 270, 90,
- Arc2D.OPEN);
- corner = arc.getPathIterator(at);
- }
- else if (step == 7)
- {
- // create top right corner
- arc.setArc(x + w - arcW, y, arcW, arcH, 0, 90, Arc2D.OPEN);
- corner = arc.getPathIterator(at);
- }
- }
- }
- };
- }
-
- /**
- * Return true if the given rectangle intersects this shape.
- * @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)
- {
- // Check if any corner is within the rectangle
- return (contains(x, y) || contains(x, y + h) || contains(x + w, y + h)
- || contains(x + w, y));
- }
-
- /**
- * Set the boundary of this round rectangle.
- * @param x The x coordinate
- * @param y The y coordinate
- * @param w The width
- * @param h The height
- */
- public void setFrame(double x, double y, double w, double h)
- {
- // This is a bit lame.
- setRoundRect(x, y, w, h, getArcWidth(), getArcHeight());
- }
-
- /**
- * Set the values of this round rectangle to be the same as those
- * of the argument.
- * @param rr The round rectangle to copy
- */
- public void setRoundRect(RoundRectangle2D rr)
- {
- setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(),
- rr.getArcWidth(), rr.getArcHeight());
- }
-
- /**
- * A subclass of RoundRectangle which keeps its parameters as
- * doubles.
- */
- public static class Double extends RoundRectangle2D
- {
- /** The height of the corner arc. */
- public double archeight;
-
- /** The width of the corner arc. */
- public double arcwidth;
-
- /** The x coordinate of this object. */
- public double x;
-
- /** The y coordinate of this object. */
- public double y;
-
- /** The width of this object. */
- public double width;
-
- /** The height of this object. */
- public double height;
-
- /**
- * Construct a new instance, with all parameters set to 0.
- */
- public Double()
- {
- }
-
- /**
- * Construct a new instance with the given arguments.
- * @param x The x coordinate
- * @param y The y coordinate
- * @param w The width
- * @param h The height
- * @param arcWidth The arc width
- * @param arcHeight The arc height
- */
- public Double(double x, double y, double w, double h, double arcWidth,
- double arcHeight)
- {
- this.x = x;
- this.y = y;
- this.width = w;
- this.height = h;
- this.arcwidth = arcWidth;
- this.archeight = arcHeight;
- }
-
- public double getArcHeight()
- {
- return archeight;
- }
-
- public double getArcWidth()
- {
- return arcwidth;
- }
-
- public Rectangle2D getBounds2D()
- {
- return new Rectangle2D.Double(x, y, width, height);
- }
-
- public double getX()
- {
- return x;
- }
-
- public double getY()
- {
- return y;
- }
-
- public double getWidth()
- {
- return width;
- }
-
- public double getHeight()
- {
- return height;
- }
-
- public boolean isEmpty()
- {
- return width <= 0 || height <= 0;
- }
-
- public void setRoundRect(double x, double y, double w, double h,
- double arcWidth, double arcHeight)
- {
- this.x = x;
- this.y = y;
- this.width = w;
- this.height = h;
- this.arcwidth = arcWidth;
- this.archeight = arcHeight;
- }
- } // class Double
-
- /**
- * A subclass of RoundRectangle which keeps its parameters as
- * floats.
- */
- public static class Float extends RoundRectangle2D
- {
- /** The height of the corner arc. */
- public float archeight;
-
- /** The width of the corner arc. */
- public float arcwidth;
-
- /** The x coordinate of this object. */
- public float x;
-
- /** The y coordinate of this object. */
- public float y;
-
- /** The width of this object. */
- public float width;
-
- /** The height of this object. */
- public float height;
-
- /**
- * Construct a new instance, with all parameters set to 0.
- */
- public Float()
- {
- }
-
- /**
- * Construct a new instance with the given arguments.
- * @param x The x coordinate
- * @param y The y coordinate
- * @param w The width
- * @param h The height
- * @param arcWidth The arc width
- * @param arcHeight The arc height
- */
- public Float(float x, float y, float w, float h, float arcWidth,
- float arcHeight)
- {
- this.x = x;
- this.y = y;
- this.width = w;
- this.height = h;
- this.arcwidth = arcWidth;
- this.archeight = arcHeight;
- }
-
- public double getArcHeight()
- {
- return archeight;
- }
-
- public double getArcWidth()
- {
- return arcwidth;
- }
-
- public Rectangle2D getBounds2D()
- {
- return new Rectangle2D.Float(x, y, width, height);
- }
-
- public double getX()
- {
- return x;
- }
-
- public double getY()
- {
- return y;
- }
-
- public double getWidth()
- {
- return width;
- }
-
- public double getHeight()
- {
- return height;
- }
-
- public boolean isEmpty()
- {
- return width <= 0 || height <= 0;
- }
-
- /**
- * Sets the dimensions for this rounded rectangle.
- *
- * @param x the x-coordinate of the top left corner.
- * @param y the y-coordinate of the top left corner.
- * @param w the width of the rectangle.
- * @param h the height of the rectangle.
- * @param arcWidth the arc width.
- * @param arcHeight the arc height.
- *
- * @see #setRoundRect(double, double, double, double, double, double)
- */
- public void setRoundRect(float x, float y, float w, float h,
- float arcWidth, float arcHeight)
- {
- this.x = x;
- this.y = y;
- this.width = w;
- this.height = h;
- this.arcwidth = arcWidth;
- this.archeight = arcHeight;
- }
-
- public void setRoundRect(double x, double y, double w, double h,
- double arcWidth, double arcHeight)
- {
- this.x = (float) x;
- this.y = (float) y;
- this.width = (float) w;
- this.height = (float) h;
- this.arcwidth = (float) arcWidth;
- this.archeight = (float) arcHeight;
- }
- } // class Float
-} // class RoundRectangle2D
diff --git a/libjava/classpath/java/awt/geom/doc-files/Area-1.png b/libjava/classpath/java/awt/geom/doc-files/Area-1.png
deleted file mode 100644
index 44650f2..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/Area-1.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-1.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-1.png
deleted file mode 100644
index 1784509..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-1.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-2.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-2.png
deleted file mode 100644
index 1ddae9f..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-2.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-3.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-3.png
deleted file mode 100644
index b200dad..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-3.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-4.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-4.png
deleted file mode 100644
index e57ffdc..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-4.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-5.png b/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-5.png
deleted file mode 100644
index 701ab13..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/CubicCurve2D-5.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/Ellipse-1.png b/libjava/classpath/java/awt/geom/doc-files/Ellipse-1.png
deleted file mode 100644
index 8317db6..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/Ellipse-1.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/FlatteningPathIterator-1.html b/libjava/classpath/java/awt/geom/doc-files/FlatteningPathIterator-1.html
deleted file mode 100644
index 5a52d69..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/FlatteningPathIterator-1.html
+++ /dev/null
@@ -1,481 +0,0 @@
-<?xml version="1.0" encoding="US-ASCII"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
- <title>The GNU Implementation of java.awt.geom.FlatteningPathIterator</title>
- <meta name="author" content="Sascha Brawer" />
- <style type="text/css"><!--
- td { white-space: nowrap; }
- li { margin: 2mm 0; }
- --></style>
-</head>
-<body>
-
-<h1>The GNU Implementation of FlatteningPathIterator</h1>
-
-<p><i><a href="http://www.dandelis.ch/people/brawer/">Sascha
-Brawer</a>, November 2003</i></p>
-
-<p>This document describes the GNU implementation of the class
-<code>java.awt.geom.FlatteningPathIterator</code>. It does
-<em>not</em> describe how a programmer should use this class; please
-refer to the generated API documentation for this purpose. Instead, it
-is intended for maintenance programmers who want to understand the
-implementation, for example because they want to extend the class or
-fix a bug.</p>
-
-
-<h2>Data Structures</h2>
-
-<p>The algorithm uses a stack. Its allocation is delayed to the time
-when the source path iterator actually returns the first curved
-segment (either <code>SEG_QUADTO</code> or <code>SEG_CUBICTO</code>).
-If the input path does not contain any curved segments, the value of
-the <code>stack</code> variable stays <code>null</code>. In this quite
-common case, the memory consumption is minimal.</p>
-
-<dl><dt><code>stack</code></dt><dd>The variable <code>stack</code> is
-a <code>double</code> array that holds the start, control and end
-points of individual sub-segments.</dd>
-
-<dt><code>recLevel</code></dt><dd>The variable <code>recLevel</code>
-holds how many recursive sub-divisions were needed to calculate a
-segment. The original curve has recursion level 0. For each
-sub-division, the corresponding recursion level is increased by
-one.</dd>
-
-<dt><code>stackSize</code></dt><dd>Finally, the variable
-<code>stackSize</code> indicates how many sub-segments are stored on
-the stack.</dd></dl>
-
-<h2>Algorithm</h2>
-
-<p>The implementation separately processes each segment that the
-base iterator returns.</p>
-
-<p>In the case of <code>SEG_CLOSE</code>,
-<code>SEG_MOVETO</code> and <code>SEG_LINETO</code> segments, the
-implementation simply hands the segment to the consumer, without actually
-doing anything.</p>
-
-<p>Any <code>SEG_QUADTO</code> and <code>SEG_CUBICTO</code> segments
-need to be flattened. Flattening is performed with a fixed-sized
-stack, holding the coordinates of subdivided segments. When the base
-iterator returns a <code>SEG_QUADTO</code> and
-<code>SEG_CUBICTO</code> segments, it is recursively flattened as
-follows:</p>
-
-<ol><li>Intialization: Allocate memory for the stack (unless a
-sufficiently large stack has been allocated previously). Push the
-original quadratic or cubic curve onto the stack. Mark that segment as
-having a <code>recLevel</code> of zero.</li>
-
-<li>If the stack is empty, flattening the segment is complete,
-and the next segment is fetched from the base iterator.</li>
-
-<li>If the stack is not empty, pop a curve segment from the
-stack.
-
- <ul><li>If its <code>recLevel</code> exceeds the recursion limit,
- hand the current segment to the consumer.</li>
-
- <li>Calculate the squared flatness of the segment. If it smaller
- than <code>flatnessSq</code>, hand the current segment to the
- consumer.</li>
-
- <li>Otherwise, split the segment in two halves. Push the right
- half onto the stack. Then, push the left half onto the stack.
- Continue with step two.</li></ul></li>
-</ol>
-
-<p>The implementation is slightly complicated by the fact that
-consumers <em>pull</em> the flattened segments from the
-<code>FlatteningPathIterator</code>. This means that we actually
-cannot &#x201c;hand the curent segment over to the consumer.&#x201d;
-But the algorithm is easier to understand if one assumes a
-<em>push</em> paradigm.</p>
-
-
-<h2>Example</h2>
-
-<p>The following example shows how a
-<code>FlatteningPathIterator</code> processes a
-<code>SEG_QUADTO</code> segment. It is (arbitrarily) assumed that the
-recursion limit was set to 2.</p>
-
-<blockquote>
-<table border="1" cellspacing="0" cellpadding="8">
- <tr align="center" valign="baseline">
- <th></th><th>A</th><th>B</th><th>C</th>
- <th>D</th><th>E</th><th>F</th><th>G</th><th>H</th>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[0]</code></th>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td><i>S<sub>ll</sub>.x</i></td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[1]</code></th>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td><i>S<sub>ll</sub>.y</i></td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[2]</code></th>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td><i>C<sub>ll</sub>.x</i></td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[3]</code></th>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td><i>C<sub>ll</sub>.y</i></td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[4]</code></th>
- <td>&#x2014;</td>
- <td><i>S<sub>l</sub>.x</i></td>
- <td><i>E<sub>ll</sub>.x</i>
- = <i>S<sub>lr</sub>.x</i></td>
- <td><i>S<sub>lr</sub>.x</i></td>
- <td>&#x2014;</td>
- <td><i>S<sub>rl</sub>.x</i></td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[5]</code></th>
- <td>&#x2014;</td>
- <td><i>S<sub>l</sub>.y</i></td>
- <td><i>E<sub>ll</sub>.x</i>
- = <i>S<sub>lr</sub>.y</i></td>
- <td><i>S<sub>lr</sub>.y</i></td>
- <td>&#x2014;</td>
- <td><i>S<sub>rl</sub>.y</i></td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[6]</code></th>
- <td>&#x2014;</td>
- <td><i>C<sub>l</sub>.x</i></td>
- <td><i>C<sub>lr</sub>.x</i></td>
- <td><i>C<sub>lr</sub>.x</i></td>
- <td>&#x2014;</td>
- <td><i>C<sub>rl</sub>.x</i></td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[7]</code></th>
- <td>&#x2014;</td>
- <td><i>C<sub>l</sub>.y</i></td>
- <td><i>C<sub>lr</sub>.y</i></td>
- <td><i>C<sub>lr</sub>.y</i></td>
- <td>&#x2014;</td>
- <td><i>C<sub>rl</sub>.y</i></td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[8]</code></th>
- <td><i>S.x</i></td>
- <td><i>E<sub>l</sub>.x</i>
- = <i>S<sub>r</sub>.x</i></td>
- <td><i>E<sub>lr</sub>.x</i>
- = <i>S<sub>r</sub>.x</i></td>
- <td><i>E<sub>lr</sub>.x</i>
- = <i>S<sub>r</sub>.x</i></td>
- <td><i>S<sub>r</sub>.x</i></td>
- <td><i>E<sub>rl</sub>.x</i>
- = <i>S<sub>rr</sub>.x</i></td>
- <td><i>S<sub>rr</sub>.x</i></td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[9]</code></th>
- <td><i>S.y</i></td>
- <td><i>E<sub>l</sub>.y</i>
- = <i>S<sub>r</sub>.y</i></td>
- <td><i>E<sub>lr</sub>.y</i>
- = <i>S<sub>r</sub>.y</i></td>
- <td><i>E<sub>lr</sub>.y</i>
- = <i>S<sub>r</sub>.y</i></td>
- <td><i>S<sub>r</sub>.y</i></td>
- <td><i>E<sub>rl</sub>.y</i>
- = <i>S<sub>rr</sub>.y</i></td>
- <td><i>S<sub>rr</sub>.y</i></td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[10]</code></th>
- <td><i>C.x</i></td>
- <td><i>C<sub>r</sub>.x</i></td>
- <td><i>C<sub>r</sub>.x</i></td>
- <td><i>C<sub>r</sub>.x</i></td>
- <td><i>C<sub>r</sub>.x</i></td>
- <td><i>C<sub>rr</sub>.x</i></td>
- <td><i>C<sub>rr</sub>.x</i></td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[11]</code></th>
- <td><i>C.y</i></td>
- <td><i>C<sub>r</sub>.y</i></td>
- <td><i>C<sub>r</sub>.y</i></td>
- <td><i>C<sub>r</sub>.y</i></td>
- <td><i>C<sub>r</sub>.y</i></td>
- <td><i>C<sub>rr</sub>.y</i></td>
- <td><i>C<sub>rr</sub>.y</i></td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[12]</code></th>
- <td><i>E.x</i></td>
- <td><i>E<sub>r</sub>.x</i></td>
- <td><i>E<sub>r</sub>.x</i></td>
- <td><i>E<sub>r</sub>.x</i></td>
- <td><i>E<sub>r</sub>.x</i></td>
- <td><i>E<sub>rr</sub>.x</i></td>
- <td><i>E<sub>rr</sub>.x</i></td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stack[13]</code></th>
- <td><i>E.y</i></td>
- <td><i>E<sub>r</sub>.y</i></td>
- <td><i>E<sub>r</sub>.y</i></td>
- <td><i>E<sub>r</sub>.y</i></td>
- <td><i>E<sub>r</sub>.y</i></td>
- <td><i>E<sub>rr</sub>.y</i></td>
- <td><i>E<sub>rr</sub>.x</i></td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>stackSize</code></th>
- <td>1</td>
- <td>2</td>
- <td>3</td>
- <td>2</td>
- <td>1</td>
- <td>2</td>
- <td>1</td>
- <td>0</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>recLevel[2]</code></th>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>2</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>recLevel[1]</code></th>
- <td>&#x2014;</td>
- <td>1</td>
- <td>2</td>
- <td>2</td>
- <td>&#x2014;</td>
- <td>2</td>
- <td>&#x2014;</td>
- <td>&#x2014;</td>
- </tr>
- <tr align="center" valign="baseline">
- <th><code>recLevel[0]</code></th>
- <td>0</td>
- <td>1</td>
- <td>1</td>
- <td>1</td>
- <td>1</td>
- <td>2</td>
- <td>2</td>
- <td>&#x2014;</td>
- </tr>
- </table>
-</blockquote>
-
-<ol>
-
-<li>The data structures are initialized as follows.
-
-<ul><li>The segment&#x2019;s end point <i>E</i>, control point
-<i>C</i>, and start point <i>S</i> are pushed onto the stack.</li>
-
- <li>Currently, the curve in the stack would be approximated by one
- single straight line segment (<i>S</i> &#x2013; <i>E</i>).
- Therefore, <code>stackSize</code> is set to 1.</li>
-
- <li>This single straight line segment is approximating the original
- curve, which can be seen as the result of zero recursive
- splits. Therefore, <code>recLevel[0]</code> is set to
- zero.</li></ul>
-
-Column A shows the state after the initialization step.</li>
-
-<li>The algorithm proceeds by taking the topmost curve segment
-(<i>S</i> &#x2013; <i>C</i> &#x2013; <i>E</i>) from the stack.
-
- <ul><li>The recursion level of this segment (stored in
- <code>recLevel[0]</code>) is zero, which is smaller than
- the limit 2.</li>
-
- <li>The method <code>java.awt.geom.QuadCurve2D.getFlatnessSq</code>
- is called to calculate the squared flatness.</li>
-
- <li>For the sake of argument, we assume that the squared flatness is
- exceeding the threshold stored in <code>flatnessSq</code>. Thus, the
- curve segment <i>S</i> &#x2013; <i>C</i> &#x2013; <i>E</i> gets
- subdivided into a left and a right half, namely
- <i>S<sub>l</sub></i> &#x2013; <i>C<sub>l</sub></i> &#x2013;
- <i>E<sub>l</sub></i> and <i>S<sub>r</sub></i> &#x2013;
- <i>C<sub>r</sub></i> &#x2013; <i>E<sub>r</sub></i>. Both halves are
- pushed onto the stack, so the left half is now on top.
-
- <br />&nbsp;<br />The left half starts at the same point
- as the original curve, so <i>S<sub>l</sub></i> has the same
- coordinates as <i>S</i>. Similarly, the end point of the right
- half and of the original curve are identical
- (<i>E<sub>r</sub></i> = <i>E</i>). More interestingly, the left
- half ends where the right half starts. Because
- <i>E<sub>l</sub></i> = <i>S<sub>r</sub></i>, their coordinates need
- to be stored only once, which amounts to saving 16 bytes (two
- <code>double</code> values) for each iteration.</li></ul>
-
-Column B shows the state after the first iteration.</li>
-
-<li>Again, the topmost curve segment (<i>S<sub>l</sub></i>
-&#x2013; <i>C<sub>l</sub></i> &#x2013; <i>E<sub>l</sub></i>) is
-taken from the stack.
-
- <ul><li>The recursion level of this segment (stored in
- <code>recLevel[1]</code>) is 1, which is smaller than
- the limit 2.</li>
-
- <li>The method <code>java.awt.geom.QuadCurve2D.getFlatnessSq</code>
- is called to calculate the squared flatness.</li>
-
- <li>Assuming that the segment is still not considered
- flat enough, it gets subdivided into a left
- (<i>S<sub>ll</sub></i> &#x2013; <i>C<sub>ll</sub></i> &#x2013;
- <i>E<sub>ll</sub></i>) and a right (<i>S<sub>lr</sub></i>
- &#x2013; <i>C<sub>lr</sub></i> &#x2013; <i>E<sub>lr</sub></i>)
- half.</li></ul>
-
-Column C shows the state after the second iteration.</li>
-
-<li>The topmost curve segment (<i>S<sub>ll</sub></i> &#x2013;
-<i>C<sub>ll</sub></i> &#x2013; <i>E<sub>ll</sub></i>) is popped from
-the stack.
-
- <ul><li>The recursion level of this segment (stored in
- <code>recLevel[2]</code>) is 2, which is <em>not</em> smaller than
- the limit 2. Therefore, a <code>SEG_LINETO</code> (from
- <i>S<sub>ll</sub></i> to <i>E<sub>ll</sub></i>) is passed to the
- consumer.</li></ul>
-
- The new state is shown in column D.</li>
-
-
-<li>The topmost curve segment (<i>S<sub>lr</sub></i> &#x2013;
-<i>C<sub>lr</sub></i> &#x2013; <i>E<sub>lr</sub></i>) is popped from
-the stack.
-
- <ul><li>The recursion level of this segment (stored in
- <code>recLevel[1]</code>) is 2, which is <em>not</em> smaller than
- the limit 2. Therefore, a <code>SEG_LINETO</code> (from
- <i>S<sub>lr</sub></i> to <i>E<sub>lr</sub></i>) is passed to the
- consumer.</li></ul>
-
- The new state is shown in column E.</li>
-
-<li>The algorithm proceeds by taking the topmost curve segment
-(<i>S<sub>r</sub></i> &#x2013; <i>C<sub>r</sub></i> &#x2013;
-<i>E<sub>r</sub></i>) from the stack.
-
- <ul><li>The recursion level of this segment (stored in
- <code>recLevel[0]</code>) is 1, which is smaller than
- the limit 2.</li>
-
- <li>The method <code>java.awt.geom.QuadCurve2D.getFlatnessSq</code>
- is called to calculate the squared flatness.</li>
-
- <li>For the sake of argument, we again assume that the squared
- flatness is exceeding the threshold stored in
- <code>flatnessSq</code>. Thus, the curve segment
- (<i>S<sub>r</sub></i> &#x2013; <i>C<sub>r</sub></i> &#x2013;
- <i>E<sub>r</sub></i>) is subdivided into a left and a right half,
- namely
- <i>S<sub>rl</sub></i> &#x2013; <i>C<sub>rl</sub></i> &#x2013;
- <i>E<sub>rl</sub></i> and <i>S<sub>rr</sub></i> &#x2013;
- <i>C<sub>rr</sub></i> &#x2013; <i>E<sub>rr</sub></i>. Both halves
- are pushed onto the stack.</li></ul>
-
- The new state is shown in column F.</li>
-
-<li>The topmost curve segment (<i>S<sub>rl</sub></i> &#x2013;
-<i>C<sub>rl</sub></i> &#x2013; <i>E<sub>rl</sub></i>) is popped from
-the stack.
-
- <ul><li>The recursion level of this segment (stored in
- <code>recLevel[2]</code>) is 2, which is <em>not</em> smaller than
- the limit 2. Therefore, a <code>SEG_LINETO</code> (from
- <i>S<sub>rl</sub></i> to <i>E<sub>rl</sub></i>) is passed to the
- consumer.</li></ul>
-
- The new state is shown in column G.</li>
-
-<li>The topmost curve segment (<i>S<sub>rr</sub></i> &#x2013;
-<i>C<sub>rr</sub></i> &#x2013; <i>E<sub>rr</sub></i>) is popped from
-the stack.
-
- <ul><li>The recursion level of this segment (stored in
- <code>recLevel[2]</code>) is 2, which is <em>not</em> smaller than
- the limit 2. Therefore, a <code>SEG_LINETO</code> (from
- <i>S<sub>rr</sub></i> to <i>E<sub>rr</sub></i>) is passed to the
- consumer.</li></ul>
-
- The new state is shown in column H.</li>
-
-<li>The stack is now empty. The FlatteningPathIterator will fetch the
-next segment from the base iterator, and process it.</li>
-
-</ol>
-
-<p>In order to split the most recently pushed segment, the
-<code>subdivideQuadratic()</code> method passes <code>stack</code>
-directly to
-<code>QuadCurve2D.subdivide(double[],int,double[],int,double[],int)</code>.
-Because the stack grows towards the beginning of the array, no data
-needs to be copied around: <code>subdivide</code> will directly store
-the result into the stack, which will have the contents shown to the
-right.</p>
-
-</body>
-</html>
diff --git a/libjava/classpath/java/awt/geom/doc-files/GeneralPath-1.png b/libjava/classpath/java/awt/geom/doc-files/GeneralPath-1.png
deleted file mode 100644
index d1d75d5..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/GeneralPath-1.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-1.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-1.png
deleted file mode 100644
index 7c2ec0e..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-1.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-2.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-2.png
deleted file mode 100644
index 496180c..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-2.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-3.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-3.png
deleted file mode 100644
index a7557ba..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-3.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-4.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-4.png
deleted file mode 100644
index 835c064..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-4.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-5.png b/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-5.png
deleted file mode 100644
index 72110cd..0000000
--- a/libjava/classpath/java/awt/geom/doc-files/QuadCurve2D-5.png
+++ /dev/null
Binary files differ
diff --git a/libjava/classpath/java/awt/geom/package.html b/libjava/classpath/java/awt/geom/package.html
deleted file mode 100644
index c8ee827..0000000
--- a/libjava/classpath/java/awt/geom/package.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<!-- package.html - describes classes in java.awt.geom package.
- Copyright (C) 2002 Free Software Foundation, Inc.
-
-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. -->
-
-<html>
-<head><title>GNU Classpath - java.awt.geom</title></head>
-
-<body>
-<p>Classes to represent 2D objects and different path transformations.</p>
-
-</body>
-</html>