|
|
|
@ -41,56 +41,76 @@ FT_BEGIN_HEADER |
|
|
|
|
* LCD Filtering |
|
|
|
|
* |
|
|
|
|
* @abstract: |
|
|
|
|
* Reduce color fringes of LCD-optimized bitmaps. |
|
|
|
|
* Reduce color fringes of subpixel-rendered bitmaps. |
|
|
|
|
* |
|
|
|
|
* @description: |
|
|
|
|
* The @FT_Library_SetLcdFilter API can be used to specify a low-pass |
|
|
|
|
* filter, which is then applied to LCD-optimized bitmaps generated |
|
|
|
|
* through @FT_Render_Glyph. This is useful to reduce color fringes |
|
|
|
|
* that would occur with unfiltered rendering. |
|
|
|
|
* Subpixel rendering exploits the color-striped structure of LCD |
|
|
|
|
* pixels, increasing the available resolution in the direction of the |
|
|
|
|
* stripe (usually horizontal RGB) by a factor of~3. Since these |
|
|
|
|
* subpixels are color pixels, using them unfiltered creates severe |
|
|
|
|
* color fringes. Use the @FT_Library_SetLcdFilter API to specify a |
|
|
|
|
* low-pass filter, which is then applied to subpixel-rendered bitmaps |
|
|
|
|
* generated through @FT_Render_Glyph. |
|
|
|
|
* |
|
|
|
|
* Note that no filter is active by default, and that this function is |
|
|
|
|
* *not* implemented in default builds of the library. You need to |
|
|
|
|
* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file |
|
|
|
|
* in order to activate it. |
|
|
|
|
* |
|
|
|
|
* FreeType generates alpha coverage maps, which are linear by nature. |
|
|
|
|
* For instance, the value 0x80 in bitmap representation means that |
|
|
|
|
* (within numerical precision) 0x80/0xFF fraction of that pixel is |
|
|
|
|
* covered by the glyph's outline. The blending function for placing |
|
|
|
|
* text over a background is |
|
|
|
|
* |
|
|
|
|
* { |
|
|
|
|
* dst = alpha * src + (1 - alpha) * dst , |
|
|
|
|
* } |
|
|
|
|
* |
|
|
|
|
* which is known as OVER. However, when calculating the output of the |
|
|
|
|
* OVER operator, the source colors should first be transformed to a |
|
|
|
|
* linear color space, then alpha blended in that space, and transformed |
|
|
|
|
* back to the output color space. |
|
|
|
|
* |
|
|
|
|
* When linear light blending is used, the default FIR5 filtering |
|
|
|
|
* weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as |
|
|
|
|
* they have been designed for black on white rendering while lacking |
|
|
|
|
* gamma correction. To preserve color neutrality, weights for a FIR5 |
|
|
|
|
* filter should be chosen according to two free parameters `a' and `c', |
|
|
|
|
* and the FIR weights should be |
|
|
|
|
* |
|
|
|
|
* { |
|
|
|
|
* [a - c, a + c, 2 * a, a + c, a - c] . |
|
|
|
|
* } |
|
|
|
|
* |
|
|
|
|
* This formula generates equal weights for all the color primaries |
|
|
|
|
* across the filter kernel, which makes it colorless. One suggested |
|
|
|
|
* set of weights is |
|
|
|
|
* |
|
|
|
|
* { |
|
|
|
|
* [0x10, 0x50, 0x60, 0x50, 0x10] , |
|
|
|
|
* } |
|
|
|
|
* |
|
|
|
|
* where `a' has value 0x30 and `c' value 0x20. The weights in filter |
|
|
|
|
* may have a sum larger than 0x100, which increases coloration slightly |
|
|
|
|
* but also improves contrast. |
|
|
|
|
* A filter should have two properties: |
|
|
|
|
* |
|
|
|
|
* 1) It should be normalized, meaning the sum of the 5~components |
|
|
|
|
* should be 256 (0x100). It is possible to go above or under this |
|
|
|
|
* target sum, however: going under means tossing out contrast, going |
|
|
|
|
* over means invoking clamping and thereby non-linearities that |
|
|
|
|
* increase contrast somewhat at the expense of greater distortion |
|
|
|
|
* and color-fringing. Contrast is better enhanced through stem |
|
|
|
|
* darkening. |
|
|
|
|
* |
|
|
|
|
* 2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}' |
|
|
|
|
* where a~+ b~=~c. It distributes the computed coverage for one |
|
|
|
|
* subpixel to all subpixels equally, sacrificing some won resolution |
|
|
|
|
* but drastically reducing color-fringing. Positioning improvements |
|
|
|
|
* remain! Note that color-fringing can only really be minimized |
|
|
|
|
* when using a color-balanced filter and alpha-blending the glyph |
|
|
|
|
* onto a surface in linear space; see @FT_Render_Glyph. |
|
|
|
|
* |
|
|
|
|
* Regarding the form, a filter can be a `boxy' filter or a `beveled' |
|
|
|
|
* filter. Boxy filters are sharper but are less forgiving of non-ideal |
|
|
|
|
* gamma curves of a screen (viewing angles!), beveled filters are |
|
|
|
|
* fuzzier but more tolerant. |
|
|
|
|
* |
|
|
|
|
* Examples: |
|
|
|
|
* |
|
|
|
|
* - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor |
|
|
|
|
* normalized. |
|
|
|
|
* |
|
|
|
|
* - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not |
|
|
|
|
* normalized. |
|
|
|
|
* |
|
|
|
|
* - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not |
|
|
|
|
* balanced. |
|
|
|
|
* |
|
|
|
|
* - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not |
|
|
|
|
* balanced. |
|
|
|
|
* |
|
|
|
|
* - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost |
|
|
|
|
* balanced. |
|
|
|
|
* |
|
|
|
|
* - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost |
|
|
|
|
* balanced. |
|
|
|
|
* |
|
|
|
|
* It is important to understand that linear alpha blending and gamma |
|
|
|
|
* correction is critical for correctly rendering glyphs onto surfaces |
|
|
|
|
* without artifacts and even more critical when subpixel rendering is |
|
|
|
|
* involved. |
|
|
|
|
* |
|
|
|
|
* Each of the 3~alpha values (subpixels) is independently used to blend |
|
|
|
|
* one color channel. That is, red alpha blends the red channel of the |
|
|
|
|
* text color with the red channel of the background pixel. The |
|
|
|
|
* distribution of density values by the color-balanced filter assumes |
|
|
|
|
* alpha blending is done in linear space; only then color artifacts |
|
|
|
|
* cancel out. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -111,10 +131,21 @@ FT_BEGIN_HEADER |
|
|
|
|
* The default filter reduces color fringes considerably, at the cost |
|
|
|
|
* of a slight blurriness in the output. |
|
|
|
|
* |
|
|
|
|
* It is a beveled, normalized, and color-balanced five-tap filter |
|
|
|
|
* that is more forgiving to screens with non-ideal gamma curves and |
|
|
|
|
* viewing angles. Note that while color-fringing is reduced, it can |
|
|
|
|
* only be minimized by using linear alpha blending and gamma |
|
|
|
|
* correction to render glyphs onto surfaces. |
|
|
|
|
* |
|
|
|
|
* FT_LCD_FILTER_LIGHT :: |
|
|
|
|
* The light filter is a variant that produces less blurriness at the |
|
|
|
|
* cost of slightly more color fringes than the default one. It might |
|
|
|
|
* be better, depending on taste, your monitor, or your personal vision. |
|
|
|
|
* The light filter is a variant that is sharper at the cost of |
|
|
|
|
* slightly more color fringes than the default one. |
|
|
|
|
* |
|
|
|
|
* It is a boxy, normalized, and color-balanced three-tap filter that |
|
|
|
|
* is less forgiving to screens with non-ideal gamma curves and |
|
|
|
|
* viewing angles. This filter works best when the rendering system |
|
|
|
|
* uses linear alpha blending and gamma correction to render glyphs |
|
|
|
|
* onto surfaces. |
|
|
|
|
* |
|
|
|
|
* FT_LCD_FILTER_LEGACY :: |
|
|
|
|
* This filter corresponds to the original libXft color filter. It |
|
|
|
|