src/java.desktop/share/classes/java/awt/Rectangle.java

Print this page




  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.</a>
  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  * <p>
  52  * <a name="NonExistant">
  53  * A {@code Rectangle} whose width or height is negative has neither
  54  * location nor dimension along those axes with negative dimensions.
  55  * Such a {@code Rectangle} is treated as non-existant along those axes.
  56  * Such a {@code Rectangle} is also empty with respect to containment
  57  * calculations and methods which test if it contains or intersects a
  58  * point or rectangle will always return false.
  59  * Methods which combine such a {@code Rectangle} with a point or rectangle
  60  * will ignore the {@code Rectangle} entirely in generating the result.
  61  * If two {@code Rectangle} objects are combined and each has a negative
  62  * dimension, the result will have at least one negative dimension.
  63  * </a>
  64  * <p>
  65  * Methods which affect only the location of a {@code Rectangle} will
  66  * operate on its location regardless of whether or not it has a negative
  67  * or zero dimension along either axis.
  68  * <p>
  69  * Note that a {@code Rectangle} constructed with the default no-argument
  70  * constructor will have dimensions of {@code 0x0} and therefore be empty.
  71  * That {@code Rectangle} will still have a location of {@code (0,0)} and
  72  * will contribute that location to the union and add operations.
  73  * Code attempting to accumulate the bounds of a set of points should
  74  * therefore initially construct the {@code Rectangle} with a specifically
  75  * negative width and height or it should use the first point in the set


  89  *     }
  90  * }</pre>
  91  * <p>
  92  * This class uses 32-bit integers to store its location and dimensions.
  93  * Frequently operations may produce a result that exceeds the range of
  94  * a 32-bit integer.
  95  * The methods will calculate their results in a way that avoids any
  96  * 32-bit overflow for intermediate results and then choose the best
  97  * representation to store the final results back into the 32-bit fields
  98  * which hold the location and dimensions.
  99  * The location of the result will be stored into the {@link #x} and
 100  * {@link #y} fields by clipping the true result to the nearest 32-bit value.
 101  * The values stored into the {@link #width} and {@link #height} dimension
 102  * fields will be chosen as the 32-bit values that encompass the largest
 103  * part of the true result as possible.
 104  * Generally this means that the dimension will be clipped independently
 105  * to the range of 32-bit integers except that if the location had to be
 106  * moved to store it into its pair of 32-bit fields then the dimensions
 107  * will be adjusted relative to the "best representation" of the location.
 108  * If the true result had a negative dimension and was therefore
 109  * non-existant along one or both axes, the stored dimensions will be
 110  * negative numbers in those axes.
 111  * If the true result had a location that could be represented within
 112  * the range of 32-bit integers, but zero dimension along one or both
 113  * axes, then the stored dimensions will be zero in those axes.
 114  *
 115  * @author      Sami Shaio
 116  * @since 1.0
 117  */
 118 public class Rectangle extends Rectangle2D
 119     implements Shape, java.io.Serializable
 120 {
 121 
 122     /**
 123      * The X coordinate of the upper-left corner of the <code>Rectangle</code>.
 124      *
 125      * @serial
 126      * @see #setLocation(int, int)
 127      * @see #getLocation()
 128      * @since 1.0
 129      */


 364      * and {@code height}.
 365      * If the parameters specify a {@code Rectangle} that exceeds the
 366      * maximum range of integers, the result will be the best
 367      * representation of the specified {@code Rectangle} intersected
 368      * with the maximum integer bounds.
 369      * @param x the X coordinate of the upper-left corner of
 370      *                  the specified rectangle
 371      * @param y the Y coordinate of the upper-left corner of
 372      *                  the specified rectangle
 373      * @param width the width of the specified rectangle
 374      * @param height the new height of the specified rectangle
 375      */
 376     public void setRect(double x, double y, double width, double height) {
 377         int newx, newy, neww, newh;
 378 
 379         if (x > 2.0 * Integer.MAX_VALUE) {
 380             // Too far in positive X direction to represent...
 381             // We cannot even reach the left side of the specified
 382             // rectangle even with both x & width set to MAX_VALUE.
 383             // The intersection with the "maximal integer rectangle"
 384             // is non-existant so we should use a width < 0.
 385             // REMIND: Should we try to determine a more "meaningful"
 386             // adjusted value for neww than just "-1"?
 387             newx = Integer.MAX_VALUE;
 388             neww = -1;
 389         } else {
 390             newx = clip(x, false);
 391             if (width >= 0) width += x-newx;
 392             neww = clip(width, width >= 0);
 393         }
 394 
 395         if (y > 2.0 * Integer.MAX_VALUE) {
 396             // Too far in positive Y direction to represent...
 397             newy = Integer.MAX_VALUE;
 398             newh = -1;
 399         } else {
 400             newy = clip(y, false);
 401             if (height >= 0) height += y-newy;
 402             newh = clip(height, height >= 0);
 403         }
 404 


 828         if (ty1 < ry1) ty1 = ry1;
 829         if (tx2 > rx2) tx2 = rx2;
 830         if (ty2 > ry2) ty2 = ry2;
 831         tx2 -= tx1;
 832         ty2 -= ty1;
 833         // tx2,ty2 will never overflow (they will never be
 834         // larger than the smallest of the two source w,h)
 835         // they might underflow, though...
 836         if (tx2 < Integer.MIN_VALUE) tx2 = Integer.MIN_VALUE;
 837         if (ty2 < Integer.MIN_VALUE) ty2 = Integer.MIN_VALUE;
 838         return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
 839     }
 840 
 841     /**
 842      * Computes the union of this <code>Rectangle</code> with the
 843      * specified <code>Rectangle</code>. Returns a new
 844      * <code>Rectangle</code> that
 845      * represents the union of the two rectangles.
 846      * <p>
 847      * If either {@code Rectangle} has any dimension less than zero
 848      * the rules for <a href=#NonExistant>non-existant</a> rectangles
 849      * apply.
 850      * If only one has a dimension less than zero, then the result
 851      * will be a copy of the other {@code Rectangle}.
 852      * If both have dimension less than zero, then the result will
 853      * have at least one dimension less than zero.
 854      * <p>
 855      * If the resulting {@code Rectangle} would have a dimension
 856      * too large to be expressed as an {@code int}, the result
 857      * will have a dimension of {@code Integer.MAX_VALUE} along
 858      * that dimension.
 859      * @param r the specified <code>Rectangle</code>
 860      * @return    the smallest <code>Rectangle</code> containing both
 861      *            the specified <code>Rectangle</code> and this
 862      *            <code>Rectangle</code>.
 863      */
 864     public Rectangle union(Rectangle r) {
 865         long tx2 = this.width;
 866         long ty2 = this.height;
 867         if ((tx2 | ty2) < 0) {
 868             // This rectangle has negative dimensions...
 869             // If r has non-negative dimensions then it is the answer.
 870             // If r is non-existant (has a negative dimension), then both
 871             // are non-existant and we can return any non-existant rectangle
 872             // as an answer.  Thus, returning r meets that criterion.
 873             // Either way, r is our answer.
 874             return new Rectangle(r);
 875         }
 876         long rx2 = r.width;
 877         long ry2 = r.height;
 878         if ((rx2 | ry2) < 0) {
 879             return new Rectangle(this);
 880         }
 881         int tx1 = this.x;
 882         int ty1 = this.y;
 883         tx2 += tx1;
 884         ty2 += ty1;
 885         int rx1 = r.x;
 886         int ry1 = r.y;
 887         rx2 += rx1;
 888         ry2 += ry1;
 889         if (tx1 > rx1) tx1 = rx1;
 890         if (ty1 > ry1) ty1 = ry1;
 891         if (tx2 < rx2) tx2 = rx2;
 892         if (ty2 < ry2) ty2 = ry2;
 893         tx2 -= tx1;
 894         ty2 -= ty1;
 895         // tx2,ty2 will never underflow since both original rectangles
 896         // were already proven to be non-empty
 897         // they might overflow, though...
 898         if (tx2 > Integer.MAX_VALUE) tx2 = Integer.MAX_VALUE;
 899         if (ty2 > Integer.MAX_VALUE) ty2 = Integer.MAX_VALUE;
 900         return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
 901     }
 902 
 903     /**
 904      * Adds a point, specified by the integer arguments {@code newx,newy}
 905      * to the bounds of this {@code Rectangle}.
 906      * <p>
 907      * If this {@code Rectangle} has any dimension less than zero,
 908      * the rules for <a href=#NonExistant>non-existant</a>
 909      * rectangles apply.
 910      * In that case, the new bounds of this {@code Rectangle} will
 911      * have a location equal to the specified coordinates and
 912      * width and height equal to zero.
 913      * <p>
 914      * After adding a point, a call to <code>contains</code> with the
 915      * added point as an argument does not necessarily return
 916      * <code>true</code>. The <code>contains</code> method does not
 917      * return <code>true</code> for points on the right or bottom
 918      * edges of a <code>Rectangle</code>. Therefore, if the added point
 919      * falls on the right or bottom edge of the enlarged
 920      * <code>Rectangle</code>, <code>contains</code> returns
 921      * <code>false</code> for that point.
 922      * If the specified point must be contained within the new
 923      * {@code Rectangle}, a 1x1 rectangle should be added instead:
 924      * <pre>
 925      *     r.add(newx, newy, 1, 1);
 926      * </pre>
 927      * @param newx the X coordinate of the new point
 928      * @param newy the Y coordinate of the new point


 939         long x2 = this.width;
 940         long y2 = this.height;
 941         x2 += x1;
 942         y2 += y1;
 943         if (x1 > newx) x1 = newx;
 944         if (y1 > newy) y1 = newy;
 945         if (x2 < newx) x2 = newx;
 946         if (y2 < newy) y2 = newy;
 947         x2 -= x1;
 948         y2 -= y1;
 949         if (x2 > Integer.MAX_VALUE) x2 = Integer.MAX_VALUE;
 950         if (y2 > Integer.MAX_VALUE) y2 = Integer.MAX_VALUE;
 951         reshape(x1, y1, (int) x2, (int) y2);
 952     }
 953 
 954     /**
 955      * Adds the specified {@code Point} to the bounds of this
 956      * {@code Rectangle}.
 957      * <p>
 958      * If this {@code Rectangle} has any dimension less than zero,
 959      * the rules for <a href=#NonExistant>non-existant</a>
 960      * rectangles apply.
 961      * In that case, the new bounds of this {@code Rectangle} will
 962      * have a location equal to the coordinates of the specified
 963      * {@code Point} and width and height equal to zero.
 964      * <p>
 965      * After adding a <code>Point</code>, a call to <code>contains</code>
 966      * with the added <code>Point</code> as an argument does not
 967      * necessarily return <code>true</code>. The <code>contains</code>
 968      * method does not return <code>true</code> for points on the right
 969      * or bottom edges of a <code>Rectangle</code>. Therefore if the added
 970      * <code>Point</code> falls on the right or bottom edge of the
 971      * enlarged <code>Rectangle</code>, <code>contains</code> returns
 972      * <code>false</code> for that <code>Point</code>.
 973      * If the specified point must be contained within the new
 974      * {@code Rectangle}, a 1x1 rectangle should be added instead:
 975      * <pre>
 976      *     r.add(pt.x, pt.y, 1, 1);
 977      * </pre>
 978      * @param pt the new <code>Point</code> to add to this
 979      *           <code>Rectangle</code>


1058      * values of {@code width} and {@code height} grow
1059      * from negative to non-negative or shrink from non-negative
1060      * to negative.
1061      * @param h the horizontal expansion
1062      * @param v the vertical expansion
1063      */
1064     public void grow(int h, int v) {
1065         long x0 = this.x;
1066         long y0 = this.y;
1067         long x1 = this.width;
1068         long y1 = this.height;
1069         x1 += x0;
1070         y1 += y0;
1071 
1072         x0 -= h;
1073         y0 -= v;
1074         x1 += h;
1075         y1 += v;
1076 
1077         if (x1 < x0) {
1078             // Non-existant in X direction
1079             // Final width must remain negative so subtract x0 before
1080             // it is clipped so that we avoid the risk that the clipping
1081             // of x0 will reverse the ordering of x0 and x1.
1082             x1 -= x0;
1083             if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
1084             if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
1085             else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
1086         } else { // (x1 >= x0)
1087             // Clip x0 before we subtract it from x1 in case the clipping
1088             // affects the representable area of the rectangle.
1089             if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
1090             else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
1091             x1 -= x0;
1092             // The only way x1 can be negative now is if we clipped
1093             // x0 against MIN and x1 is less than MIN - in which case
1094             // we want to leave the width negative since the result
1095             // did not intersect the representable area.
1096             if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
1097             else if (x1 > Integer.MAX_VALUE) x1 = Integer.MAX_VALUE;
1098         }
1099 
1100         if (y1 < y0) {
1101             // Non-existant in Y direction
1102             y1 -= y0;
1103             if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
1104             if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
1105             else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
1106         } else { // (y1 >= y0)
1107             if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
1108             else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
1109             y1 -= y0;
1110             if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
1111             else if (y1 > Integer.MAX_VALUE) y1 = Integer.MAX_VALUE;
1112         }
1113 
1114         reshape((int) x0, (int) y0, (int) x1, (int) y1);
1115     }
1116 
1117     /**
1118      * {@inheritDoc}
1119      * @since 1.2
1120      */
1121     public boolean isEmpty() {




  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.</a>
  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  * <p>
  52  * <a name="NonExistent">
  53  * A {@code Rectangle} whose width or height is negative has neither
  54  * location nor dimension along those axes with negative dimensions.
  55  * Such a {@code Rectangle} is treated as non-existent along those axes.
  56  * Such a {@code Rectangle} is also empty with respect to containment
  57  * calculations and methods which test if it contains or intersects a
  58  * point or rectangle will always return false.
  59  * Methods which combine such a {@code Rectangle} with a point or rectangle
  60  * will ignore the {@code Rectangle} entirely in generating the result.
  61  * If two {@code Rectangle} objects are combined and each has a negative
  62  * dimension, the result will have at least one negative dimension.
  63  * </a>
  64  * <p>
  65  * Methods which affect only the location of a {@code Rectangle} will
  66  * operate on its location regardless of whether or not it has a negative
  67  * or zero dimension along either axis.
  68  * <p>
  69  * Note that a {@code Rectangle} constructed with the default no-argument
  70  * constructor will have dimensions of {@code 0x0} and therefore be empty.
  71  * That {@code Rectangle} will still have a location of {@code (0,0)} and
  72  * will contribute that location to the union and add operations.
  73  * Code attempting to accumulate the bounds of a set of points should
  74  * therefore initially construct the {@code Rectangle} with a specifically
  75  * negative width and height or it should use the first point in the set


  89  *     }
  90  * }</pre>
  91  * <p>
  92  * This class uses 32-bit integers to store its location and dimensions.
  93  * Frequently operations may produce a result that exceeds the range of
  94  * a 32-bit integer.
  95  * The methods will calculate their results in a way that avoids any
  96  * 32-bit overflow for intermediate results and then choose the best
  97  * representation to store the final results back into the 32-bit fields
  98  * which hold the location and dimensions.
  99  * The location of the result will be stored into the {@link #x} and
 100  * {@link #y} fields by clipping the true result to the nearest 32-bit value.
 101  * The values stored into the {@link #width} and {@link #height} dimension
 102  * fields will be chosen as the 32-bit values that encompass the largest
 103  * part of the true result as possible.
 104  * Generally this means that the dimension will be clipped independently
 105  * to the range of 32-bit integers except that if the location had to be
 106  * moved to store it into its pair of 32-bit fields then the dimensions
 107  * will be adjusted relative to the "best representation" of the location.
 108  * If the true result had a negative dimension and was therefore
 109  * non-existent along one or both axes, the stored dimensions will be
 110  * negative numbers in those axes.
 111  * If the true result had a location that could be represented within
 112  * the range of 32-bit integers, but zero dimension along one or both
 113  * axes, then the stored dimensions will be zero in those axes.
 114  *
 115  * @author      Sami Shaio
 116  * @since 1.0
 117  */
 118 public class Rectangle extends Rectangle2D
 119     implements Shape, java.io.Serializable
 120 {
 121 
 122     /**
 123      * The X coordinate of the upper-left corner of the <code>Rectangle</code>.
 124      *
 125      * @serial
 126      * @see #setLocation(int, int)
 127      * @see #getLocation()
 128      * @since 1.0
 129      */


 364      * and {@code height}.
 365      * If the parameters specify a {@code Rectangle} that exceeds the
 366      * maximum range of integers, the result will be the best
 367      * representation of the specified {@code Rectangle} intersected
 368      * with the maximum integer bounds.
 369      * @param x the X coordinate of the upper-left corner of
 370      *                  the specified rectangle
 371      * @param y the Y coordinate of the upper-left corner of
 372      *                  the specified rectangle
 373      * @param width the width of the specified rectangle
 374      * @param height the new height of the specified rectangle
 375      */
 376     public void setRect(double x, double y, double width, double height) {
 377         int newx, newy, neww, newh;
 378 
 379         if (x > 2.0 * Integer.MAX_VALUE) {
 380             // Too far in positive X direction to represent...
 381             // We cannot even reach the left side of the specified
 382             // rectangle even with both x & width set to MAX_VALUE.
 383             // The intersection with the "maximal integer rectangle"
 384             // is non-existent so we should use a width < 0.
 385             // REMIND: Should we try to determine a more "meaningful"
 386             // adjusted value for neww than just "-1"?
 387             newx = Integer.MAX_VALUE;
 388             neww = -1;
 389         } else {
 390             newx = clip(x, false);
 391             if (width >= 0) width += x-newx;
 392             neww = clip(width, width >= 0);
 393         }
 394 
 395         if (y > 2.0 * Integer.MAX_VALUE) {
 396             // Too far in positive Y direction to represent...
 397             newy = Integer.MAX_VALUE;
 398             newh = -1;
 399         } else {
 400             newy = clip(y, false);
 401             if (height >= 0) height += y-newy;
 402             newh = clip(height, height >= 0);
 403         }
 404 


 828         if (ty1 < ry1) ty1 = ry1;
 829         if (tx2 > rx2) tx2 = rx2;
 830         if (ty2 > ry2) ty2 = ry2;
 831         tx2 -= tx1;
 832         ty2 -= ty1;
 833         // tx2,ty2 will never overflow (they will never be
 834         // larger than the smallest of the two source w,h)
 835         // they might underflow, though...
 836         if (tx2 < Integer.MIN_VALUE) tx2 = Integer.MIN_VALUE;
 837         if (ty2 < Integer.MIN_VALUE) ty2 = Integer.MIN_VALUE;
 838         return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
 839     }
 840 
 841     /**
 842      * Computes the union of this <code>Rectangle</code> with the
 843      * specified <code>Rectangle</code>. Returns a new
 844      * <code>Rectangle</code> that
 845      * represents the union of the two rectangles.
 846      * <p>
 847      * If either {@code Rectangle} has any dimension less than zero
 848      * the rules for <a href=#NonExistent>non-existent</a> rectangles
 849      * apply.
 850      * If only one has a dimension less than zero, then the result
 851      * will be a copy of the other {@code Rectangle}.
 852      * If both have dimension less than zero, then the result will
 853      * have at least one dimension less than zero.
 854      * <p>
 855      * If the resulting {@code Rectangle} would have a dimension
 856      * too large to be expressed as an {@code int}, the result
 857      * will have a dimension of {@code Integer.MAX_VALUE} along
 858      * that dimension.
 859      * @param r the specified <code>Rectangle</code>
 860      * @return    the smallest <code>Rectangle</code> containing both
 861      *            the specified <code>Rectangle</code> and this
 862      *            <code>Rectangle</code>.
 863      */
 864     public Rectangle union(Rectangle r) {
 865         long tx2 = this.width;
 866         long ty2 = this.height;
 867         if ((tx2 | ty2) < 0) {
 868             // This rectangle has negative dimensions...
 869             // If r has non-negative dimensions then it is the answer.
 870             // If r is non-existent (has a negative dimension), then both
 871             // are non-existent and we can return any non-existent rectangle
 872             // as an answer.  Thus, returning r meets that criterion.
 873             // Either way, r is our answer.
 874             return new Rectangle(r);
 875         }
 876         long rx2 = r.width;
 877         long ry2 = r.height;
 878         if ((rx2 | ry2) < 0) {
 879             return new Rectangle(this);
 880         }
 881         int tx1 = this.x;
 882         int ty1 = this.y;
 883         tx2 += tx1;
 884         ty2 += ty1;
 885         int rx1 = r.x;
 886         int ry1 = r.y;
 887         rx2 += rx1;
 888         ry2 += ry1;
 889         if (tx1 > rx1) tx1 = rx1;
 890         if (ty1 > ry1) ty1 = ry1;
 891         if (tx2 < rx2) tx2 = rx2;
 892         if (ty2 < ry2) ty2 = ry2;
 893         tx2 -= tx1;
 894         ty2 -= ty1;
 895         // tx2,ty2 will never underflow since both original rectangles
 896         // were already proven to be non-empty
 897         // they might overflow, though...
 898         if (tx2 > Integer.MAX_VALUE) tx2 = Integer.MAX_VALUE;
 899         if (ty2 > Integer.MAX_VALUE) ty2 = Integer.MAX_VALUE;
 900         return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
 901     }
 902 
 903     /**
 904      * Adds a point, specified by the integer arguments {@code newx,newy}
 905      * to the bounds of this {@code Rectangle}.
 906      * <p>
 907      * If this {@code Rectangle} has any dimension less than zero,
 908      * the rules for <a href=#NonExistent>non-existent</a>
 909      * rectangles apply.
 910      * In that case, the new bounds of this {@code Rectangle} will
 911      * have a location equal to the specified coordinates and
 912      * width and height equal to zero.
 913      * <p>
 914      * After adding a point, a call to <code>contains</code> with the
 915      * added point as an argument does not necessarily return
 916      * <code>true</code>. The <code>contains</code> method does not
 917      * return <code>true</code> for points on the right or bottom
 918      * edges of a <code>Rectangle</code>. Therefore, if the added point
 919      * falls on the right or bottom edge of the enlarged
 920      * <code>Rectangle</code>, <code>contains</code> returns
 921      * <code>false</code> for that point.
 922      * If the specified point must be contained within the new
 923      * {@code Rectangle}, a 1x1 rectangle should be added instead:
 924      * <pre>
 925      *     r.add(newx, newy, 1, 1);
 926      * </pre>
 927      * @param newx the X coordinate of the new point
 928      * @param newy the Y coordinate of the new point


 939         long x2 = this.width;
 940         long y2 = this.height;
 941         x2 += x1;
 942         y2 += y1;
 943         if (x1 > newx) x1 = newx;
 944         if (y1 > newy) y1 = newy;
 945         if (x2 < newx) x2 = newx;
 946         if (y2 < newy) y2 = newy;
 947         x2 -= x1;
 948         y2 -= y1;
 949         if (x2 > Integer.MAX_VALUE) x2 = Integer.MAX_VALUE;
 950         if (y2 > Integer.MAX_VALUE) y2 = Integer.MAX_VALUE;
 951         reshape(x1, y1, (int) x2, (int) y2);
 952     }
 953 
 954     /**
 955      * Adds the specified {@code Point} to the bounds of this
 956      * {@code Rectangle}.
 957      * <p>
 958      * If this {@code Rectangle} has any dimension less than zero,
 959      * the rules for <a href=#NonExistent>non-existent</a>
 960      * rectangles apply.
 961      * In that case, the new bounds of this {@code Rectangle} will
 962      * have a location equal to the coordinates of the specified
 963      * {@code Point} and width and height equal to zero.
 964      * <p>
 965      * After adding a <code>Point</code>, a call to <code>contains</code>
 966      * with the added <code>Point</code> as an argument does not
 967      * necessarily return <code>true</code>. The <code>contains</code>
 968      * method does not return <code>true</code> for points on the right
 969      * or bottom edges of a <code>Rectangle</code>. Therefore if the added
 970      * <code>Point</code> falls on the right or bottom edge of the
 971      * enlarged <code>Rectangle</code>, <code>contains</code> returns
 972      * <code>false</code> for that <code>Point</code>.
 973      * If the specified point must be contained within the new
 974      * {@code Rectangle}, a 1x1 rectangle should be added instead:
 975      * <pre>
 976      *     r.add(pt.x, pt.y, 1, 1);
 977      * </pre>
 978      * @param pt the new <code>Point</code> to add to this
 979      *           <code>Rectangle</code>


1058      * values of {@code width} and {@code height} grow
1059      * from negative to non-negative or shrink from non-negative
1060      * to negative.
1061      * @param h the horizontal expansion
1062      * @param v the vertical expansion
1063      */
1064     public void grow(int h, int v) {
1065         long x0 = this.x;
1066         long y0 = this.y;
1067         long x1 = this.width;
1068         long y1 = this.height;
1069         x1 += x0;
1070         y1 += y0;
1071 
1072         x0 -= h;
1073         y0 -= v;
1074         x1 += h;
1075         y1 += v;
1076 
1077         if (x1 < x0) {
1078             // Non-existent in X direction
1079             // Final width must remain negative so subtract x0 before
1080             // it is clipped so that we avoid the risk that the clipping
1081             // of x0 will reverse the ordering of x0 and x1.
1082             x1 -= x0;
1083             if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
1084             if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
1085             else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
1086         } else { // (x1 >= x0)
1087             // Clip x0 before we subtract it from x1 in case the clipping
1088             // affects the representable area of the rectangle.
1089             if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
1090             else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
1091             x1 -= x0;
1092             // The only way x1 can be negative now is if we clipped
1093             // x0 against MIN and x1 is less than MIN - in which case
1094             // we want to leave the width negative since the result
1095             // did not intersect the representable area.
1096             if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
1097             else if (x1 > Integer.MAX_VALUE) x1 = Integer.MAX_VALUE;
1098         }
1099 
1100         if (y1 < y0) {
1101             // Non-existent in Y direction
1102             y1 -= y0;
1103             if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
1104             if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
1105             else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
1106         } else { // (y1 >= y0)
1107             if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
1108             else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
1109             y1 -= y0;
1110             if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
1111             else if (y1 > Integer.MAX_VALUE) y1 = Integer.MAX_VALUE;
1112         }
1113 
1114         reshape((int) x0, (int) y0, (int) x1, (int) y1);
1115     }
1116 
1117     /**
1118      * {@inheritDoc}
1119      * @since 1.2
1120      */
1121     public boolean isEmpty() {