Search code examples
calgorithmtextlow-levelsmoothing

Algorithms for downscaling bitmapped fonts


This is a follow-up to this question.

I am working on a low level C app where I have to draw text. I have decided to store the font I want to use as an array (black and white, each char 128x256, perhaps), then I'd downscale it to the sizes I need with some algorithm (as grayscale, so I can have some crude font smoothing).

Note: this is a toy project, please disregard stuff like doing calculations at runtime or not.

Question is, which algorithm?

I looked up 2xSaI, but it's rather complicated. I'd like something I can read the description for and work out the code myself (I am a beginner and have been coding in C/C++ for just under a year).

Suggestions, anyone?

Thanks for your time!

Edit: Please note, the input is B&W, the output should be smoothed grayscale


Solution

  • Figure out the rectangle in the source image that will correspond to a destination pixel. For example if your source image is 50x100 and your destination is 20x40, the upper left pixel in the destination corresponds to the rectangle from (0,0) to (2.2,2.2) in the source image. Now, do an area-average over those pixels:

    • Area is 2.2 * 2.2 = 4.84. You'll scale the result by 1/4.84.
    • Pixels at (0,0), (0,1), (1,0), and (1,1) each weigh in at 1 unit.
    • Pixels at (0,2), (1,2), (2,0), and (2,1) each weigh in at 0.2 unit (because the rectangle only covers 20% of them).
    • The pixel at (2,2) weighs in at 0.04 (because the rectangle only covers 4% of it).
    • The total weight is of course 4*1 + 4*0.2 + 0.04 = 4.84.

    This one was easy because you started with source and destination pixels lined up evenly at the edge of the image. In general, you'll have partial coverage at all 4 sides/4 corners of the sliding rectangle.

    Don't bother with algorithms other than area-averaging for downscaling. Most of them are plain wrong (they result in horrible aliasing, at least with a factor smaller than 1/2) and the ones that aren't plain wrong are a good bit more painful to implement and probably won't give you better results.