31 #endif |
31 #endif |
32 |
32 |
33 |
33 |
34 FT_BEGIN_HEADER |
34 FT_BEGIN_HEADER |
35 |
35 |
36 /*************************************************************************** |
36 /************************************************************************** |
37 * |
37 * |
38 * @section: |
38 * @section: |
39 * lcd_filtering |
39 * lcd_rendering |
40 * |
40 * |
41 * @title: |
41 * @title: |
42 * LCD Filtering |
42 * Subpixel Rendering |
43 * |
43 * |
44 * @abstract: |
44 * @abstract: |
45 * Reduce color fringes of subpixel-rendered bitmaps. |
45 * API to control subpixel rendering. |
46 * |
46 * |
47 * @description: |
47 * @description: |
48 * Should you #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your |
48 * FreeType provides two alternative subpixel rendering technologies. |
49 * `ftoption.h', which enables patented ClearType-style rendering, |
49 * Should you define `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` in your |
50 * the LCD-optimized glyph bitmaps should be filtered to reduce color |
50 * `ftoption.h` file, this enables patented ClearType-style rendering. |
51 * fringes inherent to this technology. The default FreeType LCD |
51 * Otherwise, Harmony LCD rendering is enabled. These technologies are |
52 * rendering uses different technology, and API described below, |
52 * controlled differently and API described below, although always |
53 * although available, does nothing. |
53 * available, performs its function when appropriate method is enabled |
|
54 * and does nothing otherwise. |
54 * |
55 * |
55 * ClearType-style LCD rendering exploits the color-striped structure of |
56 * ClearType-style LCD rendering exploits the color-striped structure of |
56 * LCD pixels, increasing the available resolution in the direction of |
57 * LCD pixels, increasing the available resolution in the direction of |
57 * the stripe (usually horizontal RGB) by a factor of~3. Since these |
58 * the stripe (usually horizontal RGB) by a factor of~3. Using the |
58 * subpixels are color pixels, using them unfiltered creates severe |
59 * subpixels coverages unfiltered can create severe color fringes |
59 * color fringes. Use the @FT_Library_SetLcdFilter API to specify a |
60 * especially when rendering thin features. Indeed, to produce |
60 * low-pass filter, which is then applied to subpixel-rendered bitmaps |
61 * black-on-white text, the nearby color subpixels must be dimmed |
61 * generated through @FT_Render_Glyph. The filter sacrifices some of |
62 * equally. |
62 * the higher resolution to reduce color fringes, making the glyph image |
63 * |
63 * slightly blurrier. Positional improvements will remain. |
64 * A good 5-tap FIR filter should be applied to subpixel coverages |
64 * |
65 * regardless of pixel boundaries and should have these properties: |
65 * A filter should have two properties: |
66 * |
66 * |
67 * 1. It should be symmetrical, like {~a, b, c, b, a~}, to avoid |
67 * 1) It should be normalized, meaning the sum of the 5~components |
68 * any shifts in appearance. |
68 * should be 256 (0x100). It is possible to go above or under this |
69 * |
69 * target sum, however: going under means tossing out contrast, going |
70 * 2. It should be color-balanced, meaning a~+ b~=~c, to reduce color |
70 * over means invoking clamping and thereby non-linearities that |
71 * fringes by distributing the computed coverage for one subpixel to |
71 * increase contrast somewhat at the expense of greater distortion |
72 * all subpixels equally. |
72 * and color-fringing. Contrast is better enhanced through stem |
73 * |
73 * darkening. |
74 * 3. It should be normalized, meaning 2a~+ 2b~+ c~=~1.0 to maintain |
74 * |
75 * overall brightness. |
75 * 2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}' |
76 * |
76 * where a~+ b~=~c. It distributes the computed coverage for one |
77 * Boxy 3-tap filter {0, 1/3, 1/3, 1/3, 0} is sharper but is less |
77 * subpixel to all subpixels equally, sacrificing some won resolution |
78 * forgiving of non-ideal gamma curves of a screen (and viewing angles), |
78 * but drastically reducing color-fringing. Positioning improvements |
79 * beveled filters are fuzzier but more tolerant. |
79 * remain! Note that color-fringing can only really be minimized |
80 * |
80 * when using a color-balanced filter and alpha-blending the glyph |
81 * Use the @FT_Library_SetLcdFilter or @FT_Library_SetLcdFilterWeights |
81 * onto a surface in linear space; see @FT_Render_Glyph. |
82 * API to specify a low-pass filter, which is then applied to |
82 * |
83 * subpixel-rendered bitmaps generated through @FT_Render_Glyph. |
83 * Regarding the form, a filter can be a `boxy' filter or a `beveled' |
84 * |
84 * filter. Boxy filters are sharper but are less forgiving of non-ideal |
85 * Harmony LCD rendering is suitable to panels with any regular subpixel |
85 * gamma curves of a screen (viewing angles!), beveled filters are |
86 * structure, not just monitors with 3 color striped subpixels, as long |
86 * fuzzier but more tolerant. |
87 * as the color subpixels have fixed positions relative to the pixel |
87 * |
88 * center. In this case, each color channel is then rendered separately |
88 * Examples: |
89 * after shifting the outline opposite to the subpixel shift so that the |
89 * |
90 * coverage maps are aligned. This method is immune to color fringes |
90 * - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor |
91 * because the shifts do not change integral coverage. |
91 * normalized. |
92 * |
92 * |
93 * The subpixel geometry must be specified by xy-coordinates for each |
93 * - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not |
94 * subpixel. By convention they may come in the RGB order: {{-1/3, 0}, |
94 * normalized. |
95 * {0, 0}, {1/3, 0}} for standard RGB striped panel or {{-1/6, 1/4}, |
95 * |
96 * {-1/6, -1/4}, {1/3, 0}} for a certain PenTile panel. |
96 * - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not |
97 * |
97 * balanced. |
98 * Use the @FT_Library_SetLcdGeometry API to specify subpixel positions. |
98 * |
99 * If one follows the RGB order convention, the same order applies to the |
99 * - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not |
100 * resulting @FT_PIXEL_MODE_LCD and @FT_PIXEL_MODE_LCD_V bitmaps. Note, |
100 * balanced. |
101 * however, that the coordinate frame for the latter must be rotated |
101 * |
102 * clockwise. Harmony with default LCD geometry is equivalent to |
102 * - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost |
103 * ClearType with light filter. |
103 * balanced. |
104 * |
104 * |
105 * As a result of ClearType filtering or Harmony rendering, the |
105 * - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost |
106 * dimensions of LCD bitmaps can be either wider or taller than the |
106 * balanced. |
107 * dimensions of the corresponding outline with regard to the pixel grid. |
107 * |
108 * For example, for @FT_RENDER_MODE_LCD, the filter adds 2~subpixels to |
108 * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, |
109 * the left, and 2~subpixels to the right. The bitmap offset values are |
109 * @FT_Load_Glyph, and @FT_Load_Char. It does _not_ affect the output |
110 * adjusted accordingly, so clients shouldn't need to modify their layout |
110 * of @FT_Outline_Render and @FT_Outline_Get_Bitmap. |
111 * and glyph positioning code when enabling the filter. |
111 * |
112 * |
112 * If this feature is activated, the dimensions of LCD glyph bitmaps are |
113 * The ClearType and Harmony rendering is applicable to glyph bitmaps |
113 * either wider or taller than the dimensions of the corresponding |
114 * rendered through @FT_Render_Glyph, @FT_Load_Glyph, @FT_Load_Char, and |
114 * outline with regard to the pixel grid. For example, for |
115 * @FT_Glyph_To_Bitmap, when @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V |
115 * @FT_RENDER_MODE_LCD, the filter adds 3~subpixels to the left, and |
116 * is specified. This API does not control @FT_Outline_Render and |
116 * 3~subpixels to the right. The bitmap offset values are adjusted |
117 * @FT_Outline_Get_Bitmap. |
117 * accordingly, so clients shouldn't need to modify their layout and |
118 * |
118 * glyph positioning code when enabling the filter. |
119 * The described algorithms can completely remove color artefacts when |
119 * |
120 * combined with gamma-corrected alpha blending in linear space. Each of |
120 * It is important to understand that linear alpha blending and gamma |
121 * the 3~alpha values (subpixels) must by independently used to blend one |
121 * correction is critical for correctly rendering glyphs onto surfaces |
122 * color channel. That is, red alpha blends the red channel of the text |
122 * without artifacts and even more critical when subpixel rendering is |
123 * color with the red channel of the background pixel. |
123 * involved. |
124 */ |
124 * |
125 |
125 * Each of the 3~alpha values (subpixels) is independently used to blend |
126 |
126 * one color channel. That is, red alpha blends the red channel of the |
127 /************************************************************************** |
127 * text color with the red channel of the background pixel. The |
|
128 * distribution of density values by the color-balanced filter assumes |
|
129 * alpha blending is done in linear space; only then color artifacts |
|
130 * cancel out. |
|
131 */ |
|
132 |
|
133 |
|
134 /**************************************************************************** |
|
135 * |
128 * |
136 * @enum: |
129 * @enum: |
137 * FT_LcdFilter |
130 * FT_LcdFilter |
138 * |
131 * |
139 * @description: |
132 * @description: |
143 * FT_LCD_FILTER_NONE :: |
136 * FT_LCD_FILTER_NONE :: |
144 * Do not perform filtering. When used with subpixel rendering, this |
137 * Do not perform filtering. When used with subpixel rendering, this |
145 * results in sometimes severe color fringes. |
138 * results in sometimes severe color fringes. |
146 * |
139 * |
147 * FT_LCD_FILTER_DEFAULT :: |
140 * FT_LCD_FILTER_DEFAULT :: |
148 * The default filter reduces color fringes considerably, at the cost |
141 * This is a beveled, normalized, and color-balanced five-tap filter |
149 * of a slight blurriness in the output. |
142 * with weights of [0x08 0x4D 0x56 0x4D 0x08] in 1/256th units. |
150 * |
|
151 * It is a beveled, normalized, and color-balanced five-tap filter |
|
152 * that is more forgiving to screens with non-ideal gamma curves and |
|
153 * viewing angles. Note that while color-fringing is reduced, it can |
|
154 * only be minimized by using linear alpha blending and gamma |
|
155 * correction to render glyphs onto surfaces. The default filter |
|
156 * weights are [0x08 0x4D 0x56 0x4D 0x08]. |
|
157 * |
143 * |
158 * FT_LCD_FILTER_LIGHT :: |
144 * FT_LCD_FILTER_LIGHT :: |
159 * The light filter is a variant that is sharper at the cost of |
145 * this is a boxy, normalized, and color-balanced three-tap filter with |
160 * slightly more color fringes than the default one. |
146 * weights of [0x00 0x55 0x56 0x55 0x00] in 1/256th units. |
161 * |
|
162 * It is a boxy, normalized, and color-balanced three-tap filter that |
|
163 * is less forgiving to screens with non-ideal gamma curves and |
|
164 * viewing angles. This filter works best when the rendering system |
|
165 * uses linear alpha blending and gamma correction to render glyphs |
|
166 * onto surfaces. The light filter weights are |
|
167 * [0x00 0x55 0x56 0x55 0x00]. |
|
168 * |
147 * |
169 * FT_LCD_FILTER_LEGACY :: |
148 * FT_LCD_FILTER_LEGACY :: |
|
149 * FT_LCD_FILTER_LEGACY1 :: |
170 * This filter corresponds to the original libXft color filter. It |
150 * This filter corresponds to the original libXft color filter. It |
171 * provides high contrast output but can exhibit really bad color |
151 * provides high contrast output but can exhibit really bad color |
172 * fringes if glyphs are not extremely well hinted to the pixel grid. |
152 * fringes if glyphs are not extremely well hinted to the pixel grid. |
173 * In other words, it only works well if the TrueType bytecode |
|
174 * interpreter is enabled *and* high-quality hinted fonts are used. |
|
175 * |
|
176 * This filter is only provided for comparison purposes, and might be |
153 * This filter is only provided for comparison purposes, and might be |
177 * disabled or stay unsupported in the future. |
154 * disabled or stay unsupported in the future. The second value is |
178 * |
155 * provided for compatibility with FontConfig, which historically used |
179 * FT_LCD_FILTER_LEGACY1 :: |
156 * different enumeration, sometimes incorrectly forwarded to FreeType. |
180 * For historical reasons, the FontConfig library returns a different |
157 * |
181 * enumeration value for legacy LCD filtering. To make code work that |
158 * @since: |
182 * (incorrectly) forwards FontConfig's enumeration value to |
159 * 2.3.0 (`FT_LCD_FILTER_LEGACY1` since 2.6.2) |
183 * @FT_Library_SetLcdFilter without proper mapping, it is thus easiest |
|
184 * to have another enumeration value, which is completely equal to |
|
185 * `FT_LCD_FILTER_LEGACY'. |
|
186 * |
|
187 * @since: |
|
188 * 2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2) |
|
189 */ |
160 */ |
190 typedef enum FT_LcdFilter_ |
161 typedef enum FT_LcdFilter_ |
191 { |
162 { |
192 FT_LCD_FILTER_NONE = 0, |
163 FT_LCD_FILTER_NONE = 0, |
193 FT_LCD_FILTER_DEFAULT = 1, |
164 FT_LCD_FILTER_DEFAULT = 1, |
296 #define FT_LCD_FILTER_FIVE_TAPS 5 |
268 #define FT_LCD_FILTER_FIVE_TAPS 5 |
297 |
269 |
298 typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS]; |
270 typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS]; |
299 |
271 |
300 |
272 |
|
273 /************************************************************************** |
|
274 * |
|
275 * @function: |
|
276 * FT_Library_SetLcdGeometry |
|
277 * |
|
278 * @description: |
|
279 * This function can be used to modify default positions of color |
|
280 * subpixels, which controls Harmony LCD rendering. |
|
281 * |
|
282 * @input: |
|
283 * library :: |
|
284 * A handle to the target library instance. |
|
285 * |
|
286 * sub :: |
|
287 * A pointer to an array of 3 vectors in 26.6 fractional pixel format; |
|
288 * the function modifies the default values, see the note below. |
|
289 * |
|
290 * @return: |
|
291 * FreeType error code. 0~means success. |
|
292 * |
|
293 * @note: |
|
294 * Subpixel geometry examples: |
|
295 * |
|
296 * - {{-21, 0}, {0, 0}, {21, 0}} is the default, corresponding to 3 color |
|
297 * stripes shifted by a third of a pixel. This could be an RGB panel. |
|
298 * |
|
299 * - {{21, 0}, {0, 0}, {-21, 0}} looks the same as the default but can |
|
300 * specify a BGR panel instead, while keeping the bitmap in the same |
|
301 * RGB888 format. |
|
302 * |
|
303 * - {{0, 21}, {0, 0}, {0, -21}} is the vertical RGB, but the bitmap |
|
304 * stays RGB888 as a result. |
|
305 * |
|
306 * - {{-11, 16}, {-11, -16}, {22, 0}} is a certain PenTile arrangement. |
|
307 * |
|
308 * This function does nothing and returns `FT_Err_Unimplemented_Feature` |
|
309 * in the context of ClearType-style subpixel rendering when |
|
310 * `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is defined in your build of the |
|
311 * library. |
|
312 * |
|
313 * @since: |
|
314 * 2.10.0 |
|
315 */ |
|
316 FT_EXPORT( FT_Error ) |
|
317 FT_Library_SetLcdGeometry( FT_Library library, |
|
318 FT_Vector sub[3] ); |
|
319 |
301 /* */ |
320 /* */ |
302 |
321 |
303 |
322 |
304 FT_END_HEADER |
323 FT_END_HEADER |
305 |
324 |