001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.graphics;
011:
012: import org.eclipse.swt.internal.SerializableCompatibility;
013: import org.eclipse.swt.*;
014:
015: /**
016: * Instances of this class represent rectangular areas in an
017: * (x, y) coordinate system. The top left corner of the rectangle
018: * is specified by its x and y values, and the extent of the
019: * rectangle is specified by its width and height.
020: * <p>
021: * The coordinate space for rectangles and points is considered
022: * to have increasing values downward and to the right from its
023: * origin making this the normal, computer graphics oriented notion
024: * of (x, y) coordinates rather than the strict mathematical one.
025: * </p>
026: * <p>
027: * The hashCode() method in this class uses the values of the public
028: * fields to compute the hash value. When storing instances of the
029: * class in hashed collections, do not modify these fields after the
030: * object has been inserted.
031: * </p>
032: * <p>
033: * Application code does <em>not</em> need to explicitly release the
034: * resources managed by each instance when those instances are no longer
035: * required, and thus no <code>dispose()</code> method is provided.
036: * </p>
037: *
038: * @see Point
039: */
040:
041: public final class Rectangle implements SerializableCompatibility {
042:
043: /**
044: * the x coordinate of the rectangle
045: */
046: public int x;
047:
048: /**
049: * the y coordinate of the rectangle
050: */
051: public int y;
052:
053: /**
054: * the width of the rectangle
055: */
056: public int width;
057:
058: /**
059: * the height of the rectangle
060: */
061: public int height;
062:
063: static final long serialVersionUID = 3256439218279428914L;
064:
065: /**
066: * Construct a new instance of this class given the
067: * x, y, width and height values.
068: *
069: * @param x the x coordinate of the origin of the rectangle
070: * @param y the y coordinate of the origin of the rectangle
071: * @param width the width of the rectangle
072: * @param height the height of the rectangle
073: */
074: public Rectangle(int x, int y, int width, int height) {
075: this .x = x;
076: this .y = y;
077: this .width = width;
078: this .height = height;
079: }
080:
081: /**
082: * Destructively replaces the x, y, width and height values
083: * in the receiver with ones which represent the union of the
084: * rectangles specified by the receiver and the given rectangle.
085: * <p>
086: * The union of two rectangles is the smallest single rectangle
087: * that completely covers both of the areas covered by the two
088: * given rectangles.
089: * </p>
090: *
091: * @param rect the rectangle to merge with the receiver
092: *
093: * @exception IllegalArgumentException <ul>
094: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
095: * </ul>
096: */
097: public void add(Rectangle rect) {
098: if (rect == null)
099: SWT.error(SWT.ERROR_NULL_ARGUMENT);
100: int left = x < rect.x ? x : rect.x;
101: int top = y < rect.y ? y : rect.y;
102: int lhs = x + width;
103: int rhs = rect.x + rect.width;
104: int right = lhs > rhs ? lhs : rhs;
105: lhs = y + height;
106: rhs = rect.y + rect.height;
107: int bottom = lhs > rhs ? lhs : rhs;
108: x = left;
109: y = top;
110: width = right - left;
111: height = bottom - top;
112: }
113:
114: /**
115: * Returns <code>true</code> if the point specified by the
116: * arguments is inside the area specified by the receiver,
117: * and <code>false</code> otherwise.
118: *
119: * @param x the x coordinate of the point to test for containment
120: * @param y the y coordinate of the point to test for containment
121: * @return <code>true</code> if the rectangle contains the point and <code>false</code> otherwise
122: */
123: public boolean contains(int x, int y) {
124: return (x >= this .x) && (y >= this .y) && ((x - this .x) < width)
125: && ((y - this .y) < height);
126: }
127:
128: /**
129: * Returns <code>true</code> if the given point is inside the
130: * area specified by the receiver, and <code>false</code>
131: * otherwise.
132: *
133: * @param pt the point to test for containment
134: * @return <code>true</code> if the rectangle contains the point and <code>false</code> otherwise
135: *
136: * @exception IllegalArgumentException <ul>
137: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
138: * </ul>
139: */
140: public boolean contains(Point pt) {
141: if (pt == null)
142: SWT.error(SWT.ERROR_NULL_ARGUMENT);
143: return contains(pt.x, pt.y);
144: }
145:
146: /**
147: * Compares the argument to the receiver, and returns true
148: * if they represent the <em>same</em> object using a class
149: * specific comparison.
150: *
151: * @param object the object to compare with this object
152: * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
153: *
154: * @see #hashCode()
155: */
156: public boolean equals(Object object) {
157: if (object == this )
158: return true;
159: if (!(object instanceof Rectangle))
160: return false;
161: Rectangle r = (Rectangle) object;
162: return (r.x == this .x) && (r.y == this .y)
163: && (r.width == this .width) && (r.height == this .height);
164: }
165:
166: /**
167: * Returns an integer hash code for the receiver. Any two
168: * objects that return <code>true</code> when passed to
169: * <code>equals</code> must return the same value for this
170: * method.
171: *
172: * @return the receiver's hash
173: *
174: * @see #equals(Object)
175: */
176: public int hashCode() {
177: return x ^ y ^ width ^ height;
178: }
179:
180: /**
181: * Destructively replaces the x, y, width and height values
182: * in the receiver with ones which represent the intersection of the
183: * rectangles specified by the receiver and the given rectangle.
184: *
185: * @param rect the rectangle to intersect with the receiver
186: *
187: * @exception IllegalArgumentException <ul>
188: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
189: * </ul>
190: *
191: * since 3.0
192: */
193: public void intersect(Rectangle rect) {
194: if (rect == null)
195: SWT.error(SWT.ERROR_NULL_ARGUMENT);
196: if (this == rect)
197: return;
198: int left = x > rect.x ? x : rect.x;
199: int top = y > rect.y ? y : rect.y;
200: int lhs = x + width;
201: int rhs = rect.x + rect.width;
202: int right = lhs < rhs ? lhs : rhs;
203: lhs = y + height;
204: rhs = rect.y + rect.height;
205: int bottom = lhs < rhs ? lhs : rhs;
206: x = right < left ? 0 : left;
207: y = bottom < top ? 0 : top;
208: width = right < left ? 0 : right - left;
209: height = bottom < top ? 0 : bottom - top;
210: }
211:
212: /**
213: * Returns a new rectangle which represents the intersection
214: * of the receiver and the given rectangle.
215: * <p>
216: * The intersection of two rectangles is the rectangle that
217: * covers the area which is contained within both rectangles.
218: * </p>
219: *
220: * @param rect the rectangle to intersect with the receiver
221: * @return the intersection of the receiver and the argument
222: *
223: * @exception IllegalArgumentException <ul>
224: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
225: * </ul>
226: */
227: public Rectangle intersection(Rectangle rect) {
228: if (rect == null)
229: SWT.error(SWT.ERROR_NULL_ARGUMENT);
230: if (this == rect)
231: return new Rectangle(x, y, width, height);
232: int left = x > rect.x ? x : rect.x;
233: int top = y > rect.y ? y : rect.y;
234: int lhs = x + width;
235: int rhs = rect.x + rect.width;
236: int right = lhs < rhs ? lhs : rhs;
237: lhs = y + height;
238: rhs = rect.y + rect.height;
239: int bottom = lhs < rhs ? lhs : rhs;
240: return new Rectangle(right < left ? 0 : left, bottom < top ? 0
241: : top, right < left ? 0 : right - left,
242: bottom < top ? 0 : bottom - top);
243: }
244:
245: /**
246: * Returns <code>true</code> if the rectangle described by the
247: * arguments intersects with the receiver and <code>false</code>
248: * otherwise.
249: * <p>
250: * Two rectangles intersect if the area of the rectangle
251: * representing their intersection is not empty.
252: * </p>
253: *
254: * @param x the x coordinate of the origin of the rectangle
255: * @param y the y coordinate of the origin of the rectangle
256: * @param width the width of the rectangle
257: * @param height the height of the rectangle
258: * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise
259: *
260: * @exception IllegalArgumentException <ul>
261: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
262: * </ul>
263: *
264: * @see #intersection(Rectangle)
265: * @see #isEmpty()
266: *
267: * @since 3.0
268: */
269: public boolean intersects(int x, int y, int width, int height) {
270: return (x < this .x + this .width) && (y < this .y + this .height)
271: && (x + width > this .x) && (y + height > this .y);
272: }
273:
274: /**
275: * Returns <code>true</code> if the given rectangle intersects
276: * with the receiver and <code>false</code> otherwise.
277: * <p>
278: * Two rectangles intersect if the area of the rectangle
279: * representing their intersection is not empty.
280: * </p>
281: *
282: * @param rect the rectangle to test for intersection
283: * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise
284: *
285: * @exception IllegalArgumentException <ul>
286: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
287: * </ul>
288: *
289: * @see #intersection(Rectangle)
290: * @see #isEmpty()
291: */
292: public boolean intersects(Rectangle rect) {
293: if (rect == null)
294: SWT.error(SWT.ERROR_NULL_ARGUMENT);
295: return rect == this
296: || intersects(rect.x, rect.y, rect.width, rect.height);
297: }
298:
299: /**
300: * Returns <code>true</code> if the receiver does not cover any
301: * area in the (x, y) coordinate plane, and <code>false</code> if
302: * the receiver does cover some area in the plane.
303: * <p>
304: * A rectangle is considered to <em>cover area</em> in the
305: * (x, y) coordinate plane if both its width and height are
306: * non-zero.
307: * </p>
308: *
309: * @return <code>true</code> if the receiver is empty, and <code>false</code> otherwise
310: */
311: public boolean isEmpty() {
312: return (width <= 0) || (height <= 0);
313: }
314:
315: /**
316: * Returns a string containing a concise, human-readable
317: * description of the receiver.
318: *
319: * @return a string representation of the rectangle
320: */
321: public String toString() {
322: return "Rectangle {" + x + ", " + y + ", " + width + ", " + height + "}"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
323: }
324:
325: /**
326: * Returns a new rectangle which represents the union of
327: * the receiver and the given rectangle.
328: * <p>
329: * The union of two rectangles is the smallest single rectangle
330: * that completely covers both of the areas covered by the two
331: * given rectangles.
332: * </p>
333: *
334: * @param rect the rectangle to perform union with
335: * @return the union of the receiver and the argument
336: *
337: * @exception IllegalArgumentException <ul>
338: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
339: * </ul>
340: *
341: * @see #add(Rectangle)
342: */
343: public Rectangle union(Rectangle rect) {
344: if (rect == null)
345: SWT.error(SWT.ERROR_NULL_ARGUMENT);
346: int left = x < rect.x ? x : rect.x;
347: int top = y < rect.y ? y : rect.y;
348: int lhs = x + width;
349: int rhs = rect.x + rect.width;
350: int right = lhs > rhs ? lhs : rhs;
351: lhs = y + height;
352: rhs = rect.y + rect.height;
353: int bottom = lhs > rhs ? lhs : rhs;
354: return new Rectangle(left, top, right - left, bottom - top);
355: }
356:
357: }
|