• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ide.common.api;
18 
19 import com.google.common.annotations.Beta;
20 import com.android.annotations.NonNull;
21 import com.android.annotations.Nullable;
22 
23 
24 /**
25  * Mutable rectangle bounds.
26  * <p/>
27  * To be valid, w >= 1 and h >= 1.
28  * By definition:
29  * - right side = x + w - 1.
30  * - bottom side = y + h - 1.
31  * <p>
32  * <b>NOTE: This is not a public or final API; if you rely on this be prepared
33  * to adjust your code for the next tools release.</b>
34  * </p>
35  */
36 @Beta
37 public class Rect {
38     public int x, y, w, h;
39 
40     /** Initialize an invalid rectangle. */
Rect()41     public Rect() {
42     }
43 
44     /** Initialize rectangle to the given values. They can be invalid. */
Rect(int x, int y, int w, int h)45     public Rect(int x, int y, int w, int h) {
46         set(x, y, w, h);
47     }
48 
49     /** Initialize rectangle to the given values. They can be invalid. */
Rect(@onNull Rect r)50     public Rect(@NonNull Rect r) {
51         set(r);
52     }
53 
54     /** Initialize rectangle to the given values. They can be invalid. */
55     @NonNull
set(int x, int y, int w, int h)56     public Rect set(int x, int y, int w, int h) {
57         this.x = x;
58         this.y = y;
59         this.w = w;
60         this.h = h;
61         return this;
62     }
63 
64     /** Initialize rectangle to match the given one. */
65     @NonNull
set(@onNull Rect r)66     public Rect set(@NonNull Rect r) {
67         set(r.x, r.y, r.w, r.h);
68         return this;
69     }
70 
71     /** Returns a new instance of a rectangle with the same values. */
72     @NonNull
copy()73     public Rect copy() {
74         return new Rect(x, y, w, h);
75     }
76 
77     /** Returns true if the rectangle has valid bounds, i.e. w>0 and h>0. */
isValid()78     public boolean isValid() {
79         return w > 0 && h > 0;
80     }
81 
82     /** Returns true if the rectangle contains the x,y coordinates, borders included. */
contains(int x, int y)83     public boolean contains(int x, int y) {
84         return isValid() &&
85             x >= this.x &&
86             y >= this.y &&
87             x < (this.x + this.w) &&
88             y < (this.y + this.h);
89     }
90 
91     /** Returns true if the rectangle contains the x,y coordinates, borders included. */
contains(@ullable Point p)92     public boolean contains(@Nullable Point p) {
93         return p != null && contains(p.x, p.y);
94     }
95 
96     /**
97      * Moves this rectangle by setting it's x,y coordinates to the new values.
98      * @return Returns self, for chaining.
99      */
100     @NonNull
moveTo(int x, int y)101     public Rect moveTo(int x, int y) {
102         this.x = x;
103         this.y = y;
104         return this;
105     }
106 
107     /**
108      * Offsets this rectangle by adding the given x,y deltas to the x,y coordinates.
109      * @return Returns self, for chaining.
110      */
111     @NonNull
offsetBy(int x, int y)112     public Rect offsetBy(int x, int y) {
113         this.x += x;
114         this.y += y;
115         return this;
116     }
117 
118     @NonNull
getCenter()119     public Point getCenter() {
120         return new Point(x + (w > 0 ? w / 2 : 0),
121                          y + (h > 0 ? h / 2 : 0));
122     }
123 
124     @NonNull
getTopLeft()125     public Point getTopLeft() {
126         return new Point(x, y);
127     }
128 
129     @NonNull
getBottomLeft()130     public Point getBottomLeft() {
131         return new Point(x,
132                          y + (h > 0 ? h : 0));
133     }
134 
135     @NonNull
getTopRight()136     public Point getTopRight() {
137         return new Point(x + (w > 0 ? w : 0),
138                          y);
139     }
140 
141     @NonNull
getBottomRight()142     public Point getBottomRight() {
143         return new Point(x + (w > 0 ? w : 0),
144                          y + (h > 0 ? h : 0));
145     }
146 
147     /**
148      * Returns the X coordinate of the right hand side of the rectangle
149      *
150      * @return the X coordinate of the right hand side of the rectangle
151      */
x2()152     public int x2() {
153         return x + w;
154     }
155 
156     /**
157      * Returns the Y coordinate of the bottom of the rectangle
158      *
159      * @return the Y coordinate of the bottom of the rectangle
160      */
y2()161     public int y2() {
162         return y + h;
163     }
164 
165     /**
166      * Returns the X coordinate of the center of the rectangle
167      *
168      * @return the X coordinate of the center of the rectangle
169      */
centerX()170     public int centerX() {
171         return x + w / 2;
172     }
173 
174     /**
175      * Returns the Y coordinate of the center of the rectangle
176      *
177      * @return the Y coordinate of the center of the rectangle
178      */
centerY()179     public int centerY() {
180         return y + h / 2;
181     }
182 
183     @Override
toString()184     public String toString() {
185         return String.format("Rect [(%d,%d)-(%d,%d): %dx%d]", x, y, x + w, y + h, w, h);
186     }
187 
188     @Override
equals(Object obj)189     public boolean equals(Object obj) {
190         if (obj instanceof Rect) {
191             Rect rhs = (Rect) obj;
192             // validity must be equal on both sides.
193             if (isValid() != rhs.isValid()) {
194                 return false;
195             }
196             // an invalid rect is equal to any other invalid rect regardless of coordinates
197             if (!isValid() && !rhs.isValid()) {
198                 return true;
199             }
200 
201             return this.x == rhs.x && this.y == rhs.y && this.w == rhs.w && this.h == rhs.h;
202         }
203 
204         return false;
205     }
206 
207     @Override
hashCode()208     public int hashCode() {
209         int hc = x;
210         hc ^= ((y >>  8) & 0x0FFFFFF) | ((y & 0x00000FF) << 24);
211         hc ^= ((w >> 16) & 0x000FFFF) | ((w & 0x000FFFF) << 16);
212         hc ^= ((h >> 24) & 0x00000FF) | ((h & 0x0FFFFFF) <<  8);
213         return hc;
214     }
215 
216     /**
217      * Returns the center point in the rectangle
218      *
219      * @return the center point in the rectangle
220      */
221     @NonNull
center()222     public Point center() {
223         return new Point(x + w / 2, y + h / 2);
224     }
225 }
226