/**
  * {@collect.stats} Adds a <code>Rectangle</code> to this <code>Rectangle</code>. The resulting
  * <code>Rectangle</code> is the union of the two rectangles.
  *
  * <p>If either {@code Rectangle} has any dimension less than 0, the result will have the
  * dimensions of the other {@code Rectangle}. If both {@code Rectangle}s have at least one
  * dimension less than 0, the result will have at least one dimension less than 0.
  *
  * <p>If either {@code Rectangle} has one or both dimensions equal to 0, the result along those
  * axes with 0 dimensions will be equivalent to the results obtained by adding the corresponding
  * origin coordinate to the result rectangle along that axis, similar to the operation of the
  * {@link #add(Point)} method, but contribute no further dimension beyond that.
  *
  * <p>If the resulting {@code Rectangle} would have a dimension too large to be expressed as an
  * {@code int}, the result will have a dimension of {@code Integer.MAX_VALUE} along that
  * dimension.
  *
  * @param r the specified <code>Rectangle</code>
  */
 public void add(Rectangle r) {
   long tx2 = this.width;
   long ty2 = this.height;
   if ((tx2 | ty2) < 0) {
     reshape(r.x, r.y, r.width, r.height);
   }
   long rx2 = r.width;
   long ry2 = r.height;
   if ((rx2 | ry2) < 0) {
     return;
   }
   int tx1 = this.x;
   int ty1 = this.y;
   tx2 += tx1;
   ty2 += ty1;
   int rx1 = r.x;
   int ry1 = r.y;
   rx2 += rx1;
   ry2 += ry1;
   if (tx1 > rx1) tx1 = rx1;
   if (ty1 > ry1) ty1 = ry1;
   if (tx2 < rx2) tx2 = rx2;
   if (ty2 < ry2) ty2 = ry2;
   tx2 -= tx1;
   ty2 -= ty1;
   // tx2,ty2 will never underflow since both original
   // rectangles were non-empty
   // they might overflow, though...
   if (tx2 > Integer.MAX_VALUE) tx2 = Integer.MAX_VALUE;
   if (ty2 > Integer.MAX_VALUE) ty2 = Integer.MAX_VALUE;
   reshape(tx1, ty1, (int) tx2, (int) ty2);
 }
  /**
   * {@collect.stats} Sets the bounds of this {@code Rectangle} to the integer bounds which
   * encompass the specified {@code x}, {@code y}, {@code width}, and {@code height}. If the
   * parameters specify a {@code Rectangle} that exceeds the maximum range of integers, the result
   * will be the best representation of the specified {@code Rectangle} intersected with the maximum
   * integer bounds.
   *
   * @param x the X coordinate of the upper-left corner of the specified rectangle
   * @param y the Y coordinate of the upper-left corner of the specified rectangle
   * @param width the width of the specified rectangle
   * @param height the new height of the specified rectangle
   */
  public void setRect(double x, double y, double width, double height) {
    int newx, newy, neww, newh;

    if (x > 2.0 * Integer.MAX_VALUE) {
      // Too far in positive X direction to represent...
      // We cannot even reach the left side of the specified
      // rectangle even with both x & width set to MAX_VALUE.
      // The intersection with the "maximal integer rectangle"
      // is non-existant so we should use a width < 0.
      // REMIND: Should we try to determine a more "meaningful"
      // adjusted value for neww than just "-1"?
      newx = Integer.MAX_VALUE;
      neww = -1;
    } else {
      newx = clip(x, false);
      if (width >= 0) width += x - newx;
      neww = clip(width, width >= 0);
    }

    if (y > 2.0 * Integer.MAX_VALUE) {
      // Too far in positive Y direction to represent...
      newy = Integer.MAX_VALUE;
      newh = -1;
    } else {
      newy = clip(y, false);
      if (height >= 0) height += y - newy;
      newh = clip(height, height >= 0);
    }

    reshape(newx, newy, neww, newh);
  }
  /**
   * {@collect.stats} Resizes the <code>Rectangle</code> both horizontally and vertically.
   *
   * <p>This method modifies the <code>Rectangle</code> so that it is <code>h</code> units larger on
   * both the left and right side, and <code>v</code> units larger at both the top and bottom.
   *
   * <p>The new <code>Rectangle</code> has {@code (x - h, y - v)} as its upper-left corner, width of
   * {@code (width + 2h)}, and a height of {@code (height + 2v)}.
   *
   * <p>If negative values are supplied for <code>h</code> and <code>v</code>, the size of the
   * <code>Rectangle</code> decreases accordingly. The {@code grow} method will check for integer
   * overflow and underflow, but does not check whether the resulting values of {@code width} and
   * {@code height} grow from negative to non-negative or shrink from non-negative to negative.
   *
   * @param h the horizontal expansion
   * @param v the vertical expansion
   */
  public void grow(int h, int v) {
    long x0 = this.x;
    long y0 = this.y;
    long x1 = this.width;
    long y1 = this.height;
    x1 += x0;
    y1 += y0;

    x0 -= h;
    y0 -= v;
    x1 += h;
    y1 += v;

    if (x1 < x0) {
      // Non-existant in X direction
      // Final width must remain negative so subtract x0 before
      // it is clipped so that we avoid the risk that the clipping
      // of x0 will reverse the ordering of x0 and x1.
      x1 -= x0;
      if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
      if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
      else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
    } else { // (x1 >= x0)
      // Clip x0 before we subtract it from x1 in case the clipping
      // affects the representable area of the rectangle.
      if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
      else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
      x1 -= x0;
      // The only way x1 can be negative now is if we clipped
      // x0 against MIN and x1 is less than MIN - in which case
      // we want to leave the width negative since the result
      // did not intersect the representable area.
      if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
      else if (x1 > Integer.MAX_VALUE) x1 = Integer.MAX_VALUE;
    }

    if (y1 < y0) {
      // Non-existant in Y direction
      y1 -= y0;
      if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
      if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
      else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
    } else { // (y1 >= y0)
      if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
      else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
      y1 -= y0;
      if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
      else if (y1 > Integer.MAX_VALUE) y1 = Integer.MAX_VALUE;
    }

    reshape((int) x0, (int) y0, (int) x1, (int) y1);
  }
 /**
  * {@collect.stats} Adds a point, specified by the integer arguments {@code newx,newy} to the
  * bounds of this {@code Rectangle}.
  *
  * <p>If this {@code Rectangle} has any dimension less than zero, the rules for <a
  * href=#NonExistant>non-existant</a> rectangles apply. In that case, the new bounds of this
  * {@code Rectangle} will have a location equal to the specified coordinates and width and height
  * equal to zero.
  *
  * <p>After adding a point, a call to <code>contains</code> with the added point as an argument
  * does not necessarily return <code>true</code>. The <code>contains</code> method does not return
  * <code>true</code> for points on the right or bottom edges of a <code>Rectangle</code>.
  * Therefore, if the added point falls on the right or bottom edge of the enlarged <code>Rectangle
  * </code>, <code>contains</code> returns <code>false</code> for that point. If the specified
  * point must be contained within the new {@code Rectangle}, a 1x1 rectangle should be added
  * instead:
  *
  * <pre>
  *     r.add(newx, newy, 1, 1);
  * </pre>
  *
  * @param newx the X coordinate of the new point
  * @param newy the Y coordinate of the new point
  */
 public void add(int newx, int newy) {
   if ((width | height) < 0) {
     this.x = newx;
     this.y = newy;
     this.width = this.height = 0;
     return;
   }
   int x1 = this.x;
   int y1 = this.y;
   long x2 = this.width;
   long y2 = this.height;
   x2 += x1;
   y2 += y1;
   if (x1 > newx) x1 = newx;
   if (y1 > newy) y1 = newy;
   if (x2 < newx) x2 = newx;
   if (y2 < newy) y2 = newy;
   x2 -= x1;
   y2 -= y1;
   if (x2 > Integer.MAX_VALUE) x2 = Integer.MAX_VALUE;
   if (y2 > Integer.MAX_VALUE) y2 = Integer.MAX_VALUE;
   reshape(x1, y1, (int) x2, (int) y2);
 }
Exemplo n.º 5
0
 /**
  * Sets the bounding <code>Rectangle</code> of this <code>Rectangle</code> to the specified <code>
  * x</code>, <code>y</code>, <code>width</code>, and <code>height</code>.
  *
  * <p>This method is included for completeness, to parallel the <code>setBounds</code> method of
  * <code>Component</code>.
  *
  * @param x the new x coordinate for the top-left corner of this <code>Rectangle</code>
  * @param y the new y coordinate for the top-left corner of this <code>Rectangle</code>
  * @param width the new width for this <code>Rectangle</code>
  * @param height the new height for this <code>Rectangle</code>
  * @see #getBounds
  * @see java.awt.Component#setBounds(int, int, int, int)
  * @since JDK1.1
  */
 public void setBounds(int x, int y, int width, int height) {
   reshape(x, y, width, height);
 }