-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSize.cs
More file actions
419 lines (378 loc) · 16.2 KB
/
Size.cs
File metadata and controls
419 lines (378 loc) · 16.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
namespace Eto.Drawing;
/// <summary>
/// Represents a size with width and height components
/// </summary>
/// <copyright>(c) 2014 by Curtis Wensley</copyright>
/// <license type="BSD-3">See LICENSE for full terms</license>
[sc.TypeConverter(typeof(SizeConverterInternal))]
public struct Size : IEquatable<Size>
{
/// <summary>
/// Gets or sets the width
/// </summary>
public int Width { get; set; }
/// <summary>
/// Gets or sets the height
/// </summary>
public int Height { get; set; }
/// <summary>
/// Gets an empty size with a zero width and height
/// </summary>
public static readonly Size Empty = new Size (0, 0);
/// <summary>
/// Converts a floating point <paramref name="size"/> to an integral size by rounding the width and height
/// </summary>
/// <param name="size">Size to convert</param>
/// <returns>A new instance of a Size class with rounded width and height values of the specified <paramref name="size"/></returns>
public static Size Round (SizeF size)
{
return new Size ((int)Math.Round (size.Width), (int)Math.Round (size.Height));
}
/// <summary>
/// Converts a floating point <paramref name="size"/> to an integral size by truncating the width and height
/// </summary>
/// <param name="size">Size to convert</param>
/// <returns>A new instance of a Size struct with truncated width and height values of the specified <paramref name="size"/></returns>
public static Size Truncate (SizeF size)
{
return new Size ((int)size.Width, (int)size.Height);
}
/// <summary>
/// Returns the minimum width and height of two sizes
/// </summary>
/// <param name="size1">First size to get the minimum values</param>
/// <param name="size2">Second size to get the minimum values</param>
/// <returns>A new instance of a Size struct with the minimum width and height of either sizes</returns>
public static Size Min (Size size1, Size size2)
{
return new Size (Math.Min (size1.Width, size2.Width), Math.Min (size1.Height, size2.Height));
}
/// <summary>
/// Returns the maximum width and height of two sizes
/// </summary>
/// <param name="size1">First size to get the maximum values</param>
/// <param name="size2">Second size to get the maximum values</param>
/// <returns>A new instance of a Size struct with the maximum width and height of either sizes</returns>
public static Size Max (Size size1, Size size2)
{
return new Size (Math.Max (size1.Width, size2.Width), Math.Max (size1.Height, size2.Height));
}
/// <summary>
/// Returns the absolute width and height of the specified <paramref name="size"/>
/// </summary>
/// <param name="size">Size to convert</param>
/// <returns>A new instance of a Size struct with absolute (positive) width and height</returns>
public static Size Abs (Size size)
{
return new Size (Math.Abs (size.Width), Math.Abs (size.Height));
}
/// <summary>
/// Converts a floating point <paramref name="size"/> to an integral size by rounding the width and height to the
/// next integral value.
/// </summary>
/// <remarks>
/// This is useful to get a size struct that includes the floating point values completely. As opposed to the
/// <see cref="Round"/>, which will round down to the nearest integral number.
///
/// For example, a Width or Height of 2.1 or 2.6 would be translated to 3.
/// </remarks>
/// <param name="size">Size.</param>
public static Size Ceiling (SizeF size)
{
return new Size((int)Math.Ceiling(size.Width), (int)Math.Ceiling(size.Height));
}
/// <summary>
/// Size with width and height with a maximum int value
/// </summary>
public static readonly Size MaxValue = new Size (Int32.MaxValue, Int32.MaxValue);
/// <summary>
/// Size with width and height with a minimum int value
/// </summary>
public static readonly Size MinValue = new Size (Int32.MinValue, Int32.MinValue);
/// <summary>
/// Initializes a new Size class with an identical width and height
/// </summary>
/// <param name="size">Initial width and height of the size</param>
public Size (int size)
: this()
{
Width = size;
Height = size;
}
/// <summary>
/// Initializes a new Size class with the specified width and height
/// </summary>
/// <param name="width">Initial width of the size</param>
/// <param name="height">Initial height of the size</param>
public Size (int width, int height)
: this()
{
Width = width;
Height = height;
}
/// <summary>
/// Initializes a new Size class with width and height corresponding to the <see cref="Point.X"/> and <see cref="Point.Y"/> of the specified <paramref name="point"/>
/// </summary>
/// <param name="point">Point to convert to a Size struct</param>
public Size (Point point)
: this(point.X, point.Y)
{
}
/// <summary>
/// Initializes a new Size with the truncated width and height of size.
/// </summary>
/// <param name="size"></param>
public Size(SizeF size)
: this((int)size.Width, (int)size.Height)
{
}
/// <summary>
/// Fits this size to the specified <paramref name="constraint"/>, keeping the aspect
/// </summary>
/// <returns>The new size with the same aspect ratio with the width/height equal or within the constraint</returns>
/// <param name="constraint">Constraint to fit the new size into</param>
public Size FitTo (Size constraint)
{
double ratioX = (double) constraint.Width / (double)Width;
double ratioY = (double) constraint.Height / (double)Height;
// use whichever multiplier is smaller
double ratio = ratioX < ratioY ? ratioX : ratioY;
return new Size((int)(Width * ratio), (int)(Height * ratio));
}
/// <summary>
/// Gets a value indicating that the specified <paramref name="point"/> is within the <see cref="Width"/> and <see cref="Height"/> of this size
/// </summary>
/// <param name="point">Point to test</param>
/// <returns>True if the <paramref name="point"/> has an X and Y value between 0 and the Width and Height of this size, respectively. False otherwise</returns>
public bool Contains (Point point)
{
return Contains (point.X, point.Y);
}
/// <summary>
/// Gets a value indicating that the specified <paramref name="x"/> and <paramref name="y"/> values are within the <see cref="Width"/> and <see cref="Height"/> of this size
/// </summary>
/// <param name="x">X value to test</param>
/// <param name="y">Y value to test</param>
/// <returns>True if the <paramref name="x"/> and <paramref name="y"/> values are greater than or equal to 0 and less than the Width and Height of this size, respectively. False otherwise</returns>
public bool Contains (int x, int y)
{
if (Width == 0 || Height == 0)
return false;
return (x >= 0 && x < Width && y >= 0 && y < Height);
}
/// <summary>
/// Gets a value indicating that both the <see cref="Width"/> and <see cref="Height"/> are zero
/// </summary>
public bool IsZero
{
get { return Width == 0 && Height == 0; }
}
/// <summary>
/// Gets a value indicating that either the <see cref="Width"/> or <see cref="Height"/> are zero
/// </summary>
public bool IsEmpty
{
get { return Width == 0 || Height == 0; }
}
/// <summary>
/// Negates the Width and Height of the specified <paramref name="size"/> value
/// </summary>
/// <param name="size">Size to negate</param>
/// <returns>A new size that has a negative value of each of the Width and Height</returns>
public static Size operator - (Size size)
{
return new Size (-size.Width, -size.Height);
}
/// <summary>
/// Multiplies the <see cref="Width"/> and <see cref="Height"/> of two sizes
/// </summary>
/// <param name="size1">First size to multiply</param>
/// <param name="size2">Second size to multiply</param>
/// <returns>A new instance of a Size struct with the product of both sizes</returns>
public static Size operator * (Size size1, Size size2)
{
return new Size (size1.Width * size2.Width, size1.Height * size2.Height);
}
/// <summary>
/// Multiplies the <see cref="Width"/> and <see cref="Height"/> of a <paramref name="size"/> by the specified <paramref name="factor"/>
/// </summary>
/// <param name="size">Size to multiply</param>
/// <param name="factor">Factor to multiply both the Width and Height by</param>
/// <returns>A new instance of a Size struct with the product of the <paramref name="size"/> and <paramref name="factor"/></returns>
public static Size operator * (Size size, int factor)
{
return new Size (size.Width * factor, size.Height * factor);
}
/// <summary>
/// Multiplies the <see cref="Width"/> and <see cref="Height"/> of a <paramref name="size"/> by the specified <paramref name="factor"/>
/// </summary>
/// <param name="size">Size to multiply</param>
/// <param name="factor">Factor to multiply both the Width and Height by</param>
/// <returns>A new instance of a Size struct with the product of the <paramref name="size"/> and <paramref name="factor"/></returns>
public static Size operator * (int factor, Size size)
{
return new Size (size.Width * factor, size.Height * factor);
}
/// <summary>
/// Multiplies the <see cref="Width"/> and <see cref="Height"/> of a <paramref name="size"/> by the specified floating point <paramref name="factor"/>
/// </summary>
/// <param name="size">Size to multiply</param>
/// <param name="factor">Factor to multiply both the Width and Height by</param>
/// <returns>A new instance of a SizeF struct with the product of the <paramref name="size"/> and <paramref name="factor"/></returns>
public static SizeF operator * (Size size, float factor)
{
return new SizeF (size.Width * factor, size.Height * factor);
}
/// <summary>
/// Divides the <see cref="Width"/> and <see cref="Height"/> of two sizes
/// </summary>
/// <param name="size1">Size to divide</param>
/// <param name="size2">Size to divide by</param>
/// <returns>A new instance of a Size struct with the division of <paramref name="size1"/> by <paramref name="size2"/></returns>
public static Size operator / (Size size1, Size size2)
{
return new Size (size1.Width / size2.Width, size1.Height / size2.Height);
}
/// <summary>
/// Divides the <see cref="Width"/> and <see cref="Height"/> of a <paramref name="size"/> by the specified <paramref name="factor"/>
/// </summary>
/// <param name="size">Size to divide</param>
/// <param name="factor">Factor to divide both the Width and Height by</param>
/// <returns>A new instance of a Size struct with the width and height of <paramref name="size"/> divided by <paramref name="factor"/></returns>
public static Size operator / (Size size, int factor)
{
return new Size (size.Width / factor, size.Height / factor);
}
/// <summary>
/// Adds the <see cref="Width"/> and <see cref="Height"/> values of two sizes together
/// </summary>
/// <param name="size1">First size to add</param>
/// <param name="size2">Second size to add</param>
/// <returns>A new instance of a Size struct with the addition of the width and height of both sizes</returns>
public static Size operator + (Size size1, Size size2)
{
return new Size (size1.Width + size2.Width, size1.Height + size2.Height);
}
/// <summary>
/// Subtracts the <see cref="Width"/> and <see cref="Height"/> value of one size from another
/// </summary>
/// <param name="size1">Size to subtract from</param>
/// <param name="size2">Size to subtract</param>
/// <returns>A new instance of a Size struct with the width and height of <paramref name="size1"/> minus <paramref name="size2"/></returns>
public static Size operator - (Size size1, Size size2)
{
return new Size (size1.Width - size2.Width, size1.Height - size2.Height);
}
/// <summary>
/// Adds the <see cref="Point.X"/> and <see cref="Point.Y"/> value to the <see cref="Width"/> and <see cref="Height"/> of a size
/// </summary>
/// <param name="size">Size to add to</param>
/// <param name="point">Point with values to add</param>
/// <returns>A new instance of a Size struct with the width and height of <paramref name="size"/> plus <paramref name="point"/></returns>
public static Size operator + (Size size, Point point)
{
return new Size (size.Width + point.X, size.Height + point.Y);
}
/// <summary>
/// Subtracts the <see cref="Point.X"/> and <see cref="Point.Y"/> value from the <see cref="Width"/> and <see cref="Height"/> of a size
/// </summary>
/// <param name="size">Size to subtract from</param>
/// <param name="point">Point with values to subtract</param>
/// <returns>A new instance of a Size struct with the width and height of <paramref name="size"/> minus <paramref name="point"/></returns>
public static Size operator - (Size size, Point point)
{
return new Size (size.Width - point.X, size.Height - point.Y);
}
/// <summary>
/// Subtracts a <paramref name="value"/> from the <see cref="Width"/> and <see cref="Height"/> of the specified <paramref name="size"/>
/// </summary>
/// <param name="size">Size to subtract from</param>
/// <param name="value">Value to subtract from the width and height</param>
/// <returns>A new instance of a Size struct with the width and height of <paramref name="size"/> minus <paramref name="value"/></returns>
public static Size operator - (Size size, int value)
{
return new Size (size.Width - value, size.Height - value);
}
/// <summary>
/// Adds a <paramref name="value"/> to the <see cref="Width"/> and <see cref="Height"/> of the specified <paramref name="size"/>
/// </summary>
/// <param name="size">Size to add to</param>
/// <param name="value">Value to add to the width and height</param>
/// <returns>A new instance of a Size struct with the width and height of <paramref name="size"/> plus <paramref name="value"/></returns>
public static Size operator + (Size size, int value)
{
return new Size (size.Width + value, size.Height + value);
}
/// <summary>
/// Compares two sizes for equality
/// </summary>
/// <param name="size1">First size to compare</param>
/// <param name="size2">Second size to compare</param>
/// <returns>True if both the width and height of both sizes are equal, false otherwise</returns>
public static bool operator == (Size size1, Size size2)
{
return (size1.Width == size2.Width && size1.Height == size2.Height);
}
/// <summary>
/// Compares two sizes for inequality
/// </summary>
/// <param name="size1">First size to compare</param>
/// <param name="size2">Second size to compare</param>
/// <returns>True if either the width and height of both sizes are not equal, false if they are both equal</returns>
public static bool operator != (Size size1, Size size2)
{
return (size1.Width != size2.Width || size1.Height != size2.Height);
}
/// <summary>
/// Explicit conversion from a <see cref="SizeF"/> to a <see cref="Size"/> by truncating values
/// </summary>
/// <param name="size">Size to convert</param>
/// <returns>A new instance of a Size with the value of the specified <paramref name="size"/></returns>
public static explicit operator Size (SizeF size)
{
return new Size ((int)size.Width, (int)size.Height);
}
/// <summary>
/// Explicit conversion from a <paramref name="point"/> to a Size with a Width and Height of the X and Y values of the point, respectively
/// </summary>
/// <param name="point">Point to convert</param>
/// <returns>A new size with the width and height of the X and Y values of the point, respectively</returns>
public static explicit operator Size (Point point)
{
return new Size (point);
}
/// <summary>
/// Compares this size to the specified <paramref name="obj"/>
/// </summary>
/// <param name="obj">Object to compare with</param>
/// <returns>True if the specified <paramref name="obj"/> is a Size and is equal to this instance</returns>
public override bool Equals (object obj)
{
return obj is Size && (Size)obj == this;
}
/// <summary>
/// Gets the hash code for this Size
/// </summary>
/// <returns>Hash code value for this size</returns>
public override int GetHashCode ()
{
return Width ^ Height;
}
/// <summary>
/// Converts this Size struct to a string
/// </summary>
/// <returns>String representation of this Size</returns>
public override string ToString ()
{
return String.Format (CultureInfo.InvariantCulture, "{0},{1}", Width, Height);
}
/// <summary>
/// Compares this size to the <paramref name="other"/> size
/// </summary>
/// <param name="other">Other size to compare with</param>
/// <returns>True if the <paramref name="other"/> size is equal to this instance</returns>
public bool Equals (Size other)
{
return other == this;
}
}