From 6c85913c976dcda6d6fca0433cb5684460dd4c1b Mon Sep 17 00:00:00 2001 From: demorome Date: Sat, 29 Nov 2025 22:39:20 -0400 Subject: [PATCH 01/23] improve Color struct --- src/Graphics/Color.cs | 2042 ++++++++++++++++++++++------------------- 1 file changed, 1109 insertions(+), 933 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index de66d26..34362e6 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -14,942 +14,1118 @@ using System.Runtime.CompilerServices; using System.Text; using System.Numerics; +using System.Runtime.InteropServices; -namespace MoonWorks.Graphics +namespace MoonWorks.Graphics; + +/// +/// Describes a 32-bit packed color. +/// +[StructLayout(LayoutKind.Sequential, Size = 4, Pack = 4)] +public record struct Color(byte R, byte G, byte B, byte A = 255) { + public Color(int r, int g, int b, int a = 255) : this( + (byte) int.Clamp(r, 0, 255), + (byte) int.Clamp(g, 0, 255), + (byte) int.Clamp(b, 0, 255), + (byte) int.Clamp(a, 0, 255) + ) { } + + /// + /// Constructs an RGBA color from scalars which represent red, green, blue and alpha values. + /// + /// Red component value from 0.0f to 1.0f. + /// Green component value from 0.0f to 1.0f. + /// Blue component value from 0.0f to 1.0f. + /// Alpha component value from 0.0f to 1.0f. + public Color(float r, float g, float b, float a) : this( + (byte) (System.Math.Clamp(r, 0, 1) * byte.MaxValue), + (byte) (System.Math.Clamp(g, 0, 1) * byte.MaxValue), + (byte) (System.Math.Clamp(b, 0, 1) * byte.MaxValue), + (byte) (System.Math.Clamp(a, 0, 1) * byte.MaxValue) + ) { } + + /// + /// Constructs an RGBA color from scalars which represent red, green, blue values. Alpha is assumed to be 1. + /// + /// Red component value from 0.0f to 1.0f. + /// Green component value from 0.0f to 1.0f. + /// Blue component value from 0.0f to 1.0f. + public Color(float r, float g, float b) : this( + (byte) (System.Math.Clamp(r, 0, 1) * byte.MaxValue), + (byte) (System.Math.Clamp(g, 0, 1) * byte.MaxValue), + (byte) (System.Math.Clamp(b, 0, 1) * byte.MaxValue), + (byte) 255 + ) { } + + public Color(Vector4 vector) : this(vector.X, vector.Y, vector.Z, vector.W) { } + /// - /// Describes a 32-bit packed color. + /// Gets packed RGBA value of this . + /// NOTE: Because of endianness, if you format this value directly as a hex string, + /// the order of bytes may be wrong. /// - public record struct Color(byte R, byte G, byte B, byte A = 255) + public readonly uint PackedValue() => Unsafe.BitCast(this); + + /// + /// Gets a representation for a packed RGBA value. + /// + public static Color FromPacked(uint rgba) => Unsafe.BitCast(rgba); + + /// + /// Gets a representation for this object. + /// + /// A representation for this object. + public Vector3 ToVector3() { - public Color(int r, int g, int b, int a = 255) : this( - (byte) int.Clamp(r, 0, 255), - (byte) int.Clamp(g, 0, 255), - (byte) int.Clamp(b, 0, 255), - (byte) int.Clamp(a, 0, 255) - ) { } - - /// - /// Constructs an RGBA color from scalars which represent red, green, blue and alpha values. - /// - /// Red component value from 0.0f to 1.0f. - /// Green component value from 0.0f to 1.0f. - /// Blue component value from 0.0f to 1.0f. - /// Alpha component value from 0.0f to 1.0f. - public Color(float r, float g, float b, float a) : this( - (byte) (System.Math.Clamp(r, 0, 1) * byte.MaxValue), - (byte) (System.Math.Clamp(g, 0, 1) * byte.MaxValue), - (byte) (System.Math.Clamp(b, 0, 1) * byte.MaxValue), - (byte) (System.Math.Clamp(a, 0, 1) * byte.MaxValue) - ) { } - - /// - /// Constructs an RGBA color from scalars which represent red, green, blue values. Alpha is assumed to be 1. - /// - /// Red component value from 0.0f to 1.0f. - /// Green component value from 0.0f to 1.0f. - /// Blue component value from 0.0f to 1.0f. - public Color(float r, float g, float b) : this( - (byte) (System.Math.Clamp(r, 0, 1) * byte.MaxValue), - (byte) (System.Math.Clamp(g, 0, 1) * byte.MaxValue), - (byte) (System.Math.Clamp(b, 0, 1) * byte.MaxValue), - (byte) 255 - ) { } - - public Color(Vector4 vector) : this(vector.X, vector.Y, vector.Z, vector.W) { } - - /// - /// Gets packed value of this . - /// - public readonly uint PackedValue() => Unsafe.BitCast(this); - - /// - /// Transparent color (R:0,G:0,B:0,A:0). - /// - public static Color Transparent => new(0, 0, 0, 0); - - /// - /// AliceBlue color (R:240,G:248,B:255,A:255). - /// - public static Color AliceBlue => new(240, 248, 255); - - /// - /// AntiqueWhite color (R:250,G:235,B:215,A:255). - /// - public static Color AntiqueWhite => new(250, 235, 215); - - /// - /// Aqua color (R:0,G:255,B:255,A:255). - /// - public static Color Aqua => new(0, 255, 255); - - /// - /// Aquamarine color (R:127,G:255,B:212,A:255). - /// - public static Color Aquamarine => new(127, 255, 212); - - /// - /// Azure color (R:240,G:255,B:255,A:255). - /// - public static Color Azure => new(240, 255, 255); - - /// - /// Beige color (R:245,G:245,B:220,A:255). - /// - public static Color Beige => new(245, 245, 220); - - /// - /// Bisque color (R:255,G:228,B:196,A:255). - /// - public static Color Bisque => new(255, 228, 196); - - /// - /// Black color (R:0,G:0,B:0,A:255). - /// - public static Color Black => new(0, 0, 0); - - /// - /// BlanchedAlmond color (R:255,G:235,B:205,A:255). - /// - public static Color BlanchedAlmond => new(255, 235, 205); - - /// - /// Blue color (R:0,G:0,B:255,A:255). - /// - public static Color Blue => new(0, 0, 255); - - /// - /// BlueViolet color (R:138,G:43,B:226,A:255). - /// - public static Color BlueViolet => new(138, 43, 226); - - /// - /// Brown color (R:165,G:42,B:42,A:255). - /// - public static Color Brown => new(165, 42, 42); - - /// - /// BurlyWood color (R:222,G:184,B:135,A:255). - /// - public static Color BurlyWood => new(222, 184, 135); - - /// - /// CadetBlue color (R:95,G:158,B:160,A:255). - /// - public static Color CadetBlue => new(95, 158, 160); - - /// - /// Chartreuse color (R:127,G:255,B:0,A:255). - /// - public static Color Chartreuse => new(127, 255, 0); - - /// - /// Chocolate color (R:210,G:105,B:30,A:255). - /// - public static Color Chocolate => new(210, 105, 30); - - /// - /// Coral color (R:255,G:127,B:80,A:255). - /// - public static Color Coral => new (255, 127, 80); - - /// - /// CornflowerBlue color (R:100,G:149,B:237,A:255). - /// - public static Color CornflowerBlue => new(100, 149, 237); - - /// - /// Cornsilk color (R:255,G:248,B:220,A:255). - /// - public static Color Cornsilk => new(255, 248, 220); - - /// - /// Crimson color (R:220,G:20,B:60,A:255). - /// - public static Color Crimson => new(220, 20, 60); - - /// - /// Cyan color (R:0,G:255,B:255,A:255). - /// - public static Color Cyan => new(0, 255, 255); - - /// - /// DarkBlue color (R:0,G:0,B:139,A:255). - /// - public static Color DarkBlue => new(0, 0, 139); - - /// - /// DarkCyan color (R:0,G:139,B:139,A:255). - /// - public static Color DarkCyan => new(0, 139, 139); - - /// - /// DarkGoldenrod color (R:184,G:134,B:11,A:255). - /// - public static Color DarkGoldenrod => new(184, 134, 11); - - /// - /// DarkGray color (R:169,G:169,B:169,A:255). - /// - public static Color DarkGray => new(169, 169, 169); - - /// - /// DarkGreen color (R:0,G:100,B:0,A:255). - /// - public static Color DarkGreen => new(0, 100, 0); - - /// - /// DarkKhaki color (R:189,G:183,B:107,A:255). - /// - public static Color DarkKhaki => new(189, 183, 107); - - /// - /// DarkMagenta color (R:139,G:0,B:139,A:255). - /// - public static Color DarkMagenta => new(139, 0, 139); - - /// - /// DarkOliveGreen color (R:85,G:107,B:47,A:255). - /// - public static Color DarkOliveGreen => new(85, 107, 47); - - /// - /// DarkOrange color (R:255,G:140,B:0,A:255). - /// - public static Color DarkOrange => new(255, 140, 0); - - /// - /// DarkOrchid color (R:153,G:50,B:204,A:255). - /// - public static Color DarkOrchid => new(153, 50, 204); - - /// - /// DarkRed color (R:139,G:0,B:0,A:255). - /// - public static Color DarkRed => new(139, 0, 0); - - /// - /// DarkSalmon color (R:233,G:150,B:122,A:255). - /// - public static Color DarkSalmon => new(233, 150, 122); - - /// - /// DarkSeaGreen color (R:143,G:188,B:139,A:255). - /// - public static Color DarkSeaGreen => new(143, 188, 139); - - /// - /// DarkSlateBlue color (R:72,G:61,B:139,A:255). - /// - public static Color DarkSlateBlue => new(72, 61, 139); - - /// - /// DarkSlateGray color (R:47,G:79,B:79,A:255). - /// - public static Color DarkSlateGray => new(47, 79, 79); - - /// - /// DarkTurquoise color (R:0,G:206,B:209,A:255). - /// - public static Color DarkTurquoise => new(0, 206, 209); - - /// - /// DarkViolet color (R:148,G:0,B:211,A:255). - /// - public static Color DarkViolet => new(148, 0, 211); - - /// - /// DeepPink color (R:255,G:20,B:147,A:255). - /// - public static Color DeepPink => new(255, 20, 147); - - /// - /// DeepSkyBlue color (R:0,G:191,B:255,A:255). - /// - public static Color DeepSkyBlue => new(0, 191, 255); - - /// - /// DimGray color (R:105,G:105,B:105,A:255). - /// - public static Color DimGray => new(105, 105, 105); - - /// - /// DodgerBlue color (R:30,G:144,B:255,A:255). - /// - public static Color DodgerBlue => new(30, 144, 255); - - /// - /// Firebrick color (R:178,G:34,B:34,A:255). - /// - public static Color Firebrick => new(178, 34, 34); - - /// - /// FloralWhite color (R:255,G:250,B:240,A:255). - /// - public static Color FloralWhite => new(255, 250, 240); - - /// - /// ForestGreen color (R:34,G:139,B:34,A:255). - /// - public static Color ForestGreen => new(34, 139, 34); - - /// - /// Fuchsia color (R:255,G:0,B:255,A:255). - /// - public static Color Fuchsia => new(255, 0, 255); - - /// - /// Gainsboro color (R:220,G:220,B:220,A:255). - /// - public static Color Gainsboro => new(220, 220, 220); - - /// - /// GhostWhite color (R:248,G:248,B:255,A:255). - /// - public static Color GhostWhite => new(248, 248, 255); - - /// - /// Gold color (R:255,G:215,B:0,A:255). - /// - public static Color Gold => new(255, 215, 0); - - /// - /// Goldenrod color (R:218,G:165,B:32,A:255). - /// - public static Color Goldenrod => new(218, 165, 32); - - /// - /// Gray color (R:128,G:128,B:128,A:255). - /// - public static Color Gray => new(128, 128, 128); - - /// - /// Green color (R:0,G:128,B:0,A:255). - /// - public static Color Green => new(0, 128, 0); - - /// - /// GreenYellow color (R:173,G:255,B:47,A:255). - /// - public static Color GreenYellow => new(173, 255, 47); - - /// - /// Honeydew color (R:240,G:255,B:240,A:255). - /// - public static Color Honeydew => new(240, 255, 240); - - /// - /// HotPink color (R:255,G:105,B:180,A:255). - /// - public static Color HotPink => new(255, 105, 180); - - /// - /// IndianRed color (R:205,G:92,B:92,A:255). - /// - public static Color IndianRed => new(205, 92, 92); - - /// - /// Indigo color (R:75,G:0,B:130,A:255). - /// - public static Color Indigo => new(75, 0, 130); - - /// - /// Ivory color (R:255,G:255,B:240,A:255). - /// - public static Color Ivory => new(255, 255, 240); - - /// - /// Khaki color (R:240,G:230,B:140,A:255). - /// - public static Color Khaki => new(240, 230, 140); - - /// - /// Lavender color (R:230,G:230,B:250,A:255). - /// - public static Color Lavender => new(230, 230, 250); - - /// - /// LavenderBlush color (R:255,G:240,B:245,A:255). - /// - public static Color LavenderBlush => new(255, 240, 245); - - /// - /// LawnGreen color (R:124,G:252,B:0,A:255). - /// - public static Color LawnGreen => new(124, 252, 0); - - /// - /// LemonChiffon color (R:255,G:250,B:205,A:255). - /// - public static Color LemonChiffon => new(255, 250, 205); - - /// - /// LightBlue color (R:173,G:216,B:230,A:255). - /// - public static Color LightBlue => new(173, 216, 230); - - /// - /// LightCoral color (R:240,G:128,B:128,A:255). - /// - public static Color LightCoral => new(240, 128, 128); - - /// - /// LightCyan color (R:224,G:255,B:255,A:255). - /// - public static Color LightCyan => new(224, 255, 255); - - /// - /// LightGoldenrodYellow color (R:250,G:250,B:210,A:255). - /// - public static Color LightGoldenrodYellow => new(250, 250, 210); - - /// - /// LightGray color (R:211,G:211,B:211,A:255). - /// - public static Color LightGray => new(211, 211, 211); - - /// - /// LightGreen color (R:144,G:238,B:144,A:255). - /// - public static Color LightGreen => new(144, 238, 144); - - /// - /// LightPink color (R:255,G:182,B:193,A:255). - /// - public static Color LightPink => new(255, 182, 193); - - /// - /// LightSalmon color (R:255,G:160,B:122,A:255). - /// - public static Color LightSalmon => new(255, 160, 122); - - /// - /// LightSeaGreen color (R:32,G:178,B:170,A:255). - /// - public static Color LightSeaGreen => new(32, 178, 170); - - /// - /// LightSkyBlue color (R:135,G:206,B:250,A:255). - /// - public static Color LightSkyBlue => new(135, 206, 250); - - /// - /// LightSlateGray color (R:119,G:136,B:153,A:255). - /// - public static Color LightSlateGray => new(119, 136, 153); - - /// - /// LightSteelBlue color (R:176,G:196,B:222,A:255). - /// - public static Color LightSteelBlue => new(179, 196, 222); - - /// - /// LightYellow color (R:255,G:255,B:224,A:255). - /// - public static Color LightYellow => new(255, 255, 224); - - /// - /// Lime color (R:0,G:255,B:0,A:255). - /// - public static Color Lime => new(0, 255, 0); - - /// - /// LimeGreen color (R:50,G:205,B:50,A:255). - /// - public static Color LimeGreen => new(50, 205, 50); - - /// - /// Linen color (R:250,G:240,B:230,A:255). - /// - public static Color Linen => new(250, 240, 230); - - /// - /// Magenta color (R:255,G:0,B:255,A:255). - /// - public static Color Magenta => new(255, 0, 255); - - /// - /// Maroon color (R:128,G:0,B:0,A:255). - /// - public static Color Maroon => new(128, 0, 0, 255); - - /// - /// MediumAquamarine color (R:102,G:205,B:170,A:255). - /// - public static Color MediumAquamarine => new(102, 205, 170); - - /// - /// MediumBlue color (R:0,G:0,B:205,A:255). - /// - public static Color MediumBlue => new(0, 0, 205); - - /// - /// MediumOrchid color (R:186,G:85,B:211,A:255). - /// - public static Color MediumOrchid => new(186, 85, 211); - - /// - /// MediumPurple color (R:147,G:112,B:219,A:255). - /// - public static Color MediumPurple => new(147, 112, 219); - - /// - /// MediumSeaGreen color (R:60,G:179,B:113,A:255). - /// - public static Color MediumSeaGreen => new(60, 179, 113); - - /// - /// MediumSlateBlue color (R:123,G:104,B:238,A:255). - /// - public static Color MediumSlateBlue => new(123, 104, 238); - - /// - /// MediumSpringGreen color (R:0,G:250,B:154,A:255). - /// - public static Color MediumSpringGreen => new(0, 250, 154); - - /// - /// MediumTurquoise color (R:72,G:209,B:204,A:255). - /// - public static Color MediumTurquoise => new(72, 209, 204); - - /// - /// MediumVioletRed color (R:199,G:21,B:133,A:255). - /// - public static Color MediumVioletRed => new(199, 21, 133); - - /// - /// MidnightBlue color (R:25,G:25,B:112,A:255). - /// - public static Color MidnightBlue => new(25, 25, 112); - - /// - /// MintCream color (R:245,G:255,B:250,A:255). - /// - public static Color MintCream => new(245, 255, 250); - - /// - /// MistyRose color (R:255,G:228,B:225,A:255). - /// - public static Color MistyRose => new(255, 228, 225); - - /// - /// Moccasin color (R:255,G:228,B:181,A:255). - /// - public static Color Moccasin => new(255, 228, 181); - - /// - /// NavajoWhite color (R:255,G:222,B:173,A:255). - /// - public static Color NavajoWhite => new(255, 222, 173); - - /// - /// Navy color (R:0,G:0,B:128,A:255). - /// - public static Color Navy => new(0, 0, 128); - - /// - /// OldLace color (R:253,G:245,B:230,A:255). - /// - public static Color OldLace => new(253, 245, 230); - - /// - /// Olive color (R:128,G:128,B:0,A:255). - /// - public static Color Olive => new(128, 128, 0); - - /// - /// OliveDrab color (R:107,G:142,B:35,A:255). - /// - public static Color OliveDrab => new(107, 142, 35); - - /// - /// Orange color (R:255,G:165,B:0,A:255). - /// - public static Color Orange => new(255, 165, 0); - - /// - /// OrangeRed color (R:255,G:69,B:0,A:255). - /// - public static Color OrangeRed => new(255, 69, 0); - - /// - /// Orchid color (R:218,G:112,B:214,A:255). - /// - public static Color Orchid => new(218, 112, 214); - - /// - /// PaleGoldenrod color (R:238,G:232,B:170,A:255). - /// - public static Color PaleGoldenrod => new(238, 232, 170); - - /// - /// PaleGreen color (R:152,G:251,B:152,A:255). - /// - public static Color PaleGreen => new(152, 251, 152); - - /// - /// PaleTurquoise color (R:175,G:238,B:238,A:255). - /// - public static Color PaleTurquoise => new(175, 238, 238); - - /// - /// PaleVioletRed color (R:219,G:112,B:147,A:255). - /// - public static Color PaleVioletRed => new(219, 112, 147); - - /// - /// PapayaWhip color (R:255,G:239,B:213,A:255). - /// - public static Color PapayaWhip => new(255, 239, 213); - - /// - /// PeachPuff color (R:255,G:218,B:185,A:255). - /// - public static Color PeachPuff => new(255, 218, 185); - - /// - /// Peru color (R:205,G:133,B:63,A:255). - /// - public static Color Peru => new(205, 133, 63); - - /// - /// Pink color (R:255,G:192,B:203,A:255). - /// - public static Color Pink => new(255, 192, 203); - - /// - /// Plum color (R:221,G:160,B:221,A:255). - /// - public static Color Plum => new(221, 160, 221); - - /// - /// PowderBlue color (R:176,G:224,B:230,A:255). - /// - public static Color PowderBlue => new(176, 224, 230); - - /// - /// Purple color (R:128,G:0,B:128,A:255). - /// - public static Color Purple => new(128, 0, 128); - - /// - /// Red color (R:255,G:0,B:0,A:255). - /// - public static Color Red => new(255, 0, 0); - - /// - /// RosyBrown color (R:188,G:143,B:143,A:255). - /// - public static Color RosyBrown => new(188, 143, 143); - - /// - /// RoyalBlue color (R:65,G:105,B:225,A:255). - /// - public static Color RoyalBlue => new(65, 105, 225); - - /// - /// SaddleBrown color (R:139,G:69,B:19,A:255). - /// - public static Color SaddleBrown => new(139, 69, 19); - - /// - /// Salmon color (R:250,G:128,B:114,A:255). - /// - public static Color Salmon => new(250, 128, 114); - - /// - /// SandyBrown color (R:244,G:164,B:96,A:255). - /// - public static Color SandyBrown => new(244, 164, 96); - - /// - /// SeaGreen color (R:46,G:139,B:87,A:255). - /// - public static Color SeaGreen => new(46, 139, 87); - - /// - /// SeaShell color (R:255,G:245,B:238,A:255). - /// - public static Color SeaShell => new(255, 245, 238); - - /// - /// Sienna color (R:160,G:82,B:45,A:255). - /// - public static Color Sienna => new(160, 82, 45); - - /// - /// Silver color (R:192,G:192,B:192,A:255). - /// - public static Color Silver => new(192, 192, 192); - - /// - /// SkyBlue color (R:135,G:206,B:235,A:255). - /// - public static Color SkyBlue => new(135, 206, 235); - - /// - /// SlateBlue color (R:106,G:90,B:205,A:255). - /// - public static Color SlateBlue => new(106, 90, 205); - - /// - /// SlateGray color (R:112,G:128,B:144,A:255). - /// - public static Color SlateGray => new(112, 128, 144); - - /// - /// Snow color (R:255,G:250,B:250,A:255). - /// - public static Color Snow => new(255, 250, 250); - - /// - /// SpringGreen color (R:0,G:255,B:127,A:255). - /// - public static Color SpringGreen => new(0, 255, 127); - - /// - /// SteelBlue color (R:70,G:130,B:180,A:255). - /// - public static Color SteelBlue => new(70, 130, 180); - - /// - /// Tan color (R:210,G:180,B:140,A:255). - /// - public static Color Tan => new(210, 180, 140); - - /// - /// Teal color (R:0,G:128,B:128,A:255). - /// - public static Color Teal => new(0, 128, 128); - - /// - /// Thistle color (R:216,G:191,B:216,A:255). - /// - public static Color Thistle => new(216, 191, 216); - - /// - /// Tomato color (R:255,G:99,B:71,A:255). - /// - public static Color Tomato => new(255, 99, 71); - - /// - /// Turquoise color (R:64,G:224,B:208,A:255). - /// - public static Color Turquoise => new(64, 224, 208); - - /// - /// Violet color (R:238,G:130,B:238,A:255). - /// - public static Color Violet => new(238, 130, 238); - - /// - /// Wheat color (R:245,G:222,B:179,A:255). - /// - public static Color Wheat => new(245, 222, 179); - - /// - /// White color (R:255,G:255,B:255,A:255). - /// - public static Color White => new(255, 255, 255); - - /// - /// WhiteSmoke color (R:245,G:245,B:245,A:255). - /// - public static Color WhiteSmoke => new(245, 245, 245); - - /// - /// Yellow color (R:255,G:255,B:0,A:255). - /// - public static Color Yellow => new(255, 255, 0); - - /// - /// YellowGreen color (R:154,G:205,B:50,A:255). - /// - public static Color YellowGreen => new(154, 205, 50); - - /// - /// Gets a representation for this object. - /// - /// A representation for this object. - public Vector3 ToVector3() - { - return new Vector3(R / 255.0f, G / 255.0f, B / 255.0f); - } - - /// - /// Gets a representation for this object. - /// - /// A representation for this object. - public Vector4 ToVector4() - { - return new Vector4(R / 255.0f, G / 255.0f, B / 255.0f, A / 255.0f); - } - - /// - /// Performs linear interpolation of . - /// - /// Source . - /// Destination . - /// Interpolation factor. - /// Interpolated . - public static Color Lerp(Color value1, Color value2, float amount) - { - amount = float.Clamp(amount, 0.0f, 1.0f); - return new Color( - float.Lerp(value1.R / 255f, value2.R / 255f, amount), - float.Lerp(value1.G / 255f, value2.G / 255f, amount), - float.Lerp(value1.B / 255f, value2.B / 255f, amount), - float.Lerp(value1.A / 255f, value2.A / 255f, amount) - ); - } - - /// - /// Translate a non-premultipled alpha to a - /// that contains premultiplied alpha. - /// - /// A representing color. - /// A which contains premultiplied alpha data. - public static Color FromNonPremultiplied(System.Numerics.Vector4 vector) - { - return new Color( - vector.X * vector.W, - vector.Y * vector.W, - vector.Z * vector.W, - vector.W - ); - } - - /// - /// Translate a non-premultipled alpha to a - /// that contains premultiplied alpha. - /// - /// Red component value. - /// Green component value. - /// Blue component value. - /// Alpha component value. - /// A which contains premultiplied alpha data. - public static Color FromNonPremultiplied(byte r, byte g, byte b, byte a) - { - return new Color( - r * a / 255, - g * a / 255, - b * a / 255, - a - ); - } - - // Modified from one of the responses here: - // https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both/6930407#6930407 - public static Color FromHSV(float r, float g, float b) - { - r = (100 + r) % 1f; - - float hueSlice = 6 * r; // [0, 6) - float hueSliceInteger = MathF.Floor(hueSlice); - - // In [0,1) for each hue slice - float hueSliceInterpolant = hueSlice - hueSliceInteger; - - Vector3 tempRGB = new Vector3( - b * (1f - g), - b * (1f - g * hueSliceInterpolant), - b * (1f - g * (1f - hueSliceInterpolant)) - ); - - // The idea here to avoid conditions is to notice that the conversion code can be rewritten: - // if ( var_i == 0 ) { R = V ; G = TempRGB.z ; B = TempRGB.x } - // else if ( var_i == 2 ) { R = TempRGB.x ; G = V ; B = TempRGB.z } - // else if ( var_i == 4 ) { R = TempRGB.z ; G = TempRGB.x ; B = V } - // - // else if ( var_i == 1 ) { R = TempRGB.y ; G = V ; B = TempRGB.x } - // else if ( var_i == 3 ) { R = TempRGB.x ; G = TempRGB.y ; B = V } - // else if ( var_i == 5 ) { R = V ; G = TempRGB.x ; B = TempRGB.y } - // - // This shows several things: - // . A separation between even and odd slices - // . If slices (0,2,4) and (1,3,5) can be rewritten as basically being slices (0,1,2) then - // the operation simply amounts to performing a "rotate right" on the RGB components - // . The base value to rotate is either (V, B, R) for even slices or (G, V, R) for odd slices - // - float isOddSlice = hueSliceInteger % 2f; // 0 if even (slices 0, 2, 4), 1 if odd (slices 1, 3, 5) - float threeSliceSelector = 0.5f * (hueSliceInteger - isOddSlice); // (0, 1, 2) corresponding to slices (0, 2, 4) and (1, 3, 5) - - Vector3 scrollingRGBForEvenSlices = new Vector3(b, tempRGB.Z, tempRGB.X); // (V, Temp Blue, Temp Red) for even slices (0, 2, 4) - Vector3 scrollingRGBForOddSlices = new Vector3(tempRGB.Y, b, tempRGB.X); // (Temp Green, V, Temp Red) for odd slices (1, 3, 5) - Vector3 scrollingRGB = Vector3.Lerp(scrollingRGBForEvenSlices, scrollingRGBForOddSlices, isOddSlice); - - float IsNotFirstSlice = float.Clamp(threeSliceSelector, 0f, 1f); // 1 if NOT the first slice (true for slices 1 and 2) - float IsNotSecondSlice = float.Clamp(threeSliceSelector - 1f, 0f, 1f); // 1 if NOT the first or second slice (true only for slice 2) - - Vector3 color = Vector3.Lerp( - scrollingRGB, - Vector3.Lerp( - new Vector3(scrollingRGB.Z, scrollingRGB.X, scrollingRGB.Y), - new Vector3(scrollingRGB.Y, scrollingRGB.Z, scrollingRGB.X), - IsNotSecondSlice - ), - IsNotFirstSlice - ); - - return new Color(color.X, color.Y, color.Z, 1f); - } - - public static Color FromHSV(int r, int g, int b) - { - return FromHSV(r / 255f, g / 255f, b / 255f); - } - - /// - /// Multiply by value. - /// - /// Source . - /// Multiplicator. - /// Multiplication result. - public static Color operator *(Color value, float scale) - { - return new Color( - value.R * scale / 255f, - value.G * scale / 255f, - value.B * scale / 255f, - value.A * scale / 255f - ); - } - - /// - /// Returns a representation of this in the format: - /// {R:[red] G:[green] B:[blue] A:[alpha]} - /// - /// representation of this . - public override string ToString() - { - StringBuilder sb = new StringBuilder(25); - sb.Append("{R:"); - sb.Append(R); - sb.Append(" G:"); - sb.Append(G); - sb.Append(" B:"); - sb.Append(B); - sb.Append(" A:"); - sb.Append(A); - sb.Append("}"); - return sb.ToString(); - } - - public static implicit operator VertexStructs.Ubyte4Norm(Color color) => new VertexStructs.Ubyte4Norm - { - X = color.R, - Y = color.G, - Z = color.B, - W = color.A - }; - - public static implicit operator FColor(Color color) => new FColor - { - R = color.R / 255f, - G = color.G / 255f, - B = color.B / 255f, - A = color.A / 255f - }; + return new Vector3(R / 255.0f, G / 255.0f, B / 255.0f); } -} + + /// + /// Gets a representation for this object. + /// + /// A representation for this object. + public Vector4 ToVector4() + { + return new Vector4(R / 255.0f, G / 255.0f, B / 255.0f, A / 255.0f); + } + + /// + /// Performs linear interpolation of . + /// + /// Source . + /// Destination . + /// Interpolation factor. + /// Interpolated . + public static Color Lerp(Color value1, Color value2, float amount) + { + amount = float.Clamp(amount, 0.0f, 1.0f); + return new Color( + float.Lerp(value1.R / 255f, value2.R / 255f, amount), + float.Lerp(value1.G / 255f, value2.G / 255f, amount), + float.Lerp(value1.B / 255f, value2.B / 255f, amount), + float.Lerp(value1.A / 255f, value2.A / 255f, amount) + ); + } + + /// + /// Translate a non-premultipled alpha to a + /// that contains premultiplied alpha. + /// + /// A representing color. + /// A which contains premultiplied alpha data. + public static Color FromNonPremultiplied(System.Numerics.Vector4 vector) + { + return new Color( + vector.X * vector.W, + vector.Y * vector.W, + vector.Z * vector.W, + vector.W + ); + } + + /// + /// Translate a non-premultipled alpha to a + /// that contains premultiplied alpha. + /// + /// Red component value. + /// Green component value. + /// Blue component value. + /// Alpha component value. + /// A which contains premultiplied alpha data. + public static Color FromNonPremultiplied(byte r, byte g, byte b, byte a) + { + return new Color( + r * a / 255, + g * a / 255, + b * a / 255, + a + ); + } + + // Modified from one of the responses here: + // https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both/6930407#6930407 + public static Color FromHSV(float r, float g, float b) + { + r = (100 + r) % 1f; + + float hueSlice = 6 * r; // [0, 6) + float hueSliceInteger = MathF.Floor(hueSlice); + + // In [0,1) for each hue slice + float hueSliceInterpolant = hueSlice - hueSliceInteger; + + Vector3 tempRGB = new Vector3( + b * (1f - g), + b * (1f - g * hueSliceInterpolant), + b * (1f - g * (1f - hueSliceInterpolant)) + ); + + // The idea here to avoid conditions is to notice that the conversion code can be rewritten: + // if ( var_i == 0 ) { R = V ; G = TempRGB.z ; B = TempRGB.x } + // else if ( var_i == 2 ) { R = TempRGB.x ; G = V ; B = TempRGB.z } + // else if ( var_i == 4 ) { R = TempRGB.z ; G = TempRGB.x ; B = V } + // + // else if ( var_i == 1 ) { R = TempRGB.y ; G = V ; B = TempRGB.x } + // else if ( var_i == 3 ) { R = TempRGB.x ; G = TempRGB.y ; B = V } + // else if ( var_i == 5 ) { R = V ; G = TempRGB.x ; B = TempRGB.y } + // + // This shows several things: + // . A separation between even and odd slices + // . If slices (0,2,4) and (1,3,5) can be rewritten as basically being slices (0,1,2) then + // the operation simply amounts to performing a "rotate right" on the RGB components + // . The base value to rotate is either (V, B, R) for even slices or (G, V, R) for odd slices + // + float isOddSlice = hueSliceInteger % 2f; // 0 if even (slices 0, 2, 4), 1 if odd (slices 1, 3, 5) + float threeSliceSelector = 0.5f * (hueSliceInteger - isOddSlice); // (0, 1, 2) corresponding to slices (0, 2, 4) and (1, 3, 5) + + Vector3 scrollingRGBForEvenSlices = new Vector3(b, tempRGB.Z, tempRGB.X); // (V, Temp Blue, Temp Red) for even slices (0, 2, 4) + Vector3 scrollingRGBForOddSlices = new Vector3(tempRGB.Y, b, tempRGB.X); // (Temp Green, V, Temp Red) for odd slices (1, 3, 5) + Vector3 scrollingRGB = Vector3.Lerp(scrollingRGBForEvenSlices, scrollingRGBForOddSlices, isOddSlice); + + float IsNotFirstSlice = float.Clamp(threeSliceSelector, 0f, 1f); // 1 if NOT the first slice (true for slices 1 and 2) + float IsNotSecondSlice = float.Clamp(threeSliceSelector - 1f, 0f, 1f); // 1 if NOT the first or second slice (true only for slice 2) + + Vector3 color = Vector3.Lerp( + scrollingRGB, + Vector3.Lerp( + new Vector3(scrollingRGB.Z, scrollingRGB.X, scrollingRGB.Y), + new Vector3(scrollingRGB.Y, scrollingRGB.Z, scrollingRGB.X), + IsNotSecondSlice + ), + IsNotFirstSlice + ); + + return new Color(color.X, color.Y, color.Z, 1f); + } + + public static Color FromHSV(int r, int g, int b) + { + return FromHSV(r / 255f, g / 255f, b / 255f); + } + + /// + /// Multiply by value. + /// + /// Source . + /// Multiplicator. + /// Multiplication result. + public static Color operator *(Color value, float scale) + { + return new Color( + value.R * scale / 255f, + value.G * scale / 255f, + value.B * scale / 255f, + value.A * scale / 255f + ); + } + + /// + /// Returns a representation of this in the format: + /// {R:[red] G:[green] B:[blue] A:[alpha]} + /// + /// representation of this . + public override string ToString() + { + StringBuilder sb = new StringBuilder(25); + sb.Append("{R:"); + sb.Append(R); + sb.Append(" G:"); + sb.Append(G); + sb.Append(" B:"); + sb.Append(B); + sb.Append(" A:"); + sb.Append(A); + sb.Append("}"); + return sb.ToString(); + } + +/// + /// Returns a hexadecimal representation of this in the format: + /// 0x[R][G][B][A] + /// + /// representation of this . + public string ToHexString() + { + StringBuilder sb = new StringBuilder(25); + sb.Append("#"); + sb.Append(R.ToString("X2")); + sb.Append(G.ToString("X2")); + sb.Append(B.ToString("X2")); + sb.Append(A.ToString("X2")); + return sb.ToString(); + } + + public static implicit operator VertexStructs.Ubyte4Norm(Color color) => new VertexStructs.Ubyte4Norm + { + X = color.R, + Y = color.G, + Z = color.B, + W = color.A + }; + + public static implicit operator FColor(Color color) => new FColor + { + R = color.R / 255f, + G = color.G / 255f, + B = color.B / 255f, + A = color.A / 255f + }; + + +#region Built-In Colors + /// + /// Transparent color (R:255, G:255, B:255, A:0). + /// RGBA Hex: #FFFFFF00. + /// + public static Color Transparent => FromPacked(0xFFFFFF00u); + + /// + /// AliceBlue color (R:240, G:248, B:255, A:255). + /// RGBA Hex: #F0F8FFFF. + /// + public static Color AliceBlue => FromPacked(0xF0F8FFFFu); + + /// + /// AntiqueWhite color (R:250, G:235, B:215, A:255). + /// RGBA Hex: #FAEBD7FF. + /// + public static Color AntiqueWhite => FromPacked(0xFAEBD7FFu); + + /// + /// Aqua color (R:0, G:255, B:255, A:255). + /// RGBA Hex: #00FFFFFF. + /// + public static Color Aqua => FromPacked(0x00FFFFFFu); + + /// + /// Aquamarine color (R:127, G:255, B:212, A:255). + /// RGBA Hex: #7FFFD4FF. + /// + public static Color Aquamarine => FromPacked(0x7FFFD4FFu); + + /// + /// Azure color (R:240, G:255, B:255, A:255). + /// RGBA Hex: #F0FFFFFF. + /// + public static Color Azure => FromPacked(0xF0FFFFFFu); + + /// + /// Beige color (R:245, G:245, B:220, A:255). + /// RGBA Hex: #F5F5DCFF. + /// + public static Color Beige => FromPacked(0xF5F5DCFFu); + + /// + /// Bisque color (R:255, G:228, B:196, A:255). + /// RGBA Hex: #FFE4C4FF. + /// + public static Color Bisque => FromPacked(0xFFE4C4FFu); + + /// + /// Black color (R:0, G:0, B:0, A:255). + /// RGBA Hex: #000000FF. + /// + public static Color Black => FromPacked(0x000000FFu); + + /// + /// BlanchedAlmond color (R:255, G:235, B:205, A:255). + /// RGBA Hex: #FFEBCDFF. + /// + public static Color BlanchedAlmond => FromPacked(0xFFEBCDFFu); + + /// + /// Blue color (R:0, G:0, B:255, A:255). + /// RGBA Hex: #0000FFFF. + /// + public static Color Blue => FromPacked(0x0000FFFFu); + + /// + /// BlueViolet color (R:138, G:43, B:226, A:255). + /// RGBA Hex: #8A2BE2FF. + /// + public static Color BlueViolet => FromPacked(0x8A2BE2FFu); + + /// + /// Brown color (R:165, G:42, B:42, A:255). + /// RGBA Hex: #A52A2AFF. + /// + public static Color Brown => FromPacked(0xA52A2AFFu); + + /// + /// BurlyWood color (R:222, G:184, B:135, A:255). + /// RGBA Hex: #DEB887FF. + /// + public static Color BurlyWood => FromPacked(0xDEB887FFu); + + /// + /// CadetBlue color (R:95, G:158, B:160, A:255). + /// RGBA Hex: #5F9EA0FF. + /// + public static Color CadetBlue => FromPacked(0x5F9EA0FFu); + + /// + /// Chartreuse color (R:127, G:255, B:0, A:255). + /// RGBA Hex: #7FFF00FF. + /// + public static Color Chartreuse => FromPacked(0x7FFF00FFu); + + /// + /// Chocolate color (R:210, G:105, B:30, A:255). + /// RGBA Hex: #D2691EFF. + /// + public static Color Chocolate => FromPacked(0xD2691EFFu); + + /// + /// Coral color (R:255, G:127, B:80, A:255). + /// RGBA Hex: #FF7F50FF. + /// + public static Color Coral => FromPacked(0xFF7F50FFu); + + /// + /// CornflowerBlue color (R:100, G:149, B:237, A:255). + /// RGBA Hex: #6495EDFF. + /// + public static Color CornflowerBlue => FromPacked(0x6495EDFFu); + + /// + /// Cornsilk color (R:255, G:248, B:220, A:255). + /// RGBA Hex: #FFF8DCFF. + /// + public static Color Cornsilk => FromPacked(0xFFF8DCFFu); + + /// + /// Crimson color (R:220, G:20, B:60, A:255). + /// RGBA Hex: #DC143CFF. + /// + public static Color Crimson => FromPacked(0xDC143CFFu); + + /// + /// Cyan color (R:0, G:255, B:255, A:255). + /// RGBA Hex: #00FFFFFF. + /// + public static Color Cyan => FromPacked(0x00FFFFFFu); + + /// + /// DarkBlue color (R:0, G:0, B:139, A:255). + /// RGBA Hex: #00008BFF. + /// + public static Color DarkBlue => FromPacked(0x00008BFFu); + + /// + /// DarkCyan color (R:0, G:139, B:139, A:255). + /// RGBA Hex: #008B8BFF. + /// + public static Color DarkCyan => FromPacked(0x008B8BFFu); + + /// + /// DarkGoldenrod color (R:184, G:134, B:11, A:255). + /// RGBA Hex: #B8860BFF. + /// + public static Color DarkGoldenrod => FromPacked(0xB8860BFFu); + + /// + /// DarkGray color (R:169, G:169, B:169, A:255). + /// RGBA Hex: #A9A9A9FF. + /// + public static Color DarkGray => FromPacked(0xA9A9A9FFu); + + /// + /// DarkGreen color (R:0, G:100, B:0, A:255). + /// RGBA Hex: #006400FF. + /// + public static Color DarkGreen => FromPacked(0x006400FFu); + + /// + /// DarkKhaki color (R:189, G:183, B:107, A:255). + /// RGBA Hex: #BDB76BFF. + /// + public static Color DarkKhaki => FromPacked(0xBDB76BFFu); + + /// + /// DarkMagenta color (R:139, G:0, B:139, A:255). + /// RGBA Hex: #8B008BFF. + /// + public static Color DarkMagenta => FromPacked(0x8B008BFFu); + + /// + /// DarkOliveGreen color (R:85, G:107, B:47, A:255). + /// RGBA Hex: #556B2FFF. + /// + public static Color DarkOliveGreen => FromPacked(0x556B2FFFu); + + /// + /// DarkOrange color (R:255, G:140, B:0, A:255). + /// RGBA Hex: #FF8C00FF. + /// + public static Color DarkOrange => FromPacked(0xFF8C00FFu); + + /// + /// DarkOrchid color (R:153, G:50, B:204, A:255). + /// RGBA Hex: #9932CCFF. + /// + public static Color DarkOrchid => FromPacked(0x9932CCFFu); + + /// + /// DarkRed color (R:139, G:0, B:0, A:255). + /// RGBA Hex: #8B0000FF. + /// + public static Color DarkRed => FromPacked(0x8B0000FFu); + + /// + /// DarkSalmon color (R:233, G:150, B:122, A:255). + /// RGBA Hex: #E9967AFF. + /// + public static Color DarkSalmon => FromPacked(0xE9967AFFu); + + /// + /// DarkSeaGreen color (R:143, G:188, B:143, A:255). + /// RGBA Hex: #8FBC8FFF. + /// + public static Color DarkSeaGreen => FromPacked(0x8FBC8FFFu); + + /// + /// DarkSlateBlue color (R:72, G:61, B:139, A:255). + /// RGBA Hex: #483D8BFF. + /// + public static Color DarkSlateBlue => FromPacked(0x483D8BFFu); + + /// + /// DarkSlateGray color (R:47, G:79, B:79, A:255). + /// RGBA Hex: #2F4F4FFF. + /// + public static Color DarkSlateGray => FromPacked(0x2F4F4FFFu); + + /// + /// DarkTurquoise color (R:0, G:206, B:209, A:255). + /// RGBA Hex: #00CED1FF. + /// + public static Color DarkTurquoise => FromPacked(0x00CED1FFu); + + /// + /// DarkViolet color (R:148, G:0, B:211, A:255). + /// RGBA Hex: #9400D3FF. + /// + public static Color DarkViolet => FromPacked(0x9400D3FFu); + + /// + /// DeepPink color (R:255, G:20, B:147, A:255). + /// RGBA Hex: #FF1493FF. + /// + public static Color DeepPink => FromPacked(0xFF1493FFu); + + /// + /// DeepSkyBlue color (R:0, G:191, B:255, A:255). + /// RGBA Hex: #00BFFFFF. + /// + public static Color DeepSkyBlue => FromPacked(0x00BFFFFFu); + + /// + /// DimGray color (R:105, G:105, B:105, A:255). + /// RGBA Hex: #696969FF. + /// + public static Color DimGray => FromPacked(0x696969FFu); + + /// + /// DodgerBlue color (R:30, G:144, B:255, A:255). + /// RGBA Hex: #1E90FFFF. + /// + public static Color DodgerBlue => FromPacked(0x1E90FFFFu); + + /// + /// Firebrick color (R:178, G:34, B:34, A:255). + /// RGBA Hex: #B22222FF. + /// + public static Color Firebrick => FromPacked(0xB22222FFu); + + /// + /// FloralWhite color (R:255, G:250, B:240, A:255). + /// RGBA Hex: #FFFAF0FF. + /// + public static Color FloralWhite => FromPacked(0xFFFAF0FFu); + + /// + /// ForestGreen color (R:34, G:139, B:34, A:255). + /// RGBA Hex: #228B22FF. + /// + public static Color ForestGreen => FromPacked(0x228B22FFu); + + /// + /// Fuchsia color (R:255, G:0, B:255, A:255). + /// RGBA Hex: #FF00FFFF. + /// + public static Color Fuchsia => FromPacked(0xFF00FFFFu); + + /// + /// Gainsboro color (R:220, G:220, B:220, A:255). + /// RGBA Hex: #DCDCDCFF. + /// + public static Color Gainsboro => FromPacked(0xDCDCDCFFu); + + /// + /// GhostWhite color (R:248, G:248, B:255, A:255). + /// RGBA Hex: #F8F8FFFF. + /// + public static Color GhostWhite => FromPacked(0xF8F8FFFFu); + + /// + /// Gold color (R:255, G:215, B:0, A:255). + /// RGBA Hex: #FFD700FF. + /// + public static Color Gold => FromPacked(0xFFD700FFu); + + /// + /// Goldenrod color (R:218, G:165, B:32, A:255). + /// RGBA Hex: #DAA520FF. + /// + public static Color Goldenrod => FromPacked(0xDAA520FFu); + + /// + /// Gray color (R:128, G:128, B:128, A:255). + /// RGBA Hex: #808080FF. + /// + public static Color Gray => FromPacked(0x808080FFu); + + /// + /// Green color (R:0, G:128, B:0, A:255). + /// RGBA Hex: #008000FF. + /// + public static Color Green => FromPacked(0x008000FFu); + + /// + /// GreenYellow color (R:173, G:255, B:47, A:255). + /// RGBA Hex: #ADFF2FFF. + /// + public static Color GreenYellow => FromPacked(0xADFF2FFFu); + + /// + /// Honeydew color (R:240, G:255, B:240, A:255). + /// RGBA Hex: #F0FFF0FF. + /// + public static Color Honeydew => FromPacked(0xF0FFF0FFu); + + /// + /// HotPink color (R:255, G:105, B:180, A:255). + /// RGBA Hex: #FF69B4FF. + /// + public static Color HotPink => FromPacked(0xFF69B4FFu); + + /// + /// IndianRed color (R:205, G:92, B:92, A:255). + /// RGBA Hex: #CD5C5CFF. + /// + public static Color IndianRed => FromPacked(0xCD5C5CFFu); + + /// + /// Indigo color (R:75, G:0, B:130, A:255). + /// RGBA Hex: #4B0082FF. + /// + public static Color Indigo => FromPacked(0x4B0082FFu); + + /// + /// Ivory color (R:255, G:255, B:240, A:255). + /// RGBA Hex: #FFFFF0FF. + /// + public static Color Ivory => FromPacked(0xFFFFF0FFu); + + /// + /// Khaki color (R:240, G:230, B:140, A:255). + /// RGBA Hex: #F0E68CFF. + /// + public static Color Khaki => FromPacked(0xF0E68CFFu); + + /// + /// Lavender color (R:230, G:230, B:250, A:255). + /// RGBA Hex: #E6E6FAFF. + /// + public static Color Lavender => FromPacked(0xE6E6FAFFu); + + /// + /// LavenderBlush color (R:255, G:240, B:245, A:255). + /// RGBA Hex: #FFF0F5FF. + /// + public static Color LavenderBlush => FromPacked(0xFFF0F5FFu); + + /// + /// LawnGreen color (R:124, G:252, B:0, A:255). + /// RGBA Hex: #7CFC00FF. + /// + public static Color LawnGreen => FromPacked(0x7CFC00FFu); + + /// + /// LemonChiffon color (R:255, G:250, B:205, A:255). + /// RGBA Hex: #FFFACDFF. + /// + public static Color LemonChiffon => FromPacked(0xFFFACDFFu); + + /// + /// LightBlue color (R:173, G:216, B:230, A:255). + /// RGBA Hex: #ADD8E6FF. + /// + public static Color LightBlue => FromPacked(0xADD8E6FFu); + + /// + /// LightCoral color (R:240, G:128, B:128, A:255). + /// RGBA Hex: #F08080FF. + /// + public static Color LightCoral => FromPacked(0xF08080FFu); + + /// + /// LightCyan color (R:224, G:255, B:255, A:255). + /// RGBA Hex: #E0FFFFFF. + /// + public static Color LightCyan => FromPacked(0xE0FFFFFFu); + + /// + /// LightGoldenrodYellow color (R:250, G:250, B:210, A:255). + /// RGBA Hex: #FAFAD2FF. + /// + public static Color LightGoldenrodYellow => FromPacked(0xFAFAD2FFu); + + /// + /// LightGray color (R:211, G:211, B:211, A:255). + /// RGBA Hex: #D3D3D3FF. + /// + public static Color LightGray => FromPacked(0xD3D3D3FFu); + + /// + /// LightGreen color (R:144, G:238, B:144, A:255). + /// RGBA Hex: #90EE90FF. + /// + public static Color LightGreen => FromPacked(0x90EE90FFu); + + /// + /// LightPink color (R:255, G:182, B:193, A:255). + /// RGBA Hex: #FFB6C1FF. + /// + public static Color LightPink => FromPacked(0xFFB6C1FFu); + + /// + /// LightSalmon color (R:255, G:160, B:122, A:255). + /// RGBA Hex: #FFA07AFF. + /// + public static Color LightSalmon => FromPacked(0xFFA07AFFu); + + /// + /// LightSeaGreen color (R:32, G:178, B:170, A:255). + /// RGBA Hex: #20B2AAFF. + /// + public static Color LightSeaGreen => FromPacked(0x20B2AAFFu); + + /// + /// LightSkyBlue color (R:135, G:206, B:250, A:255). + /// RGBA Hex: #87CEFAFF. + /// + public static Color LightSkyBlue => FromPacked(0x87CEFAFFu); + + /// + /// LightSlateGray color (R:119, G:136, B:153, A:255). + /// RGBA Hex: #778899FF. + /// + public static Color LightSlateGray => FromPacked(0x778899FFu); + + /// + /// LightSteelBlue color (R:176, G:196, B:222, A:255). + /// RGBA Hex: #B0C4DEFF. + /// + public static Color LightSteelBlue => FromPacked(0xB0C4DEFFu); + + /// + /// LightYellow color (R:255, G:255, B:224, A:255). + /// RGBA Hex: #FFFFE0FF. + /// + public static Color LightYellow => FromPacked(0xFFFFE0FFu); + + /// + /// Lime color (R:0, G:255, B:0, A:255). + /// RGBA Hex: #00FF00FF. + /// + public static Color Lime => FromPacked(0x00FF00FFu); + + /// + /// LimeGreen color (R:50, G:205, B:50, A:255). + /// RGBA Hex: #32CD32FF. + /// + public static Color LimeGreen => FromPacked(0x32CD32FFu); + + /// + /// Linen color (R:250, G:240, B:230, A:255). + /// RGBA Hex: #FAF0E6FF. + /// + public static Color Linen => FromPacked(0xFAF0E6FFu); + + /// + /// Magenta color (R:255, G:0, B:255, A:255). + /// RGBA Hex: #FF00FFFF. + /// + public static Color Magenta => FromPacked(0xFF00FFFFu); + + /// + /// Maroon color (R:128, G:0, B:0, A:255). + /// RGBA Hex: #800000FF. + /// + public static Color Maroon => FromPacked(0x800000FFu); + + /// + /// MediumAquamarine color (R:102, G:205, B:170, A:255). + /// RGBA Hex: #66CDAAFF. + /// + public static Color MediumAquamarine => FromPacked(0x66CDAAFFu); + + /// + /// MediumBlue color (R:0, G:0, B:205, A:255). + /// RGBA Hex: #0000CDFF. + /// + public static Color MediumBlue => FromPacked(0x0000CDFFu); + + /// + /// MediumOrchid color (R:186, G:85, B:211, A:255). + /// RGBA Hex: #BA55D3FF. + /// + public static Color MediumOrchid => FromPacked(0xBA55D3FFu); + + /// + /// MediumPurple color (R:147, G:112, B:219, A:255). + /// RGBA Hex: #9370DBFF. + /// + public static Color MediumPurple => FromPacked(0x9370DBFFu); + + /// + /// MediumSeaGreen color (R:60, G:179, B:113, A:255). + /// RGBA Hex: #3CB371FF. + /// + public static Color MediumSeaGreen => FromPacked(0x3CB371FFu); + + /// + /// MediumSlateBlue color (R:123, G:104, B:238, A:255). + /// RGBA Hex: #7B68EEFF. + /// + public static Color MediumSlateBlue => FromPacked(0x7B68EEFFu); + + /// + /// MediumSpringGreen color (R:0, G:250, B:154, A:255). + /// RGBA Hex: #00FA9AFF. + /// + public static Color MediumSpringGreen => FromPacked(0x00FA9AFFu); + + /// + /// MediumTurquoise color (R:72, G:209, B:204, A:255). + /// RGBA Hex: #48D1CCFF. + /// + public static Color MediumTurquoise => FromPacked(0x48D1CCFFu); + + /// + /// MediumVioletRed color (R:199, G:21, B:133, A:255). + /// RGBA Hex: #C71585FF. + /// + public static Color MediumVioletRed => FromPacked(0xC71585FFu); + + /// + /// MidnightBlue color (R:25, G:25, B:112, A:255). + /// RGBA Hex: #191970FF. + /// + public static Color MidnightBlue => FromPacked(0x191970FFu); + + /// + /// MintCream color (R:245, G:255, B:250, A:255). + /// RGBA Hex: #F5FFFAFF. + /// + public static Color MintCream => FromPacked(0xF5FFFAFFu); + + /// + /// MistyRose color (R:255, G:228, B:225, A:255). + /// RGBA Hex: #FFE4E1FF. + /// + public static Color MistyRose => FromPacked(0xFFE4E1FFu); + + /// + /// Moccasin color (R:255, G:228, B:181, A:255). + /// RGBA Hex: #FFE4B5FF. + /// + public static Color Moccasin => FromPacked(0xFFE4B5FFu); + + /// + /// NavajoWhite color (R:255, G:222, B:173, A:255). + /// RGBA Hex: #FFDEADFF. + /// + public static Color NavajoWhite => FromPacked(0xFFDEADFFu); + + /// + /// Navy color (R:0, G:0, B:128, A:255). + /// RGBA Hex: #000080FF. + /// + public static Color Navy => FromPacked(0x000080FFu); + + /// + /// OldLace color (R:253, G:245, B:230, A:255). + /// RGBA Hex: #FDF5E6FF. + /// + public static Color OldLace => FromPacked(0xFDF5E6FFu); + + /// + /// Olive color (R:128, G:128, B:0, A:255). + /// RGBA Hex: #808000FF. + /// + public static Color Olive => FromPacked(0x808000FFu); + + /// + /// OliveDrab color (R:107, G:142, B:35, A:255). + /// RGBA Hex: #6B8E23FF. + /// + public static Color OliveDrab => FromPacked(0x6B8E23FFu); + + /// + /// Orange color (R:255, G:165, B:0, A:255). + /// RGBA Hex: #FFA500FF. + /// + public static Color Orange => FromPacked(0xFFA500FFu); + + /// + /// OrangeRed color (R:255, G:69, B:0, A:255). + /// RGBA Hex: #FF4500FF. + /// + public static Color OrangeRed => FromPacked(0xFF4500FFu); + + /// + /// Orchid color (R:218, G:112, B:214, A:255). + /// RGBA Hex: #DA70D6FF. + /// + public static Color Orchid => FromPacked(0xDA70D6FFu); + + /// + /// PaleGoldenrod color (R:238, G:232, B:170, A:255). + /// RGBA Hex: #EEE8AAFF. + /// + public static Color PaleGoldenrod => FromPacked(0xEEE8AAFFu); + + /// + /// PaleGreen color (R:152, G:251, B:152, A:255). + /// RGBA Hex: #98FB98FF. + /// + public static Color PaleGreen => FromPacked(0x98FB98FFu); + + /// + /// PaleTurquoise color (R:175, G:238, B:238, A:255). + /// RGBA Hex: #AFEEEEFF. + /// + public static Color PaleTurquoise => FromPacked(0xAFEEEEFFu); + + /// + /// PaleVioletRed color (R:219, G:112, B:147, A:255). + /// RGBA Hex: #DB7093FF. + /// + public static Color PaleVioletRed => FromPacked(0xDB7093FFu); + + /// + /// PapayaWhip color (R:255, G:239, B:213, A:255). + /// RGBA Hex: #FFEFD5FF. + /// + public static Color PapayaWhip => FromPacked(0xFFEFD5FFu); + + /// + /// PeachPuff color (R:255, G:218, B:185, A:255). + /// RGBA Hex: #FFDAB9FF. + /// + public static Color PeachPuff => FromPacked(0xFFDAB9FFu); + + /// + /// Peru color (R:205, G:133, B:63, A:255). + /// RGBA Hex: #CD853FFF. + /// + public static Color Peru => FromPacked(0xCD853FFFu); + + /// + /// Pink color (R:255, G:192, B:203, A:255). + /// RGBA Hex: #FFC0CBFF. + /// + public static Color Pink => FromPacked(0xFFC0CBFFu); + + /// + /// Plum color (R:221, G:160, B:221, A:255). + /// RGBA Hex: #DDA0DDFF. + /// + public static Color Plum => FromPacked(0xDDA0DDFFu); + + /// + /// PowderBlue color (R:176, G:224, B:230, A:255). + /// RGBA Hex: #B0E0E6FF. + /// + public static Color PowderBlue => FromPacked(0xB0E0E6FFu); + + /// + /// Purple color (R:128, G:0, B:128, A:255). + /// RGBA Hex: #800080FF. + /// + public static Color Purple => FromPacked(0x800080FFu); + + /// + /// Red color (R:255, G:0, B:0, A:255). + /// RGBA Hex: #FF0000FF. + /// + public static Color Red => FromPacked(0xFF0000FFu); + + /// + /// RosyBrown color (R:188, G:143, B:143, A:255). + /// RGBA Hex: #BC8F8FFF. + /// + public static Color RosyBrown => FromPacked(0xBC8F8FFFu); + + /// + /// RoyalBlue color (R:65, G:105, B:225, A:255). + /// RGBA Hex: #4169E1FF. + /// + public static Color RoyalBlue => FromPacked(0x4169E1FFu); + + /// + /// SaddleBrown color (R:139, G:69, B:19, A:255). + /// RGBA Hex: #8B4513FF. + /// + public static Color SaddleBrown => FromPacked(0x8B4513FFu); + + /// + /// Salmon color (R:250, G:128, B:114, A:255). + /// RGBA Hex: #FA8072FF. + /// + public static Color Salmon => FromPacked(0xFA8072FFu); + + /// + /// SandyBrown color (R:244, G:164, B:96, A:255). + /// RGBA Hex: #F4A460FF. + /// + public static Color SandyBrown => FromPacked(0xF4A460FFu); + + /// + /// SeaGreen color (R:46, G:139, B:87, A:255). + /// RGBA Hex: #2E8B57FF. + /// + public static Color SeaGreen => FromPacked(0x2E8B57FFu); + + /// + /// SeaShell color (R:255, G:245, B:238, A:255). + /// RGBA Hex: #FFF5EEFF. + /// + public static Color SeaShell => FromPacked(0xFFF5EEFFu); + + /// + /// Sienna color (R:160, G:82, B:45, A:255). + /// RGBA Hex: #A0522DFF. + /// + public static Color Sienna => FromPacked(0xA0522DFFu); + + /// + /// Silver color (R:192, G:192, B:192, A:255). + /// RGBA Hex: #C0C0C0FF. + /// + public static Color Silver => FromPacked(0xC0C0C0FFu); + + /// + /// SkyBlue color (R:135, G:206, B:235, A:255). + /// RGBA Hex: #87CEEBFF. + /// + public static Color SkyBlue => FromPacked(0x87CEEBFFu); + + /// + /// SlateBlue color (R:106, G:90, B:205, A:255). + /// RGBA Hex: #6A5ACDFF. + /// + public static Color SlateBlue => FromPacked(0x6A5ACDFFu); + + /// + /// SlateGray color (R:112, G:128, B:144, A:255). + /// RGBA Hex: #708090FF. + /// + public static Color SlateGray => FromPacked(0x708090FFu); + + /// + /// Snow color (R:255, G:250, B:250, A:255). + /// RGBA Hex: #FFFAFAFF. + /// + public static Color Snow => FromPacked(0xFFFAFAFFu); + + /// + /// SpringGreen color (R:0, G:255, B:127, A:255). + /// RGBA Hex: #00FF7FFF. + /// + public static Color SpringGreen => FromPacked(0x00FF7FFFu); + + /// + /// SteelBlue color (R:70, G:130, B:180, A:255). + /// RGBA Hex: #4682B4FF. + /// + public static Color SteelBlue => FromPacked(0x4682B4FFu); + + /// + /// Tan color (R:210, G:180, B:140, A:255). + /// RGBA Hex: #D2B48CFF. + /// + public static Color Tan => FromPacked(0xD2B48CFFu); + + /// + /// Teal color (R:0, G:128, B:128, A:255). + /// RGBA Hex: #008080FF. + /// + public static Color Teal => FromPacked(0x008080FFu); + + /// + /// Thistle color (R:216, G:191, B:216, A:255). + /// RGBA Hex: #D8BFD8FF. + /// + public static Color Thistle => FromPacked(0xD8BFD8FFu); + + /// + /// Tomato color (R:255, G:99, B:71, A:255). + /// RGBA Hex: #FF6347FF. + /// + public static Color Tomato => FromPacked(0xFF6347FFu); + + /// + /// Turquoise color (R:64, G:224, B:208, A:255). + /// RGBA Hex: #40E0D0FF. + /// + public static Color Turquoise => FromPacked(0x40E0D0FFu); + + /// + /// Violet color (R:238, G:130, B:238, A:255). + /// RGBA Hex: #EE82EEFF. + /// + public static Color Violet => FromPacked(0xEE82EEFFu); + + /// + /// Wheat color (R:245, G:222, B:179, A:255). + /// RGBA Hex: #F5DEB3FF. + /// + public static Color Wheat => FromPacked(0xF5DEB3FFu); + + /// + /// White color (R:255, G:255, B:255, A:255). + /// RGBA Hex: #FFFFFFFF. + /// + public static Color White => FromPacked(0xFFFFFFFFu); + + /// + /// WhiteSmoke color (R:245, G:245, B:245, A:255). + /// RGBA Hex: #F5F5F5FF. + /// + public static Color WhiteSmoke => FromPacked(0xF5F5F5FFu); + + /// + /// Yellow color (R:255, G:255, B:0, A:255). + /// RGBA Hex: #FFFF00FF. + /// + public static Color Yellow => FromPacked(0xFFFF00FFu); + + /// + /// YellowGreen color (R:154, G:205, B:50, A:255). + /// RGBA Hex: #9ACD32FF. + /// + public static Color YellowGreen => FromPacked(0x9ACD32FFu); + + /// + /// RebeccaPurple color (R:102, G:51, B:153, A:255). + /// RGBA Hex: #663399FF. + /// + public static Color RebeccaPurple => FromPacked(0x663399FFu); + +#endregion Built-In Colors + +} \ No newline at end of file From fb30177a22db142db21a8ee2223556be76c1ce51 Mon Sep 17 00:00:00 2001 From: demorome Date: Sat, 29 Nov 2025 22:49:03 -0400 Subject: [PATCH 02/23] fix misaligned comment --- src/Graphics/Color.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 34362e6..19e75d3 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -240,7 +240,7 @@ public override string ToString() return sb.ToString(); } -/// + /// /// Returns a hexadecimal representation of this in the format: /// 0x[R][G][B][A] /// From bd848b5bec9cd8e47039fa6e120789aa5ebb97b2 Mon Sep 17 00:00:00 2001 From: demorome Date: Sat, 29 Nov 2025 23:54:44 -0400 Subject: [PATCH 03/23] avoid using byte-order-sensitive value in ctor, add warning for FromPacked() --- src/Graphics/Color.cs | 579 +++++++++++++++++++++--------------------- 1 file changed, 291 insertions(+), 288 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 19e75d3..92fcaf0 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -62,13 +62,16 @@ public Color(Vector4 vector) : this(vector.X, vector.Y, vector.Z, vector.W) { } /// /// Gets packed RGBA value of this . - /// NOTE: Because of endianness, if you format this value directly as a hex string, - /// the order of bytes may be wrong. + /// NOTE: Because of endianness, if you format this value directly as a hex string, + /// the order of bytes may be wrong. /// public readonly uint PackedValue() => Unsafe.BitCast(this); /// /// Gets a representation for a packed RGBA value. + /// NEVER plug in a value that wasn't generated by PackedValue(), + /// unless you're SURE you can deal with an endianness mismatch. + /// Example: it's NOT safe to take 0xF0F8FFFF from AliceBlue and plug it into here! /// public static Color FromPacked(uint rgba) => Unsafe.BitCast(rgba); @@ -243,11 +246,12 @@ public override string ToString() /// /// Returns a hexadecimal representation of this in the format: /// 0x[R][G][B][A] + /// Thus, it's in Big Endian format. /// /// representation of this . public string ToHexString() { - StringBuilder sb = new StringBuilder(25); + StringBuilder sb = new StringBuilder(10); sb.Append("#"); sb.Append(R.ToString("X2")); sb.Append(G.ToString("X2")); @@ -275,856 +279,855 @@ public string ToHexString() #region Built-In Colors /// - /// Transparent color (R:255, G:255, B:255, A:0). - /// RGBA Hex: #FFFFFF00. + /// Transparent color (R:0, G:0, B:0, A:0). /// - public static Color Transparent => FromPacked(0xFFFFFF00u); + public static Color Transparent => new((byte)0, (byte)0, (byte)0, (byte)0); /// /// AliceBlue color (R:240, G:248, B:255, A:255). - /// RGBA Hex: #F0F8FFFF. + /// RGBA Hex: #F0F8FFFF. /// - public static Color AliceBlue => FromPacked(0xF0F8FFFFu); + public static Color AliceBlue => new((byte)240, (byte)248, (byte)255); /// /// AntiqueWhite color (R:250, G:235, B:215, A:255). - /// RGBA Hex: #FAEBD7FF. + /// RGBA Hex: #FAEBD7FF. /// - public static Color AntiqueWhite => FromPacked(0xFAEBD7FFu); + public static Color AntiqueWhite => new((byte)250, (byte)235, (byte)215); /// /// Aqua color (R:0, G:255, B:255, A:255). - /// RGBA Hex: #00FFFFFF. + /// RGBA Hex: #00FFFFFF. /// - public static Color Aqua => FromPacked(0x00FFFFFFu); + public static Color Aqua => new((byte)0, (byte)255, (byte)255); /// /// Aquamarine color (R:127, G:255, B:212, A:255). - /// RGBA Hex: #7FFFD4FF. + /// RGBA Hex: #7FFFD4FF. /// - public static Color Aquamarine => FromPacked(0x7FFFD4FFu); + public static Color Aquamarine => new((byte)127, (byte)255, (byte)212); /// /// Azure color (R:240, G:255, B:255, A:255). - /// RGBA Hex: #F0FFFFFF. + /// RGBA Hex: #F0FFFFFF. /// - public static Color Azure => FromPacked(0xF0FFFFFFu); + public static Color Azure => new((byte)240, (byte)255, (byte)255); /// /// Beige color (R:245, G:245, B:220, A:255). - /// RGBA Hex: #F5F5DCFF. + /// RGBA Hex: #F5F5DCFF. /// - public static Color Beige => FromPacked(0xF5F5DCFFu); + public static Color Beige => new((byte)245, (byte)245, (byte)220); /// /// Bisque color (R:255, G:228, B:196, A:255). - /// RGBA Hex: #FFE4C4FF. + /// RGBA Hex: #FFE4C4FF. /// - public static Color Bisque => FromPacked(0xFFE4C4FFu); + public static Color Bisque => new((byte)255, (byte)228, (byte)196); /// /// Black color (R:0, G:0, B:0, A:255). - /// RGBA Hex: #000000FF. + /// RGBA Hex: #000000FF. /// - public static Color Black => FromPacked(0x000000FFu); + public static Color Black => new((byte)0, (byte)0, (byte)0); /// /// BlanchedAlmond color (R:255, G:235, B:205, A:255). - /// RGBA Hex: #FFEBCDFF. + /// RGBA Hex: #FFEBCDFF. /// - public static Color BlanchedAlmond => FromPacked(0xFFEBCDFFu); + public static Color BlanchedAlmond => new((byte)255, (byte)235, (byte)205); /// /// Blue color (R:0, G:0, B:255, A:255). - /// RGBA Hex: #0000FFFF. + /// RGBA Hex: #0000FFFF. /// - public static Color Blue => FromPacked(0x0000FFFFu); + public static Color Blue => new((byte)0, (byte)0, (byte)255); /// /// BlueViolet color (R:138, G:43, B:226, A:255). - /// RGBA Hex: #8A2BE2FF. + /// RGBA Hex: #8A2BE2FF. /// - public static Color BlueViolet => FromPacked(0x8A2BE2FFu); + public static Color BlueViolet => new((byte)138, (byte)43, (byte)226); /// /// Brown color (R:165, G:42, B:42, A:255). - /// RGBA Hex: #A52A2AFF. + /// RGBA Hex: #A52A2AFF. /// - public static Color Brown => FromPacked(0xA52A2AFFu); + public static Color Brown => new((byte)165, (byte)42, (byte)42); /// /// BurlyWood color (R:222, G:184, B:135, A:255). - /// RGBA Hex: #DEB887FF. + /// RGBA Hex: #DEB887FF. /// - public static Color BurlyWood => FromPacked(0xDEB887FFu); + public static Color BurlyWood => new((byte)222, (byte)184, (byte)135); /// /// CadetBlue color (R:95, G:158, B:160, A:255). - /// RGBA Hex: #5F9EA0FF. + /// RGBA Hex: #5F9EA0FF. /// - public static Color CadetBlue => FromPacked(0x5F9EA0FFu); + public static Color CadetBlue => new((byte)95, (byte)158, (byte)160); /// /// Chartreuse color (R:127, G:255, B:0, A:255). - /// RGBA Hex: #7FFF00FF. + /// RGBA Hex: #7FFF00FF. /// - public static Color Chartreuse => FromPacked(0x7FFF00FFu); + public static Color Chartreuse => new((byte)127, (byte)255, (byte)0); /// /// Chocolate color (R:210, G:105, B:30, A:255). - /// RGBA Hex: #D2691EFF. + /// RGBA Hex: #D2691EFF. /// - public static Color Chocolate => FromPacked(0xD2691EFFu); + public static Color Chocolate => new((byte)210, (byte)105, (byte)30); /// /// Coral color (R:255, G:127, B:80, A:255). - /// RGBA Hex: #FF7F50FF. + /// RGBA Hex: #FF7F50FF. /// - public static Color Coral => FromPacked(0xFF7F50FFu); + public static Color Coral => new((byte)255, (byte)127, (byte)80); /// /// CornflowerBlue color (R:100, G:149, B:237, A:255). - /// RGBA Hex: #6495EDFF. + /// RGBA Hex: #6495EDFF. /// - public static Color CornflowerBlue => FromPacked(0x6495EDFFu); + public static Color CornflowerBlue => new((byte)100, (byte)149, (byte)237); /// /// Cornsilk color (R:255, G:248, B:220, A:255). - /// RGBA Hex: #FFF8DCFF. + /// RGBA Hex: #FFF8DCFF. /// - public static Color Cornsilk => FromPacked(0xFFF8DCFFu); + public static Color Cornsilk => new((byte)255, (byte)248, (byte)220); /// /// Crimson color (R:220, G:20, B:60, A:255). - /// RGBA Hex: #DC143CFF. + /// RGBA Hex: #DC143CFF. /// - public static Color Crimson => FromPacked(0xDC143CFFu); + public static Color Crimson => new((byte)220, (byte)20, (byte)60); /// /// Cyan color (R:0, G:255, B:255, A:255). - /// RGBA Hex: #00FFFFFF. + /// RGBA Hex: #00FFFFFF. /// - public static Color Cyan => FromPacked(0x00FFFFFFu); + public static Color Cyan => new((byte)0, (byte)255, (byte)255); /// /// DarkBlue color (R:0, G:0, B:139, A:255). - /// RGBA Hex: #00008BFF. + /// RGBA Hex: #00008BFF. /// - public static Color DarkBlue => FromPacked(0x00008BFFu); + public static Color DarkBlue => new((byte)0, (byte)0, (byte)139); /// /// DarkCyan color (R:0, G:139, B:139, A:255). - /// RGBA Hex: #008B8BFF. + /// RGBA Hex: #008B8BFF. /// - public static Color DarkCyan => FromPacked(0x008B8BFFu); + public static Color DarkCyan => new((byte)0, (byte)139, (byte)139); /// /// DarkGoldenrod color (R:184, G:134, B:11, A:255). - /// RGBA Hex: #B8860BFF. + /// RGBA Hex: #B8860BFF. /// - public static Color DarkGoldenrod => FromPacked(0xB8860BFFu); + public static Color DarkGoldenrod => new((byte)184, (byte)134, (byte)11); /// /// DarkGray color (R:169, G:169, B:169, A:255). - /// RGBA Hex: #A9A9A9FF. + /// RGBA Hex: #A9A9A9FF. /// - public static Color DarkGray => FromPacked(0xA9A9A9FFu); + public static Color DarkGray => new((byte)169, (byte)169, (byte)169); /// /// DarkGreen color (R:0, G:100, B:0, A:255). - /// RGBA Hex: #006400FF. + /// RGBA Hex: #006400FF. /// - public static Color DarkGreen => FromPacked(0x006400FFu); + public static Color DarkGreen => new((byte)0, (byte)100, (byte)0); /// /// DarkKhaki color (R:189, G:183, B:107, A:255). - /// RGBA Hex: #BDB76BFF. + /// RGBA Hex: #BDB76BFF. /// - public static Color DarkKhaki => FromPacked(0xBDB76BFFu); + public static Color DarkKhaki => new((byte)189, (byte)183, (byte)107); /// /// DarkMagenta color (R:139, G:0, B:139, A:255). - /// RGBA Hex: #8B008BFF. + /// RGBA Hex: #8B008BFF. /// - public static Color DarkMagenta => FromPacked(0x8B008BFFu); + public static Color DarkMagenta => new((byte)139, (byte)0, (byte)139); /// /// DarkOliveGreen color (R:85, G:107, B:47, A:255). - /// RGBA Hex: #556B2FFF. + /// RGBA Hex: #556B2FFF. /// - public static Color DarkOliveGreen => FromPacked(0x556B2FFFu); + public static Color DarkOliveGreen => new((byte)85, (byte)107, (byte)47); /// /// DarkOrange color (R:255, G:140, B:0, A:255). - /// RGBA Hex: #FF8C00FF. + /// RGBA Hex: #FF8C00FF. /// - public static Color DarkOrange => FromPacked(0xFF8C00FFu); + public static Color DarkOrange => new((byte)255, (byte)140, (byte)0); /// /// DarkOrchid color (R:153, G:50, B:204, A:255). - /// RGBA Hex: #9932CCFF. + /// RGBA Hex: #9932CCFF. /// - public static Color DarkOrchid => FromPacked(0x9932CCFFu); + public static Color DarkOrchid => new((byte)153, (byte)50, (byte)204); /// /// DarkRed color (R:139, G:0, B:0, A:255). - /// RGBA Hex: #8B0000FF. + /// RGBA Hex: #8B0000FF. /// - public static Color DarkRed => FromPacked(0x8B0000FFu); + public static Color DarkRed => new((byte)139, (byte)0, (byte)0); /// /// DarkSalmon color (R:233, G:150, B:122, A:255). - /// RGBA Hex: #E9967AFF. + /// RGBA Hex: #E9967AFF. /// - public static Color DarkSalmon => FromPacked(0xE9967AFFu); + public static Color DarkSalmon => new((byte)233, (byte)150, (byte)122); /// /// DarkSeaGreen color (R:143, G:188, B:143, A:255). - /// RGBA Hex: #8FBC8FFF. + /// RGBA Hex: #8FBC8FFF. /// - public static Color DarkSeaGreen => FromPacked(0x8FBC8FFFu); + public static Color DarkSeaGreen => new((byte)143, (byte)188, (byte)143); /// /// DarkSlateBlue color (R:72, G:61, B:139, A:255). - /// RGBA Hex: #483D8BFF. + /// RGBA Hex: #483D8BFF. /// - public static Color DarkSlateBlue => FromPacked(0x483D8BFFu); + public static Color DarkSlateBlue => new((byte)72, (byte)61, (byte)139); /// /// DarkSlateGray color (R:47, G:79, B:79, A:255). - /// RGBA Hex: #2F4F4FFF. + /// RGBA Hex: #2F4F4FFF. /// - public static Color DarkSlateGray => FromPacked(0x2F4F4FFFu); + public static Color DarkSlateGray => new((byte)47, (byte)79, (byte)79); /// /// DarkTurquoise color (R:0, G:206, B:209, A:255). - /// RGBA Hex: #00CED1FF. + /// RGBA Hex: #00CED1FF. /// - public static Color DarkTurquoise => FromPacked(0x00CED1FFu); + public static Color DarkTurquoise => new((byte)0, (byte)206, (byte)209); /// /// DarkViolet color (R:148, G:0, B:211, A:255). - /// RGBA Hex: #9400D3FF. + /// RGBA Hex: #9400D3FF. /// - public static Color DarkViolet => FromPacked(0x9400D3FFu); + public static Color DarkViolet => new((byte)148, (byte)0, (byte)211); /// /// DeepPink color (R:255, G:20, B:147, A:255). - /// RGBA Hex: #FF1493FF. + /// RGBA Hex: #FF1493FF. /// - public static Color DeepPink => FromPacked(0xFF1493FFu); + public static Color DeepPink => new((byte)255, (byte)20, (byte)147); /// /// DeepSkyBlue color (R:0, G:191, B:255, A:255). - /// RGBA Hex: #00BFFFFF. + /// RGBA Hex: #00BFFFFF. /// - public static Color DeepSkyBlue => FromPacked(0x00BFFFFFu); + public static Color DeepSkyBlue => new((byte)0, (byte)191, (byte)255); /// /// DimGray color (R:105, G:105, B:105, A:255). - /// RGBA Hex: #696969FF. + /// RGBA Hex: #696969FF. /// - public static Color DimGray => FromPacked(0x696969FFu); + public static Color DimGray => new((byte)105, (byte)105, (byte)105); /// /// DodgerBlue color (R:30, G:144, B:255, A:255). - /// RGBA Hex: #1E90FFFF. + /// RGBA Hex: #1E90FFFF. /// - public static Color DodgerBlue => FromPacked(0x1E90FFFFu); + public static Color DodgerBlue => new((byte)30, (byte)144, (byte)255); /// /// Firebrick color (R:178, G:34, B:34, A:255). - /// RGBA Hex: #B22222FF. + /// RGBA Hex: #B22222FF. /// - public static Color Firebrick => FromPacked(0xB22222FFu); + public static Color Firebrick => new((byte)178, (byte)34, (byte)34); /// /// FloralWhite color (R:255, G:250, B:240, A:255). - /// RGBA Hex: #FFFAF0FF. + /// RGBA Hex: #FFFAF0FF. /// - public static Color FloralWhite => FromPacked(0xFFFAF0FFu); + public static Color FloralWhite => new((byte)255, (byte)250, (byte)240); /// /// ForestGreen color (R:34, G:139, B:34, A:255). - /// RGBA Hex: #228B22FF. + /// RGBA Hex: #228B22FF. /// - public static Color ForestGreen => FromPacked(0x228B22FFu); + public static Color ForestGreen => new((byte)34, (byte)139, (byte)34); /// /// Fuchsia color (R:255, G:0, B:255, A:255). - /// RGBA Hex: #FF00FFFF. + /// RGBA Hex: #FF00FFFF. /// - public static Color Fuchsia => FromPacked(0xFF00FFFFu); + public static Color Fuchsia => new((byte)255, (byte)0, (byte)255); /// /// Gainsboro color (R:220, G:220, B:220, A:255). - /// RGBA Hex: #DCDCDCFF. + /// RGBA Hex: #DCDCDCFF. /// - public static Color Gainsboro => FromPacked(0xDCDCDCFFu); + public static Color Gainsboro => new((byte)220, (byte)220, (byte)220); /// /// GhostWhite color (R:248, G:248, B:255, A:255). - /// RGBA Hex: #F8F8FFFF. + /// RGBA Hex: #F8F8FFFF. /// - public static Color GhostWhite => FromPacked(0xF8F8FFFFu); + public static Color GhostWhite => new((byte)248, (byte)248, (byte)255); /// /// Gold color (R:255, G:215, B:0, A:255). - /// RGBA Hex: #FFD700FF. + /// RGBA Hex: #FFD700FF. /// - public static Color Gold => FromPacked(0xFFD700FFu); + public static Color Gold => new((byte)255, (byte)215, (byte)0); /// /// Goldenrod color (R:218, G:165, B:32, A:255). - /// RGBA Hex: #DAA520FF. + /// RGBA Hex: #DAA520FF. /// - public static Color Goldenrod => FromPacked(0xDAA520FFu); + public static Color Goldenrod => new((byte)218, (byte)165, (byte)32); /// /// Gray color (R:128, G:128, B:128, A:255). - /// RGBA Hex: #808080FF. + /// RGBA Hex: #808080FF. /// - public static Color Gray => FromPacked(0x808080FFu); + public static Color Gray => new((byte)128, (byte)128, (byte)128); /// /// Green color (R:0, G:128, B:0, A:255). - /// RGBA Hex: #008000FF. + /// RGBA Hex: #008000FF. /// - public static Color Green => FromPacked(0x008000FFu); + public static Color Green => new((byte)0, (byte)128, (byte)0); /// /// GreenYellow color (R:173, G:255, B:47, A:255). - /// RGBA Hex: #ADFF2FFF. + /// RGBA Hex: #ADFF2FFF. /// - public static Color GreenYellow => FromPacked(0xADFF2FFFu); + public static Color GreenYellow => new((byte)173, (byte)255, (byte)47); /// /// Honeydew color (R:240, G:255, B:240, A:255). - /// RGBA Hex: #F0FFF0FF. + /// RGBA Hex: #F0FFF0FF. /// - public static Color Honeydew => FromPacked(0xF0FFF0FFu); + public static Color Honeydew => new((byte)240, (byte)255, (byte)240); /// /// HotPink color (R:255, G:105, B:180, A:255). - /// RGBA Hex: #FF69B4FF. + /// RGBA Hex: #FF69B4FF. /// - public static Color HotPink => FromPacked(0xFF69B4FFu); + public static Color HotPink => new((byte)255, (byte)105, (byte)180); /// /// IndianRed color (R:205, G:92, B:92, A:255). - /// RGBA Hex: #CD5C5CFF. + /// RGBA Hex: #CD5C5CFF. /// - public static Color IndianRed => FromPacked(0xCD5C5CFFu); + public static Color IndianRed => new((byte)205, (byte)92, (byte)92); /// /// Indigo color (R:75, G:0, B:130, A:255). - /// RGBA Hex: #4B0082FF. + /// RGBA Hex: #4B0082FF. /// - public static Color Indigo => FromPacked(0x4B0082FFu); + public static Color Indigo => new((byte)75, (byte)0, (byte)130); /// /// Ivory color (R:255, G:255, B:240, A:255). - /// RGBA Hex: #FFFFF0FF. + /// RGBA Hex: #FFFFF0FF. /// - public static Color Ivory => FromPacked(0xFFFFF0FFu); + public static Color Ivory => new((byte)255, (byte)255, (byte)240); /// /// Khaki color (R:240, G:230, B:140, A:255). - /// RGBA Hex: #F0E68CFF. + /// RGBA Hex: #F0E68CFF. /// - public static Color Khaki => FromPacked(0xF0E68CFFu); + public static Color Khaki => new((byte)240, (byte)230, (byte)140); /// /// Lavender color (R:230, G:230, B:250, A:255). - /// RGBA Hex: #E6E6FAFF. + /// RGBA Hex: #E6E6FAFF. /// - public static Color Lavender => FromPacked(0xE6E6FAFFu); + public static Color Lavender => new((byte)230, (byte)230, (byte)250); /// /// LavenderBlush color (R:255, G:240, B:245, A:255). - /// RGBA Hex: #FFF0F5FF. + /// RGBA Hex: #FFF0F5FF. /// - public static Color LavenderBlush => FromPacked(0xFFF0F5FFu); + public static Color LavenderBlush => new((byte)255, (byte)240, (byte)245); /// /// LawnGreen color (R:124, G:252, B:0, A:255). - /// RGBA Hex: #7CFC00FF. + /// RGBA Hex: #7CFC00FF. /// - public static Color LawnGreen => FromPacked(0x7CFC00FFu); + public static Color LawnGreen => new((byte)124, (byte)252, (byte)0); /// /// LemonChiffon color (R:255, G:250, B:205, A:255). - /// RGBA Hex: #FFFACDFF. + /// RGBA Hex: #FFFACDFF. /// - public static Color LemonChiffon => FromPacked(0xFFFACDFFu); + public static Color LemonChiffon => new((byte)255, (byte)250, (byte)205); /// /// LightBlue color (R:173, G:216, B:230, A:255). - /// RGBA Hex: #ADD8E6FF. + /// RGBA Hex: #ADD8E6FF. /// - public static Color LightBlue => FromPacked(0xADD8E6FFu); + public static Color LightBlue => new((byte)173, (byte)216, (byte)230); /// /// LightCoral color (R:240, G:128, B:128, A:255). - /// RGBA Hex: #F08080FF. + /// RGBA Hex: #F08080FF. /// - public static Color LightCoral => FromPacked(0xF08080FFu); + public static Color LightCoral => new((byte)240, (byte)128, (byte)128); /// /// LightCyan color (R:224, G:255, B:255, A:255). - /// RGBA Hex: #E0FFFFFF. + /// RGBA Hex: #E0FFFFFF. /// - public static Color LightCyan => FromPacked(0xE0FFFFFFu); + public static Color LightCyan => new((byte)224, (byte)255, (byte)255); /// /// LightGoldenrodYellow color (R:250, G:250, B:210, A:255). - /// RGBA Hex: #FAFAD2FF. + /// RGBA Hex: #FAFAD2FF. /// - public static Color LightGoldenrodYellow => FromPacked(0xFAFAD2FFu); + public static Color LightGoldenrodYellow => new((byte)250, (byte)250, (byte)210); /// /// LightGray color (R:211, G:211, B:211, A:255). - /// RGBA Hex: #D3D3D3FF. + /// RGBA Hex: #D3D3D3FF. /// - public static Color LightGray => FromPacked(0xD3D3D3FFu); + public static Color LightGray => new((byte)211, (byte)211, (byte)211); /// /// LightGreen color (R:144, G:238, B:144, A:255). - /// RGBA Hex: #90EE90FF. + /// RGBA Hex: #90EE90FF. /// - public static Color LightGreen => FromPacked(0x90EE90FFu); + public static Color LightGreen => new((byte)144, (byte)238, (byte)144); /// /// LightPink color (R:255, G:182, B:193, A:255). - /// RGBA Hex: #FFB6C1FF. + /// RGBA Hex: #FFB6C1FF. /// - public static Color LightPink => FromPacked(0xFFB6C1FFu); + public static Color LightPink => new((byte)255, (byte)182, (byte)193); /// /// LightSalmon color (R:255, G:160, B:122, A:255). - /// RGBA Hex: #FFA07AFF. + /// RGBA Hex: #FFA07AFF. /// - public static Color LightSalmon => FromPacked(0xFFA07AFFu); + public static Color LightSalmon => new((byte)255, (byte)160, (byte)122); /// /// LightSeaGreen color (R:32, G:178, B:170, A:255). - /// RGBA Hex: #20B2AAFF. + /// RGBA Hex: #20B2AAFF. /// - public static Color LightSeaGreen => FromPacked(0x20B2AAFFu); + public static Color LightSeaGreen => new((byte)32, (byte)178, (byte)170); /// /// LightSkyBlue color (R:135, G:206, B:250, A:255). - /// RGBA Hex: #87CEFAFF. + /// RGBA Hex: #87CEFAFF. /// - public static Color LightSkyBlue => FromPacked(0x87CEFAFFu); + public static Color LightSkyBlue => new((byte)135, (byte)206, (byte)250); /// /// LightSlateGray color (R:119, G:136, B:153, A:255). - /// RGBA Hex: #778899FF. + /// RGBA Hex: #778899FF. /// - public static Color LightSlateGray => FromPacked(0x778899FFu); + public static Color LightSlateGray => new((byte)119, (byte)136, (byte)153); /// /// LightSteelBlue color (R:176, G:196, B:222, A:255). - /// RGBA Hex: #B0C4DEFF. + /// RGBA Hex: #B0C4DEFF. /// - public static Color LightSteelBlue => FromPacked(0xB0C4DEFFu); + public static Color LightSteelBlue => new((byte)176, (byte)196, (byte)222); /// /// LightYellow color (R:255, G:255, B:224, A:255). - /// RGBA Hex: #FFFFE0FF. + /// RGBA Hex: #FFFFE0FF. /// - public static Color LightYellow => FromPacked(0xFFFFE0FFu); + public static Color LightYellow => new((byte)255, (byte)255, (byte)224); /// /// Lime color (R:0, G:255, B:0, A:255). - /// RGBA Hex: #00FF00FF. + /// RGBA Hex: #00FF00FF. /// - public static Color Lime => FromPacked(0x00FF00FFu); + public static Color Lime => new((byte)0, (byte)255, (byte)0); /// /// LimeGreen color (R:50, G:205, B:50, A:255). - /// RGBA Hex: #32CD32FF. + /// RGBA Hex: #32CD32FF. /// - public static Color LimeGreen => FromPacked(0x32CD32FFu); + public static Color LimeGreen => new((byte)50, (byte)205, (byte)50); /// /// Linen color (R:250, G:240, B:230, A:255). - /// RGBA Hex: #FAF0E6FF. + /// RGBA Hex: #FAF0E6FF. /// - public static Color Linen => FromPacked(0xFAF0E6FFu); + public static Color Linen => new((byte)250, (byte)240, (byte)230); /// /// Magenta color (R:255, G:0, B:255, A:255). - /// RGBA Hex: #FF00FFFF. + /// RGBA Hex: #FF00FFFF. /// - public static Color Magenta => FromPacked(0xFF00FFFFu); + public static Color Magenta => new((byte)255, (byte)0, (byte)255); /// /// Maroon color (R:128, G:0, B:0, A:255). - /// RGBA Hex: #800000FF. + /// RGBA Hex: #800000FF. /// - public static Color Maroon => FromPacked(0x800000FFu); + public static Color Maroon => new((byte)128, (byte)0, (byte)0); /// /// MediumAquamarine color (R:102, G:205, B:170, A:255). - /// RGBA Hex: #66CDAAFF. + /// RGBA Hex: #66CDAAFF. /// - public static Color MediumAquamarine => FromPacked(0x66CDAAFFu); + public static Color MediumAquamarine => new((byte)102, (byte)205, (byte)170); /// /// MediumBlue color (R:0, G:0, B:205, A:255). - /// RGBA Hex: #0000CDFF. + /// RGBA Hex: #0000CDFF. /// - public static Color MediumBlue => FromPacked(0x0000CDFFu); + public static Color MediumBlue => new((byte)0, (byte)0, (byte)205); /// /// MediumOrchid color (R:186, G:85, B:211, A:255). - /// RGBA Hex: #BA55D3FF. + /// RGBA Hex: #BA55D3FF. /// - public static Color MediumOrchid => FromPacked(0xBA55D3FFu); + public static Color MediumOrchid => new((byte)186, (byte)85, (byte)211); /// /// MediumPurple color (R:147, G:112, B:219, A:255). - /// RGBA Hex: #9370DBFF. + /// RGBA Hex: #9370DBFF. /// - public static Color MediumPurple => FromPacked(0x9370DBFFu); + public static Color MediumPurple => new((byte)147, (byte)112, (byte)219); /// /// MediumSeaGreen color (R:60, G:179, B:113, A:255). - /// RGBA Hex: #3CB371FF. + /// RGBA Hex: #3CB371FF. /// - public static Color MediumSeaGreen => FromPacked(0x3CB371FFu); + public static Color MediumSeaGreen => new((byte)60, (byte)179, (byte)113); /// /// MediumSlateBlue color (R:123, G:104, B:238, A:255). - /// RGBA Hex: #7B68EEFF. + /// RGBA Hex: #7B68EEFF. /// - public static Color MediumSlateBlue => FromPacked(0x7B68EEFFu); + public static Color MediumSlateBlue => new((byte)123, (byte)104, (byte)238); /// /// MediumSpringGreen color (R:0, G:250, B:154, A:255). - /// RGBA Hex: #00FA9AFF. + /// RGBA Hex: #00FA9AFF. /// - public static Color MediumSpringGreen => FromPacked(0x00FA9AFFu); + public static Color MediumSpringGreen => new((byte)0, (byte)250, (byte)154); /// /// MediumTurquoise color (R:72, G:209, B:204, A:255). - /// RGBA Hex: #48D1CCFF. + /// RGBA Hex: #48D1CCFF. /// - public static Color MediumTurquoise => FromPacked(0x48D1CCFFu); + public static Color MediumTurquoise => new((byte)72, (byte)209, (byte)204); /// /// MediumVioletRed color (R:199, G:21, B:133, A:255). - /// RGBA Hex: #C71585FF. + /// RGBA Hex: #C71585FF. /// - public static Color MediumVioletRed => FromPacked(0xC71585FFu); + public static Color MediumVioletRed => new((byte)199, (byte)21, (byte)133); /// /// MidnightBlue color (R:25, G:25, B:112, A:255). - /// RGBA Hex: #191970FF. + /// RGBA Hex: #191970FF. /// - public static Color MidnightBlue => FromPacked(0x191970FFu); + public static Color MidnightBlue => new((byte)25, (byte)25, (byte)112); /// /// MintCream color (R:245, G:255, B:250, A:255). - /// RGBA Hex: #F5FFFAFF. + /// RGBA Hex: #F5FFFAFF. /// - public static Color MintCream => FromPacked(0xF5FFFAFFu); + public static Color MintCream => new((byte)245, (byte)255, (byte)250); /// /// MistyRose color (R:255, G:228, B:225, A:255). - /// RGBA Hex: #FFE4E1FF. + /// RGBA Hex: #FFE4E1FF. /// - public static Color MistyRose => FromPacked(0xFFE4E1FFu); + public static Color MistyRose => new((byte)255, (byte)228, (byte)225); /// /// Moccasin color (R:255, G:228, B:181, A:255). - /// RGBA Hex: #FFE4B5FF. + /// RGBA Hex: #FFE4B5FF. /// - public static Color Moccasin => FromPacked(0xFFE4B5FFu); + public static Color Moccasin => new((byte)255, (byte)228, (byte)181); /// /// NavajoWhite color (R:255, G:222, B:173, A:255). - /// RGBA Hex: #FFDEADFF. + /// RGBA Hex: #FFDEADFF. /// - public static Color NavajoWhite => FromPacked(0xFFDEADFFu); + public static Color NavajoWhite => new((byte)255, (byte)222, (byte)173); /// /// Navy color (R:0, G:0, B:128, A:255). - /// RGBA Hex: #000080FF. + /// RGBA Hex: #000080FF. /// - public static Color Navy => FromPacked(0x000080FFu); + public static Color Navy => new((byte)0, (byte)0, (byte)128); /// /// OldLace color (R:253, G:245, B:230, A:255). - /// RGBA Hex: #FDF5E6FF. + /// RGBA Hex: #FDF5E6FF. /// - public static Color OldLace => FromPacked(0xFDF5E6FFu); + public static Color OldLace => new((byte)253, (byte)245, (byte)230); /// /// Olive color (R:128, G:128, B:0, A:255). - /// RGBA Hex: #808000FF. + /// RGBA Hex: #808000FF. /// - public static Color Olive => FromPacked(0x808000FFu); + public static Color Olive => new((byte)128, (byte)128, (byte)0); /// /// OliveDrab color (R:107, G:142, B:35, A:255). - /// RGBA Hex: #6B8E23FF. + /// RGBA Hex: #6B8E23FF. /// - public static Color OliveDrab => FromPacked(0x6B8E23FFu); + public static Color OliveDrab => new((byte)107, (byte)142, (byte)35); /// /// Orange color (R:255, G:165, B:0, A:255). - /// RGBA Hex: #FFA500FF. + /// RGBA Hex: #FFA500FF. /// - public static Color Orange => FromPacked(0xFFA500FFu); + public static Color Orange => new((byte)255, (byte)165, (byte)0); /// /// OrangeRed color (R:255, G:69, B:0, A:255). - /// RGBA Hex: #FF4500FF. + /// RGBA Hex: #FF4500FF. /// - public static Color OrangeRed => FromPacked(0xFF4500FFu); + public static Color OrangeRed => new((byte)255, (byte)69, (byte)0); /// /// Orchid color (R:218, G:112, B:214, A:255). - /// RGBA Hex: #DA70D6FF. + /// RGBA Hex: #DA70D6FF. /// - public static Color Orchid => FromPacked(0xDA70D6FFu); + public static Color Orchid => new((byte)218, (byte)112, (byte)214); /// /// PaleGoldenrod color (R:238, G:232, B:170, A:255). - /// RGBA Hex: #EEE8AAFF. + /// RGBA Hex: #EEE8AAFF. /// - public static Color PaleGoldenrod => FromPacked(0xEEE8AAFFu); + public static Color PaleGoldenrod => new((byte)238, (byte)232, (byte)170); /// /// PaleGreen color (R:152, G:251, B:152, A:255). - /// RGBA Hex: #98FB98FF. + /// RGBA Hex: #98FB98FF. /// - public static Color PaleGreen => FromPacked(0x98FB98FFu); + public static Color PaleGreen => new((byte)152, (byte)251, (byte)152); /// /// PaleTurquoise color (R:175, G:238, B:238, A:255). - /// RGBA Hex: #AFEEEEFF. + /// RGBA Hex: #AFEEEEFF. /// - public static Color PaleTurquoise => FromPacked(0xAFEEEEFFu); + public static Color PaleTurquoise => new((byte)175, (byte)238, (byte)238); /// /// PaleVioletRed color (R:219, G:112, B:147, A:255). - /// RGBA Hex: #DB7093FF. + /// RGBA Hex: #DB7093FF. /// - public static Color PaleVioletRed => FromPacked(0xDB7093FFu); + public static Color PaleVioletRed => new((byte)219, (byte)112, (byte)147); /// /// PapayaWhip color (R:255, G:239, B:213, A:255). - /// RGBA Hex: #FFEFD5FF. + /// RGBA Hex: #FFEFD5FF. /// - public static Color PapayaWhip => FromPacked(0xFFEFD5FFu); + public static Color PapayaWhip => new((byte)255, (byte)239, (byte)213); /// /// PeachPuff color (R:255, G:218, B:185, A:255). - /// RGBA Hex: #FFDAB9FF. + /// RGBA Hex: #FFDAB9FF. /// - public static Color PeachPuff => FromPacked(0xFFDAB9FFu); + public static Color PeachPuff => new((byte)255, (byte)218, (byte)185); /// /// Peru color (R:205, G:133, B:63, A:255). - /// RGBA Hex: #CD853FFF. + /// RGBA Hex: #CD853FFF. /// - public static Color Peru => FromPacked(0xCD853FFFu); + public static Color Peru => new((byte)205, (byte)133, (byte)63); /// /// Pink color (R:255, G:192, B:203, A:255). - /// RGBA Hex: #FFC0CBFF. + /// RGBA Hex: #FFC0CBFF. /// - public static Color Pink => FromPacked(0xFFC0CBFFu); + public static Color Pink => new((byte)255, (byte)192, (byte)203); /// /// Plum color (R:221, G:160, B:221, A:255). - /// RGBA Hex: #DDA0DDFF. + /// RGBA Hex: #DDA0DDFF. /// - public static Color Plum => FromPacked(0xDDA0DDFFu); + public static Color Plum => new((byte)221, (byte)160, (byte)221); /// /// PowderBlue color (R:176, G:224, B:230, A:255). - /// RGBA Hex: #B0E0E6FF. + /// RGBA Hex: #B0E0E6FF. /// - public static Color PowderBlue => FromPacked(0xB0E0E6FFu); + public static Color PowderBlue => new((byte)176, (byte)224, (byte)230); /// /// Purple color (R:128, G:0, B:128, A:255). - /// RGBA Hex: #800080FF. + /// RGBA Hex: #800080FF. /// - public static Color Purple => FromPacked(0x800080FFu); + public static Color Purple => new((byte)128, (byte)0, (byte)128); /// /// Red color (R:255, G:0, B:0, A:255). - /// RGBA Hex: #FF0000FF. + /// RGBA Hex: #FF0000FF. /// - public static Color Red => FromPacked(0xFF0000FFu); + public static Color Red => new((byte)255, (byte)0, (byte)0); /// /// RosyBrown color (R:188, G:143, B:143, A:255). - /// RGBA Hex: #BC8F8FFF. + /// RGBA Hex: #BC8F8FFF. /// - public static Color RosyBrown => FromPacked(0xBC8F8FFFu); + public static Color RosyBrown => new((byte)188, (byte)143, (byte)143); /// /// RoyalBlue color (R:65, G:105, B:225, A:255). - /// RGBA Hex: #4169E1FF. + /// RGBA Hex: #4169E1FF. /// - public static Color RoyalBlue => FromPacked(0x4169E1FFu); + public static Color RoyalBlue => new((byte)65, (byte)105, (byte)225); /// /// SaddleBrown color (R:139, G:69, B:19, A:255). - /// RGBA Hex: #8B4513FF. + /// RGBA Hex: #8B4513FF. /// - public static Color SaddleBrown => FromPacked(0x8B4513FFu); + public static Color SaddleBrown => new((byte)139, (byte)69, (byte)19); /// /// Salmon color (R:250, G:128, B:114, A:255). - /// RGBA Hex: #FA8072FF. + /// RGBA Hex: #FA8072FF. /// - public static Color Salmon => FromPacked(0xFA8072FFu); + public static Color Salmon => new((byte)250, (byte)128, (byte)114); /// /// SandyBrown color (R:244, G:164, B:96, A:255). - /// RGBA Hex: #F4A460FF. + /// RGBA Hex: #F4A460FF. /// - public static Color SandyBrown => FromPacked(0xF4A460FFu); + public static Color SandyBrown => new((byte)244, (byte)164, (byte)96); /// /// SeaGreen color (R:46, G:139, B:87, A:255). - /// RGBA Hex: #2E8B57FF. + /// RGBA Hex: #2E8B57FF. /// - public static Color SeaGreen => FromPacked(0x2E8B57FFu); + public static Color SeaGreen => new((byte)46, (byte)139, (byte)87); /// /// SeaShell color (R:255, G:245, B:238, A:255). - /// RGBA Hex: #FFF5EEFF. + /// RGBA Hex: #FFF5EEFF. /// - public static Color SeaShell => FromPacked(0xFFF5EEFFu); + public static Color SeaShell => new((byte)255, (byte)245, (byte)238); /// /// Sienna color (R:160, G:82, B:45, A:255). - /// RGBA Hex: #A0522DFF. + /// RGBA Hex: #A0522DFF. /// - public static Color Sienna => FromPacked(0xA0522DFFu); + public static Color Sienna => new((byte)160, (byte)82, (byte)45); /// /// Silver color (R:192, G:192, B:192, A:255). - /// RGBA Hex: #C0C0C0FF. + /// RGBA Hex: #C0C0C0FF. /// - public static Color Silver => FromPacked(0xC0C0C0FFu); + public static Color Silver => new((byte)192, (byte)192, (byte)192); /// /// SkyBlue color (R:135, G:206, B:235, A:255). - /// RGBA Hex: #87CEEBFF. + /// RGBA Hex: #87CEEBFF. /// - public static Color SkyBlue => FromPacked(0x87CEEBFFu); + public static Color SkyBlue => new((byte)135, (byte)206, (byte)235); /// /// SlateBlue color (R:106, G:90, B:205, A:255). - /// RGBA Hex: #6A5ACDFF. + /// RGBA Hex: #6A5ACDFF. /// - public static Color SlateBlue => FromPacked(0x6A5ACDFFu); + public static Color SlateBlue => new((byte)106, (byte)90, (byte)205); /// /// SlateGray color (R:112, G:128, B:144, A:255). - /// RGBA Hex: #708090FF. + /// RGBA Hex: #708090FF. /// - public static Color SlateGray => FromPacked(0x708090FFu); + public static Color SlateGray => new((byte)112, (byte)128, (byte)144); /// /// Snow color (R:255, G:250, B:250, A:255). - /// RGBA Hex: #FFFAFAFF. + /// RGBA Hex: #FFFAFAFF. /// - public static Color Snow => FromPacked(0xFFFAFAFFu); + public static Color Snow => new((byte)255, (byte)250, (byte)250); /// /// SpringGreen color (R:0, G:255, B:127, A:255). - /// RGBA Hex: #00FF7FFF. + /// RGBA Hex: #00FF7FFF. /// - public static Color SpringGreen => FromPacked(0x00FF7FFFu); + public static Color SpringGreen => new((byte)0, (byte)255, (byte)127); /// /// SteelBlue color (R:70, G:130, B:180, A:255). - /// RGBA Hex: #4682B4FF. + /// RGBA Hex: #4682B4FF. /// - public static Color SteelBlue => FromPacked(0x4682B4FFu); + public static Color SteelBlue => new((byte)70, (byte)130, (byte)180); /// /// Tan color (R:210, G:180, B:140, A:255). - /// RGBA Hex: #D2B48CFF. + /// RGBA Hex: #D2B48CFF. /// - public static Color Tan => FromPacked(0xD2B48CFFu); + public static Color Tan => new((byte)210, (byte)180, (byte)140); /// /// Teal color (R:0, G:128, B:128, A:255). - /// RGBA Hex: #008080FF. + /// RGBA Hex: #008080FF. /// - public static Color Teal => FromPacked(0x008080FFu); + public static Color Teal => new((byte)0, (byte)128, (byte)128); /// /// Thistle color (R:216, G:191, B:216, A:255). - /// RGBA Hex: #D8BFD8FF. + /// RGBA Hex: #D8BFD8FF. /// - public static Color Thistle => FromPacked(0xD8BFD8FFu); + public static Color Thistle => new((byte)216, (byte)191, (byte)216); /// /// Tomato color (R:255, G:99, B:71, A:255). - /// RGBA Hex: #FF6347FF. + /// RGBA Hex: #FF6347FF. /// - public static Color Tomato => FromPacked(0xFF6347FFu); + public static Color Tomato => new((byte)255, (byte)99, (byte)71); /// /// Turquoise color (R:64, G:224, B:208, A:255). - /// RGBA Hex: #40E0D0FF. + /// RGBA Hex: #40E0D0FF. /// - public static Color Turquoise => FromPacked(0x40E0D0FFu); + public static Color Turquoise => new((byte)64, (byte)224, (byte)208); /// /// Violet color (R:238, G:130, B:238, A:255). - /// RGBA Hex: #EE82EEFF. + /// RGBA Hex: #EE82EEFF. /// - public static Color Violet => FromPacked(0xEE82EEFFu); + public static Color Violet => new((byte)238, (byte)130, (byte)238); /// /// Wheat color (R:245, G:222, B:179, A:255). - /// RGBA Hex: #F5DEB3FF. + /// RGBA Hex: #F5DEB3FF. /// - public static Color Wheat => FromPacked(0xF5DEB3FFu); + public static Color Wheat => new((byte)245, (byte)222, (byte)179); /// /// White color (R:255, G:255, B:255, A:255). - /// RGBA Hex: #FFFFFFFF. + /// RGBA Hex: #FFFFFFFF. /// - public static Color White => FromPacked(0xFFFFFFFFu); + public static Color White => new((byte)255, (byte)255, (byte)255); /// /// WhiteSmoke color (R:245, G:245, B:245, A:255). - /// RGBA Hex: #F5F5F5FF. + /// RGBA Hex: #F5F5F5FF. /// - public static Color WhiteSmoke => FromPacked(0xF5F5F5FFu); + public static Color WhiteSmoke => new((byte)245, (byte)245, (byte)245); /// /// Yellow color (R:255, G:255, B:0, A:255). - /// RGBA Hex: #FFFF00FF. + /// RGBA Hex: #FFFF00FF. /// - public static Color Yellow => FromPacked(0xFFFF00FFu); + public static Color Yellow => new((byte)255, (byte)255, (byte)0); /// /// YellowGreen color (R:154, G:205, B:50, A:255). - /// RGBA Hex: #9ACD32FF. + /// RGBA Hex: #9ACD32FF. /// - public static Color YellowGreen => FromPacked(0x9ACD32FFu); + public static Color YellowGreen => new((byte)154, (byte)205, (byte)50); /// /// RebeccaPurple color (R:102, G:51, B:153, A:255). - /// RGBA Hex: #663399FF. + /// RGBA Hex: #663399FF. /// - public static Color RebeccaPurple => FromPacked(0x663399FFu); + public static Color RebeccaPurple => new((byte)102, (byte)51, (byte)153); #endregion Built-In Colors From 6c8ba9ff4046b401d3b60fc6de9169dfc6599cc1 Mon Sep 17 00:00:00 2001 From: demorome Date: Mon, 1 Dec 2025 00:03:19 -0400 Subject: [PATCH 04/23] remove unecessary Size limitation for struct layout --- src/Graphics/Color.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 92fcaf0..b24f354 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -21,7 +21,6 @@ namespace MoonWorks.Graphics; /// /// Describes a 32-bit packed color. /// -[StructLayout(LayoutKind.Sequential, Size = 4, Pack = 4)] public record struct Color(byte R, byte G, byte B, byte A = 255) { public Color(int r, int g, int b, int a = 255) : this( From ad4079b85e5bad9cb5923cd4b336d0da70e90388 Mon Sep 17 00:00:00 2001 From: demorome Date: Mon, 1 Dec 2025 00:07:46 -0400 Subject: [PATCH 05/23] remove #region, replaced with a simple comment --- src/Graphics/Color.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index b24f354..9545195 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -276,7 +276,8 @@ public string ToHexString() }; -#region Built-In Colors +///=== Built-In Colors + /// /// Transparent color (R:0, G:0, B:0, A:0). /// @@ -1127,7 +1128,4 @@ public string ToHexString() /// RGBA Hex: #663399FF. /// public static Color RebeccaPurple => new((byte)102, (byte)51, (byte)153); - -#endregion Built-In Colors - } \ No newline at end of file From 783d3c57b2d8867abec47d598554fd3102c414b2 Mon Sep 17 00:00:00 2001 From: demorome Date: Mon, 1 Dec 2025 13:34:34 -0400 Subject: [PATCH 06/23] rework Color.FromPacked() to use a type-safe PackedColor interface --- src/Graphics/Color.cs | 16 ++--- src/Graphics/PackedColor.cs | 123 ++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 src/Graphics/PackedColor.cs diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 9545195..ba291e3 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -14,7 +14,6 @@ using System.Runtime.CompilerServices; using System.Text; using System.Numerics; -using System.Runtime.InteropServices; namespace MoonWorks.Graphics; @@ -60,19 +59,18 @@ public Color(float r, float g, float b) : this( public Color(Vector4 vector) : this(vector.X, vector.Y, vector.Z, vector.W) { } /// - /// Gets packed RGBA value of this . + /// Gets a packed RGBA value of this . /// NOTE: Because of endianness, if you format this value directly as a hex string, - /// the order of bytes may be wrong. + /// the order of bytes may be unexpected. /// public readonly uint PackedValue() => Unsafe.BitCast(this); /// - /// Gets a representation for a packed RGBA value. - /// NEVER plug in a value that wasn't generated by PackedValue(), - /// unless you're SURE you can deal with an endianness mismatch. - /// Example: it's NOT safe to take 0xF0F8FFFF from AliceBlue and plug it into here! - /// - public static Color FromPacked(uint rgba) => Unsafe.BitCast(rgba); + /// Gets a representation for a value. + /// + /// The to convert. + /// A representation for the . + public static Color FromPacked(PackedColor packedColor) => Unsafe.BitCast(packedColor.RGBA); /// /// Gets a representation for this object. diff --git a/src/Graphics/PackedColor.cs b/src/Graphics/PackedColor.cs new file mode 100644 index 0000000..e45ddd7 --- /dev/null +++ b/src/Graphics/PackedColor.cs @@ -0,0 +1,123 @@ +using System; +using System.Runtime.CompilerServices; +using System.Text; +using System.Numerics; + +namespace MoonWorks.Graphics; + +/// +/// A packed as 4 bytes in an unsigned integer representation. +/// This represensation exists to prevent footguns related to endianness. +/// Using static constructors, we guarantee that we can safely bit-cast this value into a . +/// +public readonly record struct PackedColor() +{ + public readonly uint RGBA; + + /// + /// Disable default constructor w/ parameter. + /// We don't want people to shoot themselves in the foot by passing in + /// an integer literal without thinking of endianness. + /// + private PackedColor(uint rgba) : this() + { + RGBA = rgba; + } + + /// + /// Returns a representation of a value. + /// + /// The to convert. + /// A representation of a value + public static PackedColor FromColor(Color color) + => new PackedColor(Unsafe.BitCast(color)); + + /// + /// Returns a representation of a packed RGBA value + /// whose endianness matches the struct. + /// Example use-case: convert the result of + /// into a , such that we can now explicitly bit-cast it + /// back into a . + /// Of course, the result of could've + /// been directly bit-casted anyways, but using these facilities is good practice + /// since it forces the user to think about endianness for other cases. + /// + /// The to convert. + /// + public static PackedColor FromCurrentEndianRGBA(uint rgba) + { + return new PackedColor(rgba); + } + + /// + /// Converts a big-endian-packed RGBA color into a whose endianness matches the struct. + /// Example valid input: `0xF0F8FFFF`, aka AliceBlue. + /// + /// A big-endian packed color that specifies R, G, B, and A values. + /// A , which can then be safely bit-cast to a . + public static PackedColor FromBigEndianRGBA(uint bigEndian_RGBA) + { + if (BitConverter.IsLittleEndian) + { + // Reverse the byte order of the big-endian-packed color into little-endian format. + // This is because our Color struct is currently little-endian, + // so we need to maintain convertability. + return new PackedColor(ReversedEndiannessColor.ToLittleEndian(bigEndian_RGBA)); + } + else + { + // Endianness matches, so we don't need to do anything special. + // This is an uncommon case, since most computers are little-endian. + return new PackedColor(bigEndian_RGBA); + } + } + + /// + /// Converts a big-endian-packed RGB color into a whose endianness matches the struct. + /// Example valid input: `0xF0F8FF`, aka AliceBlue. + /// The above will be interpeted as a big-endian input of `0xF0F8FF(AlphaByte)`. + /// + /// A big-endian packed color that specifies R, G, and B values. + /// The Alpha channel value for the color. + /// A , which can then be safely bit-cast to a . + public static PackedColor FromBigEndianRGB(int bigEndian_RGB, byte alpha = 255) + { + // Shift by 8 bits up, since `0xF0F8FF` is supposed to be interpreted as `0xF0F8FF(AlphaByte)`. + var bigEndian_RGBA = ((uint)bigEndian_RGB << 8) | alpha; + return FromBigEndianRGBA(bigEndian_RGBA); + } + + public Color ToColor() + { + return Color.FromPacked(this); + } + + private readonly record struct ReversedEndiannessColor(byte A, byte B, byte G, byte R) + { + /// + /// Transforms a big-endian packed color value into little-endian. + /// There's no reason to call this if our architecture is big-endian; doing so is a bug. + /// + /// A big-endian packed color value that must be reversed into little-endian. + /// A little-endian RGBA packed value,such that it can be bit-cast into a . + public static uint ToLittleEndian(uint bigEndian_RGBA) + { + var reversedColor = FromBigEndian_RGBA(bigEndian_RGBA); + return reversedColor.PackedValue(); + } + + private static ReversedEndiannessColor FromBigEndian_RGBA(uint bigEndian_RGBA) + => Unsafe.BitCast(bigEndian_RGBA); + + private Color ToRegularColor() + { + return new Color(R, G, B, A); + } + + private uint PackedValue() + { + var color = ToRegularColor(); + return color.PackedValue(); + } + } +} \ No newline at end of file From 8c3a62300d2f03402f3b3a46f2b75714077da643 Mon Sep 17 00:00:00 2001 From: demorome Date: Mon, 1 Dec 2025 13:51:04 -0400 Subject: [PATCH 07/23] rename misleading private function in ReversedEndiannessColor struct --- src/Graphics/PackedColor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Graphics/PackedColor.cs b/src/Graphics/PackedColor.cs index e45ddd7..466e799 100644 --- a/src/Graphics/PackedColor.cs +++ b/src/Graphics/PackedColor.cs @@ -103,7 +103,7 @@ private readonly record struct ReversedEndiannessColor(byte A, byte B, byte G, b public static uint ToLittleEndian(uint bigEndian_RGBA) { var reversedColor = FromBigEndian_RGBA(bigEndian_RGBA); - return reversedColor.PackedValue(); + return reversedColor.RegularColorPackedValue(); } private static ReversedEndiannessColor FromBigEndian_RGBA(uint bigEndian_RGBA) @@ -114,7 +114,7 @@ private Color ToRegularColor() return new Color(R, G, B, A); } - private uint PackedValue() + private uint RegularColorPackedValue() { var color = ToRegularColor(); return color.PackedValue(); From b3a601abaac1c23cbe01e000ae7260448402d00d Mon Sep 17 00:00:00 2001 From: demorome Date: Mon, 1 Dec 2025 14:17:29 -0400 Subject: [PATCH 08/23] add PackedValue warning about not saving it directly to a file --- src/Graphics/Color.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index ba291e3..0466668 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -62,6 +62,11 @@ public Color(Vector4 vector) : this(vector.X, vector.Y, vector.Z, vector.W) { } /// Gets a packed RGBA value of this . /// NOTE: Because of endianness, if you format this value directly as a hex string, /// the order of bytes may be unexpected. + /// DO NOT store this value directly into a file + /// without formatting it to a specific endianness! + /// Otherwise, if the value is read back and the color is naively reconstructed + /// through , an endianness mismatch may occur + /// with different machines reading that file. /// public readonly uint PackedValue() => Unsafe.BitCast(this); From 9300b131b73e890add033941af36b65b5de72bd5 Mon Sep 17 00:00:00 2001 From: demorome Date: Mon, 1 Dec 2025 14:32:16 -0400 Subject: [PATCH 09/23] allow choosing prefix for ToHexString() --- src/Graphics/Color.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 0466668..08f07e0 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -247,14 +247,22 @@ public override string ToString() /// /// Returns a hexadecimal representation of this in the format: - /// 0x[R][G][B][A] + /// (Prefix)[R][G][B][A] /// Thus, it's in Big Endian format. /// + /// "#" prefix if false, "0x" otherwise. /// representation of this . - public string ToHexString() + public string ToHexString(bool hashtagOrHexadecimalPrefix = false) { StringBuilder sb = new StringBuilder(10); - sb.Append("#"); + if (!hashtagOrHexadecimalPrefix) + { + sb.Append("#"); + } + else + { + sb.Append("0x"); + } sb.Append(R.ToString("X2")); sb.Append(G.ToString("X2")); sb.Append(B.ToString("X2")); From 9f8e36181712736f80ff7cf29b7a24ddd0f8b5e7 Mon Sep 17 00:00:00 2001 From: demorome Date: Mon, 1 Dec 2025 15:06:24 -0400 Subject: [PATCH 10/23] Remove FromCurrentEndianRGBA and FromColor constructors due to footgun concerns and limited use-cases --- src/Graphics/Color.cs | 4 ++-- src/Graphics/PackedColor.cs | 28 ++-------------------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 08f07e0..91466f6 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -65,8 +65,8 @@ public Color(Vector4 vector) : this(vector.X, vector.Y, vector.Z, vector.W) { } /// DO NOT store this value directly into a file /// without formatting it to a specific endianness! /// Otherwise, if the value is read back and the color is naively reconstructed - /// through , an endianness mismatch may occur - /// with different machines reading that file. + /// via an , an endianness mismatch may occur + /// for different machines reading that file. /// public readonly uint PackedValue() => Unsafe.BitCast(this); diff --git a/src/Graphics/PackedColor.cs b/src/Graphics/PackedColor.cs index 466e799..29b6eb7 100644 --- a/src/Graphics/PackedColor.cs +++ b/src/Graphics/PackedColor.cs @@ -8,7 +8,8 @@ namespace MoonWorks.Graphics; /// /// A packed as 4 bytes in an unsigned integer representation. /// This represensation exists to prevent footguns related to endianness. -/// Using static constructors, we guarantee that we can safely bit-cast this value into a . +/// With appropriately-used static constructors, we guarantee +/// that we can safely bit-cast this value into a . /// public readonly record struct PackedColor() { @@ -23,31 +24,6 @@ private PackedColor(uint rgba) : this() { RGBA = rgba; } - - /// - /// Returns a representation of a value. - /// - /// The to convert. - /// A representation of a value - public static PackedColor FromColor(Color color) - => new PackedColor(Unsafe.BitCast(color)); - - /// - /// Returns a representation of a packed RGBA value - /// whose endianness matches the struct. - /// Example use-case: convert the result of - /// into a , such that we can now explicitly bit-cast it - /// back into a . - /// Of course, the result of could've - /// been directly bit-casted anyways, but using these facilities is good practice - /// since it forces the user to think about endianness for other cases. - /// - /// The to convert. - /// - public static PackedColor FromCurrentEndianRGBA(uint rgba) - { - return new PackedColor(rgba); - } /// /// Converts a big-endian-packed RGBA color into a whose endianness matches the struct. From 2d36f3959a55967b06525247e3ac1cf4750ac166 Mon Sep 17 00:00:00 2001 From: demorome Date: Mon, 1 Dec 2025 18:20:48 -0400 Subject: [PATCH 11/23] remove PackedColor, port FromBigEndianRGB(A) to Color, using Noel Berry's superior implementation --- licenses/foster.LICENSE | 21 ++++++++ src/Graphics/Color.cs | 50 ++++++++++++++++--- src/Graphics/PackedColor.cs | 99 ------------------------------------- 3 files changed, 65 insertions(+), 105 deletions(-) create mode 100644 licenses/foster.LICENSE delete mode 100644 src/Graphics/PackedColor.cs diff --git a/licenses/foster.LICENSE b/licenses/foster.LICENSE new file mode 100644 index 0000000..3ec8ba3 --- /dev/null +++ b/licenses/foster.LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Noel Berry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 91466f6..baef361 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -8,6 +8,11 @@ * Derived from code by the Mono.Xna Team (Copyright 2006). * Released under the MIT License. See monoxna.LICENSE for details. + * + * Derived from code by Noel Berry (Copyright 2023). + * Released under the MIT License. See foster.LICENSE for details. + * Specifically, we're using their clever implementation for FromBigEndianRGB(A), + * which utilizes integer overflow. */ using System; @@ -58,6 +63,21 @@ public Color(float r, float g, float b) : this( public Color(Vector4 vector) : this(vector.X, vector.Y, vector.Z, vector.W) { } + // Private, to enforce using explicit FromBigEndianRGB(A) functions. + private Color(uint bigEndian_RGBA) : this( + (byte)(bigEndian_RGBA >> 24), // R + (byte)(bigEndian_RGBA >> 16), // G + (byte)(bigEndian_RGBA >> 8), // B + (byte)bigEndian_RGBA // A + ) { } + + private Color(int bigEndian_RGB, byte alpha = 255) : this( + (byte)(bigEndian_RGB >> 16), // R + (byte)(bigEndian_RGB >> 8), // G + (byte)bigEndian_RGB, // B + alpha + ) { } + /// /// Gets a packed RGBA value of this . /// NOTE: Because of endianness, if you format this value directly as a hex string, @@ -67,15 +87,33 @@ public Color(Vector4 vector) : this(vector.X, vector.Y, vector.Z, vector.W) { } /// Otherwise, if the value is read back and the color is naively reconstructed /// via an , an endianness mismatch may occur /// for different machines reading that file. + /// For this reason, a straightforward "FromPackedValue()" function will never be exposed. /// public readonly uint PackedValue() => Unsafe.BitCast(this); - - /// - /// Gets a representation for a value. + + /// + /// Converts a big-endian RGBA packed color into a . + /// Example valid input: `0xF0F8FFFF`, aka AliceBlue. + /// + /// A big-endian packed color that specifies R, G, B, and A values. + /// A representation for the big-endian RGBA packed value. + public static Color FromBigEndianRGBA(uint bigEndian_RGBA) + { + return new Color(bigEndian_RGBA); + } + + /// + /// Converts a big-endian RGBA packed color into a . + /// Example valid input: `0xF0F8FF`, aka AliceBlue. + /// The above will be interpeted as a big-endian input of `0xF0F8FF(AlphaByte)`. /// - /// The to convert. - /// A representation for the . - public static Color FromPacked(PackedColor packedColor) => Unsafe.BitCast(packedColor.RGBA); + /// A big-endian packed color that specifies R, G, and B values. + /// The Alpha channel value for the color. + /// A representation for the big-endian RGBA packed value. + public static Color FromBigEndianRGB(int bigEndian_RGB, byte alpha = 255) + { + return new Color(bigEndian_RGB, alpha); + } /// /// Gets a representation for this object. diff --git a/src/Graphics/PackedColor.cs b/src/Graphics/PackedColor.cs deleted file mode 100644 index 29b6eb7..0000000 --- a/src/Graphics/PackedColor.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using System.Text; -using System.Numerics; - -namespace MoonWorks.Graphics; - -/// -/// A packed as 4 bytes in an unsigned integer representation. -/// This represensation exists to prevent footguns related to endianness. -/// With appropriately-used static constructors, we guarantee -/// that we can safely bit-cast this value into a . -/// -public readonly record struct PackedColor() -{ - public readonly uint RGBA; - - /// - /// Disable default constructor w/ parameter. - /// We don't want people to shoot themselves in the foot by passing in - /// an integer literal without thinking of endianness. - /// - private PackedColor(uint rgba) : this() - { - RGBA = rgba; - } - - /// - /// Converts a big-endian-packed RGBA color into a whose endianness matches the struct. - /// Example valid input: `0xF0F8FFFF`, aka AliceBlue. - /// - /// A big-endian packed color that specifies R, G, B, and A values. - /// A , which can then be safely bit-cast to a . - public static PackedColor FromBigEndianRGBA(uint bigEndian_RGBA) - { - if (BitConverter.IsLittleEndian) - { - // Reverse the byte order of the big-endian-packed color into little-endian format. - // This is because our Color struct is currently little-endian, - // so we need to maintain convertability. - return new PackedColor(ReversedEndiannessColor.ToLittleEndian(bigEndian_RGBA)); - } - else - { - // Endianness matches, so we don't need to do anything special. - // This is an uncommon case, since most computers are little-endian. - return new PackedColor(bigEndian_RGBA); - } - } - - /// - /// Converts a big-endian-packed RGB color into a whose endianness matches the struct. - /// Example valid input: `0xF0F8FF`, aka AliceBlue. - /// The above will be interpeted as a big-endian input of `0xF0F8FF(AlphaByte)`. - /// - /// A big-endian packed color that specifies R, G, and B values. - /// The Alpha channel value for the color. - /// A , which can then be safely bit-cast to a . - public static PackedColor FromBigEndianRGB(int bigEndian_RGB, byte alpha = 255) - { - // Shift by 8 bits up, since `0xF0F8FF` is supposed to be interpreted as `0xF0F8FF(AlphaByte)`. - var bigEndian_RGBA = ((uint)bigEndian_RGB << 8) | alpha; - return FromBigEndianRGBA(bigEndian_RGBA); - } - - public Color ToColor() - { - return Color.FromPacked(this); - } - - private readonly record struct ReversedEndiannessColor(byte A, byte B, byte G, byte R) - { - /// - /// Transforms a big-endian packed color value into little-endian. - /// There's no reason to call this if our architecture is big-endian; doing so is a bug. - /// - /// A big-endian packed color value that must be reversed into little-endian. - /// A little-endian RGBA packed value,such that it can be bit-cast into a . - public static uint ToLittleEndian(uint bigEndian_RGBA) - { - var reversedColor = FromBigEndian_RGBA(bigEndian_RGBA); - return reversedColor.RegularColorPackedValue(); - } - - private static ReversedEndiannessColor FromBigEndian_RGBA(uint bigEndian_RGBA) - => Unsafe.BitCast(bigEndian_RGBA); - - private Color ToRegularColor() - { - return new Color(R, G, B, A); - } - - private uint RegularColorPackedValue() - { - var color = ToRegularColor(); - return color.PackedValue(); - } - } -} \ No newline at end of file From e388c1b7ba4a0d37c456b3779cc276f1ed64bbb2 Mon Sep 17 00:00:00 2001 From: demorome Date: Fri, 19 Dec 2025 21:31:16 -0400 Subject: [PATCH 12/23] remove Foster credits+license, since the color unpacking trick is actually pretty common. Proof: https://community.particle.io/t/extracting-rgb-color-value/30170/2 --- licenses/foster.LICENSE | 21 --------------------- src/Graphics/Color.cs | 8 ++------ 2 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 licenses/foster.LICENSE diff --git a/licenses/foster.LICENSE b/licenses/foster.LICENSE deleted file mode 100644 index 3ec8ba3..0000000 --- a/licenses/foster.LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Noel Berry - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index baef361..d86963e 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -8,11 +8,6 @@ * Derived from code by the Mono.Xna Team (Copyright 2006). * Released under the MIT License. See monoxna.LICENSE for details. - * - * Derived from code by Noel Berry (Copyright 2023). - * Released under the MIT License. See foster.LICENSE for details. - * Specifically, we're using their clever implementation for FromBigEndianRGB(A), - * which utilizes integer overflow. */ using System; @@ -65,6 +60,7 @@ public Color(Vector4 vector) : this(vector.X, vector.Y, vector.Z, vector.W) { } // Private, to enforce using explicit FromBigEndianRGB(A) functions. private Color(uint bigEndian_RGBA) : this( + // Casting to byte triggers overflow behavior, meaning we retain the 8 least significant bits. (byte)(bigEndian_RGBA >> 24), // R (byte)(bigEndian_RGBA >> 16), // G (byte)(bigEndian_RGBA >> 8), // B @@ -325,7 +321,7 @@ public string ToHexString(bool hashtagOrHexadecimalPrefix = false) }; -///=== Built-In Colors + //MARK: Built-In Colors /// /// Transparent color (R:0, G:0, B:0, A:0). From 12b6890f849999765ec90d51691bd408978c7528 Mon Sep 17 00:00:00 2001 From: demorome Date: Fri, 19 Dec 2025 21:38:41 -0400 Subject: [PATCH 13/23] rename PackedValue to UnsafePackedValue, use
instead of noisy tags. --- src/Graphics/Color.cs | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index d86963e..e8b9466 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -76,20 +76,19 @@ private Color(int bigEndian_RGB, byte alpha = 255) : this( /// /// Gets a packed RGBA value of this . - /// NOTE: Because of endianness, if you format this value directly as a hex string, - /// the order of bytes may be unexpected. - /// DO NOT store this value directly into a file - /// without formatting it to a specific endianness! - /// Otherwise, if the value is read back and the color is naively reconstructed - /// via an , an endianness mismatch may occur - /// for different machines reading that file. - /// For this reason, a straightforward "FromPackedValue()" function will never be exposed. - /// - public readonly uint PackedValue() => Unsafe.BitCast(this); + /// Its endianness depends on the machine running this code.
+ /// NOTE: Because of endianness, if you format this value directly as a hex string, + /// the order of bytes may be unexpected.
+ /// DO NOT store this value directly into a file!
+ /// Otherwise, if the value is read back and the color is naively reconstructed + /// via an Unsafe.BitCast, an endianness mismatch may occur + /// for different machines reading that file. + ///
+ public readonly uint UnsafePackedValue() => Unsafe.BitCast(this); /// - /// Converts a big-endian RGBA packed color into a . - /// Example valid input: `0xF0F8FFFF`, aka AliceBlue. + /// Converts a big-endian RGBA packed color into a .
+ /// Example valid input: `0xF0F8FFFF`, aka AliceBlue. ///
/// A big-endian packed color that specifies R, G, B, and A values. /// A representation for the big-endian RGBA packed value. @@ -99,9 +98,9 @@ public static Color FromBigEndianRGBA(uint bigEndian_RGBA) } /// - /// Converts a big-endian RGBA packed color into a . - /// Example valid input: `0xF0F8FF`, aka AliceBlue. - /// The above will be interpeted as a big-endian input of `0xF0F8FF(AlphaByte)`. + /// Converts a big-endian RGBA packed color into a .
+ /// Example valid input: `0xF0F8FF`, aka AliceBlue. + /// The above will be interpeted as a big-endian input of `0xF0F8FF(AlphaByte)`.
///
/// A big-endian packed color that specifies R, G, and B values. /// The Alpha channel value for the color. @@ -281,8 +280,8 @@ public override string ToString() /// /// Returns a hexadecimal representation of this in the format: - /// (Prefix)[R][G][B][A] - /// Thus, it's in Big Endian format. + /// (Prefix)[R][G][B][A]
+ /// Thus, it's in Big Endian format. ///
/// "#" prefix if false, "0x" otherwise. /// representation of this . From 58180c8b9e7eebdf428c34dde37ccfb9a24383a8 Mon Sep 17 00:00:00 2001 From: demorome Date: Fri, 19 Dec 2025 22:07:55 -0400 Subject: [PATCH 14/23] remove PackedValue, add BigEndianPackedValue --- src/Graphics/Color.cs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index e8b9466..f5d3f67 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -73,18 +73,15 @@ private Color(int bigEndian_RGB, byte alpha = 255) : this( (byte)bigEndian_RGB, // B alpha ) { } - - /// - /// Gets a packed RGBA value of this . - /// Its endianness depends on the machine running this code.
- /// NOTE: Because of endianness, if you format this value directly as a hex string, - /// the order of bytes may be unexpected.
- /// DO NOT store this value directly into a file!
- /// Otherwise, if the value is read back and the color is naively reconstructed - /// via an Unsafe.BitCast, an endianness mismatch may occur - /// for different machines reading that file. - ///
- public readonly uint UnsafePackedValue() => Unsafe.BitCast(this); + + /// + /// Returns the in a Big-Endian UInt32 packed value format. + /// Thus, the value is in RGBA byte-order. + /// + public readonly uint BigEndianPackedValue() + { + return ((uint)R << 24) | ((uint)G << 16) | ((uint)B << 8) | A; + } /// /// Converts a big-endian RGBA packed color into a .
From 0bb57fb014ae5a2045e47ca2792fcc11818c04b2 Mon Sep 17 00:00:00 2001 From: demorome Date: Fri, 19 Dec 2025 23:07:56 -0400 Subject: [PATCH 15/23] optimize ToHexString --- src/Graphics/Color.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index f5d3f67..9edea89 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -293,10 +293,7 @@ public string ToHexString(bool hashtagOrHexadecimalPrefix = false) { sb.Append("0x"); } - sb.Append(R.ToString("X2")); - sb.Append(G.ToString("X2")); - sb.Append(B.ToString("X2")); - sb.Append(A.ToString("X2")); + sb.Append(BigEndianPackedValue().ToString("X8")); return sb.ToString(); } From 5dae5f2bda7fc4136534fbcabbcd13843993fe8e Mon Sep 17 00:00:00 2001 From: demorome Date: Fri, 19 Dec 2025 23:11:41 -0400 Subject: [PATCH 16/23] replace the last remaining tags with
--- src/Graphics/Color.cs | 566 +++++++++++++++++++++--------------------- 1 file changed, 283 insertions(+), 283 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 9edea89..819332d 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -277,7 +277,7 @@ public override string ToString() /// /// Returns a hexadecimal representation of this in the format: - /// (Prefix)[R][G][B][A]
+ /// (Prefix)[R][G][B][A]
/// Thus, it's in Big Endian format. ///
/// "#" prefix if false, "0x" otherwise. @@ -322,848 +322,848 @@ public string ToHexString(bool hashtagOrHexadecimalPrefix = false) public static Color Transparent => new((byte)0, (byte)0, (byte)0, (byte)0); /// - /// AliceBlue color (R:240, G:248, B:255, A:255). - /// RGBA Hex: #F0F8FFFF. + /// AliceBlue color (R:240, G:248, B:255, A:255).
+ /// RGBA Hex: #F0F8FFFF. ///
public static Color AliceBlue => new((byte)240, (byte)248, (byte)255); /// - /// AntiqueWhite color (R:250, G:235, B:215, A:255). - /// RGBA Hex: #FAEBD7FF. + /// AntiqueWhite color (R:250, G:235, B:215, A:255).
+ /// RGBA Hex: #FAEBD7FF. ///
public static Color AntiqueWhite => new((byte)250, (byte)235, (byte)215); /// - /// Aqua color (R:0, G:255, B:255, A:255). - /// RGBA Hex: #00FFFFFF. + /// Aqua color (R:0, G:255, B:255, A:255).
+ /// RGBA Hex: #00FFFFFF. ///
public static Color Aqua => new((byte)0, (byte)255, (byte)255); /// - /// Aquamarine color (R:127, G:255, B:212, A:255). - /// RGBA Hex: #7FFFD4FF. + /// Aquamarine color (R:127, G:255, B:212, A:255).
+ /// RGBA Hex: #7FFFD4FF. ///
public static Color Aquamarine => new((byte)127, (byte)255, (byte)212); /// - /// Azure color (R:240, G:255, B:255, A:255). - /// RGBA Hex: #F0FFFFFF. + /// Azure color (R:240, G:255, B:255, A:255).
+ /// RGBA Hex: #F0FFFFFF. ///
public static Color Azure => new((byte)240, (byte)255, (byte)255); /// - /// Beige color (R:245, G:245, B:220, A:255). - /// RGBA Hex: #F5F5DCFF. + /// Beige color (R:245, G:245, B:220, A:255).
+ /// RGBA Hex: #F5F5DCFF. ///
public static Color Beige => new((byte)245, (byte)245, (byte)220); /// - /// Bisque color (R:255, G:228, B:196, A:255). - /// RGBA Hex: #FFE4C4FF. + /// Bisque color (R:255, G:228, B:196, A:255).
+ /// RGBA Hex: #FFE4C4FF. ///
public static Color Bisque => new((byte)255, (byte)228, (byte)196); /// - /// Black color (R:0, G:0, B:0, A:255). - /// RGBA Hex: #000000FF. + /// Black color (R:0, G:0, B:0, A:255).
+ /// RGBA Hex: #000000FF. ///
public static Color Black => new((byte)0, (byte)0, (byte)0); /// - /// BlanchedAlmond color (R:255, G:235, B:205, A:255). - /// RGBA Hex: #FFEBCDFF. + /// BlanchedAlmond color (R:255, G:235, B:205, A:255).
+ /// RGBA Hex: #FFEBCDFF. ///
public static Color BlanchedAlmond => new((byte)255, (byte)235, (byte)205); /// - /// Blue color (R:0, G:0, B:255, A:255). - /// RGBA Hex: #0000FFFF. + /// Blue color (R:0, G:0, B:255, A:255).
+ /// RGBA Hex: #0000FFFF. ///
public static Color Blue => new((byte)0, (byte)0, (byte)255); /// - /// BlueViolet color (R:138, G:43, B:226, A:255). - /// RGBA Hex: #8A2BE2FF. + /// BlueViolet color (R:138, G:43, B:226, A:255).
+ /// RGBA Hex: #8A2BE2FF. ///
public static Color BlueViolet => new((byte)138, (byte)43, (byte)226); /// - /// Brown color (R:165, G:42, B:42, A:255). - /// RGBA Hex: #A52A2AFF. + /// Brown color (R:165, G:42, B:42, A:255).
+ /// RGBA Hex: #A52A2AFF. ///
public static Color Brown => new((byte)165, (byte)42, (byte)42); /// - /// BurlyWood color (R:222, G:184, B:135, A:255). - /// RGBA Hex: #DEB887FF. + /// BurlyWood color (R:222, G:184, B:135, A:255).
+ /// RGBA Hex: #DEB887FF. ///
public static Color BurlyWood => new((byte)222, (byte)184, (byte)135); /// - /// CadetBlue color (R:95, G:158, B:160, A:255). - /// RGBA Hex: #5F9EA0FF. + /// CadetBlue color (R:95, G:158, B:160, A:255).
+ /// RGBA Hex: #5F9EA0FF. ///
public static Color CadetBlue => new((byte)95, (byte)158, (byte)160); /// - /// Chartreuse color (R:127, G:255, B:0, A:255). - /// RGBA Hex: #7FFF00FF. + /// Chartreuse color (R:127, G:255, B:0, A:255).
+ /// RGBA Hex: #7FFF00FF. ///
public static Color Chartreuse => new((byte)127, (byte)255, (byte)0); /// - /// Chocolate color (R:210, G:105, B:30, A:255). - /// RGBA Hex: #D2691EFF. + /// Chocolate color (R:210, G:105, B:30, A:255).
+ /// RGBA Hex: #D2691EFF. ///
public static Color Chocolate => new((byte)210, (byte)105, (byte)30); /// - /// Coral color (R:255, G:127, B:80, A:255). - /// RGBA Hex: #FF7F50FF. + /// Coral color (R:255, G:127, B:80, A:255).
+ /// RGBA Hex: #FF7F50FF. ///
public static Color Coral => new((byte)255, (byte)127, (byte)80); /// - /// CornflowerBlue color (R:100, G:149, B:237, A:255). - /// RGBA Hex: #6495EDFF. + /// CornflowerBlue color (R:100, G:149, B:237, A:255).
+ /// RGBA Hex: #6495EDFF. ///
public static Color CornflowerBlue => new((byte)100, (byte)149, (byte)237); /// - /// Cornsilk color (R:255, G:248, B:220, A:255). - /// RGBA Hex: #FFF8DCFF. + /// Cornsilk color (R:255, G:248, B:220, A:255).
+ /// RGBA Hex: #FFF8DCFF. ///
public static Color Cornsilk => new((byte)255, (byte)248, (byte)220); /// - /// Crimson color (R:220, G:20, B:60, A:255). - /// RGBA Hex: #DC143CFF. + /// Crimson color (R:220, G:20, B:60, A:255).
+ /// RGBA Hex: #DC143CFF. ///
public static Color Crimson => new((byte)220, (byte)20, (byte)60); /// - /// Cyan color (R:0, G:255, B:255, A:255). - /// RGBA Hex: #00FFFFFF. + /// Cyan color (R:0, G:255, B:255, A:255).
+ /// RGBA Hex: #00FFFFFF. ///
public static Color Cyan => new((byte)0, (byte)255, (byte)255); /// - /// DarkBlue color (R:0, G:0, B:139, A:255). - /// RGBA Hex: #00008BFF. + /// DarkBlue color (R:0, G:0, B:139, A:255).
+ /// RGBA Hex: #00008BFF. ///
public static Color DarkBlue => new((byte)0, (byte)0, (byte)139); /// - /// DarkCyan color (R:0, G:139, B:139, A:255). - /// RGBA Hex: #008B8BFF. + /// DarkCyan color (R:0, G:139, B:139, A:255).
+ /// RGBA Hex: #008B8BFF. ///
public static Color DarkCyan => new((byte)0, (byte)139, (byte)139); /// - /// DarkGoldenrod color (R:184, G:134, B:11, A:255). - /// RGBA Hex: #B8860BFF. + /// DarkGoldenrod color (R:184, G:134, B:11, A:255).
+ /// RGBA Hex: #B8860BFF. ///
public static Color DarkGoldenrod => new((byte)184, (byte)134, (byte)11); /// - /// DarkGray color (R:169, G:169, B:169, A:255). - /// RGBA Hex: #A9A9A9FF. + /// DarkGray color (R:169, G:169, B:169, A:255).
+ /// RGBA Hex: #A9A9A9FF. ///
public static Color DarkGray => new((byte)169, (byte)169, (byte)169); /// - /// DarkGreen color (R:0, G:100, B:0, A:255). - /// RGBA Hex: #006400FF. + /// DarkGreen color (R:0, G:100, B:0, A:255).
+ /// RGBA Hex: #006400FF. ///
public static Color DarkGreen => new((byte)0, (byte)100, (byte)0); /// - /// DarkKhaki color (R:189, G:183, B:107, A:255). - /// RGBA Hex: #BDB76BFF. + /// DarkKhaki color (R:189, G:183, B:107, A:255).
+ /// RGBA Hex: #BDB76BFF. ///
public static Color DarkKhaki => new((byte)189, (byte)183, (byte)107); /// - /// DarkMagenta color (R:139, G:0, B:139, A:255). - /// RGBA Hex: #8B008BFF. + /// DarkMagenta color (R:139, G:0, B:139, A:255).
+ /// RGBA Hex: #8B008BFF. ///
public static Color DarkMagenta => new((byte)139, (byte)0, (byte)139); /// - /// DarkOliveGreen color (R:85, G:107, B:47, A:255). - /// RGBA Hex: #556B2FFF. + /// DarkOliveGreen color (R:85, G:107, B:47, A:255).
+ /// RGBA Hex: #556B2FFF. ///
public static Color DarkOliveGreen => new((byte)85, (byte)107, (byte)47); /// - /// DarkOrange color (R:255, G:140, B:0, A:255). - /// RGBA Hex: #FF8C00FF. + /// DarkOrange color (R:255, G:140, B:0, A:255).
+ /// RGBA Hex: #FF8C00FF. ///
public static Color DarkOrange => new((byte)255, (byte)140, (byte)0); /// - /// DarkOrchid color (R:153, G:50, B:204, A:255). - /// RGBA Hex: #9932CCFF. + /// DarkOrchid color (R:153, G:50, B:204, A:255).
+ /// RGBA Hex: #9932CCFF. ///
public static Color DarkOrchid => new((byte)153, (byte)50, (byte)204); /// - /// DarkRed color (R:139, G:0, B:0, A:255). - /// RGBA Hex: #8B0000FF. + /// DarkRed color (R:139, G:0, B:0, A:255).
+ /// RGBA Hex: #8B0000FF. ///
public static Color DarkRed => new((byte)139, (byte)0, (byte)0); /// - /// DarkSalmon color (R:233, G:150, B:122, A:255). - /// RGBA Hex: #E9967AFF. + /// DarkSalmon color (R:233, G:150, B:122, A:255).
+ /// RGBA Hex: #E9967AFF. ///
public static Color DarkSalmon => new((byte)233, (byte)150, (byte)122); /// - /// DarkSeaGreen color (R:143, G:188, B:143, A:255). - /// RGBA Hex: #8FBC8FFF. + /// DarkSeaGreen color (R:143, G:188, B:143, A:255).
+ /// RGBA Hex: #8FBC8FFF. ///
public static Color DarkSeaGreen => new((byte)143, (byte)188, (byte)143); /// - /// DarkSlateBlue color (R:72, G:61, B:139, A:255). - /// RGBA Hex: #483D8BFF. + /// DarkSlateBlue color (R:72, G:61, B:139, A:255).
+ /// RGBA Hex: #483D8BFF. ///
public static Color DarkSlateBlue => new((byte)72, (byte)61, (byte)139); /// - /// DarkSlateGray color (R:47, G:79, B:79, A:255). - /// RGBA Hex: #2F4F4FFF. + /// DarkSlateGray color (R:47, G:79, B:79, A:255).
+ /// RGBA Hex: #2F4F4FFF. ///
public static Color DarkSlateGray => new((byte)47, (byte)79, (byte)79); /// - /// DarkTurquoise color (R:0, G:206, B:209, A:255). - /// RGBA Hex: #00CED1FF. + /// DarkTurquoise color (R:0, G:206, B:209, A:255).
+ /// RGBA Hex: #00CED1FF. ///
public static Color DarkTurquoise => new((byte)0, (byte)206, (byte)209); /// - /// DarkViolet color (R:148, G:0, B:211, A:255). - /// RGBA Hex: #9400D3FF. + /// DarkViolet color (R:148, G:0, B:211, A:255).
+ /// RGBA Hex: #9400D3FF. ///
public static Color DarkViolet => new((byte)148, (byte)0, (byte)211); /// - /// DeepPink color (R:255, G:20, B:147, A:255). - /// RGBA Hex: #FF1493FF. + /// DeepPink color (R:255, G:20, B:147, A:255).
+ /// RGBA Hex: #FF1493FF. ///
public static Color DeepPink => new((byte)255, (byte)20, (byte)147); /// - /// DeepSkyBlue color (R:0, G:191, B:255, A:255). - /// RGBA Hex: #00BFFFFF. + /// DeepSkyBlue color (R:0, G:191, B:255, A:255).
+ /// RGBA Hex: #00BFFFFF. ///
public static Color DeepSkyBlue => new((byte)0, (byte)191, (byte)255); /// - /// DimGray color (R:105, G:105, B:105, A:255). - /// RGBA Hex: #696969FF. + /// DimGray color (R:105, G:105, B:105, A:255).
+ /// RGBA Hex: #696969FF. ///
public static Color DimGray => new((byte)105, (byte)105, (byte)105); /// - /// DodgerBlue color (R:30, G:144, B:255, A:255). - /// RGBA Hex: #1E90FFFF. + /// DodgerBlue color (R:30, G:144, B:255, A:255).
+ /// RGBA Hex: #1E90FFFF. ///
public static Color DodgerBlue => new((byte)30, (byte)144, (byte)255); /// - /// Firebrick color (R:178, G:34, B:34, A:255). - /// RGBA Hex: #B22222FF. + /// Firebrick color (R:178, G:34, B:34, A:255).
+ /// RGBA Hex: #B22222FF. ///
public static Color Firebrick => new((byte)178, (byte)34, (byte)34); /// - /// FloralWhite color (R:255, G:250, B:240, A:255). - /// RGBA Hex: #FFFAF0FF. + /// FloralWhite color (R:255, G:250, B:240, A:255).
+ /// RGBA Hex: #FFFAF0FF. ///
public static Color FloralWhite => new((byte)255, (byte)250, (byte)240); /// - /// ForestGreen color (R:34, G:139, B:34, A:255). - /// RGBA Hex: #228B22FF. + /// ForestGreen color (R:34, G:139, B:34, A:255).
+ /// RGBA Hex: #228B22FF. ///
public static Color ForestGreen => new((byte)34, (byte)139, (byte)34); /// - /// Fuchsia color (R:255, G:0, B:255, A:255). - /// RGBA Hex: #FF00FFFF. + /// Fuchsia color (R:255, G:0, B:255, A:255).
+ /// RGBA Hex: #FF00FFFF. ///
public static Color Fuchsia => new((byte)255, (byte)0, (byte)255); /// - /// Gainsboro color (R:220, G:220, B:220, A:255). - /// RGBA Hex: #DCDCDCFF. + /// Gainsboro color (R:220, G:220, B:220, A:255).
+ /// RGBA Hex: #DCDCDCFF. ///
public static Color Gainsboro => new((byte)220, (byte)220, (byte)220); /// - /// GhostWhite color (R:248, G:248, B:255, A:255). - /// RGBA Hex: #F8F8FFFF. + /// GhostWhite color (R:248, G:248, B:255, A:255).
+ /// RGBA Hex: #F8F8FFFF. ///
public static Color GhostWhite => new((byte)248, (byte)248, (byte)255); /// - /// Gold color (R:255, G:215, B:0, A:255). - /// RGBA Hex: #FFD700FF. + /// Gold color (R:255, G:215, B:0, A:255).
+ /// RGBA Hex: #FFD700FF. ///
public static Color Gold => new((byte)255, (byte)215, (byte)0); /// - /// Goldenrod color (R:218, G:165, B:32, A:255). - /// RGBA Hex: #DAA520FF. + /// Goldenrod color (R:218, G:165, B:32, A:255).
+ /// RGBA Hex: #DAA520FF. ///
public static Color Goldenrod => new((byte)218, (byte)165, (byte)32); /// - /// Gray color (R:128, G:128, B:128, A:255). - /// RGBA Hex: #808080FF. + /// Gray color (R:128, G:128, B:128, A:255).
+ /// RGBA Hex: #808080FF. ///
public static Color Gray => new((byte)128, (byte)128, (byte)128); /// - /// Green color (R:0, G:128, B:0, A:255). - /// RGBA Hex: #008000FF. + /// Green color (R:0, G:128, B:0, A:255).
+ /// RGBA Hex: #008000FF. ///
public static Color Green => new((byte)0, (byte)128, (byte)0); /// - /// GreenYellow color (R:173, G:255, B:47, A:255). - /// RGBA Hex: #ADFF2FFF. + /// GreenYellow color (R:173, G:255, B:47, A:255).
+ /// RGBA Hex: #ADFF2FFF. ///
public static Color GreenYellow => new((byte)173, (byte)255, (byte)47); /// - /// Honeydew color (R:240, G:255, B:240, A:255). - /// RGBA Hex: #F0FFF0FF. + /// Honeydew color (R:240, G:255, B:240, A:255).
+ /// RGBA Hex: #F0FFF0FF. ///
public static Color Honeydew => new((byte)240, (byte)255, (byte)240); /// - /// HotPink color (R:255, G:105, B:180, A:255). - /// RGBA Hex: #FF69B4FF. + /// HotPink color (R:255, G:105, B:180, A:255).
+ /// RGBA Hex: #FF69B4FF. ///
public static Color HotPink => new((byte)255, (byte)105, (byte)180); /// - /// IndianRed color (R:205, G:92, B:92, A:255). - /// RGBA Hex: #CD5C5CFF. + /// IndianRed color (R:205, G:92, B:92, A:255).
+ /// RGBA Hex: #CD5C5CFF. ///
public static Color IndianRed => new((byte)205, (byte)92, (byte)92); /// - /// Indigo color (R:75, G:0, B:130, A:255). - /// RGBA Hex: #4B0082FF. + /// Indigo color (R:75, G:0, B:130, A:255).
+ /// RGBA Hex: #4B0082FF. ///
public static Color Indigo => new((byte)75, (byte)0, (byte)130); /// - /// Ivory color (R:255, G:255, B:240, A:255). - /// RGBA Hex: #FFFFF0FF. + /// Ivory color (R:255, G:255, B:240, A:255).
+ /// RGBA Hex: #FFFFF0FF. ///
public static Color Ivory => new((byte)255, (byte)255, (byte)240); /// - /// Khaki color (R:240, G:230, B:140, A:255). - /// RGBA Hex: #F0E68CFF. + /// Khaki color (R:240, G:230, B:140, A:255).
+ /// RGBA Hex: #F0E68CFF. ///
public static Color Khaki => new((byte)240, (byte)230, (byte)140); /// - /// Lavender color (R:230, G:230, B:250, A:255). - /// RGBA Hex: #E6E6FAFF. + /// Lavender color (R:230, G:230, B:250, A:255).
+ /// RGBA Hex: #E6E6FAFF. ///
public static Color Lavender => new((byte)230, (byte)230, (byte)250); /// - /// LavenderBlush color (R:255, G:240, B:245, A:255). - /// RGBA Hex: #FFF0F5FF. + /// LavenderBlush color (R:255, G:240, B:245, A:255).
+ /// RGBA Hex: #FFF0F5FF. ///
public static Color LavenderBlush => new((byte)255, (byte)240, (byte)245); /// - /// LawnGreen color (R:124, G:252, B:0, A:255). - /// RGBA Hex: #7CFC00FF. + /// LawnGreen color (R:124, G:252, B:0, A:255).
+ /// RGBA Hex: #7CFC00FF. ///
public static Color LawnGreen => new((byte)124, (byte)252, (byte)0); /// - /// LemonChiffon color (R:255, G:250, B:205, A:255). - /// RGBA Hex: #FFFACDFF. + /// LemonChiffon color (R:255, G:250, B:205, A:255).
+ /// RGBA Hex: #FFFACDFF. ///
public static Color LemonChiffon => new((byte)255, (byte)250, (byte)205); /// - /// LightBlue color (R:173, G:216, B:230, A:255). - /// RGBA Hex: #ADD8E6FF. + /// LightBlue color (R:173, G:216, B:230, A:255).
+ /// RGBA Hex: #ADD8E6FF. ///
public static Color LightBlue => new((byte)173, (byte)216, (byte)230); /// - /// LightCoral color (R:240, G:128, B:128, A:255). - /// RGBA Hex: #F08080FF. + /// LightCoral color (R:240, G:128, B:128, A:255).
+ /// RGBA Hex: #F08080FF. ///
public static Color LightCoral => new((byte)240, (byte)128, (byte)128); /// - /// LightCyan color (R:224, G:255, B:255, A:255). - /// RGBA Hex: #E0FFFFFF. + /// LightCyan color (R:224, G:255, B:255, A:255).
+ /// RGBA Hex: #E0FFFFFF. ///
public static Color LightCyan => new((byte)224, (byte)255, (byte)255); /// - /// LightGoldenrodYellow color (R:250, G:250, B:210, A:255). - /// RGBA Hex: #FAFAD2FF. + /// LightGoldenrodYellow color (R:250, G:250, B:210, A:255).
+ /// RGBA Hex: #FAFAD2FF. ///
public static Color LightGoldenrodYellow => new((byte)250, (byte)250, (byte)210); /// - /// LightGray color (R:211, G:211, B:211, A:255). - /// RGBA Hex: #D3D3D3FF. + /// LightGray color (R:211, G:211, B:211, A:255).
+ /// RGBA Hex: #D3D3D3FF. ///
public static Color LightGray => new((byte)211, (byte)211, (byte)211); /// - /// LightGreen color (R:144, G:238, B:144, A:255). - /// RGBA Hex: #90EE90FF. + /// LightGreen color (R:144, G:238, B:144, A:255).
+ /// RGBA Hex: #90EE90FF. ///
public static Color LightGreen => new((byte)144, (byte)238, (byte)144); /// - /// LightPink color (R:255, G:182, B:193, A:255). - /// RGBA Hex: #FFB6C1FF. + /// LightPink color (R:255, G:182, B:193, A:255).
+ /// RGBA Hex: #FFB6C1FF. ///
public static Color LightPink => new((byte)255, (byte)182, (byte)193); /// - /// LightSalmon color (R:255, G:160, B:122, A:255). - /// RGBA Hex: #FFA07AFF. + /// LightSalmon color (R:255, G:160, B:122, A:255).
+ /// RGBA Hex: #FFA07AFF. ///
public static Color LightSalmon => new((byte)255, (byte)160, (byte)122); /// - /// LightSeaGreen color (R:32, G:178, B:170, A:255). - /// RGBA Hex: #20B2AAFF. + /// LightSeaGreen color (R:32, G:178, B:170, A:255).
+ /// RGBA Hex: #20B2AAFF. ///
public static Color LightSeaGreen => new((byte)32, (byte)178, (byte)170); /// - /// LightSkyBlue color (R:135, G:206, B:250, A:255). - /// RGBA Hex: #87CEFAFF. + /// LightSkyBlue color (R:135, G:206, B:250, A:255).
+ /// RGBA Hex: #87CEFAFF. ///
public static Color LightSkyBlue => new((byte)135, (byte)206, (byte)250); /// - /// LightSlateGray color (R:119, G:136, B:153, A:255). - /// RGBA Hex: #778899FF. + /// LightSlateGray color (R:119, G:136, B:153, A:255).
+ /// RGBA Hex: #778899FF. ///
public static Color LightSlateGray => new((byte)119, (byte)136, (byte)153); /// - /// LightSteelBlue color (R:176, G:196, B:222, A:255). - /// RGBA Hex: #B0C4DEFF. + /// LightSteelBlue color (R:176, G:196, B:222, A:255).
+ /// RGBA Hex: #B0C4DEFF. ///
public static Color LightSteelBlue => new((byte)176, (byte)196, (byte)222); /// - /// LightYellow color (R:255, G:255, B:224, A:255). - /// RGBA Hex: #FFFFE0FF. + /// LightYellow color (R:255, G:255, B:224, A:255).
+ /// RGBA Hex: #FFFFE0FF. ///
public static Color LightYellow => new((byte)255, (byte)255, (byte)224); /// - /// Lime color (R:0, G:255, B:0, A:255). - /// RGBA Hex: #00FF00FF. + /// Lime color (R:0, G:255, B:0, A:255).
+ /// RGBA Hex: #00FF00FF. ///
public static Color Lime => new((byte)0, (byte)255, (byte)0); /// - /// LimeGreen color (R:50, G:205, B:50, A:255). - /// RGBA Hex: #32CD32FF. + /// LimeGreen color (R:50, G:205, B:50, A:255).
+ /// RGBA Hex: #32CD32FF. ///
public static Color LimeGreen => new((byte)50, (byte)205, (byte)50); /// - /// Linen color (R:250, G:240, B:230, A:255). - /// RGBA Hex: #FAF0E6FF. + /// Linen color (R:250, G:240, B:230, A:255).
+ /// RGBA Hex: #FAF0E6FF. ///
public static Color Linen => new((byte)250, (byte)240, (byte)230); /// - /// Magenta color (R:255, G:0, B:255, A:255). - /// RGBA Hex: #FF00FFFF. + /// Magenta color (R:255, G:0, B:255, A:255).
+ /// RGBA Hex: #FF00FFFF. ///
public static Color Magenta => new((byte)255, (byte)0, (byte)255); /// - /// Maroon color (R:128, G:0, B:0, A:255). - /// RGBA Hex: #800000FF. + /// Maroon color (R:128, G:0, B:0, A:255).
+ /// RGBA Hex: #800000FF. ///
public static Color Maroon => new((byte)128, (byte)0, (byte)0); /// - /// MediumAquamarine color (R:102, G:205, B:170, A:255). - /// RGBA Hex: #66CDAAFF. + /// MediumAquamarine color (R:102, G:205, B:170, A:255).
+ /// RGBA Hex: #66CDAAFF. ///
public static Color MediumAquamarine => new((byte)102, (byte)205, (byte)170); /// - /// MediumBlue color (R:0, G:0, B:205, A:255). - /// RGBA Hex: #0000CDFF. + /// MediumBlue color (R:0, G:0, B:205, A:255).
+ /// RGBA Hex: #0000CDFF. ///
public static Color MediumBlue => new((byte)0, (byte)0, (byte)205); /// - /// MediumOrchid color (R:186, G:85, B:211, A:255). - /// RGBA Hex: #BA55D3FF. + /// MediumOrchid color (R:186, G:85, B:211, A:255).
+ /// RGBA Hex: #BA55D3FF. ///
public static Color MediumOrchid => new((byte)186, (byte)85, (byte)211); /// - /// MediumPurple color (R:147, G:112, B:219, A:255). - /// RGBA Hex: #9370DBFF. + /// MediumPurple color (R:147, G:112, B:219, A:255).
+ /// RGBA Hex: #9370DBFF. ///
public static Color MediumPurple => new((byte)147, (byte)112, (byte)219); /// - /// MediumSeaGreen color (R:60, G:179, B:113, A:255). - /// RGBA Hex: #3CB371FF. + /// MediumSeaGreen color (R:60, G:179, B:113, A:255).
+ /// RGBA Hex: #3CB371FF. ///
public static Color MediumSeaGreen => new((byte)60, (byte)179, (byte)113); /// - /// MediumSlateBlue color (R:123, G:104, B:238, A:255). - /// RGBA Hex: #7B68EEFF. + /// MediumSlateBlue color (R:123, G:104, B:238, A:255).
+ /// RGBA Hex: #7B68EEFF. ///
public static Color MediumSlateBlue => new((byte)123, (byte)104, (byte)238); /// - /// MediumSpringGreen color (R:0, G:250, B:154, A:255). - /// RGBA Hex: #00FA9AFF. + /// MediumSpringGreen color (R:0, G:250, B:154, A:255).
+ /// RGBA Hex: #00FA9AFF. ///
public static Color MediumSpringGreen => new((byte)0, (byte)250, (byte)154); /// - /// MediumTurquoise color (R:72, G:209, B:204, A:255). - /// RGBA Hex: #48D1CCFF. + /// MediumTurquoise color (R:72, G:209, B:204, A:255).
+ /// RGBA Hex: #48D1CCFF. ///
public static Color MediumTurquoise => new((byte)72, (byte)209, (byte)204); /// - /// MediumVioletRed color (R:199, G:21, B:133, A:255). - /// RGBA Hex: #C71585FF. + /// MediumVioletRed color (R:199, G:21, B:133, A:255).
+ /// RGBA Hex: #C71585FF. ///
public static Color MediumVioletRed => new((byte)199, (byte)21, (byte)133); /// - /// MidnightBlue color (R:25, G:25, B:112, A:255). - /// RGBA Hex: #191970FF. + /// MidnightBlue color (R:25, G:25, B:112, A:255).
+ /// RGBA Hex: #191970FF. ///
public static Color MidnightBlue => new((byte)25, (byte)25, (byte)112); /// - /// MintCream color (R:245, G:255, B:250, A:255). - /// RGBA Hex: #F5FFFAFF. + /// MintCream color (R:245, G:255, B:250, A:255).
+ /// RGBA Hex: #F5FFFAFF. ///
public static Color MintCream => new((byte)245, (byte)255, (byte)250); /// - /// MistyRose color (R:255, G:228, B:225, A:255). - /// RGBA Hex: #FFE4E1FF. + /// MistyRose color (R:255, G:228, B:225, A:255).
+ /// RGBA Hex: #FFE4E1FF. ///
public static Color MistyRose => new((byte)255, (byte)228, (byte)225); /// - /// Moccasin color (R:255, G:228, B:181, A:255). - /// RGBA Hex: #FFE4B5FF. + /// Moccasin color (R:255, G:228, B:181, A:255).
+ /// RGBA Hex: #FFE4B5FF. ///
public static Color Moccasin => new((byte)255, (byte)228, (byte)181); /// - /// NavajoWhite color (R:255, G:222, B:173, A:255). - /// RGBA Hex: #FFDEADFF. + /// NavajoWhite color (R:255, G:222, B:173, A:255).
+ /// RGBA Hex: #FFDEADFF. ///
public static Color NavajoWhite => new((byte)255, (byte)222, (byte)173); /// - /// Navy color (R:0, G:0, B:128, A:255). - /// RGBA Hex: #000080FF. + /// Navy color (R:0, G:0, B:128, A:255).
+ /// RGBA Hex: #000080FF. ///
public static Color Navy => new((byte)0, (byte)0, (byte)128); /// - /// OldLace color (R:253, G:245, B:230, A:255). - /// RGBA Hex: #FDF5E6FF. + /// OldLace color (R:253, G:245, B:230, A:255).
+ /// RGBA Hex: #FDF5E6FF. ///
public static Color OldLace => new((byte)253, (byte)245, (byte)230); /// - /// Olive color (R:128, G:128, B:0, A:255). - /// RGBA Hex: #808000FF. + /// Olive color (R:128, G:128, B:0, A:255).
+ /// RGBA Hex: #808000FF. ///
public static Color Olive => new((byte)128, (byte)128, (byte)0); /// - /// OliveDrab color (R:107, G:142, B:35, A:255). - /// RGBA Hex: #6B8E23FF. + /// OliveDrab color (R:107, G:142, B:35, A:255).
+ /// RGBA Hex: #6B8E23FF. ///
public static Color OliveDrab => new((byte)107, (byte)142, (byte)35); /// - /// Orange color (R:255, G:165, B:0, A:255). - /// RGBA Hex: #FFA500FF. + /// Orange color (R:255, G:165, B:0, A:255).
+ /// RGBA Hex: #FFA500FF. ///
public static Color Orange => new((byte)255, (byte)165, (byte)0); /// - /// OrangeRed color (R:255, G:69, B:0, A:255). - /// RGBA Hex: #FF4500FF. + /// OrangeRed color (R:255, G:69, B:0, A:255).
+ /// RGBA Hex: #FF4500FF. ///
public static Color OrangeRed => new((byte)255, (byte)69, (byte)0); /// - /// Orchid color (R:218, G:112, B:214, A:255). - /// RGBA Hex: #DA70D6FF. + /// Orchid color (R:218, G:112, B:214, A:255).
+ /// RGBA Hex: #DA70D6FF. ///
public static Color Orchid => new((byte)218, (byte)112, (byte)214); /// - /// PaleGoldenrod color (R:238, G:232, B:170, A:255). - /// RGBA Hex: #EEE8AAFF. + /// PaleGoldenrod color (R:238, G:232, B:170, A:255).
+ /// RGBA Hex: #EEE8AAFF. ///
public static Color PaleGoldenrod => new((byte)238, (byte)232, (byte)170); /// - /// PaleGreen color (R:152, G:251, B:152, A:255). - /// RGBA Hex: #98FB98FF. + /// PaleGreen color (R:152, G:251, B:152, A:255).
+ /// RGBA Hex: #98FB98FF. ///
public static Color PaleGreen => new((byte)152, (byte)251, (byte)152); /// - /// PaleTurquoise color (R:175, G:238, B:238, A:255). - /// RGBA Hex: #AFEEEEFF. + /// PaleTurquoise color (R:175, G:238, B:238, A:255).
+ /// RGBA Hex: #AFEEEEFF. ///
public static Color PaleTurquoise => new((byte)175, (byte)238, (byte)238); /// - /// PaleVioletRed color (R:219, G:112, B:147, A:255). - /// RGBA Hex: #DB7093FF. + /// PaleVioletRed color (R:219, G:112, B:147, A:255).
+ /// RGBA Hex: #DB7093FF. ///
public static Color PaleVioletRed => new((byte)219, (byte)112, (byte)147); /// - /// PapayaWhip color (R:255, G:239, B:213, A:255). - /// RGBA Hex: #FFEFD5FF. + /// PapayaWhip color (R:255, G:239, B:213, A:255).
+ /// RGBA Hex: #FFEFD5FF. ///
public static Color PapayaWhip => new((byte)255, (byte)239, (byte)213); /// - /// PeachPuff color (R:255, G:218, B:185, A:255). - /// RGBA Hex: #FFDAB9FF. + /// PeachPuff color (R:255, G:218, B:185, A:255).
+ /// RGBA Hex: #FFDAB9FF. ///
public static Color PeachPuff => new((byte)255, (byte)218, (byte)185); /// - /// Peru color (R:205, G:133, B:63, A:255). - /// RGBA Hex: #CD853FFF. + /// Peru color (R:205, G:133, B:63, A:255).
+ /// RGBA Hex: #CD853FFF. ///
public static Color Peru => new((byte)205, (byte)133, (byte)63); /// - /// Pink color (R:255, G:192, B:203, A:255). - /// RGBA Hex: #FFC0CBFF. + /// Pink color (R:255, G:192, B:203, A:255).
+ /// RGBA Hex: #FFC0CBFF. ///
public static Color Pink => new((byte)255, (byte)192, (byte)203); /// - /// Plum color (R:221, G:160, B:221, A:255). - /// RGBA Hex: #DDA0DDFF. + /// Plum color (R:221, G:160, B:221, A:255).
+ /// RGBA Hex: #DDA0DDFF. ///
public static Color Plum => new((byte)221, (byte)160, (byte)221); /// - /// PowderBlue color (R:176, G:224, B:230, A:255). - /// RGBA Hex: #B0E0E6FF. + /// PowderBlue color (R:176, G:224, B:230, A:255).
+ /// RGBA Hex: #B0E0E6FF. ///
public static Color PowderBlue => new((byte)176, (byte)224, (byte)230); /// - /// Purple color (R:128, G:0, B:128, A:255). - /// RGBA Hex: #800080FF. + /// Purple color (R:128, G:0, B:128, A:255).
+ /// RGBA Hex: #800080FF. ///
public static Color Purple => new((byte)128, (byte)0, (byte)128); /// - /// Red color (R:255, G:0, B:0, A:255). - /// RGBA Hex: #FF0000FF. + /// Red color (R:255, G:0, B:0, A:255).
+ /// RGBA Hex: #FF0000FF. ///
public static Color Red => new((byte)255, (byte)0, (byte)0); /// - /// RosyBrown color (R:188, G:143, B:143, A:255). - /// RGBA Hex: #BC8F8FFF. + /// RosyBrown color (R:188, G:143, B:143, A:255).
+ /// RGBA Hex: #BC8F8FFF. ///
public static Color RosyBrown => new((byte)188, (byte)143, (byte)143); /// - /// RoyalBlue color (R:65, G:105, B:225, A:255). - /// RGBA Hex: #4169E1FF. + /// RoyalBlue color (R:65, G:105, B:225, A:255).
+ /// RGBA Hex: #4169E1FF. ///
public static Color RoyalBlue => new((byte)65, (byte)105, (byte)225); /// - /// SaddleBrown color (R:139, G:69, B:19, A:255). - /// RGBA Hex: #8B4513FF. + /// SaddleBrown color (R:139, G:69, B:19, A:255).
+ /// RGBA Hex: #8B4513FF. ///
public static Color SaddleBrown => new((byte)139, (byte)69, (byte)19); /// - /// Salmon color (R:250, G:128, B:114, A:255). - /// RGBA Hex: #FA8072FF. + /// Salmon color (R:250, G:128, B:114, A:255).
+ /// RGBA Hex: #FA8072FF. ///
public static Color Salmon => new((byte)250, (byte)128, (byte)114); /// - /// SandyBrown color (R:244, G:164, B:96, A:255). - /// RGBA Hex: #F4A460FF. + /// SandyBrown color (R:244, G:164, B:96, A:255).
+ /// RGBA Hex: #F4A460FF. ///
public static Color SandyBrown => new((byte)244, (byte)164, (byte)96); /// - /// SeaGreen color (R:46, G:139, B:87, A:255). - /// RGBA Hex: #2E8B57FF. + /// SeaGreen color (R:46, G:139, B:87, A:255).
+ /// RGBA Hex: #2E8B57FF. ///
public static Color SeaGreen => new((byte)46, (byte)139, (byte)87); /// - /// SeaShell color (R:255, G:245, B:238, A:255). - /// RGBA Hex: #FFF5EEFF. + /// SeaShell color (R:255, G:245, B:238, A:255).
+ /// RGBA Hex: #FFF5EEFF. ///
public static Color SeaShell => new((byte)255, (byte)245, (byte)238); /// - /// Sienna color (R:160, G:82, B:45, A:255). - /// RGBA Hex: #A0522DFF. + /// Sienna color (R:160, G:82, B:45, A:255).
+ /// RGBA Hex: #A0522DFF. ///
public static Color Sienna => new((byte)160, (byte)82, (byte)45); /// - /// Silver color (R:192, G:192, B:192, A:255). - /// RGBA Hex: #C0C0C0FF. + /// Silver color (R:192, G:192, B:192, A:255).
+ /// RGBA Hex: #C0C0C0FF. ///
public static Color Silver => new((byte)192, (byte)192, (byte)192); /// - /// SkyBlue color (R:135, G:206, B:235, A:255). - /// RGBA Hex: #87CEEBFF. + /// SkyBlue color (R:135, G:206, B:235, A:255).
+ /// RGBA Hex: #87CEEBFF. ///
public static Color SkyBlue => new((byte)135, (byte)206, (byte)235); /// - /// SlateBlue color (R:106, G:90, B:205, A:255). - /// RGBA Hex: #6A5ACDFF. + /// SlateBlue color (R:106, G:90, B:205, A:255).
+ /// RGBA Hex: #6A5ACDFF. ///
public static Color SlateBlue => new((byte)106, (byte)90, (byte)205); /// - /// SlateGray color (R:112, G:128, B:144, A:255). - /// RGBA Hex: #708090FF. + /// SlateGray color (R:112, G:128, B:144, A:255).
+ /// RGBA Hex: #708090FF. ///
public static Color SlateGray => new((byte)112, (byte)128, (byte)144); /// - /// Snow color (R:255, G:250, B:250, A:255). - /// RGBA Hex: #FFFAFAFF. + /// Snow color (R:255, G:250, B:250, A:255).
+ /// RGBA Hex: #FFFAFAFF. ///
public static Color Snow => new((byte)255, (byte)250, (byte)250); /// - /// SpringGreen color (R:0, G:255, B:127, A:255). - /// RGBA Hex: #00FF7FFF. + /// SpringGreen color (R:0, G:255, B:127, A:255).
+ /// RGBA Hex: #00FF7FFF. ///
public static Color SpringGreen => new((byte)0, (byte)255, (byte)127); /// - /// SteelBlue color (R:70, G:130, B:180, A:255). - /// RGBA Hex: #4682B4FF. + /// SteelBlue color (R:70, G:130, B:180, A:255).
+ /// RGBA Hex: #4682B4FF. ///
public static Color SteelBlue => new((byte)70, (byte)130, (byte)180); /// - /// Tan color (R:210, G:180, B:140, A:255). - /// RGBA Hex: #D2B48CFF. + /// Tan color (R:210, G:180, B:140, A:255).
+ /// RGBA Hex: #D2B48CFF. ///
public static Color Tan => new((byte)210, (byte)180, (byte)140); /// - /// Teal color (R:0, G:128, B:128, A:255). - /// RGBA Hex: #008080FF. + /// Teal color (R:0, G:128, B:128, A:255).
+ /// RGBA Hex: #008080FF. ///
public static Color Teal => new((byte)0, (byte)128, (byte)128); /// - /// Thistle color (R:216, G:191, B:216, A:255). - /// RGBA Hex: #D8BFD8FF. + /// Thistle color (R:216, G:191, B:216, A:255).
+ /// RGBA Hex: #D8BFD8FF. ///
public static Color Thistle => new((byte)216, (byte)191, (byte)216); /// - /// Tomato color (R:255, G:99, B:71, A:255). - /// RGBA Hex: #FF6347FF. + /// Tomato color (R:255, G:99, B:71, A:255).
+ /// RGBA Hex: #FF6347FF. ///
public static Color Tomato => new((byte)255, (byte)99, (byte)71); /// - /// Turquoise color (R:64, G:224, B:208, A:255). - /// RGBA Hex: #40E0D0FF. + /// Turquoise color (R:64, G:224, B:208, A:255).
+ /// RGBA Hex: #40E0D0FF. ///
public static Color Turquoise => new((byte)64, (byte)224, (byte)208); /// - /// Violet color (R:238, G:130, B:238, A:255). - /// RGBA Hex: #EE82EEFF. + /// Violet color (R:238, G:130, B:238, A:255).
+ /// RGBA Hex: #EE82EEFF. ///
public static Color Violet => new((byte)238, (byte)130, (byte)238); /// - /// Wheat color (R:245, G:222, B:179, A:255). - /// RGBA Hex: #F5DEB3FF. + /// Wheat color (R:245, G:222, B:179, A:255).
+ /// RGBA Hex: #F5DEB3FF. ///
public static Color Wheat => new((byte)245, (byte)222, (byte)179); /// - /// White color (R:255, G:255, B:255, A:255). - /// RGBA Hex: #FFFFFFFF. + /// White color (R:255, G:255, B:255, A:255).
+ /// RGBA Hex: #FFFFFFFF. ///
public static Color White => new((byte)255, (byte)255, (byte)255); /// - /// WhiteSmoke color (R:245, G:245, B:245, A:255). - /// RGBA Hex: #F5F5F5FF. + /// WhiteSmoke color (R:245, G:245, B:245, A:255).
+ /// RGBA Hex: #F5F5F5FF. ///
public static Color WhiteSmoke => new((byte)245, (byte)245, (byte)245); /// - /// Yellow color (R:255, G:255, B:0, A:255). - /// RGBA Hex: #FFFF00FF. + /// Yellow color (R:255, G:255, B:0, A:255).
+ /// RGBA Hex: #FFFF00FF. ///
public static Color Yellow => new((byte)255, (byte)255, (byte)0); /// - /// YellowGreen color (R:154, G:205, B:50, A:255). - /// RGBA Hex: #9ACD32FF. + /// YellowGreen color (R:154, G:205, B:50, A:255).
+ /// RGBA Hex: #9ACD32FF. ///
public static Color YellowGreen => new((byte)154, (byte)205, (byte)50); /// - /// RebeccaPurple color (R:102, G:51, B:153, A:255). - /// RGBA Hex: #663399FF. + /// RebeccaPurple color (R:102, G:51, B:153, A:255).
+ /// RGBA Hex: #663399FF. ///
public static Color RebeccaPurple => new((byte)102, (byte)51, (byte)153); } \ No newline at end of file From 4195e38ec6720c8c31e51548ed5933bfc1d7adc9 Mon Sep 17 00:00:00 2001 From: demorome Date: Fri, 19 Dec 2025 23:47:07 -0400 Subject: [PATCH 17/23] add Color.FromHexString --- src/Graphics/Color.cs | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 819332d..dda53ed 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -14,6 +14,7 @@ using System.Runtime.CompilerServices; using System.Text; using System.Numerics; +using System.Globalization; namespace MoonWorks.Graphics; @@ -297,6 +298,56 @@ public string ToHexString(bool hashtagOrHexadecimalPrefix = false) return sb.ToString(); } +/// + /// Returns a representation of a in hexadecimal format.
+ /// If the conversion fails, returns null.
+ /// The string must have the following big-endian format: + /// (Prefix)[R][G][B][A]*
+ /// Only "#", "0x", or no prefix at all are valid prefixes.
+ /// *: Specifying A is optional. In this case, a default of 0xFF / 255 (fully opaque) is assumed. + ///
+ /// A representation of the hex . Null if the conversion fails. + public static Color? FromHexString(string hexString) + { + if (hexString.StartsWith("0x", StringComparison.CurrentCultureIgnoreCase)) + { + hexString = hexString.Substring(2); + } + else if (hexString.StartsWith("#", StringComparison.CurrentCultureIgnoreCase)) + { + hexString = hexString.Substring(1); + } + + if (hexString.Length != 6 && hexString.Length != 8) + { + return null; + } + + uint bigEndianPackedValue; + bool success = uint.TryParse( + hexString, + NumberStyles.HexNumber, + CultureInfo.InvariantCulture, + out bigEndianPackedValue + ); + + if (!success) + { + return null; + } + + if (hexString.Length == 8) + { + // Assume all RGBA values were specified. + return FromBigEndianRGBA(bigEndianPackedValue); + } + else + { + // Assume only RGB values were specified. + return FromBigEndianRGB((int)bigEndianPackedValue); + } + } + public static implicit operator VertexStructs.Ubyte4Norm(Color color) => new VertexStructs.Ubyte4Norm { X = color.R, From 97078d0524c8ecc1ccf66cca53813bc00c286c3f Mon Sep 17 00:00:00 2001 From: demorome Date: Fri, 19 Dec 2025 23:50:50 -0400 Subject: [PATCH 18/23] ToHexString: make "0x" prefix the default --- src/Graphics/Color.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index dda53ed..eb5acf9 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -281,12 +281,12 @@ public override string ToString() /// (Prefix)[R][G][B][A]
/// Thus, it's in Big Endian format. ///
- /// "#" prefix if false, "0x" otherwise. + /// "0x" prefix if false, "#" otherwise. /// representation of this . - public string ToHexString(bool hashtagOrHexadecimalPrefix = false) + public string ToHexString(bool hexadecimalOrHashtagPrefix = false) { StringBuilder sb = new StringBuilder(10); - if (!hashtagOrHexadecimalPrefix) + if (hexadecimalOrHashtagPrefix) { sb.Append("#"); } From ac97a07a108244afbed93419060e830f0555dae6 Mon Sep 17 00:00:00 2001 From: demorome Date: Fri, 19 Dec 2025 23:51:49 -0400 Subject: [PATCH 19/23] fix comment alignement --- src/Graphics/Color.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index eb5acf9..024c255 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -298,7 +298,7 @@ public string ToHexString(bool hexadecimalOrHashtagPrefix = false) return sb.ToString(); } -/// + /// /// Returns a representation of a in hexadecimal format.
/// If the conversion fails, returns null.
/// The string must have the following big-endian format: From 2b34e3e663ffc5f2e930bde75a68636ef17c752a Mon Sep 17 00:00:00 2001 From: demorome Date: Fri, 19 Dec 2025 23:55:59 -0400 Subject: [PATCH 20/23] ToHexString: specify what the prefix options are in the summary, as a quick reference --- src/Graphics/Color.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 024c255..1b18a02 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -279,7 +279,8 @@ public override string ToString() /// /// Returns a hexadecimal representation of this in the format: /// (Prefix)[R][G][B][A]
- /// Thus, it's in Big Endian format. + /// Thus, it's in Big Endian format.
+ /// The prefix will either be "0x" (default) or "#". ///
/// "0x" prefix if false, "#" otherwise. /// representation of this . From 35f03f6af867890f41668c96f225fe4c1b68277b Mon Sep 17 00:00:00 2001 From: demorome Date: Sat, 20 Dec 2025 00:07:41 -0400 Subject: [PATCH 21/23] add cref for AliceBlue reference --- src/Graphics/Color.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 1b18a02..d7000c7 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -86,7 +86,7 @@ public readonly uint BigEndianPackedValue() /// /// Converts a big-endian RGBA packed color into a .
- /// Example valid input: `0xF0F8FFFF`, aka AliceBlue. + /// Example valid input: `0xF0F8FFFF`, aka . ///
/// A big-endian packed color that specifies R, G, B, and A values. /// A representation for the big-endian RGBA packed value. @@ -97,7 +97,7 @@ public static Color FromBigEndianRGBA(uint bigEndian_RGBA) /// /// Converts a big-endian RGBA packed color into a .
- /// Example valid input: `0xF0F8FF`, aka AliceBlue. + /// Example valid input: `0xF0F8FF`, aka . /// The above will be interpeted as a big-endian input of `0xF0F8FF(AlphaByte)`.
///
/// A big-endian packed color that specifies R, G, and B values. From 636e6797eb791ac9fec2ab7537d710d5ab1aae3d Mon Sep 17 00:00:00 2001 From: demorome Date: Sat, 20 Dec 2025 00:14:52 -0400 Subject: [PATCH 22/23] fix RGBA -> RGB comment for FromBigEndianRGB --- src/Graphics/Color.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index d7000c7..83f4f5a 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -96,13 +96,13 @@ public static Color FromBigEndianRGBA(uint bigEndian_RGBA) } /// - /// Converts a big-endian RGBA packed color into a .
+ /// Converts a big-endian RGB packed color into a .
/// Example valid input: `0xF0F8FF`, aka . - /// The above will be interpeted as a big-endian input of `0xF0F8FF(AlphaByte)`.
+ /// The above will be interpeted as a big-endian RGBA input of `0xF0F8FF(alpha)`.
///
/// A big-endian packed color that specifies R, G, and B values. /// The Alpha channel value for the color. - /// A representation for the big-endian RGBA packed value. + /// A representation for the big-endian RGB packed value. public static Color FromBigEndianRGB(int bigEndian_RGB, byte alpha = 255) { return new Color(bigEndian_RGB, alpha); From ff23c26d97a063457de22faf935a378df6735889 Mon Sep 17 00:00:00 2001 From: demorome Date: Sat, 20 Dec 2025 00:16:50 -0400 Subject: [PATCH 23/23] replace "byte-order" with "bit-order" Since "byte-order" has confusing implications with endianness. --- src/Graphics/Color.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Graphics/Color.cs b/src/Graphics/Color.cs index 83f4f5a..1b8d32d 100644 --- a/src/Graphics/Color.cs +++ b/src/Graphics/Color.cs @@ -77,7 +77,7 @@ private Color(int bigEndian_RGB, byte alpha = 255) : this( /// /// Returns the in a Big-Endian UInt32 packed value format. - /// Thus, the value is in RGBA byte-order. + /// Thus, the value is in RGBA bit-order. /// public readonly uint BigEndianPackedValue() {