| /* Copyright (C) 2000 Free Software Foundation |
| |
| This file is part of libjava. |
| |
| This software is copyrighted work licensed under the terms of the |
| Libjava License. Please consult the file "LIBJAVA_LICENSE" for |
| details. */ |
| |
| package java.awt.geom; |
| import java.awt.*; |
| import java.awt.geom.Rectangle2D; |
| |
| /** |
| * @author Tom Tromey <tromey@cygnus.com> |
| * @date April 16, 2000 |
| */ |
| |
| public abstract class RectangularShape implements Shape, Cloneable |
| { |
| protected RectangularShape () |
| { |
| } |
| |
| public abstract double getX (); |
| public abstract double getY (); |
| public abstract double getWidth (); |
| public abstract double getHeight (); |
| |
| public double getMinX () |
| { |
| return Math.min (getX (), getX () + getWidth ()); |
| } |
| |
| public double getMinY () |
| { |
| return Math.min (getY (), getY () + getHeight ()); |
| } |
| |
| public double getMaxX () |
| { |
| return Math.max (getX (), getX () + getWidth ()); |
| } |
| |
| public double getMaxY () |
| { |
| return Math.max (getY (), getY () + getHeight ()); |
| } |
| |
| public double getCenterX () |
| { |
| return getX () + getWidth () / 2; |
| } |
| |
| public double getCenterY () |
| { |
| return getY () + getHeight () / 2; |
| } |
| |
| public Rectangle2D getFrame () |
| { |
| return new Rectangle2D.Double (getX (), getY (), |
| getWidth (), getHeight ()); |
| } |
| |
| public abstract boolean isEmpty (); |
| public abstract void setFrame (double x, double y, double w, double h); |
| |
| public void setFrame (Point2D loc, Dimension2D size) |
| { |
| setFrame (loc.getX (), loc.getY (), size.getWidth (), size.getHeight ()); |
| } |
| |
| public void setFrame (Rectangle2D r) |
| { |
| setFrame (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); |
| } |
| |
| 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); |
| } |
| |
| public void setFrameFromDiagonal (Point2D p1, Point2D p2) |
| { |
| setFrameFromDiagonal (p1.getX (), p1.getY (), |
| p2.getX (), p2.getY ()); |
| } |
| |
| 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, |
| 2 * halfw, 2 * halfh); |
| } |
| |
| public void setFrameFromCenter (Point2D center, Point2D corner) |
| { |
| setFrameFromCenter (center.getX (), center.getY (), |
| corner.getX (), corner.getY ()); |
| } |
| |
| public boolean contains (Point2D p) |
| { |
| double x = p.getX (); |
| double y = p.getY (); |
| double rx = getX (); |
| double ry = getY (); |
| double w = getWidth (); |
| double h = getHeight (); |
| return x >= rx && x < rx + w && y >= ry && y < ry + h; |
| } |
| |
| public boolean intersects (Rectangle2D r) |
| { |
| double x = getX (); |
| double w = getWidth (); |
| double mx = r.getX (); |
| double mw = r.getWidth (); |
| if (x < mx || x >= mx + mw || x + w < mx || x + w >= mx + mw) |
| return false; |
| double y = getY (); |
| double h = getHeight (); |
| double my = r.getY (); |
| double mh = r.getHeight (); |
| return y >= my && y < my + mh && y + h >= my && y + h < my + mh; |
| } |
| |
| private boolean containsPoint (double x, double y) |
| { |
| double mx = getX (); |
| double mw = getWidth (); |
| if (x < mx || x >= mx + mw) |
| return false; |
| double my = getY (); |
| double mh = getHeight (); |
| return y >= my && y < my + mh; |
| } |
| |
| public boolean contains (Rectangle2D r) |
| { |
| return (containsPoint (r.getMinX (), r.getMinY ()) |
| && containsPoint (r.getMaxX (), r.getMaxY ())); |
| } |
| |
| public Rectangle getBounds () |
| { |
| return new Rectangle ((int) getX (), (int) getY (), |
| (int) getWidth (), (int) getHeight ()); |
| } |
| |
| public PathIterator getPathIterator (AffineTransform at, double flatness) |
| { |
| return at.new Iterator (new Iterator ()); |
| } |
| |
| public Object clone () |
| { |
| try |
| { |
| return super.clone (); |
| } |
| catch (CloneNotSupportedException _) {return null;} |
| } |
| |
| // This implements the PathIterator for all RectangularShape objects |
| // that don't override getPathIterator. |
| private class Iterator implements PathIterator |
| { |
| // Our current coordinate. |
| private int coord; |
| |
| private static final int START = 0; |
| private static final int END_PLUS_ONE = 5; |
| |
| public Iterator () |
| { |
| coord = START; |
| } |
| |
| public int currentSegment (double[] coords) |
| { |
| int r; |
| switch (coord) |
| { |
| case 0: |
| coords[0] = getX (); |
| coords[1] = getY (); |
| r = SEG_MOVETO; |
| break; |
| |
| case 1: |
| coords[0] = getX () + getWidth (); |
| coords[1] = getY (); |
| r = SEG_LINETO; |
| break; |
| |
| case 2: |
| coords[0] = getX () + getWidth (); |
| coords[1] = getY () + getHeight (); |
| r = SEG_LINETO; |
| break; |
| |
| case 3: |
| coords[0] = getX (); |
| coords[1] = getY () + getHeight (); |
| r = SEG_LINETO; |
| break; |
| |
| case 4: |
| r = SEG_CLOSE; |
| break; |
| |
| default: |
| // It isn't clear what to do if the caller calls us after |
| // isDone returns true. |
| r = SEG_CLOSE; |
| break; |
| } |
| |
| return r; |
| } |
| |
| public int currentSegment (float[] coords) |
| { |
| int r; |
| switch (coord) |
| { |
| case 0: |
| coords[0] = (float) getX (); |
| coords[1] = (float) getY (); |
| r = SEG_MOVETO; |
| break; |
| |
| case 1: |
| coords[0] = (float) (getX () + getWidth ()); |
| coords[1] = (float) getY (); |
| r = SEG_LINETO; |
| break; |
| |
| case 2: |
| coords[0] = (float) (getX () + getWidth ()); |
| coords[1] = (float) (getY () + getHeight ()); |
| r = SEG_LINETO; |
| break; |
| |
| case 3: |
| coords[0] = (float) getX (); |
| coords[1] = (float) (getY () + getHeight ()); |
| r = SEG_LINETO; |
| break; |
| |
| case 4: |
| default: |
| // It isn't clear what to do if the caller calls us after |
| // isDone returns true. We elect to keep returning |
| // SEG_CLOSE. |
| r = SEG_CLOSE; |
| break; |
| } |
| |
| return r; |
| } |
| |
| public int getWindingRule () |
| { |
| return WIND_NON_ZERO; |
| } |
| |
| public boolean isDone () |
| { |
| return coord == END_PLUS_ONE; |
| } |
| |
| public void next () |
| { |
| if (coord < END_PLUS_ONE) |
| ++coord; |
| } |
| } |
| } |