Which Colour Is Darker in WPF - Gray or DarkGray?

Which Colour Is Darker in WPF - Gray or DarkGray?

  • Comments 3

The answer might not be what you'd expect.

In XAML, you can express colours in a number of different ways. One option is to use the 24-bit hexadecimal RGB notation that is common in the web, for example:
   <Ellipse Width="300" Height="100" Fill="#A3BDE2" Stroke="#5C6DBE" StrokeThickness="5" />

WPF has full alpha channel support too, so you can express the hex value as #AARRGGB, as in the following:
   <Line Stroke="#7F006666" StrokeThickness="10" X1="0" X2="300" Y1="100" Y2="0" />
which draws a cyan line of 50% opacity over anything beneath it.

Another available model is scRGB, which allows you to express a colour as four single-precision floating-point numbers, allowing for an ultra-wide gamut of colour representation. One of the nice features of scRGB is that it allows you to express values outside of the RGB range of #000000..#FFFFFF, allowing you to create colours that are "darker than black" or "whiter than white". You might think this is a pretty useless feature, but when it comes to image processing this is very useful in allowing you to retain the fidelity of an image. For example, let's say that you process a photograph of a cloudy sky and pass it through a pipeline that corrects contrast, colour temperature and brightness. Without a colour mapping such as scRGB, it's possible that any step in that pipeline could blow out the detail in the image (perhaps the contrast correction creates whole blocks of the image that are white). By allowing a broader range, even though it can't be displayed on screen, it's possible to maintain that information so that by the time you get to the other end of the pipeline, the brightness correction can use information that would have otherwise been lost to bring all the colours back within a visible range. I digress, anyway.

Here's how you express an scRGB colour in XAML:
   <Rectangle Stroke="sc#1, 0.6046357, 0.223508522, 0.182969958" Fill="sc#1, 0.7785599, 1, 0"
      RadiusX="25" RadiusY="25" Width="250" Height="80" StrokeThickness="5" Margin="60" />

The final way to express a colour in XAML is to use named colours, for instance Green, SteelBlue or MediumVioletRed. These colours are the same named colours as are present in HTML or SVG and include a number of quirks and idiosyncrasies that stem from their heritage. For example, the set of named colours isn't evenly spread across the spectrum (there are many red and orange hues against a comparative lack of shades green), and some of the colours have pretty esoteric names that display a lack of cultural awareness by the original author (how many non-US readers can fathom a guess at the colour DodgerBlue represents?). Some are even spelled inconsistently (for example, Gray and DarkGray have the US spelling, whereas LightGrey has the UK spelling).

There's an even stranger phenomenon, however. These colours don't actually originate in HTML - they date still further back than that to the X Window System that originated on UNIX systems. The HTML specification defines sixteen named colours that map onto the basic sixteen colours present in the EGA palette, but the earliest browsers such as Mosaic also supported any of the other X11 named colours, based on their colour representation as defined on X. Unfortunately, some of the original sixteen named colours have different representations to the X11 equivalents, for example Green is represented in X11 in this colour, whereas in HTML it's represented in this colour. The unfortunate result is that Gray is defined as #808080 in HTML, but DarkGray is represented as #A9A9A9, meaning that they're the wrong way around. Since WPF allows the same named colours as HTML for compatibility, the result is that the same idiosyncrasies carry forward. (You can find more information on the full set of X11 colour names and their representations in Wikipedia).

My recommendation therefore is in general to use the hex or scRGB colour representations wherever possible, or you might be surprised by the colours that you pick not matching your expectations!

Here's a short sample that wraps all these elements together:
   <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Margin="30" >
      <
Rectangle Stroke="sc#1, 0.6046357, 0.223508522, 0.182969958" Fill="sc#1, 0.7785599, 1, 0"
        
RadiusX="25" RadiusY="25" Width="250" Height="80" StrokeThickness="5"
        
Canvas.Top="60" Canvas.Left="80"/>
      <
Ellipse Width="300" Height="100" Fill="#A3BDE2" Stroke="#5C6DBE" StrokeThickness="5" />
      <
Line Stroke="#77006666" StrokeThickness="10" X1="0" X2="300" Y1="100" Y2="0" />
      <
TextBlock FontFamily="Calibri" FontSize="40" Foreground="DodgerBlue"
         Canvas.Top
="150" Canvas.Left="10">
         <
Run FontStyle="Italic">This </Run>is Dodger Blue
      </TextBlock>
   </
Canvas>

and here's how that looks:

(Thanks to Hans Hugli for the inspiration for this article.)

  • I should add a comment that there's some disagreement as to what scRGB stands for - I got "specular component RGB" from Joe Beda's article here: http://www.eightypercent.net/Archive/2003/10/23.html

    However Ian Griffiths, author of the much-loved "Programming Windows Presentation Foundation" has it as "scene-referred RGB" and it turns out there are a few other non-authoritative references to that term on WL Search.

    Unfortunately you won't find a definitive answer in the Windows SDK either...
  • Could you have a blog entry on elaborating what was the motivation for such compatibility? So that someone could with push of a button convert HTML page to XBAP? If so, why couldn't you just let the converter handle the color conversion? What is your business justification for the added legacy conventions in a new platform?

    Personally I'd say: Pull the legacy stuff out while you still can unless you have hell of a good reason to have it there. It might not bite now but surely it will later.
  • Это не опечатка, LightGrey действительно пишется через &quot;E&quot;, а DarkGray и Gray че
Page 1 of 1 (3 items)