Rect.java revision 3db9393ba06bbf70fa7b4a6db1ef60396979a1d4
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 17package com.android.ide.common.api; 18 19import com.google.common.annotations.Beta; 20 21 22 23/** 24 * Mutable rectangle bounds. 25 * <p/> 26 * To be valid, w >= 1 and h >= 1. 27 * By definition: 28 * - right side = x + w - 1. 29 * - bottom side = y + h - 1. 30 * <p> 31 * <b>NOTE: This is not a public or final API; if you rely on this be prepared 32 * to adjust your code for the next tools release.</b> 33 * </p> 34 */ 35@Beta 36public class Rect { 37 public int x, y, w, h; 38 39 /** Initialize an invalid rectangle. */ 40 public Rect() { 41 } 42 43 /** Initialize rectangle to the given values. They can be invalid. */ 44 public Rect(int x, int y, int w, int h) { 45 set(x, y, w, h); 46 } 47 48 /** Initialize rectangle to the given values. They can be invalid. */ 49 public Rect(Rect r) { 50 set(r); 51 } 52 53 /** Initialize rectangle to the given values. They can be invalid. */ 54 public Rect set(int x, int y, int w, int h) { 55 this.x = x; 56 this.y = y; 57 this.w = w; 58 this.h = h; 59 return this; 60 } 61 62 /** Initialize rectangle to match the given one. */ 63 public Rect set(Rect r) { 64 set(r.x, r.y, r.w, r.h); 65 return this; 66 } 67 68 /** Returns a new instance of a rectangle with the same values. */ 69 public Rect copy() { 70 return new Rect(x, y, w, h); 71 } 72 73 /** Returns true if the rectangle has valid bounds, i.e. w>0 and h>0. */ 74 public boolean isValid() { 75 return w > 0 && h > 0; 76 } 77 78 /** Returns true if the rectangle contains the x,y coordinates, borders included. */ 79 public boolean contains(int x, int y) { 80 return isValid() && 81 x >= this.x && 82 y >= this.y && 83 x < (this.x + this.w) && 84 y < (this.y + this.h); 85 } 86 87 /** Returns true if the rectangle contains the x,y coordinates, borders included. */ 88 public boolean contains(Point p) { 89 return p != null && contains(p.x, p.y); 90 } 91 92 /** 93 * Moves this rectangle by setting it's x,y coordinates to the new values. 94 * @return Returns self, for chaining. 95 */ 96 public Rect moveTo(int x, int y) { 97 this.x = x; 98 this.y = y; 99 return this; 100 } 101 102 /** 103 * Offsets this rectangle by adding the given x,y deltas to the x,y coordinates. 104 * @return Returns self, for chaining. 105 */ 106 public Rect offsetBy(int x, int y) { 107 this.x += x; 108 this.y += y; 109 return this; 110 } 111 112 public Point getCenter() { 113 return new Point(x + (w > 0 ? w / 2 : 0), 114 y + (h > 0 ? h / 2 : 0)); 115 } 116 117 public Point getTopLeft() { 118 return new Point(x, y); 119 } 120 121 public Point getBottomLeft() { 122 return new Point(x, 123 y + (h > 0 ? h : 0)); 124 } 125 126 public Point getTopRight() { 127 return new Point(x + (w > 0 ? w : 0), 128 y); 129 } 130 131 public Point getBottomRight() { 132 return new Point(x + (w > 0 ? w : 0), 133 y + (h > 0 ? h : 0)); 134 } 135 136 /** 137 * Returns the X coordinate of the right hand side of the rectangle 138 * 139 * @return the X coordinate of the right hand side of the rectangle 140 */ 141 public int x2() { 142 return x + w; 143 } 144 145 /** 146 * Returns the Y coordinate of the bottom of the rectangle 147 * 148 * @return the Y coordinate of the bottom of the rectangle 149 */ 150 public int y2() { 151 return y + h; 152 } 153 154 /** 155 * Returns the X coordinate of the center of the rectangle 156 * 157 * @return the X coordinate of the center of the rectangle 158 */ 159 public int centerX() { 160 return x + w / 2; 161 } 162 163 /** 164 * Returns the Y coordinate of the center of the rectangle 165 * 166 * @return the Y coordinate of the center of the rectangle 167 */ 168 public int centerY() { 169 return y + h / 2; 170 } 171 172 @Override 173 public String toString() { 174 return String.format("Rect [(%d,%d)-(%d,%d): %dx%d]", x, y, x + w, y + h, w, h); 175 } 176 177 @Override 178 public boolean equals(Object obj) { 179 if (obj instanceof Rect) { 180 Rect rhs = (Rect) obj; 181 // validity must be equal on both sides. 182 if (isValid() != rhs.isValid()) { 183 return false; 184 } 185 // an invalid rect is equal to any other invalid rect regardless of coordinates 186 if (!isValid() && !rhs.isValid()) { 187 return true; 188 } 189 190 return this.x == rhs.x && this.y == rhs.y && this.w == rhs.w && this.h == rhs.h; 191 } 192 193 return false; 194 } 195 196 @Override 197 public int hashCode() { 198 int hc = x; 199 hc ^= ((y >> 8) & 0x0FFFFFF) | ((y & 0x00000FF) << 24); 200 hc ^= ((w >> 16) & 0x000FFFF) | ((w & 0x000FFFF) << 16); 201 hc ^= ((h >> 24) & 0x00000FF) | ((h & 0x0FFFFFF) << 8); 202 return hc; 203 } 204 205 /** 206 * Returns the center point in the rectangle 207 * 208 * @return the center point in the rectangle 209 */ 210 public Point center() { 211 return new Point(x + w / 2, y + h / 2); 212 } 213} 214