Beautiful Code [19]
The Windows programming reference identified all 256 raster operations by the bitwise Boolean operation they performed, expressed in reverse Polish notation. For example, raster operation 0x60 corresponds to the Boolean operation PDSxa.
This means that an Exclusive-OR (x) operation is performed between the destination (D) and the source (S), and the result is combined with the pattern (P) in a bitwise AND operation (a). In color systems, the same Boolean operation is performed among the color bits of the source, destination, and pattern. As of this writing, these raster operations are documented online at http://msdn.microsoft.com/library/en-us/gdi/pantdraw_6n77.asp.
Some of these raster operations are quite useful in certain circumstances. For example, you might want to invert the destination pixels that correspond to areas where a brush is black, but display a source bitmap in areas where the brush is white. That's raster operation 0xC5. Of course, many of the 256 possibilities have little practical use, and I suspect that most of them have never been used outside of demonstration or exploratory code. Still, the sense of completeness and versatility is quite satisfying.
If we were implementing this versatile BitBlt function ourselves, how would we do it? Assume that it's 1985 and we're using the C programming language. For illustrative purposes, let's also assume that we're dealing with a one-byte-per-pixel gray shade graphics system, and that the source, destination, and pattern can be accessed through two-dimensional arrays named S, D, and P. That is, each of these variables is a pointer to a collection of byte pointers, and each byte pointer points to the beginning of a horizontal row of pixels, so that S[y][x] accesses the byte at row y and column x. The width and height of the area you're working with is stored in cx and cy (this is a traditional Windows programming variable-naming convention: the c stands for count, so these variables indicate a count of x and y values, or width and height). The rop variable stores a raster operation code from 0 to 255.
Here's some simple C code to implement using BitBlt. A switch statement uses rop to determine which operation is performed to calculate the pixel values in the destination. Only 3 of the 256 raster operations are shown here, but you get the general idea:
for (y = 0; y < cy; y++)
for (x = 0; x < cx; x++)
{
switch(rop)
{
case 0x00:
D[y][x] = 0x00;
break;
...
case 0x60:
D[y][x] = (D[y][x] ^ S[y][x]) & P[y][x];
break;
...
case 0xFF:
D[y][x] = 0xFF;
break;
}
}
This certainly is pretty code, which means that it's nice to look at and certainly crystal clear in its intentions and functionality. But beautiful code it is not, because beautiful code is also satisfying when you run it.
This code is actually a disaster because it deals with bitmaps, and bitmaps can be huge. These days, bitmaps that come out of inexpensive digital cameras can have millions of pixels. Do you really want that switch statement to be inside the row and column loops?
Should the switch logic be executed for each and every pixel? Probably not. Moving the loops inside each case certainly clutters up the code, but now at least it has a fighting chance of reasonable performance:
switch(rop)
{
case 0x00:
for (y = 0; y < cy; y++)
for (x = 0; x < cx; x++)
D[y][x] = 0x00;
break;
...
case 0x60:
for (y = 0; y < cy; y++)
for (x = 0; x < cx; x++)
D[y][x] = (D[y][x] ^ S[y][x]) & P[y][x];
break;
...
case 0xFF:
for (y = 0; y < cy; y++)
for (x = 0; x < cx; x++)
D[y][x] = 0xFF;
break;
}
Of course, if it really were 1985 and you were writing Windows, you wouldn't even be doing it in C. Early Windows applications were mostly written in C, but Windows itself was written in 8086 assembly language.
For something as important to Windows as BitBlt, an even more radical solution was required—something even faster than