summaryrefslogtreecommitdiff
path: root/graphics/java/android/graphics/RectF.java
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/java/android/graphics/RectF.java')
-rw-r--r--graphics/java/android/graphics/RectF.java478
1 files changed, 478 insertions, 0 deletions
diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java
new file mode 100644
index 000000000000..d71f2dccd2fd
--- /dev/null
+++ b/graphics/java/android/graphics/RectF.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import android.util.FloatMath;
+import com.android.internal.util.FastMath;
+
+/**
+ * RectF holds four float coordinates for a rectangle. The rectangle is
+ * represented by the coordinates of its 4 edges (left, top, right bottom).
+ * These fields can be accessed directly. Use width() and height() to retrieve
+ * the rectangle's width and height. Note: most methods do not check to see that
+ * the coordinates are sorted correctly (i.e. left <= right and top <= bottom).
+ */
+public class RectF {
+ public float left;
+ public float top;
+ public float right;
+ public float bottom;
+
+ /**
+ * Create a new empty RectF. All coordinates are initialized to 0.
+ */
+ public RectF() {}
+
+ /**
+ * Create a new rectangle with the specified coordinates. Note: no range
+ * checking is performed, so the caller must ensure that left <= right and
+ * top <= bottom.
+ *
+ * @param left The X coordinate of the left side of the rectagle
+ * @param top The Y coordinate of the top of the rectangle
+ * @param right The X coordinate of the right side of the rectagle
+ * @param bottom The Y coordinate of the bottom of the rectangle
+ */
+ public RectF(float left, float top, float right, float bottom) {
+ this.left = left;
+ this.top = top;
+ this.right = right;
+ this.bottom = bottom;
+ }
+
+ /**
+ * Create a new rectangle, initialized with the values in the specified
+ * rectangle (which is left unmodified).
+ *
+ * @param r The rectangle whose coordinates are copied into the new
+ * rectangle.
+ */
+ public RectF(RectF r) {
+ left = r.left;
+ top = r.top;
+ right = r.right;
+ bottom = r.bottom;
+ }
+
+ public RectF(Rect r) {
+ left = r.left;
+ top = r.top;
+ right = r.right;
+ bottom = r.bottom;
+ }
+
+ public String toString() {
+ return "RectF(" + left + ", " + top + ", "
+ + right + ", " + bottom + ")";
+ }
+
+ /**
+ * Returns true if the rectangle is empty (left >= right or top >= bottom)
+ */
+ public final boolean isEmpty() {
+ return left >= right || top >= bottom;
+ }
+
+ /**
+ * @return the rectangle's width. This does not check for a valid rectangle
+ * (i.e. left <= right) so the result may be negative.
+ */
+ public final float width() {
+ return right - left;
+ }
+
+ /**
+ * @return the rectangle's height. This does not check for a valid rectangle
+ * (i.e. top <= bottom) so the result may be negative.
+ */
+ public final float height() {
+ return bottom - top;
+ }
+
+ /**
+ * @return the horizontal center of the rectangle. This does not check for
+ * a valid rectangle (i.e. left <= right)
+ */
+ public final float centerX() {
+ return (left + right) * 0.5f;
+ }
+
+ /**
+ * @return the vertical center of the rectangle. This does not check for
+ * a valid rectangle (i.e. top <= bottom)
+ */
+ public final float centerY() {
+ return (top + bottom) * 0.5f;
+ }
+
+ /**
+ * Set the rectangle to (0,0,0,0)
+ */
+ public void setEmpty() {
+ left = right = top = bottom = 0;
+ }
+
+ /**
+ * Set the rectangle's coordinates to the specified values. Note: no range
+ * checking is performed, so it is up to the caller to ensure that
+ * left <= right and top <= bottom.
+ *
+ * @param left The X coordinate of the left side of the rectagle
+ * @param top The Y coordinate of the top of the rectangle
+ * @param right The X coordinate of the right side of the rectagle
+ * @param bottom The Y coordinate of the bottom of the rectangle
+ */
+ public void set(float left, float top, float right, float bottom) {
+ this.left = left;
+ this.top = top;
+ this.right = right;
+ this.bottom = bottom;
+ }
+
+ /**
+ * Copy the coordinates from src into this rectangle.
+ *
+ * @param src The rectangle whose coordinates are copied into this
+ * rectangle.
+ */
+ public void set(RectF src) {
+ this.left = src.left;
+ this.top = src.top;
+ this.right = src.right;
+ this.bottom = src.bottom;
+ }
+
+ /**
+ * Copy the coordinates from src into this rectangle.
+ *
+ * @param src The rectangle whose coordinates are copied into this
+ * rectangle.
+ */
+ public void set(Rect src) {
+ this.left = src.left;
+ this.top = src.top;
+ this.right = src.right;
+ this.bottom = src.bottom;
+ }
+
+ /**
+ * Offset the rectangle by adding dx to its left and right coordinates, and
+ * adding dy to its top and bottom coordinates.
+ *
+ * @param dx The amount to add to the rectangle's left and right coordinates
+ * @param dy The amount to add to the rectangle's top and bottom coordinates
+ */
+ public void offset(float dx, float dy) {
+ left += dx;
+ top += dy;
+ right += dx;
+ bottom += dy;
+ }
+
+ /**
+ * Offset the rectangle to a specific (left, top) position,
+ * keeping its width and height the same.
+ *
+ * @param newLeft The new "left" coordinate for the rectangle
+ * @param newTop The new "top" coordinate for the rectangle
+ */
+ public void offsetTo(float newLeft, float newTop) {
+ right += newLeft - left;
+ bottom += newTop - top;
+ left = newLeft;
+ top = newTop;
+ }
+
+ /**
+ * Inset the rectangle by (dx,dy). If dx is positive, then the sides are
+ * moved inwards, making the rectangle narrower. If dx is negative, then the
+ * sides are moved outwards, making the rectangle wider. The same holds true
+ * for dy and the top and bottom.
+ *
+ * @param dx The amount to add(subtract) from the rectangle's left(right)
+ * @param dy The amount to add(subtract) from the rectangle's top(bottom)
+ */
+ public void inset(float dx, float dy) {
+ left += dx;
+ top += dy;
+ right -= dx;
+ bottom -= dy;
+ }
+
+ /**
+ * Returns true if (x,y) is inside the rectangle. The left and top are
+ * considered to be inside, while the right and bottom are not. This means
+ * that for a x,y to be contained: left <= x < right and top <= y < bottom.
+ * An empty rectangle never contains any point.
+ *
+ * @param x The X coordinate of the point being tested for containment
+ * @param y The Y coordinate of the point being tested for containment
+ * @return true iff (x,y) are contained by the rectangle, where containment
+ * means left <= x < right and top <= y < bottom
+ */
+ public boolean contains(float x, float y) {
+ return left < right && top < bottom // check for empty first
+ && x >= left && x < right && y >= top && y < bottom;
+ }
+
+ /**
+ * Returns true iff the 4 specified sides of a rectangle are inside or equal
+ * to this rectangle. i.e. is this rectangle a superset of the specified
+ * rectangle. An empty rectangle never contains another rectangle.
+ *
+ * @param left The left side of the rectangle being tested for containment
+ * @param top The top of the rectangle being tested for containment
+ * @param right The right side of the rectangle being tested for containment
+ * @param bottom The bottom of the rectangle being tested for containment
+ * @return true iff the the 4 specified sides of a rectangle are inside or
+ * equal to this rectangle
+ */
+ public boolean contains(float left, float top, float right, float bottom) {
+ // check for empty first
+ return this.left < this.right && this.top < this.bottom
+ // now check for containment
+ && this.left <= left && this.top <= top
+ && this.right >= right && this.bottom >= bottom;
+ }
+
+ /**
+ * Returns true iff the specified rectangle r is inside or equal to this
+ * rectangle. An empty rectangle never contains another rectangle.
+ *
+ * @param r The rectangle being tested for containment.
+ * @return true iff the specified rectangle r is inside or equal to this
+ * rectangle
+ */
+ public boolean contains(RectF r) {
+ // check for empty first
+ return this.left < this.right && this.top < this.bottom
+ // now check for containment
+ && left <= r.left && top <= r.top
+ && right >= r.right && bottom >= r.bottom;
+ }
+
+ /**
+ * If the rectangle specified by left,top,right,bottom intersects this
+ * rectangle, return true and set this rectangle to that intersection,
+ * otherwise return false and do not change this rectangle. No check is
+ * performed to see if either rectangle is empty. Note: To just test for
+ * intersection, use intersects()
+ *
+ * @param left The left side of the rectangle being intersected with this
+ * rectangle
+ * @param top The top of the rectangle being intersected with this rectangle
+ * @param right The right side of the rectangle being intersected with this
+ * rectangle.
+ * @param bottom The bottom of the rectangle being intersected with this
+ * rectangle.
+ * @return true if the specified rectangle and this rectangle intersect
+ * (and this rectangle is then set to that intersection) else
+ * return false and do not change this rectangle.
+ */
+ public boolean intersect(float left, float top, float right, float bottom) {
+ if (this.left < right && left < this.right
+ && this.top < bottom && top < this.bottom) {
+ if (this.left < left) {
+ this.left = left;
+ }
+ if (this.top < top) {
+ this.top = top;
+ }
+ if (this.right > right) {
+ this.right = right;
+ }
+ if (this.bottom > bottom) {
+ this.bottom = bottom;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * If the specified rectangle intersects this rectangle, return true and set
+ * this rectangle to that intersection, otherwise return false and do not
+ * change this rectangle. No check is performed to see if either rectangle
+ * is empty. To just test for intersection, use intersects()
+ *
+ * @param r The rectangle being intersected with this rectangle.
+ * @return true if the specified rectangle and this rectangle intersect
+ * (and this rectangle is then set to that intersection) else
+ * return false and do not change this rectangle.
+ */
+ public boolean intersect(RectF r) {
+ return intersect(r.left, r.top, r.right, r.bottom);
+ }
+
+ /**
+ * If rectangles a and b intersect, return true and set this rectangle to
+ * that intersection, otherwise return false and do not change this
+ * rectangle. No check is performed to see if either rectangle is empty.
+ * To just test for intersection, use intersects()
+ *
+ * @param a The first rectangle being intersected with
+ * @param b The second rectangle being intersected with
+ * @return true iff the two specified rectangles intersect. If they do, set
+ * this rectangle to that intersection. If they do not, return
+ * false and do not change this rectangle.
+ */
+ public boolean setIntersect(RectF a, RectF b) {
+ if (a.left < b.right && b.left < a.right
+ && a.top < b.bottom && b.top < a.bottom) {
+ left = Math.max(a.left, b.left);
+ top = Math.max(a.top, b.top);
+ right = Math.min(a.right, b.right);
+ bottom = Math.min(a.bottom, b.bottom);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if this rectangle intersects the specified rectangle.
+ * In no event is this rectangle modified. No check is performed to see
+ * if either rectangle is empty. To record the intersection, use intersect()
+ * or setIntersect().
+ *
+ * @param left The left side of the rectangle being tested for intersection
+ * @param top The top of the rectangle being tested for intersection
+ * @param right The right side of the rectangle being tested for
+ * intersection
+ * @param bottom The bottom of the rectangle being tested for intersection
+ * @return true iff the specified rectangle intersects this rectangle. In
+ * no event is this rectangle modified.
+ */
+ public boolean intersects(float left, float top, float right,
+ float bottom) {
+ return this.left < right && left < this.right
+ && this.top < bottom && top < this.bottom;
+ }
+
+ /**
+ * Returns true iff the two specified rectangles intersect. In no event are
+ * either of the rectangles modified. To record the intersection,
+ * use intersect() or setIntersect().
+ *
+ * @param a The first rectangle being tested for intersection
+ * @param b The second rectangle being tested for intersection
+ * @return true iff the two specified rectangles intersect. In no event are
+ * either of the rectangles modified.
+ */
+ public static boolean intersects(RectF a, RectF b) {
+ return a.left < b.right && b.left < a.right
+ && a.top < b.bottom && b.top < a.bottom;
+ }
+
+ /**
+ * Set the dst integer Rect by rounding this rectangle's coordinates
+ * to their nearest integer values.
+ */
+ public void round(Rect dst) {
+ dst.set(FastMath.round(left), FastMath.round(top),
+ FastMath.round(right), FastMath.round(bottom));
+ }
+
+ /**
+ * Set the dst integer Rect by rounding "out" this rectangle, choosing the
+ * floor of top and left, and the ceiling of right and bottom.
+ */
+ public void roundOut(Rect dst) {
+ dst.set((int) FloatMath.floor(left), (int) FloatMath.floor(top),
+ (int) FloatMath.ceil(right), (int) FloatMath.ceil(bottom));
+ }
+
+ /**
+ * Update this Rect to enclose itself and the specified rectangle. If the
+ * specified rectangle is empty, nothing is done. If this rectangle is empty
+ * it is set to the specified rectangle.
+ *
+ * @param left The left edge being unioned with this rectangle
+ * @param top The top edge being unioned with this rectangle
+ * @param right The right edge being unioned with this rectangle
+ * @param bottom The bottom edge being unioned with this rectangle
+ */
+ public void union(float left, float top, float right, float bottom) {
+ if ((left < right) && (top < bottom)) {
+ if ((this.left < this.right) && (this.top < this.bottom)) {
+ if (this.left > left)
+ this.left = left;
+ if (this.top > top)
+ this.top = top;
+ if (this.right < right)
+ this.right = right;
+ if (this.bottom < bottom)
+ this.bottom = bottom;
+ } else {
+ this.left = left;
+ this.top = top;
+ this.right = right;
+ this.bottom = bottom;
+ }
+ }
+ }
+
+ /**
+ * Update this Rect to enclose itself and the specified rectangle. If the
+ * specified rectangle is empty, nothing is done. If this rectangle is empty
+ * it is set to the specified rectangle.
+ *
+ * @param r The rectangle being unioned with this rectangle
+ */
+ public void union(RectF r) {
+ union(r.left, r.top, r.right, r.bottom);
+ }
+
+ /**
+ * Update this Rect to enclose itself and the [x,y] coordinate. There is no
+ * check to see that this rectangle is non-empty.
+ *
+ * @param x The x coordinate of the point to add to the rectangle
+ * @param y The y coordinate of the point to add to the rectangle
+ */
+ public void union(float x, float y) {
+ if (x < left) {
+ left = x;
+ } else if (x > right) {
+ right = x;
+ }
+ if (y < top) {
+ top = y;
+ } else if (y > bottom) {
+ bottom = y;
+ }
+ }
+
+ /**
+ * Swap top/bottom or left/right if there are flipped (i.e. left > right
+ * and/or top > bottom). This can be called if
+ * the edges are computed separately, and may have crossed over each other.
+ * If the edges are already correct (i.e. left <= right and top <= bottom)
+ * then nothing is done.
+ */
+ public void sort() {
+ if (left > right) {
+ float temp = left;
+ left = right;
+ right = temp;
+ }
+ if (top > bottom) {
+ float temp = top;
+ top = bottom;
+ bottom = temp;
+ }
+ }
+}