[haiku-development] Subpixel anti-aliased font rendering

  • From: Stephan Assmus <superstippi@xxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Thu, 10 Jul 2008 16:18:23 +0200

Hi all,

today I was very happy to commit the hard work of Andrej Spielmann, who is 
implementing subpixel anti-aliased font rendering as his Google Summer of 
Code project. This technique tries to benefit from the fact that one can 
reliably address hardware pixels on digitally connected LCDs. When 
rendering text, one can base the anti-aliasing on the red/green/blue 
subpixels and effectively achieve a three times as high horizontal 
resolution. The result is sharper looking text. In Windows, this technique 
is known as ClearType. Microsoft holds some patents, but they are not the 
first who use subpixels to increase the horizontal resolution.

Technically, it isn't exactly challenging to realize, since all one needs 
to do is calculate coverage values after scaling shapes horizontally by 3. 
That's to implement the basic idea. Of course Andrej had to do a lot more 
to integrate this with the existing code base, since at a lot of places, 
the triple width needs to be accounted for, and being able to turn it off 
adds yet more work. Kudos to him for finding his way into the code base so 
quickly and producing such nice results in such a short time!

Anyways, one problem of the idea is that the different colored subpixels 
will actually be quite visible as colored edges on glyphs. This problem is 
usually addressed by running a filter kernel over the subpixel values to 
smooth things out. This of course simply adds a blur - in another words, it 
removes again some sharpness. On Windows Vista, I can see this effect quite 
easily: At perfectly straight vertical lines, I make out a pink (left) and 
cyan (right) "glow". IMPOV, this somewhat degrades the sharpness compared 
to the usual grayscale anti-aliasing although ClearType still looks a lot 
smoother overall.

Now I had the following idea: If the counter-action to the colored edges is 
to reduce the sharpness, one might as well search for a sweet spot between 
gray-scale anti-aliasing and subpixel anti-aliasing. I implemented this 
idea quite literally, the result is a very simply algorithm that has the 
added benefit of making a smooth configuration option available by which 
the user could define the spot between gray-scale and subpixel 
anti-aliasing so that the trade-off between added sharpness and colored 
edges feels just right to him. For example with high DPI LCDs, one may want 
to move further away from the gray-scale result, because subpixels are 
smaller and therefor colored edges less obvious. So a high DPI LCD, which 
is already sharper, benefits even more.

But the filtering method on the other hand has another advantage: Jagginess 
of diagonal lines is reduced. I believe this is just a result of the 
reduced sharpness, but it may nevertheless look more appealing to some or 
even most people. Therefor I have prepared some screenshots that show the 
difference:

<http://www.yellowbits.com/stuff/screen_gray.png>
        - the usual grayscale anti-aliasing

<http://www.yellowbits.com/stuff/screen_filter.png>
        - Andrej's implementation of the anti-color-fringe-filter

<http://www.yellowbits.com/stuff/screen_avg_32.png>
        - my implementation of the average/subpixel "sweetspot" with
        32/68% weighting (avg/subpixel)

<http://www.yellowbits.com/stuff/screen_avg_40.png>
        - The same with 40/60% weighting

Andrej and I are just interested in comments from more people about what 
looks better to them and why. Thanks for reading and your input!

Best regards,
-Stephan

Other related posts: