Rectangle.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. /* Rectangle.java -- represents a graphics rectangle
  2. Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package java.awt;
  32. import java.awt.geom.AffineTransform;
  33. import java.awt.geom.Rectangle2D;
  34. import java.io.Serializable;
  35. /**
  36. * This class represents a rectangle and all the interesting things you
  37. * might want to do with it. Note that the coordinate system uses
  38. * the origin (0,0) as the top left of the screen, with the x and y
  39. * values increasing as they move to the right and down respectively.
  40. *
  41. * <p>It is valid for a rectangle to have negative width or height; but it
  42. * is considered to have no area or internal points. Therefore, the behavior
  43. * in methods like <code>contains</code> or <code>intersects</code> is
  44. * undefined unless the rectangle has positive width and height.
  45. *
  46. * <p>There are some public fields; if you mess with them in an inconsistent
  47. * manner, it is your own fault when you get NullPointerException,
  48. * ArrayIndexOutOfBoundsException, or invalid results. Also, this class is
  49. * not threadsafe.
  50. *
  51. * @author Warren Levy <warrenl@cygnus.com>
  52. * @author Aaron M. Renn <arenn@urbanophile.com>
  53. * @author Eric Blake <ebb9@email.byu.edu>
  54. * @since 1.0
  55. * @status updated to 1.4
  56. */
  57. public class Rectangle extends Rectangle2D implements Shape, Serializable
  58. {
  59. /**
  60. * Compatible with JDK 1.0+.
  61. */
  62. private static final long serialVersionUID = -4345857070255674764L;
  63. /**
  64. * The X coordinate of the top-left corner of the rectangle.
  65. *
  66. * @see #setLocation(int, int)
  67. * @see #getLocation()
  68. * @serial the x coordinate
  69. */
  70. public int x;
  71. /**
  72. * The Y coordinate of the top-left corner of the rectangle.
  73. *
  74. * @see #setLocation(int, int)
  75. * @see #getLocation()
  76. * @serial the y coordinate
  77. */
  78. public int y;
  79. /**
  80. * The width of the rectangle.
  81. *
  82. * @see #setSize(int, int)
  83. * @see #getSize()
  84. * @serial
  85. */
  86. public int width;
  87. /**
  88. * The height of the rectangle.
  89. *
  90. * @see #setSize(int, int)
  91. * @see #getSize()
  92. * @serial
  93. */
  94. public int height;
  95. /**
  96. * Initializes a new instance of <code>Rectangle</code> with a top
  97. * left corner at (0,0) and a width and height of 0.
  98. */
  99. public Rectangle()
  100. {
  101. }
  102. /**
  103. * Initializes a new instance of <code>Rectangle</code> from the
  104. * coordinates of the specified rectangle.
  105. *
  106. * @param r the rectangle to copy from
  107. * @throws NullPointerException if r is null
  108. * @since 1.1
  109. */
  110. public Rectangle(Rectangle r)
  111. {
  112. x = r.x;
  113. y = r.y;
  114. width = r.width;
  115. height = r.height;
  116. }
  117. /**
  118. * Initializes a new instance of <code>Rectangle</code> from the specified
  119. * inputs.
  120. *
  121. * @param x the X coordinate of the top left corner
  122. * @param y the Y coordinate of the top left corner
  123. * @param width the width of the rectangle
  124. * @param height the height of the rectangle
  125. */
  126. public Rectangle(int x, int y, int width, int height)
  127. {
  128. this.x = x;
  129. this.y = y;
  130. this.width = width;
  131. this.height = height;
  132. }
  133. /**
  134. * Initializes a new instance of <code>Rectangle</code> with the specified
  135. * width and height. The upper left corner of the rectangle will be at
  136. * the origin (0,0).
  137. *
  138. * @param width the width of the rectangle
  139. * @param height the height of the rectange
  140. */
  141. public Rectangle(int width, int height)
  142. {
  143. this.width = width;
  144. this.height = height;
  145. }
  146. /**
  147. * Initializes a new instance of <code>Rectangle</code> with a top-left
  148. * corner represented by the specified point and the width and height
  149. * represented by the specified dimension.
  150. *
  151. * @param p the upper left corner of the rectangle
  152. * @param d the width and height of the rectangle
  153. * @throws NullPointerException if p or d is null
  154. */
  155. public Rectangle(Point p, Dimension d)
  156. {
  157. x = p.x;
  158. y = p.y;
  159. width = d.width;
  160. height = d.height;
  161. }
  162. /**
  163. * Initializes a new instance of <code>Rectangle</code> with a top left
  164. * corner at the specified point and a width and height of zero.
  165. *
  166. * @param p the upper left corner of the rectangle
  167. */
  168. public Rectangle(Point p)
  169. {
  170. x = p.x;
  171. y = p.y;
  172. }
  173. /**
  174. * Initializes a new instance of <code>Rectangle</code> with an
  175. * upper left corner at the origin (0,0) and a width and height represented
  176. * by the specified dimension.
  177. *
  178. * @param d the width and height of the rectangle
  179. */
  180. public Rectangle(Dimension d)
  181. {
  182. width = d.width;
  183. height = d.height;
  184. }
  185. /**
  186. * Get the X coordinate of the upper-left corner.
  187. *
  188. * @return the value of x, as a double
  189. */
  190. public double getX()
  191. {
  192. return x;
  193. }
  194. /**
  195. * Get the Y coordinate of the upper-left corner.
  196. *
  197. * @return the value of y, as a double
  198. */
  199. public double getY()
  200. {
  201. return y;
  202. }
  203. /**
  204. * Get the width of the rectangle.
  205. *
  206. * @return the value of width, as a double
  207. */
  208. public double getWidth()
  209. {
  210. return width;
  211. }
  212. /**
  213. * Get the height of the rectangle.
  214. *
  215. * @return the value of height, as a double
  216. */
  217. public double getHeight()
  218. {
  219. return height;
  220. }
  221. /**
  222. * Returns the bounds of this rectangle. A pretty useless method, as this
  223. * is already a rectangle; it is included to mimic the
  224. * <code>getBounds</code> method in Component.
  225. *
  226. * @return a copy of this rectangle
  227. * @see #setBounds(Rectangle)
  228. * @since 1.1
  229. */
  230. public Rectangle getBounds()
  231. {
  232. return new Rectangle(this);
  233. }
  234. /**
  235. * Returns the high-precision bounds of this rectangle. A pretty useless
  236. * method, as this is already a rectangle.
  237. *
  238. * @return a copy of this rectangle
  239. * @see #setBounds(Rectangle)
  240. * @since 1.2
  241. */
  242. public Rectangle2D getBounds2D()
  243. {
  244. return new Rectangle(x, y, width, height);
  245. }
  246. /**
  247. * Updates this rectangle to match the dimensions of the specified
  248. * rectangle.
  249. *
  250. * @param r the rectangle to update from
  251. * @throws NullPointerException if r is null
  252. * @see #setBounds(int, int, int, int)
  253. * @since 1.1
  254. */
  255. public void setBounds(Rectangle r)
  256. {
  257. x = r.x;
  258. y = r.y;
  259. width = r.width;
  260. height = r.height;
  261. }
  262. /**
  263. * Updates this rectangle to have the specified dimensions.
  264. *
  265. * @param x the new X coordinate of the upper left hand corner
  266. * @param y the new Y coordinate of the upper left hand corner
  267. * @param width the new width of this rectangle
  268. * @param height the new height of this rectangle
  269. * @since 1.1
  270. */
  271. public void setBounds(int x, int y, int width, int height)
  272. {
  273. this.x = x;
  274. this.y = y;
  275. this.width = width;
  276. this.height = height;
  277. }
  278. /**
  279. * Updates this rectangle to have the specified dimensions, as rounded to
  280. * integers.
  281. *
  282. * @param x the new X coordinate of the upper left hand corner
  283. * @param y the new Y coordinate of the upper left hand corner
  284. * @param width the new width of this rectangle
  285. * @param height the new height of this rectangle
  286. * @since 1.2
  287. */
  288. public void setRect(double x, double y, double width, double height)
  289. {
  290. this.x = (int) x;
  291. this.y = (int) y;
  292. this.width = (int) width;
  293. this.height = (int) height;
  294. }
  295. /**
  296. * Updates this rectangle to have the specified dimensions.
  297. *
  298. * @param x the new X coordinate of the upper left hand corner
  299. * @param y the new Y coordinate of the upper left hand corner
  300. * @param width the new width of this rectangle
  301. * @param height the new height of this rectangle
  302. * @deprecated use {@link #setBounds(int, int, int, int)} instead
  303. */
  304. public void reshape(int x, int y, int width, int height)
  305. {
  306. setBounds(x, y, width, height);
  307. }
  308. /**
  309. * Returns the location of this rectangle, which is the coordinates of
  310. * its upper left corner.
  311. *
  312. * @return the point where this rectangle is located
  313. * @see setLocation(Point)
  314. * @since 1.1
  315. */
  316. public Point getLocation()
  317. {
  318. return new Point(x,y);
  319. }
  320. /**
  321. * Moves the location of this rectangle by setting its upper left
  322. * corner to the specified point.
  323. *
  324. * @param p the point to move the rectangle to
  325. * @throws NullPointerException if p is null
  326. * @see #getLocation()
  327. * @since 1.1
  328. */
  329. public void setLocation(Point p)
  330. {
  331. this.x = p.x;
  332. this.y = p.y;
  333. }
  334. /**
  335. * Moves the location of this rectangle by setting its upper left
  336. * corner to the specified coordinates.
  337. *
  338. * @param x the new X coordinate for this rectangle
  339. * @param y the new Y coordinate for this rectangle
  340. * @since 1.1
  341. */
  342. public void setLocation(int x, int y)
  343. {
  344. this.x = x;
  345. this.y = y;
  346. }
  347. /**
  348. * Moves the location of this rectangle by setting its upper left
  349. * corner to the specified coordinates.
  350. *
  351. * @param x the new X coordinate for this rectangle
  352. * @param y the new Y coordinate for this rectangle
  353. * @deprecated use {@link #setLocation(int, int)} instead
  354. */
  355. public void move(int x, int y)
  356. {
  357. setLocation(x, y);
  358. }
  359. /**
  360. * Translate the location of this rectangle by the given amounts.
  361. *
  362. * @param dx the x distance to move by
  363. * @param dy the y distance to move by
  364. * @see #setLocation(int, int)
  365. */
  366. public void translate(int dx, int dy)
  367. {
  368. x += dx;
  369. y += dy;
  370. }
  371. /**
  372. * Returns the size of this rectangle.
  373. *
  374. * @return the size of this rectangle
  375. * @see #setSize(Dimension)
  376. * @since 1.1
  377. */
  378. public Dimension getSize()
  379. {
  380. return new Dimension(width, height);
  381. }
  382. /**
  383. * Sets the size of this rectangle based on the specified dimensions.
  384. *
  385. * @param d the new dimensions of the rectangle
  386. * @throws NullPointerException if d is null
  387. * @see #getSize()
  388. * @since 1.1
  389. */
  390. public void setSize(Dimension d)
  391. {
  392. width = d.width;
  393. height = d.height;
  394. }
  395. /**
  396. * Sets the size of this rectangle based on the specified dimensions.
  397. *
  398. * @param width the new width of the rectangle
  399. * @param height the new height of the rectangle
  400. * @since 1.1
  401. */
  402. public void setSize(int width, int height)
  403. {
  404. this.width = width;
  405. this.height = height;
  406. }
  407. /**
  408. * Sets the size of this rectangle based on the specified dimensions.
  409. *
  410. * @param width the new width of the rectangle
  411. * @param height the new height of the rectangle
  412. * @deprecated use {@link #setSize(int, int)} instead
  413. */
  414. public void resize(int width, int height)
  415. {
  416. setSize(width, height);
  417. }
  418. /**
  419. * Tests whether or not the specified point is inside this rectangle.
  420. * According to the contract of Shape, a point on the border is in only if
  421. * it has an adjacent point inside the rectangle in either the increasing
  422. * x or y direction.
  423. *
  424. * @param p the point to test
  425. * @return true if the point is inside the rectangle
  426. * @throws NullPointerException if p is null
  427. * @see #contains(int, int)
  428. * @since 1.1
  429. */
  430. public boolean contains(Point p)
  431. {
  432. return width > 0 && height > 0
  433. && p.x >= x && p.x < x + width
  434. && p.y >= y && p.y < y + height;
  435. }
  436. /**
  437. * Tests whether or not the specified point is inside this rectangle.
  438. * According to the contract of Shape, a point on the border is in only if
  439. * it has an adjacent point inside the rectangle in either the increasing
  440. * x or y direction.
  441. *
  442. * @param x the X coordinate of the point to test
  443. * @param y the Y coordinate of the point to test
  444. * @return true if the point is inside the rectangle
  445. * @since 1.1
  446. */
  447. public boolean contains(int x, int y)
  448. {
  449. return width > 0 && height > 0
  450. && x >= this.x && x < this.x + width
  451. && y >= this.y && y < this.y + height;
  452. }
  453. /**
  454. * Checks whether all points in the given rectangle are contained in this
  455. * rectangle.
  456. *
  457. * @param r the rectangle to check
  458. * @return true if r is contained in this rectangle
  459. * @throws NullPointerException if r is null
  460. * @see #contains(int, int, int, int)
  461. * @since 1.1
  462. */
  463. public boolean contains(Rectangle r)
  464. {
  465. return width > 0 && height > 0 && r.width > 0 && r.height > 0
  466. && r.x >= x && r.x + r.width <= x + width
  467. && r.y >= y && r.y + r.height <= y + height;
  468. }
  469. /**
  470. * Checks whether all points in the given rectangle are contained in this
  471. * rectangle.
  472. *
  473. * @param x the x coordinate of the rectangle to check
  474. * @param y the y coordinate of the rectangle to check
  475. * @param w the width of the rectangle to check
  476. * @param h the height of the rectangle to check
  477. * @return true if the parameters are contained in this rectangle
  478. * @since 1.1
  479. */
  480. public boolean contains(int x, int y, int w, int h)
  481. {
  482. return width > 0 && height > 0 && w > 0 && h > 0
  483. && x >= this.x && x + w <= this.x + this.width
  484. && y >= this.y && y + h <= this.y + this.height;
  485. }
  486. /**
  487. * Tests whether or not the specified point is inside this rectangle.
  488. *
  489. * @param x the X coordinate of the point to test
  490. * @param y the Y coordinate of the point to test
  491. * @return true if the point is inside the rectangle
  492. * @deprecated use {@link #contains(int, int)} instead
  493. */
  494. public boolean inside(int x, int y)
  495. {
  496. return contains(x, y);
  497. }
  498. /**
  499. * Tests whether or not the specified rectangle intersects this rectangle.
  500. * This means the two rectangles share at least one internal point.
  501. *
  502. * @param r the rectangle to test against
  503. * @return true if the specified rectangle intersects this one
  504. * @throws NullPointerException if r is null
  505. * @since 1.2
  506. */
  507. public boolean intersects(Rectangle r)
  508. {
  509. return width > 0 && height > 0 && r.width > 0 && r.height > 0
  510. && r.x < x + width && r.x + r.width > x
  511. && r.y < y + height && r.y + r.height > y;
  512. }
  513. /**
  514. * Determines the rectangle which is formed by the intersection of this
  515. * rectangle with the specified rectangle. If the two do not intersect,
  516. * an empty rectangle will be returned (meaning the width and/or height
  517. * will be non-positive).
  518. *
  519. * @param r the rectange to calculate the intersection with
  520. * @return a new rectangle bounding the intersection
  521. * @throws NullPointerException if r is null
  522. */
  523. public Rectangle intersection(Rectangle r)
  524. {
  525. Rectangle res = new Rectangle();
  526. intersect(this, r, res);
  527. return res;
  528. }
  529. /**
  530. * Returns the smallest rectangle that contains both this rectangle
  531. * and the specified rectangle.
  532. *
  533. * @param r the rectangle to compute the union with
  534. * @return the smallest rectangle containing both rectangles
  535. * @throws NullPointerException if r is null
  536. */
  537. public Rectangle union(Rectangle r)
  538. {
  539. Rectangle res = new Rectangle();
  540. union(this, r, res);
  541. return res;
  542. }
  543. /**
  544. * Modifies this rectangle so that it represents the smallest rectangle
  545. * that contains both the existing rectangle and the specified point.
  546. * However, if the point falls on one of the two borders which are not
  547. * inside the rectangle, a subsequent call to <code>contains</code> may
  548. * return false.
  549. *
  550. * @param x the X coordinate of the point to add to this rectangle
  551. * @param y the Y coordinate of the point to add to this rectangle
  552. */
  553. public void add(int x, int y)
  554. {
  555. add((double) x, (double) y);
  556. }
  557. /**
  558. * Modifies this rectangle so that it represents the smallest rectangle
  559. * that contains both the existing rectangle and the specified point.
  560. * However, if the point falls on one of the two borders which are not
  561. * inside the rectangle, a subsequent call to <code>contains</code> may
  562. * return false.
  563. *
  564. * @param p the point to add to this rectangle
  565. * @throws NullPointerException if p is null
  566. */
  567. public void add(Point p)
  568. {
  569. add((double) p.x, (double) p.y);
  570. }
  571. /**
  572. * Modifies this rectangle so that it represents the smallest rectangle
  573. * that contains both the existing rectangle and the specified rectangle.
  574. *
  575. * @param r the rectangle to add to this rectangle
  576. * @throws NullPointerException if r is null
  577. * @see #union(Rectangle)
  578. */
  579. public void add(Rectangle r)
  580. {
  581. union(this, r, this);
  582. }
  583. /**
  584. * Expands the rectangle by the specified amount. The horizontal
  585. * and vertical expansion values are applied both to the X,Y coordinate
  586. * of this rectangle, and its width and height. Thus the width and
  587. * height will increase by 2h and 2v accordingly.
  588. *
  589. * @param h the horizontal expansion value
  590. * @param v the vertical expansion value
  591. */
  592. public void grow(int h, int v)
  593. {
  594. x -= h;
  595. y -= v;
  596. width += h + h;
  597. height += v + v;
  598. }
  599. /**
  600. * Tests whether or not this rectangle is empty. An empty rectangle
  601. * has a non-positive width or height.
  602. *
  603. * @return true if the rectangle is empty
  604. */
  605. public boolean isEmpty()
  606. {
  607. return width <= 0 || height <= 0;
  608. }
  609. /**
  610. * Determine where the point lies with respect to this rectangle. The
  611. * result will be the binary OR of the appropriate bit masks.
  612. *
  613. * @param x the x coordinate to check
  614. * @param y the y coordinate to check
  615. * @return the binary OR of the result
  616. * @see #OUT_LEFT
  617. * @see #OUT_TOP
  618. * @see #OUT_RIGHT
  619. * @see #OUT_BOTTOM
  620. * @since 1.2
  621. */
  622. public int outcode(double x, double y)
  623. {
  624. int result = 0;
  625. if (width <= 0)
  626. result |= OUT_LEFT | OUT_RIGHT;
  627. else if (x < this.x)
  628. result |= OUT_LEFT;
  629. else if (x > this.x + width)
  630. result |= OUT_RIGHT;
  631. if (height <= 0)
  632. result |= OUT_BOTTOM | OUT_TOP;
  633. else if (y < this.y) // Remember that +y heads top-to-bottom.
  634. result |= OUT_TOP;
  635. else if (y > this.y + height)
  636. result |= OUT_BOTTOM;
  637. return result;
  638. }
  639. /**
  640. * Determines the rectangle which is formed by the intersection of this
  641. * rectangle with the specified rectangle. If the two do not intersect,
  642. * an empty rectangle will be returned (meaning the width and/or height
  643. * will be non-positive).
  644. *
  645. * @param r the rectange to calculate the intersection with
  646. * @return a new rectangle bounding the intersection
  647. * @throws NullPointerException if r is null
  648. * @since 1.2
  649. */
  650. public Rectangle2D createIntersection(Rectangle2D r)
  651. {
  652. // Favor runtime type of other rectangle.
  653. Rectangle2D res = r.getBounds2D();
  654. intersect(this, r, res);
  655. return res;
  656. }
  657. /**
  658. * Returns the smallest rectangle that contains both this rectangle
  659. * and the specified rectangle.
  660. *
  661. * @param r the rectangle to compute the union with
  662. * @return the smallest rectangle containing both rectangles
  663. * @throws NullPointerException if r is null
  664. * @since 1.2
  665. */
  666. public Rectangle2D createUnion(Rectangle2D r)
  667. {
  668. // Favor runtime type of other rectangle.
  669. Rectangle2D res = r.getBounds2D();
  670. union(this, r, res);
  671. return res;
  672. }
  673. /**
  674. * Tests this rectangle for equality against the specified object. This
  675. * will be true if an only if the specified object is an instance of
  676. * Rectangle2D with the same coordinates and dimensions.
  677. *
  678. * @param obj the object to test against for equality
  679. * @return true if the specified object is equal to this one
  680. */
  681. public boolean equals(Object obj)
  682. {
  683. if (! (obj instanceof Rectangle2D))
  684. return false;
  685. Rectangle2D r = (Rectangle2D) obj;
  686. return r.getX() == x && r.getY() == y
  687. && r.getWidth() == width && r.getHeight() == height;
  688. }
  689. /**
  690. * Returns a string representation of this rectangle. This is in the form
  691. * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width
  692. * + ",height=" + height + ']'</code>.
  693. *
  694. * @return a string representation of this rectangle
  695. */
  696. public String toString()
  697. {
  698. return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width
  699. + ",height=" + height + ']';
  700. }
  701. } // class Rectangle