Source code: org/eclipse/swt/graphics/custom/DirtyRectangle.java
1 package org.eclipse.swt.graphics.custom;
2
3 import org.eclipse.swt.SWT;
4 import org.eclipse.swt.graphics.Point;
5 import org.eclipse.swt.graphics.Rectangle;
6 import org.eclipse.swt.internal.SerializableCompatibility;
7
8 /**
9 * Custom version of org.eclipse.swt.graphics.Rectangle.
10 * Added method add(x,y,w,h) to avoid creating intermediate Rectangle objects.
11 *
12 * Instances of this class represent rectangular areas in an
13 * (x, y) coordinate system. The top left corner of the rectangle
14 * is specified by its x and y values, and the extent of the
15 * rectangle is specified by its width and height.
16 * <p>
17 * The coordinate space for rectangles and points is considered
18 * to have increasing values downward and to the right from its
19 * origin making this the normal, computer graphics oriented notion
20 * of (x, y) coordinates rather than the strict mathematical one.
21 * </p>
22 * <p>
23 * Application code does <em>not</em> need to explicitly release the
24 * resources managed by each instance when those instances are no longer
25 * required, and thus no <code>dispose()</code> method is provided.
26 * </p>
27 *
28 * @see Point
29 */
30
31 public class DirtyRectangle implements SerializableCompatibility {
32
33 /**
34 * the x coordinate of the rectangle
35 */
36 public int x;
37
38 /**
39 * the y coordinate of the rectangle
40 */
41 public int y;
42
43 /**
44 * the width of the rectangle
45 */
46 public int width;
47
48 /**
49 * the height of the rectangle
50 */
51 public int height;
52
53 /**
54 * Construct a new instance of this class given the
55 * x, y, width and height values.
56 *
57 * @param x the x coordinate of the origin of the rectangle
58 * @param y the y coordinate of the origin of the rectangle
59 * @param width the width of the rectangle
60 * @param height the height of the rectangle
61 */
62 public DirtyRectangle(int x, int y, int width, int height) {
63 this.x = x;
64 this.y = y;
65 this.width = width;
66 this.height = height;
67 }
68
69 public void init(int x, int y, int w, int h) {
70 this.x = x;
71 this.y = y;
72 this.width = w;
73 this.height = h;
74 }
75
76 public void init(Rectangle rect) {
77 init(rect.x, rect.y, rect.width, rect.height);
78 }
79
80 /**
81 * Destructively replaces the x, y, width and height values
82 * in the receiver with ones which represent the union of the
83 * rectangles specified by the receiver and the given rectangle.
84 * <p>
85 * The union of two rectangles is the smallest single rectangle
86 * that completely covers both of the areas covered by the two
87 * given rectangles.
88 * </p>
89 *
90 * @param rect the rectangle to merge with the receiver
91 *
92 * @exception IllegalArgumentException <ul>
93 * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
94 * </ul>
95 */
96 public void add(DirtyRectangle rect) {
97 if (rect == null)
98 SWT.error(SWT.ERROR_NULL_ARGUMENT);
99 int left = x < rect.x ? x : rect.x;
100 int top = y < rect.y ? y : rect.y;
101 int lhs = x + width;
102 int rhs = rect.x + rect.width;
103 int right = lhs > rhs ? lhs : rhs;
104 lhs = y + height;
105 rhs = rect.y + rect.height;
106 int bottom = lhs > rhs ? lhs : rhs;
107 x = left;
108 y = top;
109 width = right - left;
110 height = bottom - top;
111 }
112
113 public void add(Rectangle rect) {
114 add(rect.x, rect.y, rect.width, rect.height);
115 }
116
117 public void add(int xx, int yy, int ww, int hh) {
118 int left = x < xx ? x : xx;
119 int top = y < yy ? y : yy;
120 int lhs = x + width;
121 int rhs = xx + ww;
122 int right = lhs > rhs ? lhs : rhs;
123 lhs = y + height;
124 rhs = yy + hh;
125 int bottom = lhs > rhs ? lhs : rhs;
126 x = left;
127 y = top;
128 width = right - left;
129 height = bottom - top;
130 }
131
132 /**
133 * Returns <code>true</code> if the point specified by the
134 * arguments is inside the area specified by the receiver,
135 * and <code>false</code> otherwise.
136 *
137 * @param x the x coordinate of the point to test for containment
138 * @param y the y coordinate of the point to test for containment
139 * @return <code>true</code> if the rectangle contains the point and <code>false</code> otherwise
140 */
141 public boolean contains(int x, int y) {
142 return (x >= this.x) && (y >= this.y) && ((x - this.x) < width) && ((y - this.y) < height);
143 }
144
145 /**
146 * Returns <code>true</code> if the given point is inside the
147 * area specified by the receiver, and <code>false</code>
148 * otherwise.
149 *
150 * @param pt the point to test for containment
151 * @return <code>true</code> if the rectangle contains the point and <code>false</code> otherwise
152 *
153 * @exception IllegalArgumentException <ul>
154 * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
155 * </ul>
156 */
157 public boolean contains(Point pt) {
158 if (pt == null)
159 SWT.error(SWT.ERROR_NULL_ARGUMENT);
160 return contains(pt.x, pt.y);
161 }
162
163 /**
164 * Compares the argument to the receiver, and returns true
165 * if they represent the <em>same</em> object using a class
166 * specific comparison.
167 *
168 * @param object the object to compare with this object
169 * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
170 *
171 * @see #hashCode
172 */
173 public boolean equals(Object object) {
174 if (object == this)
175 return true;
176 if (!(object instanceof DirtyRectangle))
177 return false;
178 DirtyRectangle r = (DirtyRectangle) object;
179 return (r.x == this.x) && (r.y == this.y) && (r.width == this.width) && (r.height == this.height);
180 }
181
182 /**
183 * Returns an integer hash code for the receiver. Any two
184 * objects which return <code>true</code> when passed to
185 * <code>equals</code> must return the same value for this
186 * method.
187 *
188 * @return the receiver's hash
189 *
190 * @see #equals
191 */
192 public int hashCode() {
193 return x ^ y ^ width ^ height;
194 }
195
196 /**
197 * Returns a new rectangle which represents the intersection
198 * of the receiver and the given rectangle.
199 * <p>
200 * The intersection of two rectangles is the rectangle that
201 * covers the area which is contained within both rectangles.
202 * </p>
203 *
204 * @param rect the rectangle to intersect with the receiver
205 * @return the intersection of the receiver and the argument
206 *
207 * @exception IllegalArgumentException <ul>
208 * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
209 * </ul>
210 */
211 public DirtyRectangle intersection(DirtyRectangle rect) {
212 if (rect == null)
213 SWT.error(SWT.ERROR_NULL_ARGUMENT);
214 if (this == rect)
215 return new DirtyRectangle(x, y, width, height);
216 int left = x > rect.x ? x : rect.x;
217 int top = y > rect.y ? y : rect.y;
218 int lhs = x + width;
219 int rhs = rect.x + rect.width;
220 int right = lhs < rhs ? lhs : rhs;
221 lhs = y + height;
222 rhs = rect.y + rect.height;
223 int bottom = lhs < rhs ? lhs : rhs;
224 return new DirtyRectangle(
225 right < left ? 0 : left,
226 bottom < top ? 0 : top,
227 right < left ? 0 : right - left,
228 bottom < top ? 0 : bottom - top);
229 }
230
231 /**
232 * Returns <code>true</code> if the given rectangle intersects
233 * with the receiver and <code>false</code> otherwise.
234 * <p>
235 * Two rectangles intersect if the area of the rectangle
236 * representing their intersection is not empty.
237 * </p>
238 *
239 * @param rect the rectangle to test for intersection
240 * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise
241 *
242 * @exception IllegalArgumentException <ul>
243 * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
244 * </ul>
245 *
246 * @see #intersection
247 * @see #isEmpty
248 */
249 public boolean intersects(DirtyRectangle rect) {
250 if (rect == null)
251 SWT.error(SWT.ERROR_NULL_ARGUMENT);
252 return (rect == this)
253 || (rect.x < x + width)
254 && (rect.y < y + height)
255 && (rect.x + rect.width > x)
256 && (rect.y + rect.height > y);
257 }
258
259 /**
260 * Returns <code>true</code> if the receiver does not cover any
261 * area in the (x, y) coordinate plane, and <code>false</code> if
262 * the receiver does cover some area in the plane.
263 * <p>
264 * A rectangle is considered to <em>cover area</em> in the
265 * (x, y) coordinate plane if both its width and height are
266 * non-zero.
267 * </p>
268 *
269 * @return <code>true</code> if the receiver is empty, and <code>false</code> otherwise
270 */
271 public boolean isEmpty() {
272 return (width <= 0) || (height <= 0);
273 }
274
275 /**
276 * Returns a string containing a concise, human-readable
277 * description of the receiver.
278 *
279 * @return a string representation of the rectangle
280 */
281 public String toString() {
282 return "Rectangle {" + x + ", " + y + ", " + width + ", " + height + "}";
283 }
284
285 /**
286 * Returns a new rectangle which represents the union of
287 * the receiver and the given rectangle.
288 * <p>
289 * The union of two rectangles is the smallest single rectangle
290 * that completely covers both of the areas covered by the two
291 * given rectangles.
292 * </p>
293 *
294 * @param rect the rectangle to perform union with
295 * @return the union of the receiver and the argument
296 *
297 * @exception IllegalArgumentException <ul>
298 * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
299 * </ul>
300 *
301 * @see #add
302 */
303 public DirtyRectangle union(DirtyRectangle rect) {
304 if (rect == null)
305 SWT.error(SWT.ERROR_NULL_ARGUMENT);
306 int left = x < rect.x ? x : rect.x;
307 int top = y < rect.y ? y : rect.y;
308 int lhs = x + width;
309 int rhs = rect.x + rect.width;
310 int right = lhs > rhs ? lhs : rhs;
311 lhs = y + height;
312 rhs = rect.y + rect.height;
313 int bottom = lhs > rhs ? lhs : rhs;
314 return new DirtyRectangle(left, top, right - left, bottom - top);
315 }
316
317 public void clear() {
318 x = y = width = height = 0;
319 }
320 }