mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 12:30:32 +00:00
Please note that this version works only with Bochs. - To make it works was needed to renounce to all structures (a part for primitive types) so now Mode and Color are classes. - Implemented methods of Canvas DrawPoint(), DrawLine() and DrawRect() for now only color depth of 32 bit and integer coordinates are supported - Changed IoPort of Bochs / VBE to MemoryBlock and not MemoryBlock08 so I can write an 32 bit ARGB color in only an operation instead of 4, this will semplify the future work of RGB24 and RGB16 too. Changed the name to the correct one "LinearFrameBuffer". - Made VBEDriver more object oriented (used enums instead of hardcoded values, created methods and so on...) - Bugfix in the Pen class there was confusion in the setter / getter of the Color property - In VBEScreen removed the old code that is not needed anymore, added check to method arguments (that throws in case of fatal errors)
645 lines
21 KiB
C#
645 lines
21 KiB
C#
using System;
|
|
using System.Drawing;
|
|
|
|
/*
|
|
* This is the NetCore version of Color changed to a class because Cosmos does not really support structures yet
|
|
*/
|
|
namespace Cosmos.System.Graphics
|
|
{
|
|
//[StructLayout(LayoutKind.Explicit, Size = 20)]
|
|
public class Color
|
|
{
|
|
//public static readonly Color Empty = new Color();
|
|
|
|
// NOTE : The "zero" pattern (all members being 0) must represent
|
|
// : "not set". This allows "Color c;" to be correct.
|
|
|
|
private const short StateKnownColorValid = 0x0001;
|
|
private const short StateARGBValueValid = 0x0002;
|
|
private const short StateValueMask = StateARGBValueValid;
|
|
private const short StateNameValid = 0x0008;
|
|
private const long NotDefinedValue = 0;
|
|
|
|
/**
|
|
* Shift count and bit mask for A, R, G, B components in ARGB mode!
|
|
*/
|
|
private const int ARGBAlphaShift = 24;
|
|
private const int ARGBRedShift = 16;
|
|
private const int ARGBGreenShift = 8;
|
|
private const int ARGBBlueShift = 0;
|
|
|
|
// user supplied name of color. Will not be filled in if
|
|
// we map to a "knowncolor"
|
|
//
|
|
//[FieldOffset(0)]
|
|
private readonly string name;
|
|
|
|
// will contain standard 32bit sRGB (ARGB)
|
|
//
|
|
// In Cosmos reference types occupies 8 byte not 4!
|
|
//[FieldOffset(8)]
|
|
private readonly int value;
|
|
|
|
// ignored, unless "state" says it is valid
|
|
//
|
|
//[FieldOffset(12)]
|
|
private readonly int knownColor;
|
|
|
|
// implementation specific information
|
|
//
|
|
//[FieldOffset(16)]
|
|
private readonly int state;
|
|
|
|
// -------------------------------------------------------------------
|
|
// static list of "web" colors...
|
|
//
|
|
public static Color Transparent => new Color(KnownColor.Transparent);
|
|
|
|
public static Color AliceBlue => new Color(KnownColor.AliceBlue);
|
|
|
|
public static Color AntiqueWhite => new Color(KnownColor.AntiqueWhite);
|
|
|
|
public static Color Aqua => new Color(KnownColor.Aqua);
|
|
|
|
public static Color Aquamarine => new Color(KnownColor.Aquamarine);
|
|
|
|
public static Color Azure => new Color(KnownColor.Azure);
|
|
|
|
public static Color Beige => new Color(KnownColor.Beige);
|
|
|
|
public static Color Bisque => new Color(KnownColor.Bisque);
|
|
|
|
public static Color Black => new Color(KnownColor.Black);
|
|
|
|
public static Color BlanchedAlmond => new Color(KnownColor.BlanchedAlmond);
|
|
|
|
public static Color Blue => new Color(KnownColor.Blue);
|
|
|
|
public static Color BlueViolet => new Color(KnownColor.BlueViolet);
|
|
|
|
public static Color Brown => new Color(KnownColor.Brown);
|
|
|
|
public static Color BurlyWood => new Color(KnownColor.BurlyWood);
|
|
|
|
public static Color CadetBlue => new Color(KnownColor.CadetBlue);
|
|
|
|
public static Color Chartreuse => new Color(KnownColor.Chartreuse);
|
|
|
|
public static Color Chocolate => new Color(KnownColor.Chocolate);
|
|
|
|
public static Color Coral => new Color(KnownColor.Coral);
|
|
|
|
public static Color CornflowerBlue => new Color(KnownColor.CornflowerBlue);
|
|
|
|
public static Color Cornsilk => new Color(KnownColor.Cornsilk);
|
|
|
|
public static Color Crimson => new Color(KnownColor.Crimson);
|
|
|
|
public static Color Cyan => new Color(KnownColor.Cyan);
|
|
|
|
public static Color DarkBlue => new Color(KnownColor.DarkBlue);
|
|
|
|
public static Color DarkCyan => new Color(KnownColor.DarkCyan);
|
|
|
|
public static Color DarkGoldenrod => new Color(KnownColor.DarkGoldenrod);
|
|
|
|
public static Color DarkGray => new Color(KnownColor.DarkGray);
|
|
|
|
public static Color DarkGreen => new Color(KnownColor.DarkGreen);
|
|
|
|
public static Color DarkKhaki => new Color(KnownColor.DarkKhaki);
|
|
|
|
public static Color DarkMagenta => new Color(KnownColor.DarkMagenta);
|
|
|
|
public static Color DarkOliveGreen => new Color(KnownColor.DarkOliveGreen);
|
|
|
|
public static Color DarkOrange => new Color(KnownColor.DarkOrange);
|
|
|
|
public static Color DarkOrchid => new Color(KnownColor.DarkOrchid);
|
|
|
|
public static Color DarkRed => new Color(KnownColor.DarkRed);
|
|
|
|
public static Color DarkSalmon => new Color(KnownColor.DarkSalmon);
|
|
|
|
public static Color DarkSeaGreen => new Color(KnownColor.DarkSeaGreen);
|
|
|
|
public static Color DarkSlateBlue => new Color(KnownColor.DarkSlateBlue);
|
|
|
|
public static Color DarkSlateGray => new Color(KnownColor.DarkSlateGray);
|
|
|
|
public static Color DarkTurquoise => new Color(KnownColor.DarkTurquoise);
|
|
|
|
public static Color DarkViolet => new Color(KnownColor.DarkViolet);
|
|
|
|
public static Color DeepPink => new Color(KnownColor.DeepPink);
|
|
|
|
public static Color DeepSkyBlue => new Color(KnownColor.DeepSkyBlue);
|
|
|
|
public static Color DimGray => new Color(KnownColor.DimGray);
|
|
|
|
public static Color DodgerBlue => new Color(KnownColor.DodgerBlue);
|
|
|
|
public static Color Firebrick => new Color(KnownColor.Firebrick);
|
|
|
|
public static Color FloralWhite => new Color(KnownColor.FloralWhite);
|
|
|
|
public static Color ForestGreen => new Color(KnownColor.ForestGreen);
|
|
|
|
public static Color Fuchsia => new Color(KnownColor.Fuchsia);
|
|
|
|
public static Color Gainsboro => new Color(KnownColor.Gainsboro);
|
|
|
|
public static Color GhostWhite => new Color(KnownColor.GhostWhite);
|
|
|
|
public static Color Gold => new Color(KnownColor.Gold);
|
|
|
|
public static Color Goldenrod => new Color(KnownColor.Goldenrod);
|
|
|
|
public static Color Gray => new Color(KnownColor.Gray);
|
|
|
|
public static Color Green => new Color(KnownColor.Green);
|
|
|
|
public static Color GreenYellow => new Color(KnownColor.GreenYellow);
|
|
|
|
public static Color Honeydew => new Color(KnownColor.Honeydew);
|
|
|
|
public static Color HotPink => new Color(KnownColor.HotPink);
|
|
|
|
public static Color IndianRed => new Color(KnownColor.IndianRed);
|
|
|
|
public static Color Indigo => new Color(KnownColor.Indigo);
|
|
|
|
public static Color Ivory => new Color(KnownColor.Ivory);
|
|
|
|
public static Color Khaki => new Color(KnownColor.Khaki);
|
|
|
|
public static Color Lavender => new Color(KnownColor.Lavender);
|
|
|
|
public static Color LavenderBlush => new Color(KnownColor.LavenderBlush);
|
|
|
|
public static Color LawnGreen => new Color(KnownColor.LawnGreen);
|
|
|
|
public static Color LemonChiffon => new Color(KnownColor.LemonChiffon);
|
|
|
|
public static Color LightBlue => new Color(KnownColor.LightBlue);
|
|
|
|
public static Color LightCoral => new Color(KnownColor.LightCoral);
|
|
|
|
public static Color LightCyan => new Color(KnownColor.LightCyan);
|
|
|
|
public static Color LightGoldenrodYellow => new Color(KnownColor.LightGoldenrodYellow);
|
|
|
|
public static Color LightGreen => new Color(KnownColor.LightGreen);
|
|
|
|
public static Color LightGray => new Color(KnownColor.LightGray);
|
|
|
|
public static Color LightPink => new Color(KnownColor.LightPink);
|
|
|
|
public static Color LightSalmon => new Color(KnownColor.LightSalmon);
|
|
|
|
public static Color LightSeaGreen => new Color(KnownColor.LightSeaGreen);
|
|
|
|
public static Color LightSkyBlue => new Color(KnownColor.LightSkyBlue);
|
|
|
|
public static Color LightSlateGray => new Color(KnownColor.LightSlateGray);
|
|
|
|
public static Color LightSteelBlue => new Color(KnownColor.LightSteelBlue);
|
|
|
|
public static Color LightYellow => new Color(KnownColor.LightYellow);
|
|
|
|
public static Color Lime => new Color(KnownColor.Lime);
|
|
|
|
public static Color LimeGreen => new Color(KnownColor.LimeGreen);
|
|
|
|
public static Color Linen => new Color(KnownColor.Linen);
|
|
|
|
public static Color Magenta => new Color(KnownColor.Magenta);
|
|
|
|
public static Color Maroon => new Color(KnownColor.Maroon);
|
|
|
|
public static Color MediumAquamarine => new Color(KnownColor.MediumAquamarine);
|
|
|
|
public static Color MediumBlue => new Color(KnownColor.MediumBlue);
|
|
|
|
public static Color MediumOrchid => new Color(KnownColor.MediumOrchid);
|
|
|
|
public static Color MediumPurple => new Color(KnownColor.MediumPurple);
|
|
|
|
public static Color MediumSeaGreen => new Color(KnownColor.MediumSeaGreen);
|
|
|
|
public static Color MediumSlateBlue => new Color(KnownColor.MediumSlateBlue);
|
|
|
|
public static Color MediumSpringGreen => new Color(KnownColor.MediumSpringGreen);
|
|
|
|
public static Color MediumTurquoise => new Color(KnownColor.MediumTurquoise);
|
|
|
|
public static Color MediumVioletRed => new Color(KnownColor.MediumVioletRed);
|
|
|
|
public static Color MidnightBlue => new Color(KnownColor.MidnightBlue);
|
|
|
|
public static Color MintCream => new Color(KnownColor.MintCream);
|
|
|
|
public static Color MistyRose => new Color(KnownColor.MistyRose);
|
|
|
|
public static Color Moccasin => new Color(KnownColor.Moccasin);
|
|
|
|
public static Color NavajoWhite => new Color(KnownColor.NavajoWhite);
|
|
|
|
public static Color Navy => new Color(KnownColor.Navy);
|
|
|
|
public static Color OldLace => new Color(KnownColor.OldLace);
|
|
|
|
public static Color Olive => new Color(KnownColor.Olive);
|
|
|
|
public static Color OliveDrab => new Color(KnownColor.OliveDrab);
|
|
|
|
public static Color Orange => new Color(KnownColor.Orange);
|
|
|
|
public static Color OrangeRed => new Color(KnownColor.OrangeRed);
|
|
|
|
public static Color Orchid => new Color(KnownColor.Orchid);
|
|
|
|
public static Color PaleGoldenrod => new Color(KnownColor.PaleGoldenrod);
|
|
|
|
public static Color PaleGreen => new Color(KnownColor.PaleGreen);
|
|
|
|
public static Color PaleTurquoise => new Color(KnownColor.PaleTurquoise);
|
|
|
|
public static Color PaleVioletRed => new Color(KnownColor.PaleVioletRed);
|
|
|
|
public static Color PapayaWhip => new Color(KnownColor.PapayaWhip);
|
|
|
|
public static Color PeachPuff => new Color(KnownColor.PeachPuff);
|
|
|
|
public static Color Peru => new Color(KnownColor.Peru);
|
|
|
|
public static Color Pink => new Color(KnownColor.Pink);
|
|
|
|
public static Color Plum => new Color(KnownColor.Plum);
|
|
|
|
public static Color PowderBlue => new Color(KnownColor.PowderBlue);
|
|
|
|
public static Color Purple => new Color(KnownColor.Purple);
|
|
|
|
public static Color Red => new Color(KnownColor.Red);
|
|
|
|
public static Color RosyBrown => new Color(KnownColor.RosyBrown);
|
|
|
|
public static Color RoyalBlue => new Color(KnownColor.RoyalBlue);
|
|
|
|
public static Color SaddleBrown => new Color(KnownColor.SaddleBrown);
|
|
|
|
public static Color Salmon => new Color(KnownColor.Salmon);
|
|
|
|
public static Color SandyBrown => new Color(KnownColor.SandyBrown);
|
|
|
|
public static Color SeaGreen => new Color(KnownColor.SeaGreen);
|
|
|
|
public static Color SeaShell => new Color(KnownColor.SeaShell);
|
|
|
|
public static Color Sienna => new Color(KnownColor.Sienna);
|
|
|
|
public static Color Silver => new Color(KnownColor.Silver);
|
|
|
|
public static Color SkyBlue => new Color(KnownColor.SkyBlue);
|
|
|
|
public static Color SlateBlue => new Color(KnownColor.SlateBlue);
|
|
|
|
public static Color SlateGray => new Color(KnownColor.SlateGray);
|
|
|
|
public static Color Snow => new Color(KnownColor.Snow);
|
|
|
|
public static Color SpringGreen => new Color(KnownColor.SpringGreen);
|
|
|
|
public static Color SteelBlue => new Color(KnownColor.SteelBlue);
|
|
|
|
public static Color Tan => new Color(KnownColor.Tan);
|
|
|
|
public static Color Teal => new Color(KnownColor.Teal);
|
|
|
|
public static Color Thistle => new Color(KnownColor.Thistle);
|
|
|
|
public static Color Tomato => new Color(KnownColor.Tomato);
|
|
|
|
public static Color Turquoise => new Color(KnownColor.Turquoise);
|
|
|
|
public static Color Violet => new Color(KnownColor.Violet);
|
|
|
|
public static Color Wheat => new Color(KnownColor.Wheat);
|
|
|
|
public static Color White => new Color(KnownColor.White);
|
|
|
|
public static Color WhiteSmoke => new Color(KnownColor.WhiteSmoke);
|
|
|
|
public static Color Yellow => new Color(KnownColor.Yellow);
|
|
|
|
public static Color YellowGreen => new Color(KnownColor.YellowGreen);
|
|
|
|
//
|
|
// end "web" colors
|
|
// -------------------------------------------------------------------
|
|
|
|
|
|
internal Color(KnownColor knownColor)
|
|
{
|
|
value = 0;
|
|
state = StateKnownColorValid;
|
|
name = null;
|
|
this.knownColor = unchecked((short)knownColor);
|
|
}
|
|
|
|
private Color(long value, short state, string name, KnownColor knownColor)
|
|
{
|
|
this.value = (int)value;
|
|
this.state = state;
|
|
this.name = name;
|
|
this.knownColor = unchecked((short)knownColor);
|
|
}
|
|
|
|
public byte R => (byte)((Value >> ARGBRedShift) & 0xFF);
|
|
|
|
public byte G => (byte)((Value >> ARGBGreenShift) & 0xFF);
|
|
|
|
public byte B => (byte)((Value >> ARGBBlueShift) & 0xFF);
|
|
|
|
public byte A => (byte)((Value >> ARGBAlphaShift) & 0xFF);
|
|
|
|
public bool IsKnownColor => ((state & StateKnownColorValid) != 0);
|
|
|
|
public bool IsEmpty => state == 0;
|
|
|
|
public bool IsNamedColor => ((state & StateNameValid) != 0) || IsKnownColor;
|
|
|
|
public bool IsSystemColor => IsKnownColor && ((((KnownColor)knownColor) <= KnownColor.WindowText) || (((KnownColor)knownColor) > KnownColor.YellowGreen));
|
|
|
|
// Not localized because it's only used for the DebuggerDisplayAttribute, and the values are
|
|
// programmatic items.
|
|
// Also, don't inline into the attribute for performance reasons. This way means the debugger
|
|
// does 1 func-eval instead of 5.
|
|
|
|
private string NameAndARGBValue => $"{{Name={Name}, ARGB=({A}, {R}, {G}, {B})}}";
|
|
|
|
public string Name
|
|
{
|
|
get
|
|
{
|
|
if ((state & StateNameValid) != 0)
|
|
{
|
|
return name;
|
|
}
|
|
|
|
if (IsKnownColor)
|
|
{
|
|
string tablename = KnownColorTable.KnownColorToName((KnownColor)knownColor);
|
|
|
|
return tablename;
|
|
}
|
|
|
|
// if we reached here, just encode the value
|
|
//
|
|
return $"{A}-{R}-{G}-{B}";
|
|
//return Convert.ToString(value, 16);
|
|
}
|
|
}
|
|
|
|
private long Value
|
|
{
|
|
get
|
|
{
|
|
if ((state & StateValueMask) != 0)
|
|
{
|
|
return value;
|
|
}
|
|
|
|
if (IsKnownColor)
|
|
{
|
|
return KnownColorTable.KnownColorToArgb((KnownColor)knownColor);
|
|
}
|
|
|
|
return NotDefinedValue;
|
|
}
|
|
}
|
|
|
|
private static void CheckByte(int value, string name)
|
|
{
|
|
if (value < 0 || value > 255)
|
|
throw new ArgumentException($"Invalid value {value} should be between 0 and 255");
|
|
}
|
|
|
|
private static long MakeArgb(byte alpha, byte red, byte green, byte blue) =>
|
|
(long)unchecked((uint)(red << ARGBRedShift |
|
|
green << ARGBGreenShift |
|
|
blue << ARGBBlueShift |
|
|
alpha << ARGBAlphaShift)) & 0xffffffff;
|
|
|
|
public static Color FromArgb(int argb) => new Color(argb & 0xffffffff, StateARGBValueValid, null, 0);
|
|
|
|
public static Color FromArgb(int alpha, int red, int green, int blue)
|
|
{
|
|
CheckByte(alpha, nameof(alpha));
|
|
CheckByte(red, nameof(red));
|
|
CheckByte(green, nameof(green));
|
|
CheckByte(blue, nameof(blue));
|
|
return new Color(MakeArgb((byte)alpha, (byte)red, (byte)green, (byte)blue), StateARGBValueValid, null, (KnownColor)0);
|
|
}
|
|
|
|
public static Color FromArgb(int alpha, Color baseColor)
|
|
{
|
|
CheckByte(alpha, nameof(alpha));
|
|
// unchecked - because we already checked that alpha is a byte in CheckByte above
|
|
return new Color(MakeArgb(unchecked((byte)alpha), baseColor.R, baseColor.G, baseColor.B), StateARGBValueValid, null, (KnownColor)0);
|
|
}
|
|
|
|
public static Color FromArgb(int red, int green, int blue) => FromArgb(255, red, green, blue);
|
|
|
|
#if false
|
|
public static Color FromKnownColor(KnownColor color)
|
|
{
|
|
var value = (int)color;
|
|
if (value < (int)KnownColor.ActiveBorder || value > (int)KnownColor.MenuHighlight)
|
|
{
|
|
return FromName(color.ToString());
|
|
}
|
|
|
|
return new Color(color);
|
|
}
|
|
|
|
|
|
public static Color FromName(string name)
|
|
{
|
|
// try to get a known color first
|
|
Color color;
|
|
if (ColorTable.TryGetNamedColor(name, out color))
|
|
{
|
|
return color;
|
|
}
|
|
// otherwise treat it as a named color
|
|
return new Color(NotDefinedValue, StateNameValid, name, (KnownColor)0);
|
|
}
|
|
#endif
|
|
|
|
public float GetBrightness()
|
|
{
|
|
float r = R / 255.0f;
|
|
float g = G / 255.0f;
|
|
float b = B / 255.0f;
|
|
|
|
float max, min;
|
|
|
|
max = r; min = r;
|
|
|
|
if (g > max) max = g;
|
|
if (b > max) max = b;
|
|
|
|
if (g < min) min = g;
|
|
if (b < min) min = b;
|
|
|
|
return (max + min) / 2;
|
|
}
|
|
|
|
|
|
public Single GetHue()
|
|
{
|
|
if (R == G && G == B)
|
|
return 0; // 0 makes as good an UNDEFINED value as any
|
|
|
|
float r = R / 255.0f;
|
|
float g = G / 255.0f;
|
|
float b = B / 255.0f;
|
|
|
|
float max, min;
|
|
float delta;
|
|
float hue = 0.0f;
|
|
|
|
max = r; min = r;
|
|
|
|
if (g > max) max = g;
|
|
if (b > max) max = b;
|
|
|
|
if (g < min) min = g;
|
|
if (b < min) min = b;
|
|
|
|
delta = max - min;
|
|
|
|
if (r == max)
|
|
{
|
|
hue = (g - b) / delta;
|
|
}
|
|
else if (g == max)
|
|
{
|
|
hue = 2 + (b - r) / delta;
|
|
}
|
|
else if (b == max)
|
|
{
|
|
hue = 4 + (r - g) / delta;
|
|
}
|
|
hue *= 60;
|
|
|
|
if (hue < 0.0f)
|
|
{
|
|
hue += 360.0f;
|
|
}
|
|
return hue;
|
|
}
|
|
|
|
public float GetSaturation()
|
|
{
|
|
float r = R / 255.0f;
|
|
float g = G / 255.0f;
|
|
float b = B / 255.0f;
|
|
|
|
float s = 0;
|
|
|
|
float max = r;
|
|
float min = r;
|
|
|
|
if (g > max) max = g;
|
|
if (b > max) max = b;
|
|
|
|
if (g < min) min = g;
|
|
if (b < min) min = b;
|
|
|
|
// if max == min, then there is no color and
|
|
// the saturation is zero.
|
|
//
|
|
if (max != min)
|
|
{
|
|
float l = (max + min) / 2;
|
|
|
|
if (l <= .5)
|
|
{
|
|
s = (max - min) / (max + min);
|
|
}
|
|
else
|
|
{
|
|
s = (max - min) / (2 - max - min);
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
public int ToArgb() => unchecked((int)Value);
|
|
|
|
public KnownColor ToKnownColor() => (KnownColor)knownColor;
|
|
|
|
public override string ToString()
|
|
{
|
|
if ((state & StateNameValid) != 0 || (state & StateKnownColorValid) != 0)
|
|
{
|
|
return nameof(Color) + " [" + Name + "]";
|
|
}
|
|
else if ((state & StateValueMask) != 0)
|
|
{
|
|
return nameof(Color) + " [A=" + A.ToString() + ", R=" + R.ToString() + ", G=" + G.ToString() + ", B=" + B.ToString() + "]";
|
|
}
|
|
else
|
|
{
|
|
return nameof(Color) + " [Empty]";
|
|
}
|
|
}
|
|
|
|
public static bool operator ==(Color left, Color right)
|
|
{
|
|
if ((object)left == (object)right)
|
|
return true;
|
|
|
|
return (left.value == right.value
|
|
&& left.state == right.state
|
|
&& left.knownColor == right.knownColor
|
|
&& left.name == right.name);
|
|
}
|
|
|
|
#if false
|
|
public static bool operator ==(Color left, Color right) =>
|
|
left.value == right.value
|
|
&& left.state == right.state
|
|
&& left.knownColor == right.knownColor
|
|
&& left.name == right.name;
|
|
#endif
|
|
|
|
public static bool operator !=(Color left, Color right) => !(left == right);
|
|
|
|
public override bool Equals(object obj) => obj is Color && this == (Color)obj;
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
// Three cases:
|
|
// 1. We don't have a name. All relevant data, including this fact, is in the remaining fields.
|
|
// 2. We have a known name. The name will be the same instance of any other with the same
|
|
// knownColor value, so we can ignore it for hashing. Note this also hashes different to
|
|
// an unnamed color with the same ARGB value.
|
|
// 3. Have an unknown name. Will differ from other unknown-named colors only by name, so we
|
|
// can usefully use the names hash code alone.
|
|
if (name != null & !IsKnownColor)
|
|
return name.GetHashCode();
|
|
|
|
return unchecked(value.GetHashCode() ^
|
|
state.GetHashCode() ^
|
|
knownColor.GetHashCode());
|
|
#if false
|
|
return HashHelpers.Combine(
|
|
HashHelpers.Combine(value.GetHashCode(), state.GetHashCode()), knownColor.GetHashCode());
|
|
#endif
|
|
}
|
|
}
|
|
}
|