Okay, I am trying to create a two-dimensional gradient in one-bit color (e.g. every pixel is pure black or pure white).
The gradient will always be rectangular; I want to specify the gradient by specifying the desired density (of black pixels) for each of the 4 corners.
I'm sure there's algorithms out there for generating gradients in bitmaps; I'm looking for such an algorithm (I don't need the implementation).
Would a good implementation to be to do the gradient in grayscale (which I know how to do quite easily) then apply a dithering algorithm?
It would be one way, yes.
Another, perhaps easier way is to treat a given field of 1-bit pixels like a field of fewer, bigger pixels. Each of these pixels covers 4, 9 or 16 smaller pixels, and you can associate colour values with fixed patterns of coloured subpixels.
Then you do the gradient on this view.
Adobe's (now Boost's, but it won't be in the next release) Generic Image Library (GIL) might help you there: it would permit you treating this special view like it was any other image.
Well the gradient code is simple if you think about a progress bar which I know you understand how to code.
Let's say we want to go from black to white, left to right. We know the left side will be pure black or 100% black and the right will be pure white or 100% white. So let's start with black.
The density of white pixels is:
Now you need to draw a line from top to bottom using that density. Again you know a solid line from top to bottom will have (bottom-top) pixels in one color. A 50% line will have (bottom-top)/2 pixels in one color and the same amount in another color (in your case black/white).
Once you have a function that can draw a line given a certain density it's a simple matter of drawing that line at X for all of (right-left).
You can expand and create functions that paint according to density, fill rects according to density, circles, etc, etc.
To get the bit pattern you must traverse the bit field. If you have 8-bits (1 byte) and each bit is a pixel then the first pixel is 1/8 of the total byte.
It all comes down to simple normalization of values and divisions.