/* 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 * @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; } } }