I have been looking at how colors are implemented in GDI+.
System.Drawing.Color is a value type, but it is not the lightweight data structure that you might expect as in Win32. In Win32, colors were represented as 32-bit integers. The framework's Colors, in contrast, occupy 16 bytes or 128 bits. Despite the size, each color component--red, green, blue, alpha--still occupies a mere 8 bits. Apparently, four bytes are unused and the rest of the other bytes are used to point to the color's name or to identify the color is being one of standard set of known or system colors. Representing each color by its 32 bit integer representation from ToArgb() leads to space savings inside an array or structure.
Some interesting observations about color.
Color comparison does not behave as one would expect. Known colors are distinct from regularly generated colors, so Color.Red does not equal Color.FromArgb(255,0,0), which is also red. Proper color comparison requires ToArgb() be called on each color object before testing.
Colors can have names, but the name support isn't that great. It's not possible to convert from an arbitrary color to its known color. Color.Red.Name returns "Red", but Color.FromArgb(255,0,0).Name returns "ffff0000". Interestingly, Color.FromName("ffff0000") won't be recognized, even though it was returned by the Name property. Instead, as with all unknown names, it will yield a transparent color with a pointer to the same unrecognized name. The only way to determine if FromName() successfully recognized the name is to check the IsKnownColor property or call ToKnownColor() on the color returned. Better string conversion support is provided with the ColorConverter class.
In addition to the Color class, SystemColors also defines static readonly colors for various system colors like ControlText and so on. These colors are tracked automatically as system colors are changed dynamically through the control panel. The IDs for both known colors defined in the Color class and system colors defined in SystemColor are stored in the KnownColor enumeration class. Both known colors and system colors can be generated by the Color(KnownColor) constructor.
Color.Transparent is the only color defined with an alpha value set to less than the maximum; not surprisingly, its alpha is set to zero. The base color of Transparent is white not black, which can affect any gradient brush that uses that color. (For the uninitiated, the combination of alpha blending and gradient filling is the standard way of applying advanced 3D lighting effects to 2D graphics like gel buttons.)
The System.Color class is very minimal, except for the predefined colors. There are few methods, and those that do exist seem somewhat incomplete. There is a way to extract the hue, saturation, and brightness of a color, but no way to construct a color from those same coordinates in the HSB colorspace.
Avalon Colors
Based on the information on WinFX247.com, colors, represented by System.Windows.Media.Color, are going to be even heavier objects in Avalon/Longhorn, consuming at least 20 bytes, with color components represented as higher-fidelity single-precision floating point numbers. It will also includes support for scRgb, a more-accurate color system. Avalon also appears to support more operations like color arithmetic.
Comments