146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown/*
246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Copyright (C) 2006 The Android Open Source Project
346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *
446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * you may not use this file except in compliance with the License.
646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * You may obtain a copy of the License at
746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *
846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown *
1046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Unless required by applicable law or agreed to in writing, software
1146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * See the License for the specific language governing permissions and
1446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * limitations under the License.
1546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */
1646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopianpackage android.graphics;
18b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian
1946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.os.Parcel;
2046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.os.Parcelable;
2146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.io.PrintWriter;
23cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brownimport java.util.regex.Matcher;
2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.util.regex.Pattern;
25cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
26cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown/**
27cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown * Rect holds four integer coordinates for a rectangle. The rectangle is
2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * represented by the coordinates of its 4 edges (left, top, right bottom).
2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * These fields can be accessed directly. Use width() and height() to retrieve
30b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian * the rectangle's width and height. Note: most methods do not check to see that
3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * the coordinates are sorted correctly (i.e. left <= right and top <= bottom).
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */
3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownpublic final class Rect implements Parcelable {
3446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public int left;
35b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian    public int top;
36771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    public int right;
3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public int bottom;
3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    private static final Pattern FLATTENED_PATTERN = Pattern.compile(
4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "(-?\\d+) (-?\\d+) (-?\\d+) (-?\\d+)");
41cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
42cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    /**
43cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * Create a new empty Rect. All coordinates are initialized to 0.
44cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
45cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public Rect() {}
46cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
47cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    /**
48cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * Create a new rectangle with the specified coordinates. Note: no range
49cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * checking is performed, so the caller must ensure that left <= right and
50cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * top <= bottom.
51cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     *
52cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * @param left   The X coordinate of the left side of the rectangle
53cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * @param top    The Y coordinate of the top of the rectangle
54cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * @param right  The X coordinate of the right side of the rectangle
55cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * @param bottom The Y coordinate of the bottom of the rectangle
56cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
57072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    public Rect(int left, int top, int right, int bottom) {
58cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        this.left = left;
59cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        this.top = top;
60cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        this.right = right;
61cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        this.bottom = bottom;
62cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
63cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
64cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    /**
65cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * Create a new rectangle, initialized with the values in the specified
66cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * rectangle (which is left unmodified).
67cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     *
68cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * @param r The rectangle whose coordinates are copied into the new
69cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     *          rectangle.
70cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
71cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public Rect(Rect r) {
72cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        if (r == null) {
73cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            left = top = right = bottom = 0;
74cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        } else {
75072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            left = r.left;
76cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            top = r.top;
77cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            right = r.right;
78cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            bottom = r.bottom;
79cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        }
80cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
81cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
82cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    @Override
83cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public boolean equals(Object o) {
84cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        if (this == o) return true;
85cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        if (o == null || getClass() != o.getClass()) return false;
86cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
87cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        Rect r = (Rect) o;
88cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return left == r.left && top == r.top && right == r.right && bottom == r.bottom;
89cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
90cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
91cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    @Override
92cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public int hashCode() {
93cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        int result = left;
94cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        result = 31 * result + top;
957174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        result = 31 * result + right;
967174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        result = 31 * result + bottom;
977174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        return result;
987174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    }
997174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown
1007174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    @Override
101cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public String toString() {
102cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        StringBuilder sb = new StringBuilder(32);
103cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        sb.append("Rect("); sb.append(left); sb.append(", ");
104cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        sb.append(top); sb.append(" - "); sb.append(right);
105cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        sb.append(", "); sb.append(bottom); sb.append(")");
106cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return sb.toString();
107cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
108072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
109cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    /**
110cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * Return a string representation of the rectangle in a compact form.
111cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
112cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public String toShortString() {
113cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return toShortString(new StringBuilder(32));
114cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
115cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
116cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    /**
117cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * Return a string representation of the rectangle in a compact form.
118cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * @hide
119cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
120cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public String toShortString(StringBuilder sb) {
121cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        sb.setLength(0);
122cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        sb.append('['); sb.append(left); sb.append(',');
123cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        sb.append(top); sb.append("]["); sb.append(right);
12446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        sb.append(','); sb.append(bottom); sb.append(']');
125cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return sb.toString();
12646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
12746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
12846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
12946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Return a string representation of the rectangle in a well-defined format.
13046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     *
13146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * <p>You can later recover the Rect from this string through
13246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * {@link #unflattenFromString(String)}.
13346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     *
13491e328984c0d1e0f95b3d37f779d9d4fa9bfe8f8Jeff Brown     * @return Returns a new String of the form "left top right bottom"
13546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
136cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public String flattenToString() {
13746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        StringBuilder sb = new StringBuilder(32);
13846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // WARNING: Do not change the format of this string, it must be
13946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // preserved because Rects are saved in this flattened format.
14046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        sb.append(left);
1415c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        sb.append(' ');
14246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        sb.append(top);
14346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        sb.append(' ');
14491e328984c0d1e0f95b3d37f779d9d4fa9bfe8f8Jeff Brown        sb.append(right);
14546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        sb.append(' ');
146cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        sb.append(bottom);
147cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return sb.toString();
148cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
149cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
150cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    /**
15146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Returns a Rect from a string of the form returned by {@link #flattenToString},
15246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * or null if the string is not of that form.
153cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
1545c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    public static Rect unflattenFromString(String str) {
1555c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        Matcher matcher = FLATTENED_PATTERN.matcher(str);
15646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (!matcher.matches()) {
157cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            return null;
15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
159cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return new Rect(Integer.parseInt(matcher.group(1)),
160cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown                Integer.parseInt(matcher.group(2)),
161cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown                Integer.parseInt(matcher.group(3)),
162cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown                Integer.parseInt(matcher.group(4)));
16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
16446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
165cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    /**
1665c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown     * Print short representation to given writer.
16746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @hide
16846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
169cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public void printShortString(PrintWriter pw) {
17046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        pw.print('['); pw.print(left); pw.print(',');
17146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        pw.print(top); pw.print("]["); pw.print(right);
17246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        pw.print(','); pw.print(bottom); pw.print(']');
17391e328984c0d1e0f95b3d37f779d9d4fa9bfe8f8Jeff Brown    }
17446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
17646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Returns true if the rectangle is empty (left >= right or top >= bottom)
177cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
17846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public final boolean isEmpty() {
17946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return left >= right || top >= bottom;
18046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
18146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
18246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
18346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @return the rectangle's width. This does not check for a valid rectangle
18446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * (i.e. left <= right) so the result may be negative.
18546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
18646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public final int width() {
18746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return right - left;
18846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
18946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
190cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    /**
19146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @return the rectangle's height. This does not check for a valid rectangle
19246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * (i.e. top <= bottom) so the result may be negative.
193cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
194cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public final int height() {
195072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        return bottom - top;
196cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
19746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
19846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
199072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * @return the horizontal center of the rectangle. If the computed value
20046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     *         is fractional, this method returns the largest integer that is
201c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown     *         less than the computed value.
20246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
20346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public final int centerX() {
20446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return (left + right) >> 1;
20546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
20646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
20746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
20846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @return the vertical center of the rectangle. If the computed value
20946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     *         is fractional, this method returns the largest integer that is
21046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     *         less than the computed value.
211cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
21246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public final int centerY() {
21346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return (top + bottom) >> 1;
214cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
215cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
216072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    /**
217cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * @return the exact horizontal center of the rectangle as a float.
21846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
21946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public final float exactCenterX() {
220072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        return (left + right) * 0.5f;
22146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
222c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
22346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
22485a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown     * @return the exact vertical center of the rectangle as a float.
22546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
22646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public final float exactCenterY() {
227fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        return (top + bottom) * 0.5f;
22846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
22946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
23146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Set the rectangle to (0,0,0,0)
23246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
23346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public void setEmpty() {
23446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        left = right = top = bottom = 0;
235fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
23646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
23846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Set the rectangle's coordinates to the specified values. Note: no range
239072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * checking is performed, so it is up to the caller to ensure that
240072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * left <= right and top <= bottom.
241072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     *
242072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * @param left   The X coordinate of the left side of the rectangle
24346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param top    The Y coordinate of the top of the rectangle
24446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param right  The X coordinate of the right side of the rectangle
24546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param bottom The Y coordinate of the bottom of the rectangle
246cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
24746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public void set(int left, int top, int right, int bottom) {
24846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        this.left = left;
249072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        this.top = top;
25046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        this.right = right;
25146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        this.bottom = bottom;
25246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
25346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
25546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Copy the coordinates from src into this rectangle.
256cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     *
25746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param src The rectangle whose coordinates are copied into this
25846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     *           rectangle.
25946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     */
26046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    public void set(Rect src) {
26146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        this.left = src.left;
26246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        this.top = src.top;
26346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        this.right = src.right;
26446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        this.bottom = src.bottom;
26546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
26646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
26746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    /**
26846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * Offset the rectangle by adding dx to its left and right coordinates, and
269cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     * adding dy to its top and bottom coordinates.
27046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     *
27146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param dx The amount to add to the rectangle's left and right coordinates
272072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * @param dy The amount to add to the rectangle's top and bottom coordinates
273072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     */
274072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    public void offset(int dx, int dy) {
275072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        left += dx;
276072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        top += dy;
277072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        right += dx;
278072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        bottom += dy;
279072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
280072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
281771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    /**
282771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * Offset the rectangle to a specific (left, top) position,
283771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * keeping its width and height the same.
284072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     *
285072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * @param newLeft   The new "left" coordinate for the rectangle
28646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param newTop    The new "top" coordinate for the rectangle
287cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown     */
288cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    public void offsetTo(int newLeft, int newTop) {
28946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        right += newLeft - left;
290cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        bottom += newTop - top;
29146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        left = newLeft;
292072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        top = newTop;
293771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
29446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
295072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    /**
296072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * Inset the rectangle by (dx,dy). If dx is positive, then the sides are
297072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * moved inwards, making the rectangle narrower. If dx is negative, then the
29846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * sides are moved outwards, making the rectangle wider. The same holds true
29946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * for dy and the top and bottom.
300072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     *
30146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param dx The amount to add(subtract) from the rectangle's left(right)
30246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param dy The amount to add(subtract) from the rectangle's top(bottom)
303072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     */
304072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    public void inset(int dx, int dy) {
3052b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown        left += dx;
3062b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown        top += dy;
3072b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown        right -= dx;
3082b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown        bottom -= dy;
3092b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    }
3102b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
311771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    /**
3122b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     * Returns true if (x,y) is inside the rectangle. The left and top are
3132b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     * considered to be inside, while the right and bottom are not. This means
3142b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     * that for a x,y to be contained: left <= x < right and top <= y < bottom.
3152b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     * An empty rectangle never contains any point.
3162b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     *
3172b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     * @param x The X coordinate of the point being tested for containment
3182b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     * @param y The Y coordinate of the point being tested for containment
3192b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     * @return true iff (x,y) are contained by the rectangle, where containment
3202b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     *              means left <= x < right and top <= y < bottom
3212b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown     */
3222b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    public boolean contains(int x, int y) {
3232b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown        return left < right && top < bottom  // check for empty first
3242b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown               && x >= left && x < right && y >= top && y < bottom;
3252b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    }
3262b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
3272b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    /**
328072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * Returns true iff the 4 specified sides of a rectangle are inside or equal
32946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * to this rectangle. i.e. is this rectangle a superset of the specified
33046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * rectangle. An empty rectangle never contains another rectangle.
3317174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     *
3327174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     * @param left The left side of the rectangle being tested for containment
3337174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     * @param top The top of the rectangle being tested for containment
3347174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     * @param right The right side of the rectangle being tested for containment
33546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param bottom The bottom of the rectangle being tested for containment
336072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * @return true iff the the 4 specified sides of a rectangle are inside or
33790fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown     *              equal to this rectangle
33890fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown     */
33990fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown    public boolean contains(int left, int top, int right, int bottom) {
34090fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown               // check for empty first
34190fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown        return this.left < this.right && this.top < this.bottom
34290fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown               // now check for containment
343072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                && this.left <= left && this.top <= top
344072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                && this.right >= right && this.bottom >= bottom;
345072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
346771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
347072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    /**
348072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * Returns true iff the specified rectangle r is inside or equal to this
349072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown     * rectangle. An empty rectangle never contains another rectangle.
350771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *
351771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @param r The rectangle being tested for containment.
352771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @return true iff the specified rectangle r is inside or equal to this
353771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *              rectangle
3547174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     */
355771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    public boolean contains(Rect r) {
356771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown               // check for empty first
357771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        return this.left < this.right && this.top < this.bottom
358771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown               // now check for containment
359771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown               && left <= r.left && top <= r.top && right >= r.right && bottom >= r.bottom;
360771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
361771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
362771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    /**
3637174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     * If the rectangle specified by left,top,right,bottom intersects this
3647174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     * rectangle, return true and set this rectangle to that intersection,
365771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * otherwise return false and do not change this rectangle. No check is
366771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * performed to see if either rectangle is empty. Note: To just test for
3677174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     * intersection, use {@link #intersects(Rect, Rect)}.
3687174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     *
3697174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     * @param left The left side of the rectangle being intersected with this
3707174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     *             rectangle
371771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @param top The top of the rectangle being intersected with this rectangle
372771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @param right The right side of the rectangle being intersected with this
373771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *              rectangle.
374771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @param bottom The bottom of the rectangle being intersected with this
375771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *             rectangle.
376771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @return true if the specified rectangle and this rectangle intersect
377771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *              (and this rectangle is then set to that intersection) else
3787174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     *              return false and do not change this rectangle.
379771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     */
380771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    public boolean intersect(int left, int top, int right, int bottom) {
381771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (this.left < right && left < this.right && this.top < bottom && top < this.bottom) {
382771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            if (this.left < left) this.left = left;
383771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            if (this.top < top) this.top = top;
384771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            if (this.right > right) this.right = right;
3857174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            if (this.bottom > bottom) this.bottom = bottom;
3867174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            return true;
387771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
388771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        return false;
389771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
390771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
391771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    /**
392771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * If the specified rectangle intersects this rectangle, return true and set
393771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * this rectangle to that intersection, otherwise return false and do not
394771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * change this rectangle. No check is performed to see if either rectangle
395771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * is empty. To just test for intersection, use intersects()
396771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *
397771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @param r The rectangle being intersected with this rectangle.
398771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @return true if the specified rectangle and this rectangle intersect
399771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *              (and this rectangle is then set to that intersection) else
400771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *              return false and do not change this rectangle.
401771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     */
402771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    public boolean intersect(Rect r) {
4032d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        return intersect(r.left, r.top, r.right, r.bottom);
4042d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown    }
4052d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown
4062d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown    /**
4072d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown     * If rectangles a and b intersect, return true and set this rectangle to
4082d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown     * that intersection, otherwise return false and do not change this
4092d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown     * rectangle. No check is performed to see if either rectangle is empty.
4102d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown     * To just test for intersection, use intersects()
4112d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown     *
4122d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown     * @param a The first rectangle being intersected with
413771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @param b The second rectangle being intersected with
414771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * @return true iff the two specified rectangles intersect. If they do, set
415771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *              this rectangle to that intersection. If they do not, return
416771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     *              false and do not change this rectangle.
417771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     */
418771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    public boolean setIntersect(Rect a, Rect b) {
4197174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom) {
420771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            left = Math.max(a.left, b.left);
421771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            top = Math.max(a.top, b.top);
422771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            right = Math.min(a.right, b.right);
423072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            bottom = Math.min(a.bottom, b.bottom);
424771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            return true;
425771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
4262d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        return false;
427072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
428072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
429072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    /**
430771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * Returns true if this rectangle intersects the specified rectangle.
431771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * In no event is this rectangle modified. No check is performed to see
432771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * if either rectangle is empty. To record the intersection, use intersect()
433771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown     * or setIntersect().
4347174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     *
4357174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown     * @param left The left side of the rectangle being tested for intersection
43646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param top The top of the rectangle being tested for intersection
43746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param right The right side of the rectangle being tested for
43846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     *              intersection
43946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown     * @param bottom The bottom of the rectangle being tested for intersection
440b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian     * @return true iff the specified rectangle intersects this rectangle. In
441     *              no event is this rectangle modified.
442     */
443    public boolean intersects(int left, int top, int right, int bottom) {
444        return this.left < right && left < this.right && this.top < bottom && top < this.bottom;
445    }
446
447    /**
448     * Returns true iff the two specified rectangles intersect. In no event are
449     * either of the rectangles modified. To record the intersection,
450     * use {@link #intersect(Rect)} or {@link #setIntersect(Rect, Rect)}.
451     *
452     * @param a The first rectangle being tested for intersection
453     * @param b The second rectangle being tested for intersection
454     * @return true iff the two specified rectangles intersect. In no event are
455     *              either of the rectangles modified.
456     */
457    public static boolean intersects(Rect a, Rect b) {
458        return a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom;
459    }
460
461    /**
462     * Update this Rect to enclose itself and the specified rectangle. If the
463     * specified rectangle is empty, nothing is done. If this rectangle is empty
464     * it is set to the specified rectangle.
465     *
466     * @param left The left edge being unioned with this rectangle
467     * @param top The top edge being unioned with this rectangle
468     * @param right The right edge being unioned with this rectangle
469     * @param bottom The bottom edge being unioned with this rectangle
470     */
471    public void union(int left, int top, int right, int bottom) {
472        if ((left < right) && (top < bottom)) {
473            if ((this.left < this.right) && (this.top < this.bottom)) {
474                if (this.left > left) this.left = left;
475                if (this.top > top) this.top = top;
476                if (this.right < right) this.right = right;
477                if (this.bottom < bottom) this.bottom = bottom;
478            } else {
479                this.left = left;
480                this.top = top;
481                this.right = right;
482                this.bottom = bottom;
483            }
484        }
485    }
486
487    /**
488     * Update this Rect to enclose itself and the specified rectangle. If the
489     * specified rectangle is empty, nothing is done. If this rectangle is empty
490     * it is set to the specified rectangle.
491     *
492     * @param r The rectangle being unioned with this rectangle
493     */
494    public void union(Rect r) {
495        union(r.left, r.top, r.right, r.bottom);
496    }
497
498    /**
499     * Update this Rect to enclose itself and the [x,y] coordinate. There is no
500     * check to see that this rectangle is non-empty.
501     *
502     * @param x The x coordinate of the point to add to the rectangle
503     * @param y The y coordinate of the point to add to the rectangle
504     */
505    public void union(int x, int y) {
506        if (x < left) {
507            left = x;
508        } else if (x > right) {
509            right = x;
510        }
511        if (y < top) {
512            top = y;
513        } else if (y > bottom) {
514            bottom = y;
515        }
516    }
517
518    /**
519     * Swap top/bottom or left/right if there are flipped (i.e. left > right
520     * and/or top > bottom). This can be called if
521     * the edges are computed separately, and may have crossed over each other.
522     * If the edges are already correct (i.e. left <= right and top <= bottom)
523     * then nothing is done.
524     */
525    public void sort() {
526        if (left > right) {
527            int temp = left;
528            left = right;
529            right = temp;
530        }
531        if (top > bottom) {
532            int temp = top;
533            top = bottom;
534            bottom = temp;
535        }
536    }
537
538    /**
539     * Parcelable interface methods
540     */
541    public int describeContents() {
542        return 0;
543    }
544
545    /**
546     * Write this rectangle to the specified parcel. To restore a rectangle from
547     * a parcel, use readFromParcel()
548     * @param out The parcel to write the rectangle's coordinates into
549     */
550    public void writeToParcel(Parcel out, int flags) {
551        out.writeInt(left);
552        out.writeInt(top);
553        out.writeInt(right);
554        out.writeInt(bottom);
555    }
556
557    public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() {
558        /**
559         * Return a new rectangle from the data in the specified parcel.
560         */
561        public Rect createFromParcel(Parcel in) {
562            Rect r = new Rect();
563            r.readFromParcel(in);
564            return r;
565        }
566
567        /**
568         * Return an array of rectangles of the specified size.
569         */
570        public Rect[] newArray(int size) {
571            return new Rect[size];
572        }
573    };
574
575    /**
576     * Set the rectangle's coordinates from the data stored in the specified
577     * parcel. To write a rectangle to a parcel, call writeToParcel().
578     *
579     * @param in The parcel to read the rectangle's coordinates from
580     */
581    public void readFromParcel(Parcel in) {
582        left = in.readInt();
583        top = in.readInt();
584        right = in.readInt();
585        bottom = in.readInt();
586    }
587
588    /**
589     * Scales up the rect by the given scale.
590     * @hide
591     */
592    public void scale(float scale) {
593        if (scale != 1.0f) {
594            left = (int) (left * scale + 0.5f);
595            top = (int) (top * scale + 0.5f);
596            right = (int) (right * scale + 0.5f);
597            bottom = (int) (bottom * scale + 0.5f);
598        }
599    }
600}
601