History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/Rectangle.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/awt/Rectangle.java+1216−0
@@ -0,0 +1,1216 @@
1+/*
2+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.awt;
27+
28+import java.awt.geom.Rectangle2D;
29+import java.beans.Transient;
30+
31+/**
32+ * A <code>Rectangle</code> specifies an area in a coordinate space that is
33+ * enclosed by the <code>Rectangle</code> object's upper-left point
34+ * {@code (x,y)}
35+ * in the coordinate space, its width, and its height.
36+ * <p>
37+ * A <code>Rectangle</code> object's <code>width</code> and
38+ * <code>height</code> are <code>public</code> fields. The constructors
39+ * that create a <code>Rectangle</code>, and the methods that can modify
40+ * one, do not prevent setting a negative value for width or height.
41+ * <p>
42+ * <a name="Empty">
43+ * A {@code Rectangle} whose width or height is exactly zero has location
44+ * along those axes with zero dimension, but is otherwise considered empty.
45+ * The {@link #isEmpty} method will return true for such a {@code Rectangle}.
46+ * Methods which test if an empty {@code Rectangle} contains or intersects
47+ * a point or rectangle will always return false if either dimension is zero.
48+ * Methods which combine such a {@code Rectangle} with a point or rectangle
49+ * will include the location of the {@code Rectangle} on that axis in the
50+ * result as if the {@link #add(Point)} method were being called.
51+ * </a>
52+ * <p>
53+ * <a name="NonExistant">
54+ * A {@code Rectangle} whose width or height is negative has neither
55+ * location nor dimension along those axes with negative dimensions.
56+ * Such a {@code Rectangle} is treated as non-existant along those axes.
57+ * Such a {@code Rectangle} is also empty with respect to containment
58+ * calculations and methods which test if it contains or intersects a
59+ * point or rectangle will always return false.
60+ * Methods which combine such a {@code Rectangle} with a point or rectangle
61+ * will ignore the {@code Rectangle} entirely in generating the result.
62+ * If two {@code Rectangle} objects are combined and each has a negative
63+ * dimension, the result will have at least one negative dimension.
64+ * </a>
65+ * <p>
66+ * Methods which affect only the location of a {@code Rectangle} will
67+ * operate on its location regardless of whether or not it has a negative
68+ * or zero dimension along either axis.
69+ * <p>
70+ * Note that a {@code Rectangle} constructed with the default no-argument
71+ * constructor will have dimensions of {@code 0x0} and therefore be empty.
72+ * That {@code Rectangle} will still have a location of {@code (0,0)} and
73+ * will contribute that location to the union and add operations.
74+ * Code attempting to accumulate the bounds of a set of points should
75+ * therefore initially construct the {@code Rectangle} with a specifically
76+ * negative width and height or it should use the first point in the set
77+ * to construct the {@code Rectangle}.
78+ * For example:
79+ * <pre>
80+ * Rectangle bounds = new Rectangle(0, 0, -1, -1);
81+ * for (int i = 0; i < points.length; i++) {
82+ * bounds.add(points[i]);
83+ * }
84+ * </pre>
85+ * or if we know that the points array contains at least one point:
86+ * <pre>
87+ * Rectangle bounds = new Rectangle(points[0]);
88+ * for (int i = 1; i < points.length; i++) {
89+ * bounds.add(points[i]);
90+ * }
91+ * </pre>
92+ * <p>
93+ * This class uses 32-bit integers to store its location and dimensions.
94+ * Frequently operations may produce a result that exceeds the range of
95+ * a 32-bit integer.
96+ * The methods will calculate their results in a way that avoids any
97+ * 32-bit overflow for intermediate results and then choose the best
98+ * representation to store the final results back into the 32-bit fields
99+ * which hold the location and dimensions.
100+ * The location of the result will be stored into the {@link #x} and
101+ * {@link #y} fields by clipping the true result to the nearest 32-bit value.
102+ * The values stored into the {@link #width} and {@link #height} dimension
103+ * fields will be chosen as the 32-bit values that encompass the largest
104+ * part of the true result as possible.
105+ * Generally this means that the dimension will be clipped independently
106+ * to the range of 32-bit integers except that if the location had to be
107+ * moved to store it into its pair of 32-bit fields then the dimensions
108+ * will be adjusted relative to the "best representation" of the location.
109+ * If the true result had a negative dimension and was therefore
110+ * non-existant along one or both axes, the stored dimensions will be
111+ * negative numbers in those axes.
112+ * If the true result had a location that could be represented within
113+ * the range of 32-bit integers, but zero dimension along one or both
114+ * axes, then the stored dimensions will be zero in those axes.
115+ *
116+ * @author Sami Shaio
117+ * @since 1.0
118+ */
119+public class Rectangle extends Rectangle2D
120+ implements Shape, java.io.Serializable
121+{
122+
123+ /**
124+ * The X coordinate of the upper-left corner of the <code>Rectangle</code>.
125+ *
126+ * @serial
127+ * @see #setLocation(int, int)
128+ * @see #getLocation()
129+ * @since 1.0
130+ */
131+ public int x;
132+
133+ /**
134+ * The Y coordinate of the upper-left corner of the <code>Rectangle</code>.
135+ *
136+ * @serial
137+ * @see #setLocation(int, int)
138+ * @see #getLocation()
139+ * @since 1.0
140+ */
141+ public int y;
142+
143+ /**
144+ * The width of the <code>Rectangle</code>.
145+ * @serial
146+ * @see #setSize(int, int)
147+ * @see #getSize()
148+ * @since 1.0
149+ */
150+ public int width;
151+
152+ /**
153+ * The height of the <code>Rectangle</code>.
154+ *
155+ * @serial
156+ * @see #setSize(int, int)
157+ * @see #getSize()
158+ * @since 1.0
159+ */
160+ public int height;
161+
162+ /*
163+ * JDK 1.1 serialVersionUID
164+ */
165+ private static final long serialVersionUID = -4345857070255674764L;
166+
167+ /**
168+ * Initialize JNI field and method IDs
169+ */
170+ private static native void initIDs();
171+
172+ static {
173+ /* ensure that the necessary native libraries are loaded */
174+ Toolkit.loadLibraries();
175+ if (!GraphicsEnvironment.isHeadless()) {
176+ initIDs();
177+ }
178+ }
179+
180+ /**
181+ * Constructs a new <code>Rectangle</code> whose upper-left corner
182+ * is at (0,&nbsp;0) in the coordinate space, and whose width and
183+ * height are both zero.
184+ */
185+ public Rectangle() {
186+ this(0, 0, 0, 0);
187+ }
188+
189+ /**
190+ * Constructs a new <code>Rectangle</code>, initialized to match
191+ * the values of the specified <code>Rectangle</code>.
192+ * @param r the <code>Rectangle</code> from which to copy initial values
193+ * to a newly constructed <code>Rectangle</code>
194+ * @since 1.1
195+ */
196+ public Rectangle(Rectangle r) {
197+ this(r.x, r.y, r.width, r.height);
198+ }
199+
200+ /**
201+ * Constructs a new <code>Rectangle</code> whose upper-left corner is
202+ * specified as
203+ * {@code (x,y)} and whose width and height
204+ * are specified by the arguments of the same name.
205+ * @param x the specified X coordinate
206+ * @param y the specified Y coordinate
207+ * @param width the width of the <code>Rectangle</code>
208+ * @param height the height of the <code>Rectangle</code>
209+ * @since 1.0
210+ */
211+ public Rectangle(int x, int y, int width, int height) {
212+ this.x = x;
213+ this.y = y;
214+ this.width = width;
215+ this.height = height;
216+ }
217+
218+ /**
219+ * Constructs a new <code>Rectangle</code> whose upper-left corner
220+ * is at (0,&nbsp;0) in the coordinate space, and whose width and
221+ * height are specified by the arguments of the same name.
222+ * @param width the width of the <code>Rectangle</code>
223+ * @param height the height of the <code>Rectangle</code>
224+ */
225+ public Rectangle(int width, int height) {
226+ this(0, 0, width, height);
227+ }
228+
229+ /**
230+ * Constructs a new <code>Rectangle</code> whose upper-left corner is
231+ * specified by the {@link Point} argument, and
232+ * whose width and height are specified by the
233+ * {@link Dimension} argument.
234+ * @param p a <code>Point</code> that is the upper-left corner of
235+ * the <code>Rectangle</code>
236+ * @param d a <code>Dimension</code>, representing the
237+ * width and height of the <code>Rectangle</code>
238+ */
239+ public Rectangle(Point p, Dimension d) {
240+ this(p.x, p.y, d.width, d.height);
241+ }
242+
243+ /**
244+ * Constructs a new <code>Rectangle</code> whose upper-left corner is the
245+ * specified <code>Point</code>, and whose width and height are both zero.
246+ * @param p a <code>Point</code> that is the top left corner
247+ * of the <code>Rectangle</code>
248+ */
249+ public Rectangle(Point p) {
250+ this(p.x, p.y, 0, 0);
251+ }
252+
253+ /**
254+ * Constructs a new <code>Rectangle</code> whose top left corner is
255+ * (0,&nbsp;0) and whose width and height are specified
256+ * by the <code>Dimension</code> argument.
257+ * @param d a <code>Dimension</code>, specifying width and height
258+ */
259+ public Rectangle(Dimension d) {
260+ this(0, 0, d.width, d.height);
261+ }
262+
263+ /**
264+ * Returns the X coordinate of the bounding <code>Rectangle</code> in
265+ * <code>double</code> precision.
266+ * @return the X coordinate of the bounding <code>Rectangle</code>.
267+ */
268+ public double getX() {
269+ return x;
270+ }
271+
272+ /**
273+ * Returns the Y coordinate of the bounding <code>Rectangle</code> in
274+ * <code>double</code> precision.
275+ * @return the Y coordinate of the bounding <code>Rectangle</code>.
276+ */
277+ public double getY() {
278+ return y;
279+ }
280+
281+ /**
282+ * Returns the width of the bounding <code>Rectangle</code> in
283+ * <code>double</code> precision.
284+ * @return the width of the bounding <code>Rectangle</code>.
285+ */
286+ public double getWidth() {
287+ return width;
288+ }
289+
290+ /**
291+ * Returns the height of the bounding <code>Rectangle</code> in
292+ * <code>double</code> precision.
293+ * @return the height of the bounding <code>Rectangle</code>.
294+ */
295+ public double getHeight() {
296+ return height;
297+ }
298+
299+ /**
300+ * Gets the bounding <code>Rectangle</code> of this <code>Rectangle</code>.
301+ * <p>
302+ * This method is included for completeness, to parallel the
303+ * <code>getBounds</code> method of
304+ * {@link Component}.
305+ * @return a new <code>Rectangle</code>, equal to the
306+ * bounding <code>Rectangle</code> for this <code>Rectangle</code>.
307+ * @see java.awt.Component#getBounds
308+ * @see #setBounds(Rectangle)
309+ * @see #setBounds(int, int, int, int)
310+ * @since 1.1
311+ */
312+ @Transient
313+ public Rectangle getBounds() {
314+ return new Rectangle(x, y, width, height);
315+ }
316+
317+ /**
318+ * {@inheritDoc}
319+ * @since 1.2
320+ */
321+ public Rectangle2D getBounds2D() {
322+ return new Rectangle(x, y, width, height);
323+ }
324+
325+ /**
326+ * Sets the bounding <code>Rectangle</code> of this <code>Rectangle</code>
327+ * to match the specified <code>Rectangle</code>.
328+ * <p>
329+ * This method is included for completeness, to parallel the
330+ * <code>setBounds</code> method of <code>Component</code>.
331+ * @param r the specified <code>Rectangle</code>
332+ * @see #getBounds
333+ * @see java.awt.Component#setBounds(java.awt.Rectangle)
334+ * @since 1.1
335+ */
336+ public void setBounds(Rectangle r) {
337+ setBounds(r.x, r.y, r.width, r.height);
338+ }
339+
340+ /**
341+ * Sets the bounding <code>Rectangle</code> of this
342+ * <code>Rectangle</code> to the specified
343+ * <code>x</code>, <code>y</code>, <code>width</code>,
344+ * and <code>height</code>.
345+ * <p>
346+ * This method is included for completeness, to parallel the
347+ * <code>setBounds</code> method of <code>Component</code>.
348+ * @param x the new X coordinate for the upper-left
349+ * corner of this <code>Rectangle</code>
350+ * @param y the new Y coordinate for the upper-left
351+ * corner of this <code>Rectangle</code>
352+ * @param width the new width for this <code>Rectangle</code>
353+ * @param height the new height for this <code>Rectangle</code>
354+ * @see #getBounds
355+ * @see java.awt.Component#setBounds(int, int, int, int)
356+ * @since 1.1
357+ */
358+ public void setBounds(int x, int y, int width, int height) {
359+ reshape(x, y, width, height);
360+ }
361+
362+ /**
363+ * Sets the bounds of this {@code Rectangle} to the integer bounds
364+ * which encompass the specified {@code x}, {@code y}, {@code width},
365+ * and {@code height}.
366+ * If the parameters specify a {@code Rectangle} that exceeds the
367+ * maximum range of integers, the result will be the best
368+ * representation of the specified {@code Rectangle} intersected
369+ * with the maximum integer bounds.
370+ * @param x the X coordinate of the upper-left corner of
371+ * the specified rectangle
372+ * @param y the Y coordinate of the upper-left corner of
373+ * the specified rectangle
374+ * @param width the width of the specified rectangle
375+ * @param height the new height of the specified rectangle
376+ */
377+ public void setRect(double x, double y, double width, double height) {
378+ int newx, newy, neww, newh;
379+
380+ if (x > 2.0 * Integer.MAX_VALUE) {
381+ // Too far in positive X direction to represent...
382+ // We cannot even reach the left side of the specified
383+ // rectangle even with both x & width set to MAX_VALUE.
384+ // The intersection with the "maximal integer rectangle"
385+ // is non-existant so we should use a width < 0.
386+ // REMIND: Should we try to determine a more "meaningful"
387+ // adjusted value for neww than just "-1"?
388+ newx = Integer.MAX_VALUE;
389+ neww = -1;
390+ } else {
391+ newx = clip(x, false);
392+ if (width >= 0) width += x-newx;
393+ neww = clip(width, width >= 0);
394+ }
395+
396+ if (y > 2.0 * Integer.MAX_VALUE) {
397+ // Too far in positive Y direction to represent...
398+ newy = Integer.MAX_VALUE;
399+ newh = -1;
400+ } else {
401+ newy = clip(y, false);
402+ if (height >= 0) height += y-newy;
403+ newh = clip(height, height >= 0);
404+ }
405+
406+ reshape(newx, newy, neww, newh);
407+ }
408+ // Return best integer representation for v, clipped to integer
409+ // range and floor-ed or ceiling-ed, depending on the boolean.
410+ private static int clip(double v, boolean doceil) {
411+ if (v <= Integer.MIN_VALUE) {
412+ return Integer.MIN_VALUE;
413+ }
414+ if (v >= Integer.MAX_VALUE) {
415+ return Integer.MAX_VALUE;
416+ }
417+ return (int) (doceil ? Math.ceil(v) : Math.floor(v));
418+ }
419+
420+ /**
421+ * Sets the bounding <code>Rectangle</code> of this
422+ * <code>Rectangle</code> to the specified
423+ * <code>x</code>, <code>y</code>, <code>width</code>,
424+ * and <code>height</code>.
425+ * <p>
426+ * @param x the new X coordinate for the upper-left
427+ * corner of this <code>Rectangle</code>
428+ * @param y the new Y coordinate for the upper-left
429+ * corner of this <code>Rectangle</code>
430+ * @param width the new width for this <code>Rectangle</code>
431+ * @param height the new height for this <code>Rectangle</code>
432+ * @deprecated As of JDK version 1.1,
433+ * replaced by <code>setBounds(int, int, int, int)</code>.
434+ */
435+ @Deprecated
436+ public void reshape(int x, int y, int width, int height) {
437+ this.x = x;
438+ this.y = y;
439+ this.width = width;
440+ this.height = height;
441+ }
442+
443+ /**
444+ * Returns the location of this <code>Rectangle</code>.
445+ * <p>
446+ * This method is included for completeness, to parallel the
447+ * <code>getLocation</code> method of <code>Component</code>.
448+ * @return the <code>Point</code> that is the upper-left corner of
449+ * this <code>Rectangle</code>.
450+ * @see java.awt.Component#getLocation
451+ * @see #setLocation(Point)
452+ * @see #setLocation(int, int)
453+ * @since 1.1
454+ */
455+ public Point getLocation() {
456+ return new Point(x, y);
457+ }
458+
459+ /**
460+ * Moves this <code>Rectangle</code> to the specified location.
461+ * <p>
462+ * This method is included for completeness, to parallel the
463+ * <code>setLocation</code> method of <code>Component</code>.
464+ * @param p the <code>Point</code> specifying the new location
465+ * for this <code>Rectangle</code>
466+ * @see java.awt.Component#setLocation(java.awt.Point)
467+ * @see #getLocation
468+ * @since 1.1
469+ */
470+ public void setLocation(Point p) {
471+ setLocation(p.x, p.y);
472+ }
473+
474+ /**
475+ * Moves this <code>Rectangle</code> to the specified location.
476+ * <p>
477+ * This method is included for completeness, to parallel the
478+ * <code>setLocation</code> method of <code>Component</code>.
479+ * @param x the X coordinate of the new location
480+ * @param y the Y coordinate of the new location
481+ * @see #getLocation
482+ * @see java.awt.Component#setLocation(int, int)
483+ * @since 1.1
484+ */
485+ public void setLocation(int x, int y) {
486+ move(x, y);
487+ }
488+
489+ /**
490+ * Moves this <code>Rectangle</code> to the specified location.
491+ * <p>
492+ * @param x the X coordinate of the new location
493+ * @param y the Y coordinate of the new location
494+ * @deprecated As of JDK version 1.1,
495+ * replaced by <code>setLocation(int, int)</code>.
496+ */
497+ @Deprecated
498+ public void move(int x, int y) {
499+ this.x = x;
500+ this.y = y;
501+ }
502+
503+ /**
504+ * Translates this <code>Rectangle</code> the indicated distance,
505+ * to the right along the X coordinate axis, and
506+ * downward along the Y coordinate axis.
507+ * @param dx the distance to move this <code>Rectangle</code>
508+ * along the X axis
509+ * @param dy the distance to move this <code>Rectangle</code>
510+ * along the Y axis
511+ * @see java.awt.Rectangle#setLocation(int, int)
512+ * @see java.awt.Rectangle#setLocation(java.awt.Point)
513+ */
514+ public void translate(int dx, int dy) {
515+ int oldv = this.x;
516+ int newv = oldv + dx;
517+ if (dx < 0) {
518+ // moving leftward
519+ if (newv > oldv) {
520+ // negative overflow
521+ // Only adjust width if it was valid (>= 0).
522+ if (width >= 0) {
523+ // The right edge is now conceptually at
524+ // newv+width, but we may move newv to prevent
525+ // overflow. But we want the right edge to
526+ // remain at its new location in spite of the
527+ // clipping. Think of the following adjustment
528+ // conceptually the same as:
529+ // width += newv; newv = MIN_VALUE; width -= newv;
530+ width += newv - Integer.MIN_VALUE;
531+ // width may go negative if the right edge went past
532+ // MIN_VALUE, but it cannot overflow since it cannot
533+ // have moved more than MIN_VALUE and any non-negative
534+ // number + MIN_VALUE does not overflow.
535+ }
536+ newv = Integer.MIN_VALUE;
537+ }
538+ } else {
539+ // moving rightward (or staying still)
540+ if (newv < oldv) {
541+ // positive overflow
542+ if (width >= 0) {
543+ // Conceptually the same as:
544+ // width += newv; newv = MAX_VALUE; width -= newv;
545+ width += newv - Integer.MAX_VALUE;
546+ // With large widths and large displacements
547+ // we may overflow so we need to check it.
548+ if (width < 0) width = Integer.MAX_VALUE;
549+ }
550+ newv = Integer.MAX_VALUE;
551+ }
552+ }
553+ this.x = newv;
554+
555+ oldv = this.y;
556+ newv = oldv + dy;
557+ if (dy < 0) {
558+ // moving upward
559+ if (newv > oldv) {
560+ // negative overflow
561+ if (height >= 0) {
562+ height += newv - Integer.MIN_VALUE;
563+ // See above comment about no overflow in this case
564+ }
565+ newv = Integer.MIN_VALUE;
566+ }
567+ } else {
568+ // moving downward (or staying still)
569+ if (newv < oldv) {
570+ // positive overflow
571+ if (height >= 0) {
572+ height += newv - Integer.MAX_VALUE;
573+ if (height < 0) height = Integer.MAX_VALUE;
574+ }
575+ newv = Integer.MAX_VALUE;
576+ }
577+ }
578+ this.y = newv;
579+ }
580+
581+ /**
582+ * Gets the size of this <code>Rectangle</code>, represented by
583+ * the returned <code>Dimension</code>.
584+ * <p>
585+ * This method is included for completeness, to parallel the
586+ * <code>getSize</code> method of <code>Component</code>.
587+ * @return a <code>Dimension</code>, representing the size of
588+ * this <code>Rectangle</code>.
589+ * @see java.awt.Component#getSize
590+ * @see #setSize(Dimension)
591+ * @see #setSize(int, int)
592+ * @since 1.1
593+ */
594+ public Dimension getSize() {
595+ return new Dimension(width, height);
596+ }
597+
598+ /**
599+ * Sets the size of this <code>Rectangle</code> to match the
600+ * specified <code>Dimension</code>.
601+ * <p>
602+ * This method is included for completeness, to parallel the
603+ * <code>setSize</code> method of <code>Component</code>.
604+ * @param d the new size for the <code>Dimension</code> object
605+ * @see java.awt.Component#setSize(java.awt.Dimension)
606+ * @see #getSize
607+ * @since 1.1
608+ */
609+ public void setSize(Dimension d) {
610+ setSize(d.width, d.height);
611+ }
612+
613+ /**
614+ * Sets the size of this <code>Rectangle</code> to the specified
615+ * width and height.
616+ * <p>
617+ * This method is included for completeness, to parallel the
618+ * <code>setSize</code> method of <code>Component</code>.
619+ * @param width the new width for this <code>Rectangle</code>
620+ * @param height the new height for this <code>Rectangle</code>
621+ * @see java.awt.Component#setSize(int, int)
622+ * @see #getSize
623+ * @since 1.1
624+ */
625+ public void setSize(int width, int height) {
626+ resize(width, height);
627+ }
628+
629+ /**
630+ * Sets the size of this <code>Rectangle</code> to the specified
631+ * width and height.
632+ * <p>
633+ * @param width the new width for this <code>Rectangle</code>
634+ * @param height the new height for this <code>Rectangle</code>
635+ * @deprecated As of JDK version 1.1,
636+ * replaced by <code>setSize(int, int)</code>.
637+ */
638+ @Deprecated
639+ public void resize(int width, int height) {
640+ this.width = width;
641+ this.height = height;
642+ }
643+
644+ /**
645+ * Checks whether or not this <code>Rectangle</code> contains the
646+ * specified <code>Point</code>.
647+ * @param p the <code>Point</code> to test
648+ * @return <code>true</code> if the specified <code>Point</code>
649+ * is inside this <code>Rectangle</code>;
650+ * <code>false</code> otherwise.
651+ * @since 1.1
652+ */
653+ public boolean contains(Point p) {
654+ return contains(p.x, p.y);
655+ }
656+
657+ /**
658+ * Checks whether or not this <code>Rectangle</code> contains the
659+ * point at the specified location {@code (x,y)}.
660+ *
661+ * @param x the specified X coordinate
662+ * @param y the specified Y coordinate
663+ * @return <code>true</code> if the point
664+ * {@code (x,y)} is inside this
665+ * <code>Rectangle</code>;
666+ * <code>false</code> otherwise.
667+ * @since 1.1
668+ */
669+ public boolean contains(int x, int y) {
670+ return inside(x, y);
671+ }
672+
673+ /**
674+ * Checks whether or not this <code>Rectangle</code> entirely contains
675+ * the specified <code>Rectangle</code>.
676+ *
677+ * @param r the specified <code>Rectangle</code>
678+ * @return <code>true</code> if the <code>Rectangle</code>
679+ * is contained entirely inside this <code>Rectangle</code>;
680+ * <code>false</code> otherwise
681+ * @since 1.2
682+ */
683+ public boolean contains(Rectangle r) {
684+ return contains(r.x, r.y, r.width, r.height);
685+ }
686+
687+ /**
688+ * Checks whether this <code>Rectangle</code> entirely contains
689+ * the <code>Rectangle</code>
690+ * at the specified location {@code (X,Y)} with the
691+ * specified dimensions {@code (W,H)}.
692+ * @param X the specified X coordinate
693+ * @param Y the specified Y coordinate
694+ * @param W the width of the <code>Rectangle</code>
695+ * @param H the height of the <code>Rectangle</code>
696+ * @return <code>true</code> if the <code>Rectangle</code> specified by
697+ * {@code (X, Y, W, H)}
698+ * is entirely enclosed inside this <code>Rectangle</code>;
699+ * <code>false</code> otherwise.
700+ * @since 1.1
701+ */
702+ public boolean contains(int X, int Y, int W, int H) {
703+ int w = this.width;
704+ int h = this.height;
705+ if ((w | h | W | H) < 0) {
706+ // At least one of the dimensions is negative...
707+ return false;
708+ }
709+ // Note: if any dimension is zero, tests below must return false...
710+ int x = this.x;
711+ int y = this.y;
712+ if (X < x || Y < y) {
713+ return false;
714+ }
715+ w += x;
716+ W += X;
717+ if (W <= X) {
718+ // X+W overflowed or W was zero, return false if...
719+ // either original w or W was zero or
720+ // x+w did not overflow or
721+ // the overflowed x+w is smaller than the overflowed X+W
722+ if (w >= x || W > w) return false;
723+ } else {
724+ // X+W did not overflow and W was not zero, return false if...
725+ // original w was zero or
726+ // x+w did not overflow and x+w is smaller than X+W
727+ if (w >= x && W > w) return false;
728+ }
729+ h += y;
730+ H += Y;
731+ if (H <= Y) {
732+ if (h >= y || H > h) return false;
733+ } else {
734+ if (h >= y && H > h) return false;
735+ }
736+ return true;
737+ }
738+
739+ /**
740+ * Checks whether or not this <code>Rectangle</code> contains the
741+ * point at the specified location {@code (X,Y)}.
742+ *
743+ * @param X the specified X coordinate
744+ * @param Y the specified Y coordinate
745+ * @return <code>true</code> if the point
746+ * {@code (X,Y)} is inside this
747+ * <code>Rectangle</code>;
748+ * <code>false</code> otherwise.
749+ * @deprecated As of JDK version 1.1,
750+ * replaced by <code>contains(int, int)</code>.
751+ */
752+ @Deprecated
753+ public boolean inside(int X, int Y) {
754+ int w = this.width;
755+ int h = this.height;
756+ if ((w | h) < 0) {
757+ // At least one of the dimensions is negative...
758+ return false;
759+ }
760+ // Note: if either dimension is zero, tests below must return false...
761+ int x = this.x;
762+ int y = this.y;
763+ if (X < x || Y < y) {
764+ return false;
765+ }
766+ w += x;
767+ h += y;
768+ // overflow || intersect
769+ return ((w < x || w > X) &&
770+ (h < y || h > Y));
771+ }
772+
773+ /**
774+ * Determines whether or not this <code>Rectangle</code> and the specified
775+ * <code>Rectangle</code> intersect. Two rectangles intersect if
776+ * their intersection is nonempty.
777+ *
778+ * @param r the specified <code>Rectangle</code>
779+ * @return <code>true</code> if the specified <code>Rectangle</code>
780+ * and this <code>Rectangle</code> intersect;
781+ * <code>false</code> otherwise.
782+ */
783+ public boolean intersects(Rectangle r) {
784+ int tw = this.width;
785+ int th = this.height;
786+ int rw = r.width;
787+ int rh = r.height;
788+ if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
789+ return false;
790+ }
791+ int tx = this.x;
792+ int ty = this.y;
793+ int rx = r.x;
794+ int ry = r.y;
795+ rw += rx;
796+ rh += ry;
797+ tw += tx;
798+ th += ty;
799+ // overflow || intersect
800+ return ((rw < rx || rw > tx) &&
801+ (rh < ry || rh > ty) &&
802+ (tw < tx || tw > rx) &&
803+ (th < ty || th > ry));
804+ }
805+
806+ /**
807+ * Computes the intersection of this <code>Rectangle</code> with the
808+ * specified <code>Rectangle</code>. Returns a new <code>Rectangle</code>
809+ * that represents the intersection of the two rectangles.
810+ * If the two rectangles do not intersect, the result will be
811+ * an empty rectangle.
812+ *
813+ * @param r the specified <code>Rectangle</code>
814+ * @return the largest <code>Rectangle</code> contained in both the
815+ * specified <code>Rectangle</code> and in
816+ * this <code>Rectangle</code>; or if the rectangles
817+ * do not intersect, an empty rectangle.
818+ */
819+ public Rectangle intersection(Rectangle r) {
820+ int tx1 = this.x;
821+ int ty1 = this.y;
822+ int rx1 = r.x;
823+ int ry1 = r.y;
824+ long tx2 = tx1; tx2 += this.width;
825+ long ty2 = ty1; ty2 += this.height;
826+ long rx2 = rx1; rx2 += r.width;
827+ long ry2 = ry1; ry2 += r.height;
828+ if (tx1 < rx1) tx1 = rx1;
829+ if (ty1 < ry1) ty1 = ry1;
830+ if (tx2 > rx2) tx2 = rx2;
831+ if (ty2 > ry2) ty2 = ry2;
832+ tx2 -= tx1;
833+ ty2 -= ty1;
834+ // tx2,ty2 will never overflow (they will never be
835+ // larger than the smallest of the two source w,h)
836+ // they might underflow, though...
837+ if (tx2 < Integer.MIN_VALUE) tx2 = Integer.MIN_VALUE;
838+ if (ty2 < Integer.MIN_VALUE) ty2 = Integer.MIN_VALUE;
839+ return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
840+ }
841+
842+ /**
843+ * Computes the union of this <code>Rectangle</code> with the
844+ * specified <code>Rectangle</code>. Returns a new
845+ * <code>Rectangle</code> that
846+ * represents the union of the two rectangles.
847+ * <p>
848+ * If either {@code Rectangle} has any dimension less than zero
849+ * the rules for <a href=#NonExistant>non-existant</a> rectangles
850+ * apply.
851+ * If only one has a dimension less than zero, then the result
852+ * will be a copy of the other {@code Rectangle}.
853+ * If both have dimension less than zero, then the result will
854+ * have at least one dimension less than zero.
855+ * <p>
856+ * If the resulting {@code Rectangle} would have a dimension
857+ * too large to be expressed as an {@code int}, the result
858+ * will have a dimension of {@code Integer.MAX_VALUE} along
859+ * that dimension.
860+ * @param r the specified <code>Rectangle</code>
861+ * @return the smallest <code>Rectangle</code> containing both
862+ * the specified <code>Rectangle</code> and this
863+ * <code>Rectangle</code>.
864+ */
865+ public Rectangle union(Rectangle r) {
866+ long tx2 = this.width;
867+ long ty2 = this.height;
868+ if ((tx2 | ty2) < 0) {
869+ // This rectangle has negative dimensions...
870+ // If r has non-negative dimensions then it is the answer.
871+ // If r is non-existant (has a negative dimension), then both
872+ // are non-existant and we can return any non-existant rectangle
873+ // as an answer. Thus, returning r meets that criterion.
874+ // Either way, r is our answer.
875+ return new Rectangle(r);
876+ }
877+ long rx2 = r.width;
878+ long ry2 = r.height;
879+ if ((rx2 | ry2) < 0) {
880+ return new Rectangle(this);
881+ }
882+ int tx1 = this.x;
883+ int ty1 = this.y;
884+ tx2 += tx1;
885+ ty2 += ty1;
886+ int rx1 = r.x;
887+ int ry1 = r.y;
888+ rx2 += rx1;
889+ ry2 += ry1;
890+ if (tx1 > rx1) tx1 = rx1;
891+ if (ty1 > ry1) ty1 = ry1;
892+ if (tx2 < rx2) tx2 = rx2;
893+ if (ty2 < ry2) ty2 = ry2;
894+ tx2 -= tx1;
895+ ty2 -= ty1;
896+ // tx2,ty2 will never underflow since both original rectangles
897+ // were already proven to be non-empty
898+ // they might overflow, though...
899+ if (tx2 > Integer.MAX_VALUE) tx2 = Integer.MAX_VALUE;
900+ if (ty2 > Integer.MAX_VALUE) ty2 = Integer.MAX_VALUE;
901+ return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
902+ }
903+
904+ /**
905+ * Adds a point, specified by the integer arguments {@code newx,newy}
906+ * to the bounds of this {@code Rectangle}.
907+ * <p>
908+ * If this {@code Rectangle} has any dimension less than zero,
909+ * the rules for <a href=#NonExistant>non-existant</a>
910+ * rectangles apply.
911+ * In that case, the new bounds of this {@code Rectangle} will
912+ * have a location equal to the specified coordinates and
913+ * width and height equal to zero.
914+ * <p>
915+ * After adding a point, a call to <code>contains</code> with the
916+ * added point as an argument does not necessarily return
917+ * <code>true</code>. The <code>contains</code> method does not
918+ * return <code>true</code> for points on the right or bottom
919+ * edges of a <code>Rectangle</code>. Therefore, if the added point
920+ * falls on the right or bottom edge of the enlarged
921+ * <code>Rectangle</code>, <code>contains</code> returns
922+ * <code>false</code> for that point.
923+ * If the specified point must be contained within the new
924+ * {@code Rectangle}, a 1x1 rectangle should be added instead:
925+ * <pre>
926+ * r.add(newx, newy, 1, 1);
927+ * </pre>
928+ * @param newx the X coordinate of the new point
929+ * @param newy the Y coordinate of the new point
930+ */
931+ public void add(int newx, int newy) {
932+ if ((width | height) < 0) {
933+ this.x = newx;
934+ this.y = newy;
935+ this.width = this.height = 0;
936+ return;
937+ }
938+ int x1 = this.x;
939+ int y1 = this.y;
940+ long x2 = this.width;
941+ long y2 = this.height;
942+ x2 += x1;
943+ y2 += y1;
944+ if (x1 > newx) x1 = newx;
945+ if (y1 > newy) y1 = newy;
946+ if (x2 < newx) x2 = newx;
947+ if (y2 < newy) y2 = newy;
948+ x2 -= x1;
949+ y2 -= y1;
950+ if (x2 > Integer.MAX_VALUE) x2 = Integer.MAX_VALUE;
951+ if (y2 > Integer.MAX_VALUE) y2 = Integer.MAX_VALUE;
952+ reshape(x1, y1, (int) x2, (int) y2);
953+ }
954+
955+ /**
956+ * Adds the specified {@code Point} to the bounds of this
957+ * {@code Rectangle}.
958+ * <p>
959+ * If this {@code Rectangle} has any dimension less than zero,
960+ * the rules for <a href=#NonExistant>non-existant</a>
961+ * rectangles apply.
962+ * In that case, the new bounds of this {@code Rectangle} will
963+ * have a location equal to the coordinates of the specified
964+ * {@code Point} and width and height equal to zero.
965+ * <p>
966+ * After adding a <code>Point</code>, a call to <code>contains</code>
967+ * with the added <code>Point</code> as an argument does not
968+ * necessarily return <code>true</code>. The <code>contains</code>
969+ * method does not return <code>true</code> for points on the right
970+ * or bottom edges of a <code>Rectangle</code>. Therefore if the added
971+ * <code>Point</code> falls on the right or bottom edge of the
972+ * enlarged <code>Rectangle</code>, <code>contains</code> returns
973+ * <code>false</code> for that <code>Point</code>.
974+ * If the specified point must be contained within the new
975+ * {@code Rectangle}, a 1x1 rectangle should be added instead:
976+ * <pre>
977+ * r.add(pt.x, pt.y, 1, 1);
978+ * </pre>
979+ * @param pt the new <code>Point</code> to add to this
980+ * <code>Rectangle</code>
981+ */
982+ public void add(Point pt) {
983+ add(pt.x, pt.y);
984+ }
985+
986+ /**
987+ * Adds a <code>Rectangle</code> to this <code>Rectangle</code>.
988+ * The resulting <code>Rectangle</code> is the union of the two
989+ * rectangles.
990+ * <p>
991+ * If either {@code Rectangle} has any dimension less than 0, the
992+ * result will have the dimensions of the other {@code Rectangle}.
993+ * If both {@code Rectangle}s have at least one dimension less
994+ * than 0, the result will have at least one dimension less than 0.
995+ * <p>
996+ * If either {@code Rectangle} has one or both dimensions equal
997+ * to 0, the result along those axes with 0 dimensions will be
998+ * equivalent to the results obtained by adding the corresponding
999+ * origin coordinate to the result rectangle along that axis,
1000+ * similar to the operation of the {@link #add(Point)} method,
1001+ * but contribute no further dimension beyond that.
1002+ * <p>
1003+ * If the resulting {@code Rectangle} would have a dimension
1004+ * too large to be expressed as an {@code int}, the result
1005+ * will have a dimension of {@code Integer.MAX_VALUE} along
1006+ * that dimension.
1007+ * @param r the specified <code>Rectangle</code>
1008+ */
1009+ public void add(Rectangle r) {
1010+ long tx2 = this.width;
1011+ long ty2 = this.height;
1012+ if ((tx2 | ty2) < 0) {
1013+ reshape(r.x, r.y, r.width, r.height);
1014+ }
1015+ long rx2 = r.width;
1016+ long ry2 = r.height;
1017+ if ((rx2 | ry2) < 0) {
1018+ return;
1019+ }
1020+ int tx1 = this.x;
1021+ int ty1 = this.y;
1022+ tx2 += tx1;
1023+ ty2 += ty1;
1024+ int rx1 = r.x;
1025+ int ry1 = r.y;
1026+ rx2 += rx1;
1027+ ry2 += ry1;
1028+ if (tx1 > rx1) tx1 = rx1;
1029+ if (ty1 > ry1) ty1 = ry1;
1030+ if (tx2 < rx2) tx2 = rx2;
1031+ if (ty2 < ry2) ty2 = ry2;
1032+ tx2 -= tx1;
1033+ ty2 -= ty1;
1034+ // tx2,ty2 will never underflow since both original
1035+ // rectangles were non-empty
1036+ // they might overflow, though...
1037+ if (tx2 > Integer.MAX_VALUE) tx2 = Integer.MAX_VALUE;
1038+ if (ty2 > Integer.MAX_VALUE) ty2 = Integer.MAX_VALUE;
1039+ reshape(tx1, ty1, (int) tx2, (int) ty2);
1040+ }
1041+
1042+ /**
1043+ * Resizes the <code>Rectangle</code> both horizontally and vertically.
1044+ * <p>
1045+ * This method modifies the <code>Rectangle</code> so that it is
1046+ * <code>h</code> units larger on both the left and right side,
1047+ * and <code>v</code> units larger at both the top and bottom.
1048+ * <p>
1049+ * The new <code>Rectangle</code> has {@code (x - h, y - v)}
1050+ * as its upper-left corner,
1051+ * width of {@code (width + 2h)},
1052+ * and a height of {@code (height + 2v)}.
1053+ * <p>
1054+ * If negative values are supplied for <code>h</code> and
1055+ * <code>v</code>, the size of the <code>Rectangle</code>
1056+ * decreases accordingly.
1057+ * The {@code grow} method will check for integer overflow
1058+ * and underflow, but does not check whether the resulting
1059+ * values of {@code width} and {@code height} grow
1060+ * from negative to non-negative or shrink from non-negative
1061+ * to negative.
1062+ * @param h the horizontal expansion
1063+ * @param v the vertical expansion
1064+ */
1065+ public void grow(int h, int v) {
1066+ long x0 = this.x;
1067+ long y0 = this.y;
1068+ long x1 = this.width;
1069+ long y1 = this.height;
1070+ x1 += x0;
1071+ y1 += y0;
1072+
1073+ x0 -= h;
1074+ y0 -= v;
1075+ x1 += h;
1076+ y1 += v;
1077+
1078+ if (x1 < x0) {
1079+ // Non-existant in X direction
1080+ // Final width must remain negative so subtract x0 before
1081+ // it is clipped so that we avoid the risk that the clipping
1082+ // of x0 will reverse the ordering of x0 and x1.
1083+ x1 -= x0;
1084+ if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
1085+ if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
1086+ else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
1087+ } else { // (x1 >= x0)
1088+ // Clip x0 before we subtract it from x1 in case the clipping
1089+ // affects the representable area of the rectangle.
1090+ if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE;
1091+ else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE;
1092+ x1 -= x0;
1093+ // The only way x1 can be negative now is if we clipped
1094+ // x0 against MIN and x1 is less than MIN - in which case
1095+ // we want to leave the width negative since the result
1096+ // did not intersect the representable area.
1097+ if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE;
1098+ else if (x1 > Integer.MAX_VALUE) x1 = Integer.MAX_VALUE;
1099+ }
1100+
1101+ if (y1 < y0) {
1102+ // Non-existant in Y direction
1103+ y1 -= y0;
1104+ if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
1105+ if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
1106+ else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
1107+ } else { // (y1 >= y0)
1108+ if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE;
1109+ else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE;
1110+ y1 -= y0;
1111+ if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE;
1112+ else if (y1 > Integer.MAX_VALUE) y1 = Integer.MAX_VALUE;
1113+ }
1114+
1115+ reshape((int) x0, (int) y0, (int) x1, (int) y1);
1116+ }
1117+
1118+ /**
1119+ * {@inheritDoc}
1120+ * @since 1.2
1121+ */
1122+ public boolean isEmpty() {
1123+ return (width <= 0) || (height <= 0);
1124+ }
1125+
1126+ /**
1127+ * {@inheritDoc}
1128+ * @since 1.2
1129+ */
1130+ public int outcode(double x, double y) {
1131+ /*
1132+ * Note on casts to double below. If the arithmetic of
1133+ * x+w or y+h is done in int, then we may get integer
1134+ * overflow. By converting to double before the addition
1135+ * we force the addition to be carried out in double to
1136+ * avoid overflow in the comparison.
1137+ *
1138+ * See bug 4320890 for problems that this can cause.
1139+ */
1140+ int out = 0;
1141+ if (this.width <= 0) {
1142+ out |= OUT_LEFT | OUT_RIGHT;
1143+ } else if (x < this.x) {
1144+ out |= OUT_LEFT;
1145+ } else if (x > this.x + (double) this.width) {
1146+ out |= OUT_RIGHT;
1147+ }
1148+ if (this.height <= 0) {
1149+ out |= OUT_TOP | OUT_BOTTOM;
1150+ } else if (y < this.y) {
1151+ out |= OUT_TOP;
1152+ } else if (y > this.y + (double) this.height) {
1153+ out |= OUT_BOTTOM;
1154+ }
1155+ return out;
1156+ }
1157+
1158+ /**
1159+ * {@inheritDoc}
1160+ * @since 1.2
1161+ */
1162+ public Rectangle2D createIntersection(Rectangle2D r) {
1163+ if (r instanceof Rectangle) {
1164+ return intersection((Rectangle) r);
1165+ }
1166+ Rectangle2D dest = new Rectangle2D.Double();
1167+ Rectangle2D.intersect(this, r, dest);
1168+ return dest;
1169+ }
1170+
1171+ /**
1172+ * {@inheritDoc}
1173+ * @since 1.2
1174+ */
1175+ public Rectangle2D createUnion(Rectangle2D r) {
1176+ if (r instanceof Rectangle) {
1177+ return union((Rectangle) r);
1178+ }
1179+ Rectangle2D dest = new Rectangle2D.Double();
1180+ Rectangle2D.union(this, r, dest);
1181+ return dest;
1182+ }
1183+
1184+ /**
1185+ * Checks whether two rectangles are equal.
1186+ * <p>
1187+ * The result is <code>true</code> if and only if the argument is not
1188+ * <code>null</code> and is a <code>Rectangle</code> object that has the
1189+ * same upper-left corner, width, and height as
1190+ * this <code>Rectangle</code>.
1191+ * @param obj the <code>Object</code> to compare with
1192+ * this <code>Rectangle</code>
1193+ * @return <code>true</code> if the objects are equal;
1194+ * <code>false</code> otherwise.
1195+ */
1196+ public boolean equals(Object obj) {
1197+ if (obj instanceof Rectangle) {
1198+ Rectangle r = (Rectangle)obj;
1199+ return ((x == r.x) &&
1200+ (y == r.y) &&
1201+ (width == r.width) &&
1202+ (height == r.height));
1203+ }
1204+ return super.equals(obj);
1205+ }
1206+
1207+ /**
1208+ * Returns a <code>String</code> representing this
1209+ * <code>Rectangle</code> and its values.
1210+ * @return a <code>String</code> representing this
1211+ * <code>Rectangle</code> object's coordinate and size values.
1212+ */
1213+ public String toString() {
1214+ return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]";
1215+ }
1216+}