this repo has no description
1using System.Drawing;
2using System.Numerics;
3using System.Runtime.CompilerServices;
4
5namespace Peridot;
6
7/// <summary>
8/// Provides static methods to <see cref="ColorF"/> manipulation.
9/// </summary>
10public partial struct ColorF
11{
12 #region Cast operators
13 /// <summary>
14 /// Cast a <see cref="ColorF"/> to <see cref="Vector4"/>.
15 /// </summary>
16 /// <param name="color">The color to cast.</param>
17 public static implicit operator Vector4(ColorF color) => color.m_rgba;
18
19 /// <summary>
20 /// Cast a <see cref="Vector4"/> to <see cref="ColorF"/>.
21 /// </summary>
22 /// <param name="color"></param>
23 public static implicit operator ColorF(Vector4 color) => new(color);
24
25 /// <summary>
26 /// Cast a <see cref="ColorF"/> to <see cref="Color"/>.
27 /// </summary>
28 /// <param name="color"></param>
29 public static implicit operator Color(ColorF color)
30 {
31 color = Vector4.Clamp(color, Vector4.Zero, Vector4.One) * 255f;
32 return Color.FromArgb((byte)color.A, (byte)color.R, (byte)color.G, (byte)color.B);
33 }
34
35 /// <summary>
36 /// Cast a <see cref="Vector4"/> to <see cref="ColorF"/>.
37 /// </summary>
38 /// <param name="color"></param>
39 public static implicit operator ColorF(Color color)
40 {
41 return (ColorF)Vector4.Clamp(new Vector4(color.R, color.G, color.B, color.A) * (1f / 255f), Vector4.Zero, Vector4.One);
42 }
43 #endregion
44 #region Math
45
46 public static ColorF Blend(ColorF dst, ColorF src)
47 {
48 var dstA = dst.A;
49 var srcA = src.A;
50 var res = dst * (1 - srcA) + src * srcA;
51 res.A = dstA * (1 - srcA) + srcA;
52 return res;
53 }
54
55 /// <summary>
56 /// Negates the specified color.
57 /// </summary>
58 /// <param name="color">The color to negate.</param>
59 /// <returns>The negated vector.</returns>
60 [MethodImpl(MethodImplOptions.AggressiveInlining)]
61 public static ColorF Negate(ColorF color) => -color.m_rgba;
62
63 /// <summary>
64 /// Adds two colors together.
65 /// </summary>
66 /// <param name="left">The first color.</param>
67 /// <param name="right">The second color.</param>
68 /// <returns>The summed color.</returns>
69 [MethodImpl(MethodImplOptions.AggressiveInlining)]
70 public static ColorF Add(ColorF left, ColorF right) => left.m_rgba + right.m_rgba;
71
72 /// <summary>
73 /// Subtracts the second color from the first.
74 /// </summary>
75 /// <param name="left">The first color.</param>
76 /// <param name="right">The second color.</param>
77 /// <returns>The color that results from subracting <paramref name="right"/> from <paramref name="left"/>.</returns>
78
79 [MethodImpl(MethodImplOptions.AggressiveInlining)]
80 public static ColorF Subtract(ColorF left, ColorF right) => left.m_rgba - right.m_rgba;
81
82 /// <summary>
83 /// Multiplies two colors together.
84 /// </summary>
85 /// <param name="left">The first color.</param>
86 /// <param name="right">The second color.</param>
87 /// <returns>The product color.</returns>
88 [MethodImpl(MethodImplOptions.AggressiveInlining)]
89 public static ColorF Multiply(ColorF left, ColorF right) => left.m_rgba * right.m_rgba;
90
91 /// <summary>
92 /// Divides the first color by the second.
93 /// </summary>
94 /// <param name="left">The first color.</param>
95 /// <param name="right">The second color.</param>
96 /// <returns>The color that results from dividing <paramref name="left"/> by <paramref name="right"/>.</returns>
97 [MethodImpl(MethodImplOptions.AggressiveInlining)]
98 public static ColorF Divide(ColorF left, ColorF right) => left.m_rgba / right.m_rgba;
99
100 /// <summary>
101 /// Multiples the specified color by the specified scalar value.
102 /// </summary>
103 /// <param name="left">The color.</param>
104 /// <param name="right">The scalar value.</param>
105 /// <returns>The scaled color.</returns>
106 [MethodImpl(MethodImplOptions.AggressiveInlining)]
107 public static ColorF Multiply(ColorF left, float right) => left.m_rgba * right;
108
109 /// <summary>
110 /// Divides the specified color by a specified scalar value.
111 /// </summary>
112 /// <param name="left">The color.</param>
113 /// <param name="right">The scalar value.</param>
114 /// <returns>The result of the division.</returns>
115 [MethodImpl(MethodImplOptions.AggressiveInlining)]
116 public static ColorF Divide(ColorF left, float right) => left.m_rgba / right;
117
118 /// <summary>
119 /// Multiples the specified color by the specified scalar value.
120 /// </summary>
121 /// <param name="left">The scalar value.</param>
122 /// <param name="right">The color.</param>
123 /// <returns>The scaled color.</returns>
124 [MethodImpl(MethodImplOptions.AggressiveInlining)]
125 public static ColorF Multiply(float left, ColorF right) => left * right.m_rgba;
126
127 /// <summary>
128 /// Linearly interpolates between two colors.
129 /// </summary>
130 /// <param name="a">The first color.</param>
131 /// <param name="b">The second color.</param>
132 /// <param name="t">Influence of the second color on the final result.</param>
133 /// <returns><paramref name="a"/> * (1f - <paramref name="t"/>) + <paramref name="b"/> * <paramref name="t"/>.</returns>
134 [MethodImpl(MethodImplOptions.AggressiveInlining)]
135 public static ColorF Lerp(in ColorF a, in ColorF b, float t) =>
136 a + (b - a) * t;
137 #endregion
138 #region Operators
139 /// <summary>
140 /// Element-wise equality.
141 /// </summary>
142 /// <param name="left">The first value.</param>
143 /// <param name="right">The second value.</param>
144 [MethodImpl(MethodImplOptions.AggressiveInlining)]
145 public static bool operator ==(ColorF left, ColorF right) =>
146 left.Equals(right);
147
148 /// <summary>
149 /// Element-wise inequality.
150 /// </summary>
151 /// <param name="left">The first value.</param>
152 /// <param name="right">The second value.</param>
153 [MethodImpl(MethodImplOptions.AggressiveInlining)]
154 public static bool operator !=(ColorF left, ColorF right) =>
155 !left.Equals(right);
156
157 /// <summary>
158 /// Negates the specified color.
159 /// </summary>
160 /// <param name="color">The color to negate.</param>
161 /// <returns>The negated vector.</returns>
162 public static ColorF operator -(ColorF color) => Negate(color);
163
164 /// <summary>
165 /// Adds two colors together.
166 /// </summary>
167 /// <param name="left">The first color.</param>
168 /// <param name="right">The second color.</param>
169 /// <returns>The summed color.</returns>
170 public static ColorF operator +(ColorF left, ColorF right) => Add(left, right);
171
172 /// <summary>
173 /// Subtracts the second color from the first.
174 /// </summary>
175 /// <param name="left">The first color.</param>
176 /// <param name="right">The second color.</param>
177 /// <returns>The color that results from subracting <paramref name="right"/> from <paramref name="left"/>.</returns>
178 public static ColorF operator -(ColorF left, ColorF right) => Subtract(left, right);
179
180 /// <summary>
181 /// Multiplies two colors together.
182 /// </summary>
183 /// <param name="left">The first color.</param>
184 /// <param name="right">The second color.</param>
185 /// <returns>The product color.</returns>
186 public static ColorF operator *(ColorF left, ColorF right) => Multiply(left, right);
187
188 /// <summary>
189 /// Divides the first color by the second.
190 /// </summary>
191 /// <param name="left">The first color.</param>
192 /// <param name="right">The second color.</param>
193 /// <returns>The color that results from dividing <paramref name="left"/> by <paramref name="right"/>.</returns>
194 public static ColorF operator /(ColorF left, ColorF right) => Divide(left, right);
195
196 /// <summary>
197 /// Multiples the specified color by the specified scalar value.
198 /// </summary>
199 /// <param name="left">The color.</param>
200 /// <param name="right">The scalar value.</param>
201 /// <returns>The scaled color.</returns>
202 public static ColorF operator *(ColorF left, float right) => Multiply(left, right);
203
204 /// <summary>
205 /// Divides the specified color by a specified scalar value.
206 /// </summary>
207 /// <param name="left">The color.</param>
208 /// <param name="right">The scalar value.</param>
209 /// <returns>The result of the division.</returns>
210 public static ColorF operator /(ColorF left, float right) => Divide(left, right);
211
212 /// <summary>
213 /// Multiples the specified color by the specified scalar value.
214 /// </summary>
215 /// <param name="left">The scalar value.</param>
216 /// <param name="right">The color.</param>
217 /// <returns>The scaled color.</returns>
218 public static ColorF operator *(float left, ColorF right) => Multiply(left, right);
219 #endregion
220 #region Colors
221 /// <summary>
222 /// Red (1, 0, 0, 1)
223 /// </summary>
224 public static readonly ColorF Red = new(1f, 0f, 0f, 1f);
225
226 /// <summary>
227 /// Dark Red (139f / 255f, 0f, 0f, 1f)
228 /// </summary>
229 public static readonly ColorF DarkRed = new(139f / 255f, 0f, 0f, 1f);
230
231 /// <summary>
232 /// Green (0f, 1f, 0f, 1f)
233 /// </summary>
234 public static readonly ColorF Green = new(0f, 1f, 0f, 1f);
235
236 /// <summary>
237 /// Blue (0f, 0f, 1f, 1f)
238 /// </summary>
239 public static readonly ColorF Blue = new(0f, 0f, 1f, 1f);
240
241 /// <summary>
242 /// Yellow (1f, 1f, 0f, 1f)
243 /// </summary>
244 public static readonly ColorF Yellow = new(1f, 1f, 0f, 1f);
245
246 /// <summary>
247 /// Grey (128f / 255f, 128f / 255f, 128 / 255f, 1f)
248 /// </summary>
249 public static readonly ColorF Grey = new(128f / 255f, 128f / 255f, 128f / 255f, 1f);
250
251 /// <summary>
252 /// Light Grey (211f / 255f, 211f / 255f, 211f / 255f, 1f)
253 /// </summary>
254 public static readonly ColorF LightGrey = new(211f / 255f, 211f / 255f, 211f / 255f, 1f);
255
256 /// <summary>
257 /// Cyan (0f, 1f, 1f, 1f)
258 /// </summary>
259 public static readonly ColorF Cyan = new(0f, 1f, 1f, 1f);
260
261 /// <summary>
262 /// White (1f, 1f, 1f, 1f)
263 /// </summary>
264 public static readonly ColorF White = new(1f, 1f, 1f, 1f);
265
266 /// <summary>
267 /// Cornflower Blue (100f / 255f, 149f / 255f, 237f / 255f, 1f)
268 /// </summary>
269 public static readonly ColorF CornflowerBlue = new(100f / 255f, 149f / 255f, 237f / 255f, 1f);
270
271 /// <summary>
272 /// Clear (0f, 0f, 0f, 0f)
273 /// </summary>
274 public static readonly ColorF Clear = new(0f, 0f, 0f, 0f);
275
276 /// <summary>
277 /// Black (0f, 0f, 0f, 1f)
278 /// </summary>
279 public static readonly ColorF Black = new(0f, 0f, 0f, 1f);
280
281 /// <summary>
282 /// Pink (1f, 192f / 255f, 203f / 255f, 1f)
283 /// </summary>
284 public static readonly ColorF Pink = new(1f, 192f / 255f, 203f / 255f, 1f);
285
286 /// <summary>
287 /// Orange (1f, 165f / 255f, 0f, 1f)
288 /// </summary>
289 public static readonly ColorF Orange = new(1f, 165f / 255f, 0f, 1f);
290 #endregion
291}