1 /*
   2  * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt;
  27 
  28 import java.awt.geom.Rectangle2D;
  29 import java.beans.Transient;
  30 
  31 /**
  32  * A <code>Rectangle</code> specifies an area in a coordinate space that is
  33  * enclosed by the <code>Rectangle</code> object's upper-left point
  34  * {@code (x,y)}
  35  * in the coordinate space, its width, and its height.
  36  * <p>
  37  * A <code>Rectangle</code> object's <code>width</code> and
  38  * <code>height</code> are <code>public</code> fields. The constructors
  39  * that create a <code>Rectangle</code>, and the methods that can modify
  40  * one, do not prevent setting a negative value for width or height.
  41  * <p>
  42  * <a name="Empty">
  43  * A {@code Rectangle} whose width or height is exactly zero has location
  44  * along those axes with zero dimension, but is otherwise considered empty.
  45  * The {@link #isEmpty} method will return true for such a {@code Rectangle}.
  46  * Methods which test if an empty {@code Rectangle} contains or intersects
  47  * a point or rectangle will always return false if either dimension is zero.
  48  * Methods which combine such a {@code Rectangle} with a point or rectangle
  49  * will include the location of the {@code Rectangle} on that axis in the
  50  * result as if the {@link #add(Point)} method were being called.
  51  * </a>
  52  * <p>
  53  * <a name="NonExistant">
  54  * A {@code Rectangle} whose width or height is negative has neither
  55  * location nor dimension along those axes with negative dimensions.
  56  * Such a {@code Rectangle} is treated as non-existant along those axes.
  57  * Such a {@code Rectangle} is also empty with respect to containment
  58  * calculations and methods which test if it contains or intersects a
  59  * point or rectangle will always return false.
  60  * Methods which combine such a {@code Rectangle} with a point or rectangle
  61  * will ignore the {@code Rectangle} entirely in generating the result.
  62  * If two {@code Rectangle} objects are combined and each has a negative
  63  * dimension, the result will have at least one negative dimension.
  64  * </a>
  65  * <p>
  66  * Methods which affect only the location of a {@code Rectangle} will
  67  * operate on its location regardless of whether or not it has a negative
  68  * or zero dimension along either axis.
  69  * <p>
  70  * Note that a {@code Rectangle} constructed with the default no-argument
  71  * constructor will have dimensions of {@code 0x0} and therefore be empty.
  72  * That {@code Rectangle} will still have a location of {@code (0,0)} and
  73  * will contribute that location to the union and add operations.
  74  * Code attempting to accumulate the bounds of a set of points should
  75  * therefore initially construct the {@code Rectangle} with a specifically
  76  * negative width and height or it should use the first point in the set
  77  * to construct the {@code Rectangle}.
  78  * For example:
  79  * <pre>{@code
  80  *     Rectangle bounds = new Rectangle(0, 0, -1, -1);
  81  *     for (int i = 0; i < points.length; i++) {
  82  *         bounds.add(points[i]);
  83  *     }
  84  * }</pre>
  85  * or if we know that the points array contains at least one point:
  86  * <pre>{@code
  87  *     Rectangle bounds = new Rectangle(points[0]);
  88  *     for (int i = 1; i < points.length; i++) {
  89  *         bounds.add(points[i]);
  90  *     }
  91  * }</pre>
  92  * <p>
  93  * This class uses 32-bit integers to store its location and dimensions.
  94  * Frequently operations may produce a result that exceeds the range of
  95  * a 32-bit integer.
  96  * The methods will calculate their results in a way that avoids any
  97  * 32-bit overflow for intermediate results and then choose the best
  98  * representation to store the final results back into the 32-bit fields
  99  * which hold the location and dimensions.
 100  * The location of the result will be stored into the {@link #x} and
 101  * {@link #y} fields by clipping the true result to the nearest 32-bit value.
 102  * The values stored into the {@link #width} and {@link #height} dimension
 103  * fields will be chosen as the 32-bit values that encompass the largest
 104  * part of the true result as possible.
 105  * Generally this means that the dimension will be clipped independently
 106  * to the range of 32-bit integers except that if the location had to be
 107  * moved to store it into its pair of 32-bit fields then the dimensions
 108  * will be adjusted relative to the "best representation" of the location.
 109  * If the true result had a negative dimension and was therefore
 110  * non-existant along one or both axes, the stored dimensions will be
 111  * negative numbers in those axes.
 112  * If the true result had a location that could be represented within
 113  * the range of 32-bit integers, but zero dimension along one or both
 114  * axes, then the stored dimensions will be zero in those axes.
 115  *
 116  * @author      Sami Shaio
 117  * @since 1.0
 118  */
 119 public class Rectangle extends Rectangle2D
 120     implements Shape, java.io.Serializable
 121 {
 122 
 123     /**
 124      * The X coordinate of the upper-left corner of the <code>Rectangle</code>.
 125      *
 126      * @serial
 127      * @see #setLocation(int, int)
 128      * @see #getLocation()
 129      * @since 1.0
 130      */
 131     public int x;
 132 
 133     /**
 134      * The Y coordinate of the upper-left corner of the <code>Rectangle</code>.
 135      *
 136      * @serial
 137      * @see #setLocation(int, int)
 138      * @see #getLocation()
 139      * @since 1.0
 140      */
 141     public int y;
 142 
 143     /**
 144      * The width of the <code>Rectangle</code>.
 145      * @serial
 146      * @see #setSize(int, int)
 147      * @see #getSize()
 148      * @since 1.0
 149      */
 150     public int width;
 151 
 152     /**
 153      * The height of the <code>Rectangle</code>.
 154      *
 155      * @serial
 156      * @see #setSize(int, int)
 157      * @see #getSize()
 158      * @since 1.0
 159      */
 160     public int height;
 161 
 162     /*
 163      * JDK 1.1 serialVersionUID
 164      */
 165      private static final long serialVersionUID = -4345857070255674764L;
 166 
 167     /**
 168      * Initialize JNI field and method IDs
 169      */
 170     private static native void initIDs();
 171 
 172     static {
 173         /* ensure that the necessary native libraries are loaded */
 174         Toolkit.loadLibraries();
 175         if (!GraphicsEnvironment.isHeadless()) {
 176             initIDs();
 177         }
 178     }
 179 
 180     /**
 181      * Constructs a new <code>Rectangle</code> whose upper-left corner
 182      * is at (0,&nbsp;0) in the coordinate space, and whose width and
 183      * height are both zero.
 184      */
 185     public Rectangle() {
 186         this(0, 0, 0, 0);
 187     }
 188 
 189     /**
 190      * Constructs a new <code>Rectangle</code>, initialized to match
 191      * the values of the specified <code>Rectangle</code>.
 192      * @param r  the <code>Rectangle</code> from which to copy initial values
 193      *           to a newly constructed <code>Rectangle</code>
 194      * @since 1.1
 195      */
 196     public Rectangle(Rectangle r) {
 197         this(r.x, r.y, r.width, r.height);
 198     }
 199 
 200     /**
 201      * Constructs a new <code>Rectangle</code> whose upper-left corner is
 202      * specified as
 203      * {@code (x,y)} and whose width and height
 204      * are specified by the arguments of the same name.
 205      * @param     x the specified X coordinate
 206      * @param     y the specified Y coordinate
 207      * @param     width    the width of the <code>Rectangle</code>
 208      * @param     height   the height of the <code>Rectangle</code>
 209      * @since 1.0
 210      */
 211     public Rectangle(int x, int y, int width, int height) {
 212         this.x = x;
 213         this.y = y;
 214         this.width = width;
 215         this.height = height;
 216     }
 217 
 218     /**
 219      * Constructs a new <code>Rectangle</code> whose upper-left corner
 220      * is at (0,&nbsp;0) in the coordinate space, and whose width and
 221      * height are specified by the arguments of the same name.
 222      * @param width the width of the <code>Rectangle</code>
 223      * @param height the height of the <code>Rectangle</code>
 224      */
 225     public Rectangle(int width, int height) {
 226         this(0, 0, width, height);
 227     }
 228 
 229     /**
 230      * Constructs a new <code>Rectangle</code> whose upper-left corner is
 231      * specified by the {@link Point} argument, and
 232      * whose width and height are specified by the
 233      * {@link Dimension} argument.
 234      * @param p a <code>Point</code> that is the upper-left corner of
 235      * the <code>Rectangle</code>
 236      * @param d a <code>Dimension</code>, representing the
 237      * width and height of the <code>Rectangle</code>
 238      */
 239     public Rectangle(Point p, Dimension d) {
 240         this(p.x, p.y, d.width, d.height);
 241     }
 242 
 243     /**
 244      * Constructs a new <code>Rectangle</code> whose upper-left corner is the
 245      * specified <code>Point</code>, and whose width and height are both zero.
 246      * @param p a <code>Point</code> that is the top left corner
 247      * of the <code>Rectangle</code>
 248      */
 249     public Rectangle(Point p) {
 250         this(p.x, p.y, 0, 0);
 251     }
 252 
 253     /**
 254      * Constructs a new <code>Rectangle</code> whose top left corner is
 255      * (0,&nbsp;0) and whose width and height are specified
 256      * by the <code>Dimension</code> argument.
 257      * @param d a <code>Dimension</code>, specifying width and height
 258      */
 259     public Rectangle(Dimension d) {
 260         this(0, 0, d.width, d.height);
 261     }
 262 
 263     /**
 264      * Returns the X coordinate of the bounding <code>Rectangle</code> in
 265      * <code>double</code> precision.
 266      * @return the X coordinate of the bounding <code>Rectangle</code>.
 267      */
 268     public double getX() {
 269         return x;
 270     }
 271 
 272     /**
 273      * Returns the Y coordinate of the bounding <code>Rectangle</code> in
 274      * <code>double</code> precision.
 275      * @return the Y coordinate of the bounding <code>Rectangle</code>.
 276      */
 277     public double getY() {
 278         return y;
 279     }
 280 
 281     /**
 282      * Returns the width of the bounding <code>Rectangle</code> in
 283      * <code>double</code> precision.
 284      * @return the width of the bounding <code>Rectangle</code>.
 285      */
 286     public double getWidth() {
 287         return width;
 288     }
 289 
 290     /**
 291      * Returns the height of the bounding <code>Rectangle</code> in
 292      * <code>double</code> precision.
 293      * @return the height of the bounding <code>Rectangle</code>.
 294      */
 295     public double getHeight() {
 296         return height;
 297     }
 298 
 299     /**
 300      * Gets the bounding <code>Rectangle</code> of this <code>Rectangle</code>.
 301      * <p>
 302      * This method is included for completeness, to parallel the
 303      * <code>getBounds</code> method of
 304      * {@link Component}.
 305      * @return    a new <code>Rectangle</code>, equal to the
 306      * bounding <code>Rectangle</code> for this <code>Rectangle</code>.
 307      * @see       java.awt.Component#getBounds
 308      * @see       #setBounds(Rectangle)
 309      * @see       #setBounds(int, int, int, int)
 310      * @since     1.1
 311      */
 312     @Transient
 313     public Rectangle getBounds() {
 314         return new Rectangle(x, y, width, height);
 315     }
 316 
 317     /**
 318      * {@inheritDoc}
 319      * @since 1.2
 320      */
 321     public Rectangle2D getBounds2D() {
 322         return new Rectangle(x, y, width, height);
 323     }
 324 
 325     /**
 326      * Sets the bounding <code>Rectangle</code> of this <code>Rectangle</code>
 327      * to match the specified <code>Rectangle</code>.
 328      * <p>
 329      * This method is included for completeness, to parallel the
 330      * <code>setBounds</code> method of <code>Component</code>.
 331      * @param r the specified <code>Rectangle</code>
 332      * @see       #getBounds
 333      * @see       java.awt.Component#setBounds(java.awt.Rectangle)
 334      * @since     1.1
 335      */
 336     public void setBounds(Rectangle r) {
 337         setBounds(r.x, r.y, r.width, r.height);
 338     }
 339 
 340     /**
 341      * Sets the bounding <code>Rectangle</code> of this
 342      * <code>Rectangle</code> to the specified
 343      * <code>x</code>, <code>y</code>, <code>width</code>,
 344      * and <code>height</code>.
 345      * <p>
 346      * This method is included for completeness, to parallel the
 347      * <code>setBounds</code> method of <code>Component</code>.
 348      * @param x the new X coordinate for the upper-left
 349      *                    corner of this <code>Rectangle</code>
 350      * @param y the new Y coordinate for the upper-left
 351      *                    corner of this <code>Rectangle</code>
 352      * @param width the new width for this <code>Rectangle</code>
 353      * @param height the new height for this <code>Rectangle</code>
 354      * @see       #getBounds
 355      * @see       java.awt.Component#setBounds(int, int, int, int)
 356      * @since     1.1
 357      */
 358     public void setBounds(int x, int y, int width, int height) {
 359         reshape(x, y, width, height);
 360     }
 361 
 362     /**
 363      * Sets the bounds of this {@code Rectangle} to the integer bounds
 364      * which encompass the specified {@code x}, {@code y}, {@code width},
 365      * and {@code height}.
 366      * If the parameters specify a {@code Rectangle} that exceeds the
 367      * maximum range of integers, the result will be the best
 368      * representation of the specified {@code Rectangle} intersected
 369      * with the maximum integer bounds.
 370      * @param x the X coordinate of the upper-left corner of
 371      *                  the specified rectangle
 372      * @param y the Y coordinate of the upper-left corner of
 373      *                  the specified rectangle
 374      * @param width the width of the specified rectangle
 375      * @param height the new height of the specified rectangle
 376      */
 377     public void setRect(double x, double y, double width, double height) {
 378         int newx, newy, neww, newh;
 379 
 380         if (x > 2.0 * Integer.MAX_VALUE) {
 381             // Too far in positive X direction to represent...
 382             // We cannot even reach the left side of the specified
 383             // rectangle even with both x & width set to MAX_VALUE.
 384             // The intersection with the "maximal integer rectangle"
 385             // is non-existant so we should use a width < 0.
 386             // REMIND: Should we try to determine a more "meaningful"
 387             // adjusted value for neww than just "-1"?
 388             newx = Integer.MAX_VALUE;
 389             neww = -1;
 390         } else {
 391             newx = clip(x, false);
 392             if (width >= 0) width += x-newx;
 393             neww = clip(width, width >= 0);
 394         }
 395 
 396         if (y > 2.0 * Integer.MAX_VALUE) {
 397             // Too far in positive Y direction to represent...
 398             newy = Integer.MAX_VALUE;
 399             newh = -1;
 400         } else {
 401             newy = clip(y, false);
 402             if (height >= 0) height += y-newy;
 403             newh = clip(height, height >= 0);
 404         }
 405 
 406         reshape(newx, newy, neww, newh);
 407     }
 408     // Return best integer representation for v, clipped to integer
 409     // range and floor-ed or ceiling-ed, depending on the boolean.
 410     private static int clip(double v, boolean doceil) {
 411         if (v <= Integer.MIN_VALUE) {
 412             return Integer.MIN_VALUE;
 413         }
 414         if (v >= Integer.MAX_VALUE) {
 415             return Integer.MAX_VALUE;
 416         }
 417         return (int) (doceil ? Math.ceil(v) : Math.floor(v));
 418     }
 419 
 420     /**
 421      * Sets the bounding <code>Rectangle</code> of this
 422      * <code>Rectangle</code> to the specified
 423      * <code>x</code>, <code>y</code>, <code>width</code>,
 424      * and <code>height</code>.
 425      * <p>
 426      * @param x the new X coordinate for the upper-left
 427      *                    corner of this <code>Rectangle</code>
 428      * @param y the new Y coordinate for the upper-left
 429      *                    corner of this <code>Rectangle</code>
 430      * @param width the new width for this <code>Rectangle</code>
 431      * @param height the new height for this <code>Rectangle</code>
 432      * @deprecated As of JDK version 1.1,
 433      * replaced by <code>setBounds(int, int, int, int)</code>.
 434      */
 435     @Deprecated
 436     public void reshape(int x, int y, int width, int height) {
 437         this.x = x;
 438         this.y = y;
 439         this.width = width;
 440         this.height = height;
 441     }
 442 
 443     /**
 444      * Returns the location of this <code>Rectangle</code>.
 445      * <p>
 446      * This method is included for completeness, to parallel the
 447      * <code>getLocation</code> method of <code>Component</code>.
 448      * @return the <code>Point</code> that is the upper-left corner of
 449      *                  this <code>Rectangle</code>.
 450      * @see       java.awt.Component#getLocation
 451      * @see       #setLocation(Point)
 452      * @see       #setLocation(int, int)
 453      * @since     1.1
 454      */
 455     public Point getLocation() {
 456         return new Point(x, y);
 457     }
 458 
 459     /**
 460      * Moves this <code>Rectangle</code> to the specified location.
 461      * <p>
 462      * This method is included for completeness, to parallel the
 463      * <code>setLocation</code> method of <code>Component</code>.
 464      * @param p the <code>Point</code> specifying the new location
 465      *                for this <code>Rectangle</code>
 466      * @see       java.awt.Component#setLocation(java.awt.Point)
 467      * @see       #getLocation
 468      * @since     1.1
 469      */
 470     public void setLocation(Point p) {
 471         setLocation(p.x, p.y);
 472     }
 473 
 474     /**
 475      * Moves this <code>Rectangle</code> to the specified location.
 476      * <p>
 477      * This method is included for completeness, to parallel the
 478      * <code>setLocation</code> method of <code>Component</code>.
 479      * @param x the X coordinate of the new location
 480      * @param y the Y coordinate of the new location
 481      * @see       #getLocation
 482      * @see       java.awt.Component#setLocation(int, int)
 483      * @since     1.1
 484      */
 485     public void setLocation(int x, int y) {
 486         move(x, y);
 487     }
 488 
 489     /**
 490      * Moves this <code>Rectangle</code> to the specified location.
 491      * <p>
 492      * @param x the X coordinate of the new location
 493      * @param y the Y coordinate of the new location
 494      * @deprecated As of JDK version 1.1,
 495      * replaced by <code>setLocation(int, int)</code>.
 496      */
 497     @Deprecated
 498     public void move(int x, int y) {
 499         this.x = x;
 500         this.y = y;
 501     }
 502 
 503     /**
 504      * Translates this <code>Rectangle</code> the indicated distance,
 505      * to the right along the X coordinate axis, and
 506      * downward along the Y coordinate axis.
 507      * @param dx the distance to move this <code>Rectangle</code>
 508      *                 along the X axis
 509      * @param dy the distance to move this <code>Rectangle</code>
 510      *                 along the Y axis
 511      * @see       java.awt.Rectangle#setLocation(int, int)
 512      * @see       java.awt.Rectangle#setLocation(java.awt.Point)
 513      */
 514     public void translate(int dx, int dy) {
 515         int oldv = this.x;
 516         int newv = oldv + dx;
 517         if (dx < 0) {
 518             // moving leftward
 519             if (newv > oldv) {
 520                 // negative overflow
 521                 // Only adjust width if it was valid (>= 0).
 522                 if (width >= 0) {
 523                     // The right edge is now conceptually at
 524                     // newv+width, but we may move newv to prevent
 525                     // overflow.  But we want the right edge to
 526                     // remain at its new location in spite of the
 527                     // clipping.  Think of the following adjustment
 528                     // conceptually the same as:
 529                     // width += newv; newv = MIN_VALUE; width -= newv;
 530                     width += newv - Integer.MIN_VALUE;
 531                     // width may go negative if the right edge went past
 532                     // MIN_VALUE, but it cannot overflow since it cannot
 533                     // have moved more than MIN_VALUE and any non-negative
 534                     // number + MIN_VALUE does not overflow.
 535                 }
 536                 newv = Integer.MIN_VALUE;
 537             }
 538         } else {
 539             // moving rightward (or staying still)
 540             if (newv < oldv) {
 541                 // positive overflow
 542                 if (width >= 0) {
 543                     // Conceptually the same as:
 544                     // width += newv; newv = MAX_VALUE; width -= newv;
 545                     width += newv - Integer.MAX_VALUE;
 546                     // With large widths and large displacements
 547                     // we may overflow so we need to check it.
 548                     if (width < 0) width = Integer.MAX_VALUE;
 549                 }
 550                 newv = Integer.MAX_VALUE;
 551             }
 552         }
 553         this.x = newv;
 554 
 555         oldv = this.y;
 556         newv = oldv + dy;
 557         if (dy < 0) {
 558             // moving upward
 559             if (newv > oldv) {
 560                 // negative overflow
 561                 if (height >= 0) {
 562                     height += newv - Integer.MIN_VALUE;
 563                     // See above comment about no overflow in this case
 564                 }
 565                 newv = Integer.MIN_VALUE;
 566             }
 567         } else {
 568             // moving downward (or staying still)
 569             if (newv < oldv) {
 570                 // positive overflow
 571                 if (height >= 0) {
 572                     height += newv - Integer.MAX_VALUE;
 573                     if (height < 0) height = Integer.MAX_VALUE;
 574                 }
 575                 newv = Integer.MAX_VALUE;
 576             }
 577         }
 578         this.y = newv;
 579     }
 580 
 581     /**
 582      * Gets the size of this <code>Rectangle</code>, represented by
 583      * the returned <code>Dimension</code>.
 584      * <p>
 585      * This method is included for completeness, to parallel the
 586      * <code>getSize</code> method of <code>Component</code>.
 587      * @return a <code>Dimension</code>, representing the size of
 588      *            this <code>Rectangle</code>.
 589      * @see       java.awt.Component#getSize
 590      * @see       #setSize(Dimension)
 591      * @see       #setSize(int, int)
 592      * @since     1.1
 593      */
 594     public Dimension getSize() {
 595         return new Dimension(width, height);
 596     }
 597 
 598     /**
 599      * Sets the size of this <code>Rectangle</code> to match the
 600      * specified <code>Dimension</code>.
 601      * <p>
 602      * This method is included for completeness, to parallel the
 603      * <code>setSize</code> method of <code>Component</code>.
 604      * @param d the new size for the <code>Dimension</code> object
 605      * @see       java.awt.Component#setSize(java.awt.Dimension)
 606      * @see       #getSize
 607      * @since     1.1
 608      */
 609     public void setSize(Dimension d) {
 610         setSize(d.width, d.height);
 611     }
 612 
 613     /**
 614      * Sets the size of this <code>Rectangle</code> to the specified
 615      * width and height.
 616      * <p>
 617      * This method is included for completeness, to parallel the
 618      * <code>setSize</code> method of <code>Component</code>.
 619      * @param width the new width for this <code>Rectangle</code>
 620      * @param height the new height for this <code>Rectangle</code>
 621      * @see       java.awt.Component#setSize(int, int)
 622      * @see       #getSize
 623      * @since     1.1
 624      */
 625     public void setSize(int width, int height) {
 626         resize(width, height);
 627     }
 628 
 629     /**
 630      * Sets the size of this <code>Rectangle</code> to the specified
 631      * width and height.
 632      * <p>
 633      * @param width the new width for this <code>Rectangle</code>
 634      * @param height the new height for this <code>Rectangle</code>
 635      * @deprecated As of JDK version 1.1,
 636      * replaced by <code>setSize(int, int)</code>.
 637      */
 638     @Deprecated
 639     public void resize(int width, int height) {
 640         this.width = width;
 641         this.height = height;
 642     }
 643 
 644     /**
 645      * Checks whether or not this <code>Rectangle</code> contains the
 646      * specified <code>Point</code>.
 647      * @param p the <code>Point</code> to test
 648      * @return    <code>true</code> if the specified <code>Point</code>
 649      *            is inside this <code>Rectangle</code>;
 650      *            <code>false</code> otherwise.
 651      * @since     1.1
 652      */
 653     public boolean contains(Point p) {
 654         return contains(p.x, p.y);
 655     }
 656 
 657     /**
 658      * Checks whether or not this <code>Rectangle</code> contains the
 659      * point at the specified location {@code (x,y)}.
 660      *
 661      * @param  x the specified X coordinate
 662      * @param  y the specified Y coordinate
 663      * @return    <code>true</code> if the point
 664      *            {@code (x,y)} is inside this
 665      *            <code>Rectangle</code>;
 666      *            <code>false</code> otherwise.
 667      * @since     1.1
 668      */
 669     public boolean contains(int x, int y) {
 670         return inside(x, y);
 671     }
 672 
 673     /**
 674      * Checks whether or not this <code>Rectangle</code> entirely contains
 675      * the specified <code>Rectangle</code>.
 676      *
 677      * @param     r   the specified <code>Rectangle</code>
 678      * @return    <code>true</code> if the <code>Rectangle</code>
 679      *            is contained entirely inside this <code>Rectangle</code>;
 680      *            <code>false</code> otherwise
 681      * @since     1.2
 682      */
 683     public boolean contains(Rectangle r) {
 684         return contains(r.x, r.y, r.width, r.height);
 685     }
 686 
 687     /**
 688      * Checks whether this <code>Rectangle</code> entirely contains
 689      * the <code>Rectangle</code>
 690      * at the specified location {@code (X,Y)} with the
 691      * specified dimensions {@code (W,H)}.
 692      * @param     X the specified X coordinate
 693      * @param     Y the specified Y coordinate
 694      * @param     W   the width of the <code>Rectangle</code>
 695      * @param     H   the height of the <code>Rectangle</code>
 696      * @return    <code>true</code> if the <code>Rectangle</code> specified by
 697      *            {@code (X, Y, W, H)}
 698      *            is entirely enclosed inside this <code>Rectangle</code>;
 699      *            <code>false</code> otherwise.
 700      * @since     1.1
 701      */
 702     public boolean contains(int X, int Y, int W, int H) {
 703         int w = this.width;
 704         int h = this.height;
 705         if ((w | h | W | H) < 0) {
 706             // At least one of the dimensions is negative...
 707             return false;
 708         }
 709         // Note: if any dimension is zero, tests below must return false...
 710         int x = this.x;
 711         int y = this.y;
 712         if (X < x || Y < y) {
 713             return false;
 714         }
 715         w += x;
 716         W += X;
 717         if (W <= X) {
 718             // X+W overflowed or W was zero, return false if...
 719             // either original w or W was zero or
 720             // x+w did not overflow or
 721             // the overflowed x+w is smaller than the overflowed X+W
 722             if (w >= x || W > w) return false;
 723         } else {
 724             // X+W did not overflow and W was not zero, return false if...
 725             // original w was zero or
 726             // x+w did not overflow and x+w is smaller than X+W
 727             if (w >= x && W > w) return false;
 728         }
 729         h += y;
 730         H += Y;
 731         if (H <= Y) {
 732             if (h >= y || H > h) return false;
 733         } else {
 734             if (h >= y && H > h) return false;
 735         }
 736         return true;
 737     }
 738 
 739     /**
 740      * Checks whether or not this <code>Rectangle</code> contains the
 741      * point at the specified location {@code (X,Y)}.
 742      *
 743      * @param  X the specified X coordinate
 744      * @param  Y the specified Y coordinate
 745      * @return    <code>true</code> if the point
 746      *            {@code (X,Y)} is inside this
 747      *            <code>Rectangle</code>;
 748      *            <code>false</code> otherwise.
 749      * @deprecated As of JDK version 1.1,
 750      * replaced by <code>contains(int, int)</code>.
 751      */
 752     @Deprecated
 753     public boolean inside(int X, int Y) {
 754         int w = this.width;
 755         int h = this.height;
 756         if ((w | h) < 0) {
 757             // At least one of the dimensions is negative...
 758             return false;
 759         }
 760         // Note: if either dimension is zero, tests below must return false...
 761         int x = this.x;
 762         int y = this.y;
 763         if (X < x || Y < y) {
 764             return false;
 765         }
 766         w += x;
 767         h += y;
 768         //    overflow || intersect
 769         return ((w < x || w > X) &&
 770                 (h < y || h > Y));
 771     }
 772 
 773     /**
 774      * Determines whether or not this <code>Rectangle</code> and the specified
 775      * <code>Rectangle</code> intersect. Two rectangles intersect if
 776      * their intersection is nonempty.
 777      *
 778      * @param r the specified <code>Rectangle</code>
 779      * @return    <code>true</code> if the specified <code>Rectangle</code>
 780      *            and this <code>Rectangle</code> intersect;
 781      *            <code>false</code> otherwise.
 782      */
 783     public boolean intersects(Rectangle r) {
 784         int tw = this.width;
 785         int th = this.height;
 786         int rw = r.width;
 787         int rh = r.height;
 788         if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
 789             return false;
 790         }
 791         int tx = this.x;
 792         int ty = this.y;
 793         int rx = r.x;
 794         int ry = r.y;
 795         rw += rx;
 796         rh += ry;
 797         tw += tx;
 798         th += ty;
 799         //      overflow || intersect
 800         return ((rw < rx || rw > tx) &&
 801                 (rh < ry || rh > ty) &&
 802                 (tw < tx || tw > rx) &&
 803                 (th < ty || th > ry));
 804     }
 805 
 806     /**
 807      * Computes the intersection of this <code>Rectangle</code> with the
 808      * specified <code>Rectangle</code>. Returns a new <code>Rectangle</code>
 809      * that represents the intersection of the two rectangles.
 810      * If the two rectangles do not intersect, the result will be
 811      * an empty rectangle.
 812      *
 813      * @param     r   the specified <code>Rectangle</code>
 814      * @return    the largest <code>Rectangle</code> contained in both the
 815      *            specified <code>Rectangle</code> and in
 816      *            this <code>Rectangle</code>; or if the rectangles
 817      *            do not intersect, an empty rectangle.
 818      */
 819     public Rectangle intersection(Rectangle r) {
 820         int tx1 = this.x;
 821         int ty1 = this.y;
 822         int rx1 = r.x;
 823         int ry1 = r.y;
 824         long tx2 = tx1; tx2 += this.width;
 825         long ty2 = ty1; ty2 += this.height;
 826         long rx2 = rx1; rx2 += r.width;
 827         long ry2 = ry1; ry2 += r.height;
 828         if (tx1 < rx1) tx1 = rx1;
 829         if (ty1 < ry1) ty1 = ry1;
 830         if (tx2 > rx2) tx2 = rx2;
 831         if (ty2 > ry2) ty2 = ry2;
 832         tx2 -= tx1;
 833         ty2 -= ty1;
 834         // tx2,ty2 will never overflow (they will never be
 835         // larger than the smallest of the two source w,h)
 836         // they might underflow, though...
 837         if (tx2 < Integer.MIN_VALUE) tx2 = Integer.MIN_VALUE;
 838         if (ty2 < Integer.MIN_VALUE) ty2 = Integer.MIN_VALUE;
 839         return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
 840     }
 841 
 842     /**
 843      * Computes the union of this <code>Rectangle</code> with the
 844      * specified <code>Rectangle</code>. Returns a new
 845      * <code>Rectangle</code> that
 846      * represents the union of the two rectangles.
 847      * <p>
 848      * If either {@code Rectangle} has any dimension less than zero
 849      * the rules for <a href=#NonExistant>non-existant</a> rectangles
 850      * apply.
 851      * If only one has a dimension less than zero, then the result
 852      * will be a copy of the other {@code Rectangle}.
 853      * If both have dimension less than zero, then the result will
 854      * have at least one dimension less than zero.
 855      * <p>
 856      * If the resulting {@code Rectangle} would have a dimension
 857      * too large to be expressed as an {@code int}, the result
 858      * will have a dimension of {@code Integer.MAX_VALUE} along
 859      * that dimension.
 860      * @param r the specified <code>Rectangle</code>
 861      * @return    the smallest <code>Rectangle</code> containing both
 862      *            the specified <code>Rectangle</code> and this
 863      *            <code>Rectangle</code>.
 864      */
 865     public Rectangle union(Rectangle r) {
 866         long tx2 = this.width;
 867         long ty2 = this.height;
 868         if ((tx2 | ty2) < 0) {
 869             // This rectangle has negative dimensions...
 870             // If r has non-negative dimensions then it is the answer.
 871             // If r is non-existant (has a negative dimension), then both
 872             // are non-existant and we can return any non-existant rectangle
 873             // as an answer.  Thus, returning r meets that criterion.
 874             // Either way, r is our answer.
 875             return new Rectangle(r);
 876         }
 877         long rx2 = r.width;
 878         long ry2 = r.height;
 879         if ((rx2 | ry2) < 0) {
 880             return new Rectangle(this);
 881         }
 882         int tx1 = this.x;
 883         int ty1 = this.y;
 884         tx2 += tx1;
 885         ty2 += ty1;
 886         int rx1 = r.x;
 887         int ry1 = r.y;
 888         rx2 += rx1;
 889         ry2 += ry1;
 890         if (tx1 > rx1) tx1 = rx1;
 891         if (ty1 > ry1) ty1 = ry1;
 892         if (tx2 < rx2) tx2 = rx2;
 893         if (ty2 < ry2) ty2 = ry2;
 894         tx2 -= tx1;
 895         ty2 -= ty1;
 896         // tx2,ty2 will never underflow since both original rectangles
 897         // were already proven to be non-empty
 898         // they might overflow, though...
 899         if (tx2 > Integer.MAX_VALUE) tx2 = Integer.MAX_VALUE;
 900         if (ty2 > Integer.MAX_VALUE) ty2 = Integer.MAX_VALUE;
 901         return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
 902     }
 903 
 904     /**
 905      * Adds a point, specified by the integer arguments {@code newx,newy}
 906      * to the bounds of this {@code Rectangle}.
 907      * <p>
 908      * If this {@code Rectangle} has any dimension less than zero,
 909      * the rules for <a href=#NonExistant>non-existant</a>
 910      * rectangles apply.
 911      * In that case, the new bounds of this {@code Rectangle} will
 912      * have a location equal to the specified coordinates and
 913      * width and height equal to zero.
 914      * <p>
 915      * After adding a point, a call to <code>contains</code> with the
 916      * added point as an argument does not necessarily return
 917      * <code>true</code>. The <code>contains</code> method does not
 918      * return <code>true</code> for points on the right or bottom
 919      * edges of a <code>Rectangle</code>. Therefore, if the added point
 920      * falls on the right or bottom edge of the enlarged
 921      * <code>Rectangle</code>, <code>contains</code> returns
 922      * <code>false</code> for that point.
 923      * If the specified point must be contained within the new
 924      * {@code Rectangle}, a 1x1 rectangle should be added instead:
 925      * <pre>
 926      *     r.add(newx, newy, 1, 1);
 927      * </pre>
 928      * @param newx the X coordinate of the new point
 929      * @param newy the Y coordinate of the new point
 930      */
 931     public void add(int newx, int newy) {
 932         if ((width | height) < 0) {
 933             this.x = newx;
 934             this.y = newy;
 935             this.width = this.height = 0;
 936             return;
 937         }
 938         int x1 = this.x;
 939         int y1 = this.y;
 940         long x2 = this.width;
 941         long y2 = this.height;
 942         x2 += x1;
 943         y2 += y1;
 944         if (x1 > newx) x1 = newx;
 945         if (y1 > newy) y1 = newy;
 946         if (x2 < newx) x2 = newx;
 947         if (y2 < newy) y2 = newy;
 948         x2 -= x1;
 949         y2 -= y1;
 950         if (x2 > Integer.MAX_VALUE) x2 = Integer.MAX_VALUE;
 951         if (y2 > Integer.MAX_VALUE) y2 = Integer.MAX_VALUE;
 952         reshape(x1, y1, (int) x2, (int) y2);
 953     }
 954 
 955     /**
 956      * Adds the specified {@code Point} to the bounds of this
 957      * {@code Rectangle}.
 958      * <p>
 959      * If this {@code Rectangle} has any dimension less than zero,
 960      * the rules for <a href=#NonExistant>non-existant</a>
 961      * rectangles apply.
 962      * In that case, the new bounds of this {@code Rectangle} will
 963      * have a location equal to the coordinates of the specified
 964      * {@code Point} and width and height equal to zero.
 965      * <p>
 966      * After adding a <code>Point</code>, a call to <code>contains</code>
 967      * with the added <code>Point</code> as an argument does not
 968      * necessarily return <code>true</code>. The <code>contains</code>
 969      * method does not return <code>true</code> for points on the right
 970      * or bottom edges of a <code>Rectangle</code>. Therefore if the added
 971      * <code>Point</code> falls on the right or bottom edge of the
 972      * enlarged <code>Rectangle</code>, <code>contains</code> returns
 973      * <code>false</code> for that <code>Point</code>.
 974      * If the specified point must be contained within the new
 975      * {@code Rectangle}, a 1x1 rectangle should be added instead:
 976      * <pre>
 977      *     r.add(pt.x, pt.y, 1, 1);
 978      * </pre>
 979      * @param pt the new <code>Point</code> to add to this
 980      *           <code>Rectangle</code>
 981      */
 982     public void add(Point pt) {
 983         add(pt.x, pt.y);
 984     }
 985 
 986     /**
 987      * Adds a <code>Rectangle</code> to this <code>Rectangle</code>.
 988      * The resulting <code>Rectangle</code> is the union of the two
 989      * rectangles.
 990      * <p>
 991      * If either {@code Rectangle} has any dimension less than 0, the
 992      * result will have the dimensions of the other {@code Rectangle}.
 993      * If both {@code Rectangle}s have at least one dimension less
 994      * than 0, the result will have at least one dimension less than 0.
 995      * <p>
 996      * If either {@code Rectangle} has one or both dimensions equal
 997      * to 0, the result along those axes with 0 dimensions will be
 998      * equivalent to the results obtained by adding the corresponding
 999      * origin coordinate to the result rectangle along that axis,
1000      * similar to the operation of the {@link #add(Point)} method,
1001      * but contribute no further dimension beyond that.
1002      * <p>
1003      * If the resulting {@code Rectangle} would have a dimension
1004      * too large to be expressed as an {@code int}, the result
1005      * will have a dimension of {@code Integer.MAX_VALUE} along
1006      * that dimension.
1007      * @param  r the specified <code>Rectangle</code>
1008      */
1009     public void add(Rectangle r) {
1010         long tx2 = this.width;
1011         long ty2 = this.height;
1012         if ((tx2 | ty2) < 0) {
1013             reshape(r.x, r.y, r.width, r.height);
1014         }
1015         long rx2 = r.width;
1016         long ry2 = r.height;
1017         if ((rx2 | ry2) < 0) {
1018             return;
1019         }
1020         int tx1 = this.x;
1021         int ty1 = this.y;
1022         tx2 += tx1;
1023         ty2 += ty1;
1024         int rx1 = r.x;
1025         int ry1 = r.y;
1026         rx2 += rx1;
1027         ry2 += ry1;
1028         if (tx1 > rx1) tx1 = rx1;
1029         if (ty1 > ry1) ty1 = ry1;
1030         if (tx2 < rx2) tx2 = rx2;
1031         if (ty2 < ry2) ty2 = ry2;
1032         tx2 -= tx1;
1033         ty2 -= ty1;
1034         // tx2,ty2 will never underflow since both original
1035         // rectangles were non-empty
1036         // they might overflow, though...
1037         if (tx2 > Integer.MAX_VALUE) tx2 = Integer.MAX_VALUE;
1038         if (ty2 > Integer.MAX_VALUE) ty2 = Integer.MAX_VALUE;
1039         reshape(tx1, ty1, (int) tx2, (int) ty2);
1040     }
1041 
1042     /**
1043      * Resizes the <code>Rectangle</code> both horizontally and vertically.
1044      * <p>
1045      * This method modifies the <code>Rectangle</code> so that it is
1046      * <code>h</code> units larger on both the left and right side,
1047      * and <code>v</code> units larger at both the top and bottom.
1048      * <p>
1049      * The new <code>Rectangle</code> has {@code (x - h, y - v)}
1050      * as its upper-left corner,
1051      * width of {@code (width + 2h)},
1052      * and a height of {@code (height + 2v)}.
1053      * <p>
1054      * If negative values are supplied for <code>h</code> and
1055      * <code>v</code>, the size of the <code>Rectangle</code>
1056      * decreases accordingly.
1057      * The {@code grow} method will check for integer overflow
1058      * and underflow, but does not check whether the resulting
1059      * values of {@code width} and {@code height} grow
1060      * from negative to non-negative or shrink from non-negative
1061      * to negative.
1062      * @param h the horizontal expansion
1063      * @param v the vertical expansion
1064      */
1065     public void grow(int h, int v) {
1066         long x0 = this.x;
1067         long y0 = this.y;
1068         long x1 = this.width;
1069         long y1 = this.height;
1070         x1 += x0;
1071         y1 += y0;
1072 
1073         x0 -= h;
1074         y0 -= v;
1075         x1 += h;
1076         y1 += v;
1077 
1078         if (x1 < x0) {
1079             // Non-existant in X direction
1080             // Final width must remain negative so subtract x0 before
1081             // it is clipped so that we avoid the risk that the clipping
1082             // of x0 will reverse the ordering of x0 and x1.
1083             x1 -= x0;
1084             if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
1085             if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
1086             else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
1087         } else { // (x1 >= x0)
1088             // Clip x0 before we subtract it from x1 in case the clipping
1089             // affects the representable area of the rectangle.
1090             if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
1091             else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
1092             x1 -= x0;
1093             // The only way x1 can be negative now is if we clipped
1094             // x0 against MIN and x1 is less than MIN - in which case
1095             // we want to leave the width negative since the result
1096             // did not intersect the representable area.
1097             if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
1098             else if (x1 > Integer.MAX_VALUE) x1 = Integer.MAX_VALUE;
1099         }
1100 
1101         if (y1 < y0) {
1102             // Non-existant in Y direction
1103             y1 -= y0;
1104             if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
1105             if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
1106             else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
1107         } else { // (y1 >= y0)
1108             if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
1109             else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
1110             y1 -= y0;
1111             if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
1112             else if (y1 > Integer.MAX_VALUE) y1 = Integer.MAX_VALUE;
1113         }
1114 
1115         reshape((int) x0, (int) y0, (int) x1, (int) y1);
1116     }
1117 
1118     /**
1119      * {@inheritDoc}
1120      * @since 1.2
1121      */
1122     public boolean isEmpty() {
1123         return (width <= 0) || (height <= 0);
1124     }
1125 
1126     /**
1127      * {@inheritDoc}
1128      * @since 1.2
1129      */
1130     public int outcode(double x, double y) {
1131         /*
1132          * Note on casts to double below.  If the arithmetic of
1133          * x+w or y+h is done in int, then we may get integer
1134          * overflow. By converting to double before the addition
1135          * we force the addition to be carried out in double to
1136          * avoid overflow in the comparison.
1137          *
1138          * See bug 4320890 for problems that this can cause.
1139          */
1140         int out = 0;
1141         if (this.width <= 0) {
1142             out |= OUT_LEFT | OUT_RIGHT;
1143         } else if (x < this.x) {
1144             out |= OUT_LEFT;
1145         } else if (x > this.x + (double) this.width) {
1146             out |= OUT_RIGHT;
1147         }
1148         if (this.height <= 0) {
1149             out |= OUT_TOP | OUT_BOTTOM;
1150         } else if (y < this.y) {
1151             out |= OUT_TOP;
1152         } else if (y > this.y + (double) this.height) {
1153             out |= OUT_BOTTOM;
1154         }
1155         return out;
1156     }
1157 
1158     /**
1159      * {@inheritDoc}
1160      * @since 1.2
1161      */
1162     public Rectangle2D createIntersection(Rectangle2D r) {
1163         if (r instanceof Rectangle) {
1164             return intersection((Rectangle) r);
1165         }
1166         Rectangle2D dest = new Rectangle2D.Double();
1167         Rectangle2D.intersect(this, r, dest);
1168         return dest;
1169     }
1170 
1171     /**
1172      * {@inheritDoc}
1173      * @since 1.2
1174      */
1175     public Rectangle2D createUnion(Rectangle2D r) {
1176         if (r instanceof Rectangle) {
1177             return union((Rectangle) r);
1178         }
1179         Rectangle2D dest = new Rectangle2D.Double();
1180         Rectangle2D.union(this, r, dest);
1181         return dest;
1182     }
1183 
1184     /**
1185      * Checks whether two rectangles are equal.
1186      * <p>
1187      * The result is <code>true</code> if and only if the argument is not
1188      * <code>null</code> and is a <code>Rectangle</code> object that has the
1189      * same upper-left corner, width, and height as
1190      * this <code>Rectangle</code>.
1191      * @param obj the <code>Object</code> to compare with
1192      *                this <code>Rectangle</code>
1193      * @return    <code>true</code> if the objects are equal;
1194      *            <code>false</code> otherwise.
1195      */
1196     public boolean equals(Object obj) {
1197         if (obj instanceof Rectangle) {
1198             Rectangle r = (Rectangle)obj;
1199             return ((x == r.x) &&
1200                     (y == r.y) &&
1201                     (width == r.width) &&
1202                     (height == r.height));
1203         }
1204         return super.equals(obj);
1205     }
1206 
1207     /**
1208      * Returns a <code>String</code> representing this
1209      * <code>Rectangle</code> and its values.
1210      * @return a <code>String</code> representing this
1211      *               <code>Rectangle</code> object's coordinate and size values.
1212      */
1213     public String toString() {
1214         return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]";
1215     }
1216 }
--- EOF ---