A bitmap image in an icon or cursor has two parts that act on the screen: the 1-bit AND mask, then the XOR bitmap, which holds the colours. Windows applies them in that order, and together they let one pixel replace the screen, leave it alone or invert it.
How the pixels combine
For each pixel, Windows first ANDs the screen with the mask, then XORs the result with the image:
screen = (screen AND mask) XOR image
In a 1-bit image, where the colours are black (0) and white (1), there are four results:
| AND mask | XOR image | Result | What happens |
|---|---|---|---|
0 | 0 | Black | The mask clears the screen; the image leaves it clear. |
0 | 1 | White | The mask clears the screen; the image sets it. |
1 | 0 | The screen, unchanged | Transparent: the mask keeps the screen and the image does nothing. |
1 | 1 | The screen, inverted | Inverted: the mask keeps the screen and the image flips every bit of it. |
In colour images
The calculation is the same at every depth, on the screen’s red, green and blue:
| AND mask | Colour in the XOR bitmap | Result |
|---|---|---|
0 | Any | The colour replaces the screen. |
1 | Black | The screen is left alone: the pixel is transparent. A transparent pixel’s colour must be black, as black is the only colour an XOR leaves the screen unchanged with. |
1 | White | The screen is inverted, each channel becoming 255 minus itself. |
1 | Any other | The screen is XORed with the colour. The result depends on what is underneath and is rarely useful. |
Inverting is what lets a thin cursor or icon stay visible on any background, since it can never be the same as the pixels it sits on.
A worked example
On a screen pixel of #336699:
| AND mask | XOR colour | After AND | After XOR |
|---|---|---|---|
0 | #FF0000 | #000000 | #FF0000: red drawn |
1 | #000000 | #336699 | #336699: transparent |
1 | #FFFFFF | #336699 | #CC9966: inverted |
1 | #FF0000 | #336699 | #CC6699: red channel flipped |
32-bit images and alpha
From Windows XP, a 32-bit image can carry 8-bit alpha in the fourth byte of each pixel, stored straight, not premultiplied. Windows looks at the alpha bytes of the whole image to decide what it is:
| Alpha bytes | The image is | Drawn with |
|---|---|---|
| Every one 0 | Plain colours, like a 24-bit image | The AND mask and XOR, exactly as above |
| Any not 0 | Alpha-blended | Per-pixel blending; the AND mask is not used for normal drawing |
Raymond Chen gives this rule without mentioning compression, and no source says how it
applies to a 32-bit BI_BITFIELDS image. The fourth byte, which three colour masks
leave free, is the only place an alpha could be, so that is the natural reading, but it is
an inference.
An alpha-blended image is still required to have an AND mask. It should have 1 where the
alpha is 0, and 0 elsewhere, because the mask is used whenever a program draws only the mask
or reads it through GetIconInfo, for example to make a shadow. An all-zero mask
can look right when drawn normally and wrong in those other uses.
A PNG image has no AND mask at all; Windows derives one from its alpha channel.