The general rasterization algorithm is for each polygon in the image.
(A polygon is defined as one or more closed curves made of straight line segments and parametric splines — in normal practice, these are second-order squares (conical aliases) and third-order squares (cubic) Beziers. These are closed curves so that the inside is always is on the left as the curve progresses, so regular shapes work counterclockwise and holes rotate clockwise.)
(i) (projection) Convert the polygon to the same coordinate system as the destination bitmap. Resolution should not be the same, but for smoothed images it is often more: for example, FreeType uses 64 pixels.
(ii) (make monotonic in Y). If necessary, divide each segment of the polygon into smaller segments that continuously work up or down. This step is only necessary for curved segments and is relatively simple when using Bézier splines. The usual method is to halve multiple times until monotonicity is achieved. Drop all horizontal segments.
(iii) (mark the execution limits) Draw each segment in a temporary bitmap. Use Breshenem algorithm for straight lines; for curves, divide in half until the line is more than (say) 1/8 pixel from the real curve, and then use a straight line from start to finish. When drawing, mark the pixels in any way to indicate (a) whether they start or end runs - descending lines begin and ascending lines end; (b) coverage - the fraction of a pixel within a shape. Here the algorithms differ in details and where are the winding rules ( non-zero versus even-odd ).
(iv) (scan) Go through the temporary bitmap, one at a time. For each row, scan from left to right. Maintain a state that indicates whether the current position is inside the form or not (for example) by adding the number stored in the bitmap to the saved number. In simple monochrome rasterization, this number recorded in the previous step will be +1 when crossing an edge in the form and -1 when exiting the form. Accumulate pixel runs in the same state. Send runs to the drawing module: for example, FreeType emits runs consisting of the Y coordinate, start and end X coordinates, and coverage from 0 to 255. The drawing module can use coverage as an alpha value applied to the current color of the drawing, or as a mask applied to texture.
The above is a great simplification, but gives a general idea.
Most open source programs use rasterization code obtained from one of the following projects:
FreeType is a font rasterizer that contains mono rasterizer and anti-aliasing modules that are relatively easy to use autonomously - that is, for any form, not just fonts. I have successfully used this system in several commercial portable C ++ projects.
The FreeType system was inspired by Raph Levien Libart .
Anti-Grain is another popular and influential C ++ library.
There is also a border scanning flag system implemented by Kiia Kallio that looks promising and seems to be faster than Anti-Grain.
Most, but not all, of these libraries take forms made of quadratic and cubic Bezier splines, as well as straight line segments. Those that do not have (for example, the K. Kallio library) have only rectangular polygons; but it’s quite easy to “smooth” the curve into a series of line segments closer than the desired maximum distance from the actual curve. FreeType does this internally, and its code can be borrowed if necessary.