/mcs/class/System.Drawing/System.Drawing/Rectangle.cs

https://github.com/t-ashula/mono · C# · 631 lines · 245 code · 85 blank · 301 comment · 26 complexity · 07d5c2ad560f24ebf3aafcf7d3436ca8 MD5 · raw file

  1. //
  2. // System.Drawing.Rectangle.cs
  3. //
  4. // Author:
  5. // Mike Kestner (mkestner@speakeasy.net)
  6. //
  7. // Copyright (C) 2001 Mike Kestner
  8. // Copyright (C) 2004 Novell, Inc. http://www.novell.com
  9. //
  10. //
  11. // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System;
  33. using System.Runtime.InteropServices;
  34. using System.ComponentModel;
  35. namespace System.Drawing
  36. {
  37. [Serializable]
  38. [ComVisible (true)]
  39. [TypeConverter (typeof (RectangleConverter))]
  40. public struct Rectangle
  41. {
  42. private int x, y, width, height;
  43. /// <summary>
  44. /// Empty Shared Field
  45. /// </summary>
  46. ///
  47. /// <remarks>
  48. /// An uninitialized Rectangle Structure.
  49. /// </remarks>
  50. public static readonly Rectangle Empty;
  51. /// <summary>
  52. /// Ceiling Shared Method
  53. /// </summary>
  54. ///
  55. /// <remarks>
  56. /// Produces a Rectangle structure from a RectangleF
  57. /// structure by taking the ceiling of the X, Y, Width,
  58. /// and Height properties.
  59. /// </remarks>
  60. public static Rectangle Ceiling (RectangleF value)
  61. {
  62. int x, y, w, h;
  63. checked {
  64. x = (int) Math.Ceiling (value.X);
  65. y = (int) Math.Ceiling (value.Y);
  66. w = (int) Math.Ceiling (value.Width);
  67. h = (int) Math.Ceiling (value.Height);
  68. }
  69. return new Rectangle (x, y, w, h);
  70. }
  71. /// <summary>
  72. /// FromLTRB Shared Method
  73. /// </summary>
  74. ///
  75. /// <remarks>
  76. /// Produces a Rectangle structure from left, top, right,
  77. /// and bottom coordinates.
  78. /// </remarks>
  79. public static Rectangle FromLTRB (int left, int top,
  80. int right, int bottom)
  81. {
  82. return new Rectangle (left, top, right - left,
  83. bottom - top);
  84. }
  85. /// <summary>
  86. /// Inflate Shared Method
  87. /// </summary>
  88. ///
  89. /// <remarks>
  90. /// Produces a new Rectangle by inflating an existing
  91. /// Rectangle by the specified coordinate values.
  92. /// </remarks>
  93. public static Rectangle Inflate (Rectangle rect, int x, int y)
  94. {
  95. Rectangle r = new Rectangle (rect.Location, rect.Size);
  96. r.Inflate (x, y);
  97. return r;
  98. }
  99. /// <summary>
  100. /// Inflate Method
  101. /// </summary>
  102. ///
  103. /// <remarks>
  104. /// Inflates the Rectangle by a specified width and height.
  105. /// </remarks>
  106. public void Inflate (int width, int height)
  107. {
  108. Inflate (new Size (width, height));
  109. }
  110. /// <summary>
  111. /// Inflate Method
  112. /// </summary>
  113. ///
  114. /// <remarks>
  115. /// Inflates the Rectangle by a specified Size.
  116. /// </remarks>
  117. public void Inflate (Size size)
  118. {
  119. x -= size.Width;
  120. y -= size.Height;
  121. Width += size.Width * 2;
  122. Height += size.Height * 2;
  123. }
  124. /// <summary>
  125. /// Intersect Shared Method
  126. /// </summary>
  127. ///
  128. /// <remarks>
  129. /// Produces a new Rectangle by intersecting 2 existing
  130. /// Rectangles. Returns null if there is no intersection.
  131. /// </remarks>
  132. public static Rectangle Intersect (Rectangle a, Rectangle b)
  133. {
  134. // MS.NET returns a non-empty rectangle if the two rectangles
  135. // touch each other
  136. if (!a.IntersectsWithInclusive (b))
  137. return Empty;
  138. return Rectangle.FromLTRB (
  139. Math.Max (a.Left, b.Left),
  140. Math.Max (a.Top, b.Top),
  141. Math.Min (a.Right, b.Right),
  142. Math.Min (a.Bottom, b.Bottom));
  143. }
  144. /// <summary>
  145. /// Intersect Method
  146. /// </summary>
  147. ///
  148. /// <remarks>
  149. /// Replaces the Rectangle with the intersection of itself
  150. /// and another Rectangle.
  151. /// </remarks>
  152. public void Intersect (Rectangle rect)
  153. {
  154. this = Rectangle.Intersect (this, rect);
  155. }
  156. /// <summary>
  157. /// Round Shared Method
  158. /// </summary>
  159. ///
  160. /// <remarks>
  161. /// Produces a Rectangle structure from a RectangleF by
  162. /// rounding the X, Y, Width, and Height properties.
  163. /// </remarks>
  164. public static Rectangle Round (RectangleF value)
  165. {
  166. int x, y, w, h;
  167. checked {
  168. x = (int) Math.Round (value.X);
  169. y = (int) Math.Round (value.Y);
  170. w = (int) Math.Round (value.Width);
  171. h = (int) Math.Round (value.Height);
  172. }
  173. return new Rectangle (x, y, w, h);
  174. }
  175. /// <summary>
  176. /// Truncate Shared Method
  177. /// </summary>
  178. ///
  179. /// <remarks>
  180. /// Produces a Rectangle structure from a RectangleF by
  181. /// truncating the X, Y, Width, and Height properties.
  182. /// </remarks>
  183. // LAMESPEC: Should this be floor, or a pure cast to int?
  184. public static Rectangle Truncate (RectangleF value)
  185. {
  186. int x, y, w, h;
  187. checked {
  188. x = (int) value.X;
  189. y = (int) value.Y;
  190. w = (int) value.Width;
  191. h = (int) value.Height;
  192. }
  193. return new Rectangle (x, y, w, h);
  194. }
  195. /// <summary>
  196. /// Union Shared Method
  197. /// </summary>
  198. ///
  199. /// <remarks>
  200. /// Produces a new Rectangle from the union of 2 existing
  201. /// Rectangles.
  202. /// </remarks>
  203. public static Rectangle Union (Rectangle a, Rectangle b)
  204. {
  205. return FromLTRB (Math.Min (a.Left, b.Left),
  206. Math.Min (a.Top, b.Top),
  207. Math.Max (a.Right, b.Right),
  208. Math.Max (a.Bottom, b.Bottom));
  209. }
  210. /// <summary>
  211. /// Equality Operator
  212. /// </summary>
  213. ///
  214. /// <remarks>
  215. /// Compares two Rectangle objects. The return value is
  216. /// based on the equivalence of the Location and Size
  217. /// properties of the two Rectangles.
  218. /// </remarks>
  219. public static bool operator == (Rectangle left, Rectangle right)
  220. {
  221. return ((left.Location == right.Location) &&
  222. (left.Size == right.Size));
  223. }
  224. /// <summary>
  225. /// Inequality Operator
  226. /// </summary>
  227. ///
  228. /// <remarks>
  229. /// Compares two Rectangle objects. The return value is
  230. /// based on the equivalence of the Location and Size
  231. /// properties of the two Rectangles.
  232. /// </remarks>
  233. public static bool operator != (Rectangle left, Rectangle right)
  234. {
  235. return ((left.Location != right.Location) ||
  236. (left.Size != right.Size));
  237. }
  238. // -----------------------
  239. // Public Constructors
  240. // -----------------------
  241. /// <summary>
  242. /// Rectangle Constructor
  243. /// </summary>
  244. ///
  245. /// <remarks>
  246. /// Creates a Rectangle from Point and Size values.
  247. /// </remarks>
  248. public Rectangle (Point location, Size size)
  249. {
  250. x = location.X;
  251. y = location.Y;
  252. width = size.Width;
  253. height = size.Height;
  254. }
  255. /// <summary>
  256. /// Rectangle Constructor
  257. /// </summary>
  258. ///
  259. /// <remarks>
  260. /// Creates a Rectangle from a specified x,y location and
  261. /// width and height values.
  262. /// </remarks>
  263. public Rectangle (int x, int y, int width, int height)
  264. {
  265. this.x = x;
  266. this.y = y;
  267. this.width = width;
  268. this.height = height;
  269. }
  270. /// <summary>
  271. /// Bottom Property
  272. /// </summary>
  273. ///
  274. /// <remarks>
  275. /// The Y coordinate of the bottom edge of the Rectangle.
  276. /// Read only.
  277. /// </remarks>
  278. [Browsable (false)]
  279. public int Bottom {
  280. get {
  281. return y + height;
  282. }
  283. }
  284. /// <summary>
  285. /// Height Property
  286. /// </summary>
  287. ///
  288. /// <remarks>
  289. /// The Height of the Rectangle.
  290. /// </remarks>
  291. public int Height {
  292. get {
  293. return height;
  294. }
  295. set {
  296. height = value;
  297. }
  298. }
  299. /// <summary>
  300. /// IsEmpty Property
  301. /// </summary>
  302. ///
  303. /// <remarks>
  304. /// Indicates if the width or height are zero. Read only.
  305. /// </remarks>
  306. [Browsable (false)]
  307. public bool IsEmpty {
  308. get {
  309. return ((x == 0) && (y == 0) && (width == 0) && (height == 0));
  310. }
  311. }
  312. /// <summary>
  313. /// Left Property
  314. /// </summary>
  315. ///
  316. /// <remarks>
  317. /// The X coordinate of the left edge of the Rectangle.
  318. /// Read only.
  319. /// </remarks>
  320. [Browsable (false)]
  321. public int Left {
  322. get {
  323. return X;
  324. }
  325. }
  326. /// <summary>
  327. /// Location Property
  328. /// </summary>
  329. ///
  330. /// <remarks>
  331. /// The Location of the top-left corner of the Rectangle.
  332. /// </remarks>
  333. [Browsable (false)]
  334. public Point Location {
  335. get {
  336. return new Point (x, y);
  337. }
  338. set {
  339. x = value.X;
  340. y = value.Y;
  341. }
  342. }
  343. /// <summary>
  344. /// Right Property
  345. /// </summary>
  346. ///
  347. /// <remarks>
  348. /// The X coordinate of the right edge of the Rectangle.
  349. /// Read only.
  350. /// </remarks>
  351. [Browsable (false)]
  352. public int Right {
  353. get {
  354. return X + Width;
  355. }
  356. }
  357. /// <summary>
  358. /// Size Property
  359. /// </summary>
  360. ///
  361. /// <remarks>
  362. /// The Size of the Rectangle.
  363. /// </remarks>
  364. [Browsable (false)]
  365. public Size Size {
  366. get {
  367. return new Size (Width, Height);
  368. }
  369. set {
  370. Width = value.Width;
  371. Height = value.Height;
  372. }
  373. }
  374. /// <summary>
  375. /// Top Property
  376. /// </summary>
  377. ///
  378. /// <remarks>
  379. /// The Y coordinate of the top edge of the Rectangle.
  380. /// Read only.
  381. /// </remarks>
  382. [Browsable (false)]
  383. public int Top {
  384. get {
  385. return y;
  386. }
  387. }
  388. /// <summary>
  389. /// Width Property
  390. /// </summary>
  391. ///
  392. /// <remarks>
  393. /// The Width of the Rectangle.
  394. /// </remarks>
  395. public int Width {
  396. get {
  397. return width;
  398. }
  399. set {
  400. width = value;
  401. }
  402. }
  403. /// <summary>
  404. /// X Property
  405. /// </summary>
  406. ///
  407. /// <remarks>
  408. /// The X coordinate of the Rectangle.
  409. /// </remarks>
  410. public int X {
  411. get {
  412. return x;
  413. }
  414. set {
  415. x = value;
  416. }
  417. }
  418. /// <summary>
  419. /// Y Property
  420. /// </summary>
  421. ///
  422. /// <remarks>
  423. /// The Y coordinate of the Rectangle.
  424. /// </remarks>
  425. public int Y {
  426. get {
  427. return y;
  428. }
  429. set {
  430. y = value;
  431. }
  432. }
  433. /// <summary>
  434. /// Contains Method
  435. /// </summary>
  436. ///
  437. /// <remarks>
  438. /// Checks if an x,y coordinate lies within this Rectangle.
  439. /// </remarks>
  440. public bool Contains (int x, int y)
  441. {
  442. return ((x >= Left) && (x < Right) &&
  443. (y >= Top) && (y < Bottom));
  444. }
  445. /// <summary>
  446. /// Contains Method
  447. /// </summary>
  448. ///
  449. /// <remarks>
  450. /// Checks if a Point lies within this Rectangle.
  451. /// </remarks>
  452. public bool Contains (Point pt)
  453. {
  454. return Contains (pt.X, pt.Y);
  455. }
  456. /// <summary>
  457. /// Contains Method
  458. /// </summary>
  459. ///
  460. /// <remarks>
  461. /// Checks if a Rectangle lies entirely within this
  462. /// Rectangle.
  463. /// </remarks>
  464. public bool Contains (Rectangle rect)
  465. {
  466. return (rect == Intersect (this, rect));
  467. }
  468. /// <summary>
  469. /// Equals Method
  470. /// </summary>
  471. ///
  472. /// <remarks>
  473. /// Checks equivalence of this Rectangle and another object.
  474. /// </remarks>
  475. public override bool Equals (object obj)
  476. {
  477. if (!(obj is Rectangle))
  478. return false;
  479. return (this == (Rectangle) obj);
  480. }
  481. /// <summary>
  482. /// GetHashCode Method
  483. /// </summary>
  484. ///
  485. /// <remarks>
  486. /// Calculates a hashing value.
  487. /// </remarks>
  488. public override int GetHashCode ()
  489. {
  490. return (height + width) ^ x + y;
  491. }
  492. /// <summary>
  493. /// IntersectsWith Method
  494. /// </summary>
  495. ///
  496. /// <remarks>
  497. /// Checks if a Rectangle intersects with this one.
  498. /// </remarks>
  499. public bool IntersectsWith (Rectangle rect)
  500. {
  501. return !((Left >= rect.Right) || (Right <= rect.Left) ||
  502. (Top >= rect.Bottom) || (Bottom <= rect.Top));
  503. }
  504. private bool IntersectsWithInclusive (Rectangle r)
  505. {
  506. return !((Left > r.Right) || (Right < r.Left) ||
  507. (Top > r.Bottom) || (Bottom < r.Top));
  508. }
  509. /// <summary>
  510. /// Offset Method
  511. /// </summary>
  512. ///
  513. /// <remarks>
  514. /// Moves the Rectangle a specified distance.
  515. /// </remarks>
  516. public void Offset (int x, int y)
  517. {
  518. this.x += x;
  519. this.y += y;
  520. }
  521. /// <summary>
  522. /// Offset Method
  523. /// </summary>
  524. ///
  525. /// <remarks>
  526. /// Moves the Rectangle a specified distance.
  527. /// </remarks>
  528. public void Offset (Point pos)
  529. {
  530. x += pos.X;
  531. y += pos.Y;
  532. }
  533. /// <summary>
  534. /// ToString Method
  535. /// </summary>
  536. ///
  537. /// <remarks>
  538. /// Formats the Rectangle as a string in (x,y,w,h) notation.
  539. /// </remarks>
  540. public override string ToString ()
  541. {
  542. return String.Format ("{{X={0},Y={1},Width={2},Height={3}}}",
  543. x, y, width, height);
  544. }
  545. }
  546. }