1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.ComponentModel;
6 using System.Numerics.Hashing;
7 
8 namespace System.Drawing
9 {
10     /**
11      * Represents a dimension in 2D coordinate space
12      */
13     /// <summary>
14     ///    Represents the size of a rectangular region
15     ///    with an ordered pair of width and height.
16     /// </summary>
17     [Serializable]
18 #if !MONO
19     [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
20 #endif
21     public struct Size : IEquatable<Size>
22     {
23         /// <summary>
24         ///    Initializes a new instance of the <see cref='System.Drawing.Size'/> class.
25         /// </summary>
26         public static readonly Size Empty = new Size();
27 
28         private int width; // Do not rename (binary serialization)
29         private int height; // Do not rename (binary serialization)
30 
31         /**
32          * Create a new Size object from a point
33          */
34         /// <summary>
35         ///    <para>
36         ///       Initializes a new instance of the <see cref='System.Drawing.Size'/> class from
37         ///       the specified <see cref='System.Drawing.Point'/>.
38         ///    </para>
39         /// </summary>
SizeSystem.Drawing.Size40         public Size(Point pt)
41         {
42             width = pt.X;
43             height = pt.Y;
44         }
45 
46         /**
47          * Create a new Size object of the specified dimension
48          */
49         /// <summary>
50         ///    Initializes a new instance of the <see cref='System.Drawing.Size'/> class from
51         ///    the specified dimensions.
52         /// </summary>
SizeSystem.Drawing.Size53         public Size(int width, int height)
54         {
55             this.width = width;
56             this.height = height;
57         }
58 
59         /// <summary>
60         ///    Converts the specified <see cref='System.Drawing.Size'/> to a
61         /// <see cref='System.Drawing.SizeF'/>.
62         /// </summary>
63         public static implicit operator SizeF(Size p) => new SizeF(p.Width, p.Height);
64 
65         /// <summary>
66         ///    <para>
67         ///       Performs vector addition of two <see cref='System.Drawing.Size'/> objects.
68         ///    </para>
69         /// </summary>
operator +System.Drawing.Size70         public static Size operator +(Size sz1, Size sz2) => Add(sz1, sz2);
71 
72         /// <summary>
73         ///    <para>
74         ///       Contracts a <see cref='System.Drawing.Size'/> by another <see cref='System.Drawing.Size'/>
75         ///    </para>
76         /// </summary>
operator -System.Drawing.Size77         public static Size operator -(Size sz1, Size sz2) => Subtract(sz1, sz2);
78 
79         /// <summary>
80         /// Multiplies a <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
81         /// </summary>
82         /// <param name="left">Multiplier of type <see cref="int"/>.</param>
83         /// <param name="right">Multiplicand of type <see cref="Size"/>.</param>
84         /// <returns>Product of type <see cref="Size"/>.</returns>
operator *System.Drawing.Size85         public static Size operator *(int left, Size right) => Multiply(right, left);
86 
87         /// <summary>
88         /// Multiplies <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
89         /// </summary>
90         /// <param name="left">Multiplicand of type <see cref="Size"/>.</param>
91         /// <param name="right">Multiplier of type <see cref="int"/>.</param>
92         /// <returns>Product of type <see cref="Size"/>.</returns>
operator *System.Drawing.Size93         public static Size operator *(Size left, int right) => Multiply(left, right);
94 
95         /// <summary>
96         /// Divides <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
97         /// </summary>
98         /// <param name="left">Dividend of type <see cref="Size"/>.</param>
99         /// <param name="right">Divisor of type <see cref="int"/>.</param>
100         /// <returns>Result of type <see cref="Size"/>.</returns>
operator /System.Drawing.Size101         public static Size operator /(Size left, int right) => new Size(unchecked(left.width / right), unchecked(left.height / right));
102 
103         /// <summary>
104         /// Multiplies <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
105         /// </summary>
106         /// <param name="left">Multiplier of type <see cref="float"/>.</param>
107         /// <param name="right">Multiplicand of type <see cref="Size"/>.</param>
108         /// <returns>Product of type <see cref="SizeF"/>.</returns>
operator *System.Drawing.Size109         public static SizeF operator *(float left, Size right) => Multiply(right, left);
110 
111         /// <summary>
112         /// Multiplies <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
113         /// </summary>
114         /// <param name="left">Multiplicand of type <see cref="Size"/>.</param>
115         /// <param name="right">Multiplier of type <see cref="float"/>.</param>
116         /// <returns>Product of type <see cref="SizeF"/>.</returns>
operator *System.Drawing.Size117         public static SizeF operator *(Size left, float right) => Multiply(left, right);
118 
119         /// <summary>
120         /// Divides <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
121         /// </summary>
122         /// <param name="left">Dividend of type <see cref="Size"/>.</param>
123         /// <param name="right">Divisor of type <see cref="int"/>.</param>
124         /// <returns>Result of type <see cref="SizeF"/>.</returns>
operator /System.Drawing.Size125         public static SizeF operator /(Size left, float right)
126             => new SizeF(left.width / right, left.height / right);
127 
128         /// <summary>
129         ///    Tests whether two <see cref='System.Drawing.Size'/> objects
130         ///    are identical.
131         /// </summary>
operator ==System.Drawing.Size132         public static bool operator ==(Size sz1, Size sz2) => sz1.Width == sz2.Width && sz1.Height == sz2.Height;
133 
134         /// <summary>
135         ///    <para>
136         ///       Tests whether two <see cref='System.Drawing.Size'/> objects are different.
137         ///    </para>
138         /// </summary>
operator !=System.Drawing.Size139         public static bool operator !=(Size sz1, Size sz2) => !(sz1 == sz2);
140 
141         /// <summary>
142         ///    Converts the specified <see cref='System.Drawing.Size'/> to a
143         /// <see cref='System.Drawing.Point'/>.
144         /// </summary>
145         public static explicit operator Point(Size size) => new Point(size.Width, size.Height);
146 
147         /// <summary>
148         ///    Tests whether this <see cref='System.Drawing.Size'/> has zero
149         ///    width and height.
150         /// </summary>
151         [Browsable(false)]
152         public bool IsEmpty => width == 0 && height == 0;
153 
154         /**
155          * Horizontal dimension
156          */
157 
158         /// <summary>
159         ///    <para>
160         ///       Represents the horizontal component of this
161         ///    <see cref='System.Drawing.Size'/>.
162         ///    </para>
163         /// </summary>
164         public int Width
165         {
166             get { return width; }
167             set { width = value; }
168         }
169 
170         /**
171          * Vertical dimension
172          */
173 
174         /// <summary>
175         ///    Represents the vertical component of this
176         /// <see cref='System.Drawing.Size'/>.
177         /// </summary>
178         public int Height
179         {
180             get { return height; }
181             set { height = value; }
182         }
183 
184         /// <summary>
185         ///    <para>
186         ///       Performs vector addition of two <see cref='System.Drawing.Size'/> objects.
187         ///    </para>
188         /// </summary>
AddSystem.Drawing.Size189         public static Size Add(Size sz1, Size sz2) =>
190             new Size(unchecked(sz1.Width + sz2.Width), unchecked(sz1.Height + sz2.Height));
191 
192         /// <summary>
193         ///   Converts a SizeF to a Size by performing a ceiling operation on
194         ///   all the coordinates.
195         /// </summary>
196         public static Size Ceiling(SizeF value) =>
197             new Size(unchecked((int)Math.Ceiling(value.Width)), unchecked((int)Math.Ceiling(value.Height)));
198 
199         /// <summary>
200         ///    <para>
201         ///       Contracts a <see cref='System.Drawing.Size'/> by another <see cref='System.Drawing.Size'/> .
202         ///    </para>
203         /// </summary>
SubtractSystem.Drawing.Size204         public static Size Subtract(Size sz1, Size sz2) =>
205             new Size(unchecked(sz1.Width - sz2.Width), unchecked(sz1.Height - sz2.Height));
206 
207         /// <summary>
208         ///   Converts a SizeF to a Size by performing a truncate operation on
209         ///   all the coordinates.
210         /// </summary>
211         public static Size Truncate(SizeF value) => new Size(unchecked((int)value.Width), unchecked((int)value.Height));
212 
213         /// <summary>
214         ///   Converts a SizeF to a Size by performing a round operation on
215         ///   all the coordinates.
216         /// </summary>
217         public static Size Round(SizeF value) =>
218             new Size(unchecked((int)Math.Round(value.Width)), unchecked((int)Math.Round(value.Height)));
219 
220         /// <summary>
221         ///    <para>
222         ///       Tests to see whether the specified object is a
223         ///    <see cref='System.Drawing.Size'/>
224         ///    with the same dimensions as this <see cref='System.Drawing.Size'/>.
225         /// </para>
226         /// </summary>
227         public override bool Equals(object obj) => obj is Size && Equals((Size)obj);
228 
229         public bool Equals(Size other) => this == other;
230 
231         /// <summary>
232         ///    <para>
233         ///       Returns a hash code.
234         ///    </para>
235         /// </summary>
GetHashCodeSystem.Drawing.Size236         public override int GetHashCode() => HashHelpers.Combine(Width, Height);
237 
238         /// <summary>
239         ///    <para>
240         ///       Creates a human-readable string that represents this
241         ///    <see cref='System.Drawing.Size'/>.
242         ///    </para>
243         /// </summary>
ToStringSystem.Drawing.Size244         public override string ToString() => "{Width=" + width.ToString() + ", Height=" + height.ToString() + "}";
245 
246         /// <summary>
247         /// Multiplies <see cref="Size"/> by an <see cref="int"/> producing <see cref="Size"/>.
248         /// </summary>
249         /// <param name="size">Multiplicand of type <see cref="Size"/>.</param>
250         /// <param name="multiplier">Multiplier of type <see cref='int'>.</param>
251         /// <returns>Product of type <see cref="Size"/>.</returns>
MultiplySystem.Drawing.Size252         private static Size Multiply(Size size, int multiplier) =>
253             new Size(unchecked(size.width * multiplier), unchecked(size.height * multiplier));
254 
255         /// <summary>
256         /// Multiplies <see cref="Size"/> by a <see cref="float"/> producing <see cref="SizeF"/>.
257         /// </summary>
258         /// <param name="size">Multiplicand of type <see cref="Size"/>.</param>
259         /// <param name="multiplier">Multiplier of type <see cref="float"/>.</param>
260         /// <returns>Product of type SizeF.</returns>
MultiplySystem.Drawing.Size261         private static SizeF Multiply(Size size, float multiplier) =>
262             new SizeF(size.width * multiplier, size.height * multiplier);
263     }
264 }
265