Project: skia Issues People Development process History Sign in
New issue
Advanced search Search tips
Issue 1187 Enhancement for alpha correction and LCD filtering
Starred by 5 users Reported by, Mar 25 2013 Back to list
Status: New
Area: Font
Priority: Low
Type: Idea

Sign in to add a comment
I noticed that Skia calculates alpha correction table in SkFont_FreeType.c as follows:

static void build_gamma_table(uint8_t table[256], int srcI) {
    const float src = (float)srcI / 255.0f;
    const float linSrc = lin(src);
    const float linDst = 1.0f - linSrc;

The objective of the calculation here produces a table for replacing the source alpha value with a corrected alpha value for improving blending result when text is drawn using the component color srcI. The calculation for linDst makes the assumption that the background component is the inverse of the foreground component, and then calculates the alpha value that will produce the right blending using a linear component blend based on what the correct result of such blend would have been if sRGB aware blend had been used instead.

This technique improves the average error relative to performing a naive blend by quite a bit, and for the very important cases of white on black, and black on white, the result is in fact exact within the numerical precision. In many other cases, however, there will be some degree of error, because the background assumption is not always correct, and this tends to appear as coloration in LCD rendering.

Is the bg assumption the best possible? I submit that it is not necessary to make the assumption of dst = 1 - src: it is possible to simply approach the problem numerically and to exhaustively try every possible corrected alpha against every possible background choice for every (fg, alpha) pair, and calculate the error made relative to true sRGB blending result. The error can be measured as difference of the numerical value of the component either in linear or sRGB space, and then aggregated using typical statistical tools like root mean square or maximum error. I have chosen root mean square of component values in sRGB.

Attached, I have a couple of captures of the (fg, alpha) -> alpha_correction mapping colored with the RMS error made, showing that for a truly unknown background case -- a reasonable assumption to make for sake of generality -- the resulting blending can be significantly improved in average.

Here is a github project calculating what I expect to be the optimal mapping table: (The github project is just a fairly young prototype/reference implementation I am working on in the hopes that it might be useful for someone eventually.)

When using FreeType and LCD rendering, I also noticed that the kernel is probably not optimal. Skia appears to use FreeType's default 5-tap kernel, which appears to impart some degree of color fringing if used. The optimal 5-tap kernels should be of the following form: [a - c, a + c, 2 * a, a + c, a - c]. To generate a 1-sum kernel, a should be set to 1/6, and c is bounded to 0 <= c <= a.

This formulation produces equal excitation of all color components, and the degree of blurring can be adjusted by the freely chosen tunable c. The filter is colorless because all color components under the kernel receive a total excitation of 2*a: the central pixel is the only one of that color, so its weight is directly 2*a, and the other color pairs are weighted with a+c and a-c for total of 2*a.
153 KB View Download
149 KB View Download
Comment 1 by, Mar 25 2013
Unfortunately I wrote the wrong URL by habit. This is the alpha correction code URL I intended:
Project Member Comment 2 by, Mar 26 2013
Project Member Comment 3 by, Aug 26 2014
Labels: -Type-Defect Type-Idea Area-Font
Project Member Comment 4 by, Jul 16 2015
Labels: -Priority-Medium Priority-Low
Ben, Can we get your view here... core team is clearly not getting around to it, worth low or icebox priority to keep around, okay for contributors to implement if they were so inclined?
Sign in to add a comment