<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>I've taken a new approach to the alpha correction, which I describe here:</div><div><br></div><a href="https://bel.fi/alankila/lcd/alpcor.html">https://bel.fi/alankila/lcd/alpcor.html</a><div><br></div><div>I have written a C function that computes alpha correction table based on an error function that minimizes the difference between sRGB and linear blend for any (fg, bg, alpha) combination. The end product is a 64k table which contains the optimal alpha correction value for every 8-bit (fg, alpha) combination, and it can be computed in about 100 milliseconds because the alpha correction value increases monotonously when alpha is increased, and this is a strong bound for the behavior of the mapping and makes finding the correction value very fast. The chosen alpha correction value is required to produce the lowest possible maximum error between linear blend with the trial alpha, and sRGB aware blend with the correct alpha, measured in linear sRGB. The background ranges to scan can be specified, which allows reproducing the sRGB result more closely where feasible.</div><div><br></div><div>When the background is unknown, the error is maximally just 23 in linear-sRGB, so even without any knowledge of the background, the error in component brightness can be proven to be less than 10 % of the gamut's range. In many cases the error is lower, though as a general rule lighter foreground values consistently generate a poorer error bound than the dark foreground values. (The downside of approaching the problem numerically is that I don't really know why.)</div><div><br></div><div><br></div><div>The way ahead for this technique is preparation of the work in a library that I will probably call liblcdglyph. This library will receive the alphas from freetype without any LCD filtering, and convert it to LCD-filtered alpha corrected CA mask as 32-bit ARGB native endian. It will write its output to a bitmap that is large enough to contain 1 or 2 (sub)pixels of empty work area around the freetype's glyph in the direction of the LCD filtering. (Have not yet decided how many will be required, or if the orthogonal direction also needs extra space. FreeType currently requires 2 in LCD filtering direction.)</div><div><br></div><div>The library will have the following user adjustable parameters/features:</div><div><br></div><div>- desired extra thickening for black glyphs to compensate for the "light on dark looks stronger than dark on light in the human eye" problem. This could be just some ad-hoc per-pixel exponential based on foreground color, or a small 2 or 3-tap FIR in both X and Y axes. This is also the reason why the FreeType can not be allowed to do any LCD filtering. Firstly, FreeType defaults to FIR5 which looks rather poor under alpha corrected rendering, so it's best to avoid the risk that users forget to change it to FIR3. Secondly, the glyph enhancements must be performed before the LCD filtering and alpha correction steps to guarantee the correct coloration of the result. (In principle it would be great if FreeType could be told to enhance the strokes of the glyph.)</div><div><br></div><div>- background color component ranges for each of the 3 RGB components. Optimal tables may be too costly to compute in real time, so it is likely that users will be picking between small fixed set of built-in tables for some common background component ranges. It is possible that I will not implement this in the first version, as the maximum error is not very large to begin with.</div><div><br></div><div>- LCD subpixel order and direction, and probably also a grayscale output mode that avoids LCD filtering and prepares a single alpha value instead.</div><div><br></div><div>-- </div><div>Antti</div></body></html>