1 #region Copyright & License Information 2 /* 3 * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) 4 * This file is part of OpenRA, which is free software. It is made 5 * available to you under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, either version 3 of 7 * the License, or (at your option) any later version. For more 8 * information, see COPYING. 9 */ 10 #endregion 11 12 using System; 13 using System.Globalization; 14 using OpenRA.Scripting; 15 16 namespace OpenRA.Primitives 17 { 18 public struct Color : IEquatable<Color>, IScriptBindable 19 { 20 readonly long argb; 21 FromArgbOpenRA.Primitives.Color22 public static Color FromArgb(int red, int green, int blue) 23 { 24 return FromArgb(byte.MaxValue, red, green, blue); 25 } 26 FromArgbOpenRA.Primitives.Color27 public static Color FromArgb(int alpha, int red, int green, int blue) 28 { 29 return new Color(((byte)alpha << 24) + ((byte)red << 16) + ((byte)green << 8) + (byte)blue); 30 } 31 FromAhslOpenRA.Primitives.Color32 public static Color FromAhsl(int alpha, float h, float s, float l) 33 { 34 // Convert from HSL to RGB 35 var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s); 36 var p = 2 * l - q; 37 38 float[] trgb = { h + 1 / 3.0f, h, h - 1 / 3.0f }; 39 float[] rgb = { 0, 0, 0 }; 40 41 for (var k = 0; k < 3; k++) 42 { 43 while (trgb[k] < 0) trgb[k] += 1.0f; 44 while (trgb[k] > 1) trgb[k] -= 1.0f; 45 } 46 47 for (var k = 0; k < 3; k++) 48 { 49 if (trgb[k] < 1 / 6.0f) 50 rgb[k] = p + ((q - p) * 6 * trgb[k]); 51 else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5) 52 rgb[k] = q; 53 else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3) 54 rgb[k] = p + ((q - p) * 6 * (2.0f / 3 - trgb[k])); 55 else 56 rgb[k] = p; 57 } 58 59 return FromArgb(alpha, (int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255)); 60 } 61 FromAhslOpenRA.Primitives.Color62 public static Color FromAhsl(int h, int s, int l) 63 { 64 return FromAhsl(255, h / 255f, s / 255f, l / 255f); 65 } 66 FromAhslOpenRA.Primitives.Color67 public static Color FromAhsl(float h, float s, float l) 68 { 69 return FromAhsl(255, h, s, l); 70 } 71 FromAhsvOpenRA.Primitives.Color72 public static Color FromAhsv(int alpha, float h, float s, float v) 73 { 74 var ll = 0.5f * (2 - s) * v; 75 var ss = (ll >= 1 || v <= 0) ? 0 : 0.5f * s * v / (ll <= 0.5f ? ll : 1 - ll); 76 return FromAhsl(alpha, h, ss, ll); 77 } 78 FromAhsvOpenRA.Primitives.Color79 public static Color FromAhsv(float h, float s, float v) 80 { 81 return FromAhsv(255, h, s, v); 82 } 83 ToAhsvOpenRA.Primitives.Color84 public void ToAhsv(out int a, out float h, out float s, out float v) 85 { 86 var ll = 2 * GetBrightness(); 87 var ss = GetSaturation() * ((ll <= 1) ? ll : 2 - ll); 88 89 a = A; 90 h = GetHue() / 360f; 91 s = (2 * ss) / (ll + ss); 92 v = (ll + ss) / 2; 93 } 94 ColorOpenRA.Primitives.Color95 Color(long argb) 96 { 97 this.argb = argb; 98 } 99 ToArgbOpenRA.Primitives.Color100 public int ToArgb() 101 { 102 return (int)argb; 103 } 104 FromArgbOpenRA.Primitives.Color105 public static Color FromArgb(int alpha, Color baseColor) 106 { 107 return FromArgb(alpha, baseColor.R, baseColor.G, baseColor.B); 108 } 109 FromArgbOpenRA.Primitives.Color110 public static Color FromArgb(int argb) 111 { 112 return FromArgb((byte)(argb >> 24), (byte)(argb >> 16), (byte)(argb >> 8), (byte)argb); 113 } 114 FromArgbOpenRA.Primitives.Color115 public static Color FromArgb(uint argb) 116 { 117 return FromArgb((byte)(argb >> 24), (byte)(argb >> 16), (byte)(argb >> 8), (byte)argb); 118 } 119 TryParseOpenRA.Primitives.Color120 public static bool TryParse(string value, out Color color) 121 { 122 color = default(Color); 123 value = value.Trim(); 124 if (value.Length != 6 && value.Length != 8) 125 return false; 126 127 byte red, green, blue, alpha = 255; 128 if (!byte.TryParse(value.Substring(0, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out red) 129 || !byte.TryParse(value.Substring(2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out green) 130 || !byte.TryParse(value.Substring(4, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out blue)) 131 return false; 132 133 if (value.Length == 8 134 && !byte.TryParse(value.Substring(6, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out alpha)) 135 return false; 136 137 color = FromArgb(alpha, red, green, blue); 138 return true; 139 } 140 operator ==OpenRA.Primitives.Color141 public static bool operator ==(Color left, Color right) 142 { 143 return left.argb == right.argb; 144 } 145 operator !=OpenRA.Primitives.Color146 public static bool operator !=(Color left, Color right) 147 { 148 return !(left == right); 149 } 150 GetBrightnessOpenRA.Primitives.Color151 public float GetBrightness() 152 { 153 var min = Math.Min(R, Math.Min(G, B)); 154 var max = Math.Max(R, Math.Max(G, B)); 155 return (max + min) / 510f; 156 } 157 GetSaturationOpenRA.Primitives.Color158 public float GetSaturation() 159 { 160 var min = Math.Min(R, Math.Min(G, B)); 161 var max = Math.Max(R, Math.Max(G, B)); 162 if (max == min) 163 return 0.0f; 164 165 var sum = max + min; 166 if (sum > byte.MaxValue) 167 sum = 510 - sum; 168 169 return (float)(max - min) / sum; 170 } 171 GetHueOpenRA.Primitives.Color172 public float GetHue() 173 { 174 var min = Math.Min(R, Math.Min(G, B)); 175 var max = Math.Max(R, Math.Max(G, B)); 176 if (max == min) 177 return 0.0f; 178 179 var diff = (float)(max - min); 180 var rNorm = (max - R) / diff; 181 var gNorm = (max - G) / diff; 182 var bNorm = (max - B) / diff; 183 184 var hue = 0.0f; 185 if (R == max) 186 hue = 60.0f * (6.0f + bNorm - gNorm); 187 if (G == max) 188 hue = 60.0f * (2.0f + rNorm - bNorm); 189 if (B == max) 190 hue = 60.0f * (4.0f + gNorm - rNorm); 191 192 if (hue > 360.0f) 193 hue -= 360f; 194 195 return hue; 196 } 197 198 public byte A { get { return (byte)(argb >> 24); } } 199 public byte R { get { return (byte)(argb >> 16); } } 200 public byte G { get { return (byte)(argb >> 8); } } 201 public byte B { get { return (byte)argb; } } 202 EqualsOpenRA.Primitives.Color203 public bool Equals(Color other) 204 { 205 return this == other; 206 } 207 EqualsOpenRA.Primitives.Color208 public override bool Equals(object obj) 209 { 210 if (!(obj is Color)) 211 return false; 212 213 return this == (Color)obj; 214 } 215 GetHashCodeOpenRA.Primitives.Color216 public override int GetHashCode() 217 { 218 return (int)(argb ^ argb >> 32); 219 } 220 ToStringOpenRA.Primitives.Color221 public override string ToString() 222 { 223 if (A == 255) 224 return R.ToString("X2") + G.ToString("X2") + B.ToString("X2"); 225 226 return R.ToString("X2") + G.ToString("X2") + B.ToString("X2") + A.ToString("X2"); 227 } 228 229 public static Color Transparent { get { return FromArgb(0x00FFFFFF); } } 230 public static Color AliceBlue { get { return FromArgb(0xFFF0F8FF); } } 231 public static Color AntiqueWhite { get { return FromArgb(0xFFFAEBD7); } } 232 public static Color Aqua { get { return FromArgb(0xFF00FFFF); } } 233 public static Color Aquamarine { get { return FromArgb(0xFF7FFFD4); } } 234 public static Color Azure { get { return FromArgb(0xFFF0FFFF); } } 235 public static Color Beige { get { return FromArgb(0xFFF5F5DC); } } 236 public static Color Bisque { get { return FromArgb(0xFFFFE4C4); } } 237 public static Color Black { get { return FromArgb(0xFF000000); } } 238 public static Color BlanchedAlmond { get { return FromArgb(0xFFFFEBCD); } } 239 public static Color Blue { get { return FromArgb(0xFF0000FF); } } 240 public static Color BlueViolet { get { return FromArgb(0xFF8A2BE2); } } 241 public static Color Brown { get { return FromArgb(0xFFA52A2A); } } 242 public static Color BurlyWood { get { return FromArgb(0xFFDEB887); } } 243 public static Color CadetBlue { get { return FromArgb(0xFF5F9EA0); } } 244 public static Color Chartreuse { get { return FromArgb(0xFF7FFF00); } } 245 public static Color Chocolate { get { return FromArgb(0xFFD2691E); } } 246 public static Color Coral { get { return FromArgb(0xFFFF7F50); } } 247 public static Color CornflowerBlue { get { return FromArgb(0xFF6495ED); } } 248 public static Color Cornsilk { get { return FromArgb(0xFFFFF8DC); } } 249 public static Color Crimson { get { return FromArgb(0xFFDC143C); } } 250 public static Color Cyan { get { return FromArgb(0xFF00FFFF); } } 251 public static Color DarkBlue { get { return FromArgb(0xFF00008B); } } 252 public static Color DarkCyan { get { return FromArgb(0xFF008B8B); } } 253 public static Color DarkGoldenrod { get { return FromArgb(0xFFB8860B); } } 254 public static Color DarkGray { get { return FromArgb(0xFFA9A9A9); } } 255 public static Color DarkGreen { get { return FromArgb(0xFF006400); } } 256 public static Color DarkKhaki { get { return FromArgb(0xFFBDB76B); } } 257 public static Color DarkMagenta { get { return FromArgb(0xFF8B008B); } } 258 public static Color DarkOliveGreen { get { return FromArgb(0xFF556B2F); } } 259 public static Color DarkOrange { get { return FromArgb(0xFFFF8C00); } } 260 public static Color DarkOrchid { get { return FromArgb(0xFF9932CC); } } 261 public static Color DarkRed { get { return FromArgb(0xFF8B0000); } } 262 public static Color DarkSalmon { get { return FromArgb(0xFFE9967A); } } 263 public static Color DarkSeaGreen { get { return FromArgb(0xFF8FBC8B); } } 264 public static Color DarkSlateBlue { get { return FromArgb(0xFF483D8B); } } 265 public static Color DarkSlateGray { get { return FromArgb(0xFF2F4F4F); } } 266 public static Color DarkTurquoise { get { return FromArgb(0xFF00CED1); } } 267 public static Color DarkViolet { get { return FromArgb(0xFF9400D3); } } 268 public static Color DeepPink { get { return FromArgb(0xFFFF1493); } } 269 public static Color DeepSkyBlue { get { return FromArgb(0xFF00BFFF); } } 270 public static Color DimGray { get { return FromArgb(0xFF696969); } } 271 public static Color DodgerBlue { get { return FromArgb(0xFF1E90FF); } } 272 public static Color Firebrick { get { return FromArgb(0xFFB22222); } } 273 public static Color FloralWhite { get { return FromArgb(0xFFFFFAF0); } } 274 public static Color ForestGreen { get { return FromArgb(0xFF228B22); } } 275 public static Color Fuchsia { get { return FromArgb(0xFFFF00FF); } } 276 public static Color Gainsboro { get { return FromArgb(0xFFDCDCDC); } } 277 public static Color GhostWhite { get { return FromArgb(0xFFF8F8FF); } } 278 public static Color Gold { get { return FromArgb(0xFFFFD700); } } 279 public static Color Goldenrod { get { return FromArgb(0xFFDAA520); } } 280 public static Color Gray { get { return FromArgb(0xFF808080); } } 281 public static Color Green { get { return FromArgb(0xFF008000); } } 282 public static Color GreenYellow { get { return FromArgb(0xFFADFF2F); } } 283 public static Color Honeydew { get { return FromArgb(0xFFF0FFF0); } } 284 public static Color HotPink { get { return FromArgb(0xFFFF69B4); } } 285 public static Color IndianRed { get { return FromArgb(0xFFCD5C5C); } } 286 public static Color Indigo { get { return FromArgb(0xFF4B0082); } } 287 public static Color Ivory { get { return FromArgb(0xFFFFFFF0); } } 288 public static Color Khaki { get { return FromArgb(0xFFF0E68C); } } 289 public static Color Lavender { get { return FromArgb(0xFFE6E6FA); } } 290 public static Color LavenderBlush { get { return FromArgb(0xFFFFF0F5); } } 291 public static Color LawnGreen { get { return FromArgb(0xFF7CFC00); } } 292 public static Color LemonChiffon { get { return FromArgb(0xFFFFFACD); } } 293 public static Color LightBlue { get { return FromArgb(0xFFADD8E6); } } 294 public static Color LightCoral { get { return FromArgb(0xFFF08080); } } 295 public static Color LightCyan { get { return FromArgb(0xFFE0FFFF); } } 296 public static Color LightGoldenrodYellow { get { return FromArgb(0xFFFAFAD2); } } 297 public static Color LightGray { get { return FromArgb(0xFFD3D3D3); } } 298 public static Color LightGreen { get { return FromArgb(0xFF90EE90); } } 299 public static Color LightPink { get { return FromArgb(0xFFFFB6C1); } } 300 public static Color LightSalmon { get { return FromArgb(0xFFFFA07A); } } 301 public static Color LightSeaGreen { get { return FromArgb(0xFF20B2AA); } } 302 public static Color LightSkyBlue { get { return FromArgb(0xFF87CEFA); } } 303 public static Color LightSlateGray { get { return FromArgb(0xFF778899); } } 304 public static Color LightSteelBlue { get { return FromArgb(0xFFB0C4DE); } } 305 public static Color LightYellow { get { return FromArgb(0xFFFFFFE0); } } 306 public static Color Lime { get { return FromArgb(0xFF00FF00); } } 307 public static Color LimeGreen { get { return FromArgb(0xFF32CD32); } } 308 public static Color Linen { get { return FromArgb(0xFFFAF0E6); } } 309 public static Color Magenta { get { return FromArgb(0xFFFF00FF); } } 310 public static Color Maroon { get { return FromArgb(0xFF800000); } } 311 public static Color MediumAquamarine { get { return FromArgb(0xFF66CDAA); } } 312 public static Color MediumBlue { get { return FromArgb(0xFF0000CD); } } 313 public static Color MediumOrchid { get { return FromArgb(0xFFBA55D3); } } 314 public static Color MediumPurple { get { return FromArgb(0xFF9370DB); } } 315 public static Color MediumSeaGreen { get { return FromArgb(0xFF3CB371); } } 316 public static Color MediumSlateBlue { get { return FromArgb(0xFF7B68EE); } } 317 public static Color MediumSpringGreen { get { return FromArgb(0xFF00FA9A); } } 318 public static Color MediumTurquoise { get { return FromArgb(0xFF48D1CC); } } 319 public static Color MediumVioletRed { get { return FromArgb(0xFFC71585); } } 320 public static Color MidnightBlue { get { return FromArgb(0xFF191970); } } 321 public static Color MintCream { get { return FromArgb(0xFFF5FFFA); } } 322 public static Color MistyRose { get { return FromArgb(0xFFFFE4E1); } } 323 public static Color Moccasin { get { return FromArgb(0xFFFFE4B5); } } 324 public static Color NavajoWhite { get { return FromArgb(0xFFFFDEAD); } } 325 public static Color Navy { get { return FromArgb(0xFF000080); } } 326 public static Color OldLace { get { return FromArgb(0xFFFDF5E6); } } 327 public static Color Olive { get { return FromArgb(0xFF808000); } } 328 public static Color OliveDrab { get { return FromArgb(0xFF6B8E23); } } 329 public static Color Orange { get { return FromArgb(0xFFFFA500); } } 330 public static Color OrangeRed { get { return FromArgb(0xFFFF4500); } } 331 public static Color Orchid { get { return FromArgb(0xFFDA70D6); } } 332 public static Color PaleGoldenrod { get { return FromArgb(0xFFEEE8AA); } } 333 public static Color PaleGreen { get { return FromArgb(0xFF98FB98); } } 334 public static Color PaleTurquoise { get { return FromArgb(0xFFAFEEEE); } } 335 public static Color PaleVioletRed { get { return FromArgb(0xFFDB7093); } } 336 public static Color PapayaWhip { get { return FromArgb(0xFFFFEFD5); } } 337 public static Color PeachPuff { get { return FromArgb(0xFFFFDAB9); } } 338 public static Color Peru { get { return FromArgb(0xFFCD853F); } } 339 public static Color Pink { get { return FromArgb(0xFFFFC0CB); } } 340 public static Color Plum { get { return FromArgb(0xFFDDA0DD); } } 341 public static Color PowderBlue { get { return FromArgb(0xFFB0E0E6); } } 342 public static Color Purple { get { return FromArgb(0xFF800080); } } 343 public static Color Red { get { return FromArgb(0xFFFF0000); } } 344 public static Color RosyBrown { get { return FromArgb(0xFFBC8F8F); } } 345 public static Color RoyalBlue { get { return FromArgb(0xFF4169E1); } } 346 public static Color SaddleBrown { get { return FromArgb(0xFF8B4513); } } 347 public static Color Salmon { get { return FromArgb(0xFFFA8072); } } 348 public static Color SandyBrown { get { return FromArgb(0xFFF4A460); } } 349 public static Color SeaGreen { get { return FromArgb(0xFF2E8B57); } } 350 public static Color SeaShell { get { return FromArgb(0xFFFFF5EE); } } 351 public static Color Sienna { get { return FromArgb(0xFFA0522D); } } 352 public static Color Silver { get { return FromArgb(0xFFC0C0C0); } } 353 public static Color SkyBlue { get { return FromArgb(0xFF87CEEB); } } 354 public static Color SlateBlue { get { return FromArgb(0xFF6A5ACD); } } 355 public static Color SlateGray { get { return FromArgb(0xFF708090); } } 356 public static Color Snow { get { return FromArgb(0xFFFFFAFA); } } 357 public static Color SpringGreen { get { return FromArgb(0xFF00FF7F); } } 358 public static Color SteelBlue { get { return FromArgb(0xFF4682B4); } } 359 public static Color Tan { get { return FromArgb(0xFFD2B48C); } } 360 public static Color Teal { get { return FromArgb(0xFF008080); } } 361 public static Color Thistle { get { return FromArgb(0xFFD8BFD8); } } 362 public static Color Tomato { get { return FromArgb(0xFFFF6347); } } 363 public static Color Turquoise { get { return FromArgb(0xFF40E0D0); } } 364 public static Color Violet { get { return FromArgb(0xFFEE82EE); } } 365 public static Color Wheat { get { return FromArgb(0xFFF5DEB3); } } 366 public static Color White { get { return FromArgb(0xFFFFFFFF); } } 367 public static Color WhiteSmoke { get { return FromArgb(0xFFF5F5F5); } } 368 public static Color Yellow { get { return FromArgb(0xFFFFFF00); } } 369 public static Color YellowGreen { get { return FromArgb(0xFF9ACD32); } } 370 } 371 } 372