1 | /**************************************************************************** |
2 | * |
3 | * ftlcdfil.h |
4 | * |
5 | * FreeType API for color filtering of subpixel bitmap glyphs |
6 | * (specification). |
7 | * |
8 | * Copyright (C) 2006-2021 by |
9 | * David Turner, Robert Wilhelm, and Werner Lemberg. |
10 | * |
11 | * This file is part of the FreeType project, and may only be used, |
12 | * modified, and distributed under the terms of the FreeType project |
13 | * license, LICENSE.TXT. By continuing to use, modify, or distribute |
14 | * this file you indicate that you have read the license and |
15 | * understand and accept it fully. |
16 | * |
17 | */ |
18 | |
19 | |
20 | #ifndef FTLCDFIL_H_ |
21 | #define FTLCDFIL_H_ |
22 | |
23 | #include <freetype/freetype.h> |
24 | #include <freetype/ftparams.h> |
25 | |
26 | #ifdef FREETYPE_H |
27 | #error "freetype.h of FreeType 1 has been loaded!" |
28 | #error "Please fix the directory search order for header files" |
29 | #error "so that freetype.h of FreeType 2 is found first." |
30 | #endif |
31 | |
32 | |
33 | FT_BEGIN_HEADER |
34 | |
35 | /************************************************************************** |
36 | * |
37 | * @section: |
38 | * lcd_rendering |
39 | * |
40 | * @title: |
41 | * Subpixel Rendering |
42 | * |
43 | * @abstract: |
44 | * API to control subpixel rendering. |
45 | * |
46 | * @description: |
47 | * FreeType provides two alternative subpixel rendering technologies. |
48 | * Should you define `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` in your |
49 | * `ftoption.h` file, this enables ClearType-style rendering. |
50 | * Otherwise, Harmony LCD rendering is enabled. These technologies are |
51 | * controlled differently and API described below, although always |
52 | * available, performs its function when appropriate method is enabled |
53 | * and does nothing otherwise. |
54 | * |
55 | * ClearType-style LCD rendering exploits the color-striped structure of |
56 | * LCD pixels, increasing the available resolution in the direction of |
57 | * the stripe (usually horizontal RGB) by a factor of~3. Using the |
58 | * subpixel coverages unfiltered can create severe color fringes |
59 | * especially when rendering thin features. Indeed, to produce |
60 | * black-on-white text, the nearby color subpixels must be dimmed |
61 | * evenly. Therefore, an equalizing 5-tap FIR filter should be applied |
62 | * to subpixel coverages regardless of pixel boundaries and should have |
63 | * these properties: |
64 | * |
65 | * 1. It should be symmetrical, like {~a, b, c, b, a~}, to avoid |
66 | * any shifts in appearance. |
67 | * |
68 | * 2. It should be color-balanced, meaning a~+ b~=~c, to reduce color |
69 | * fringes by distributing the computed coverage for one subpixel to |
70 | * all subpixels equally. |
71 | * |
72 | * 3. It should be normalized, meaning 2a~+ 2b~+ c~=~1.0 to maintain |
73 | * overall brightness. |
74 | * |
75 | * Boxy 3-tap filter {0, 1/3, 1/3, 1/3, 0} is sharper but is less |
76 | * forgiving of non-ideal gamma curves of a screen (and viewing angles), |
77 | * beveled filters are fuzzier but more tolerant. |
78 | * |
79 | * Use the @FT_Library_SetLcdFilter or @FT_Library_SetLcdFilterWeights |
80 | * API to specify a low-pass filter, which is then applied to |
81 | * subpixel-rendered bitmaps generated through @FT_Render_Glyph. |
82 | * |
83 | * Harmony LCD rendering is suitable to panels with any regular subpixel |
84 | * structure, not just monitors with 3 color striped subpixels, as long |
85 | * as the color subpixels have fixed positions relative to the pixel |
86 | * center. In this case, each color channel can be rendered separately |
87 | * after shifting the outline opposite to the subpixel shift so that the |
88 | * coverage maps are aligned. This method is immune to color fringes |
89 | * because the shifts do not change integral coverage. |
90 | * |
91 | * The subpixel geometry must be specified by xy-coordinates for each |
92 | * subpixel. By convention they may come in the RGB order: {{-1/3, 0}, |
93 | * {0, 0}, {1/3, 0}} for standard RGB striped panel or {{-1/6, 1/4}, |
94 | * {-1/6, -1/4}, {1/3, 0}} for a certain PenTile panel. |
95 | * |
96 | * Use the @FT_Library_SetLcdGeometry API to specify subpixel positions. |
97 | * If one follows the RGB order convention, the same order applies to the |
98 | * resulting @FT_PIXEL_MODE_LCD and @FT_PIXEL_MODE_LCD_V bitmaps. Note, |
99 | * however, that the coordinate frame for the latter must be rotated |
100 | * clockwise. Harmony with default LCD geometry is equivalent to |
101 | * ClearType with light filter. |
102 | * |
103 | * As a result of ClearType filtering or Harmony shifts, the resulting |
104 | * dimensions of LCD bitmaps can be slightly wider or taller than the |
105 | * dimensions the original outline with regard to the pixel grid. |
106 | * For example, for @FT_RENDER_MODE_LCD, the filter adds 2~subpixels to |
107 | * the left, and 2~subpixels to the right. The bitmap offset values are |
108 | * adjusted accordingly, so clients shouldn't need to modify their layout |
109 | * and glyph positioning code when enabling the filter. |
110 | * |
111 | * The ClearType and Harmony rendering is applicable to glyph bitmaps |
112 | * rendered through @FT_Render_Glyph, @FT_Load_Glyph, @FT_Load_Char, and |
113 | * @FT_Glyph_To_Bitmap, when @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V |
114 | * is specified. This API does not control @FT_Outline_Render and |
115 | * @FT_Outline_Get_Bitmap. |
116 | * |
117 | * The described algorithms can completely remove color artefacts when |
118 | * combined with gamma-corrected alpha blending in linear space. Each of |
119 | * the 3~alpha values (subpixels) must by independently used to blend one |
120 | * color channel. That is, red alpha blends the red channel of the text |
121 | * color with the red channel of the background pixel. |
122 | */ |
123 | |
124 | |
125 | /************************************************************************** |
126 | * |
127 | * @enum: |
128 | * FT_LcdFilter |
129 | * |
130 | * @description: |
131 | * A list of values to identify various types of LCD filters. |
132 | * |
133 | * @values: |
134 | * FT_LCD_FILTER_NONE :: |
135 | * Do not perform filtering. When used with subpixel rendering, this |
136 | * results in sometimes severe color fringes. |
137 | * |
138 | * FT_LCD_FILTER_DEFAULT :: |
139 | * This is a beveled, normalized, and color-balanced five-tap filter |
140 | * with weights of [0x08 0x4D 0x56 0x4D 0x08] in 1/256th units. |
141 | * |
142 | * FT_LCD_FILTER_LIGHT :: |
143 | * this is a boxy, normalized, and color-balanced three-tap filter with |
144 | * weights of [0x00 0x55 0x56 0x55 0x00] in 1/256th units. |
145 | * |
146 | * FT_LCD_FILTER_LEGACY :: |
147 | * FT_LCD_FILTER_LEGACY1 :: |
148 | * This filter corresponds to the original libXft color filter. It |
149 | * provides high contrast output but can exhibit really bad color |
150 | * fringes if glyphs are not extremely well hinted to the pixel grid. |
151 | * This filter is only provided for comparison purposes, and might be |
152 | * disabled or stay unsupported in the future. The second value is |
153 | * provided for compatibility with FontConfig, which historically used |
154 | * different enumeration, sometimes incorrectly forwarded to FreeType. |
155 | * |
156 | * @since: |
157 | * 2.3.0 (`FT_LCD_FILTER_LEGACY1` since 2.6.2) |
158 | */ |
159 | typedef enum FT_LcdFilter_ |
160 | { |
161 | FT_LCD_FILTER_NONE = 0, |
162 | FT_LCD_FILTER_DEFAULT = 1, |
163 | FT_LCD_FILTER_LIGHT = 2, |
164 | FT_LCD_FILTER_LEGACY1 = 3, |
165 | FT_LCD_FILTER_LEGACY = 16, |
166 | |
167 | FT_LCD_FILTER_MAX /* do not remove */ |
168 | |
169 | } FT_LcdFilter; |
170 | |
171 | |
172 | /************************************************************************** |
173 | * |
174 | * @function: |
175 | * FT_Library_SetLcdFilter |
176 | * |
177 | * @description: |
178 | * This function is used to change filter applied to LCD decimated |
179 | * bitmaps, like the ones used when calling @FT_Render_Glyph with |
180 | * @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V. |
181 | * |
182 | * @input: |
183 | * library :: |
184 | * A handle to the target library instance. |
185 | * |
186 | * filter :: |
187 | * The filter type. |
188 | * |
189 | * You can use @FT_LCD_FILTER_NONE here to disable this feature, or |
190 | * @FT_LCD_FILTER_DEFAULT to use a default filter that should work well |
191 | * on most LCD screens. |
192 | * |
193 | * @return: |
194 | * FreeType error code. 0~means success. |
195 | * |
196 | * @note: |
197 | * Since 2.10.3 the LCD filtering is enabled with @FT_LCD_FILTER_DEFAULT. |
198 | * It is no longer necessary to call this function explicitly except |
199 | * to choose a different filter or disable filtering altogether with |
200 | * @FT_LCD_FILTER_NONE. |
201 | * |
202 | * This function does nothing but returns `FT_Err_Unimplemented_Feature` |
203 | * if the configuration macro `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is |
204 | * not defined in your build of the library. |
205 | * |
206 | * @since: |
207 | * 2.3.0 |
208 | */ |
209 | FT_EXPORT( FT_Error ) |
210 | FT_Library_SetLcdFilter( FT_Library library, |
211 | FT_LcdFilter filter ); |
212 | |
213 | |
214 | /************************************************************************** |
215 | * |
216 | * @function: |
217 | * FT_Library_SetLcdFilterWeights |
218 | * |
219 | * @description: |
220 | * This function can be used to enable LCD filter with custom weights, |
221 | * instead of using presets in @FT_Library_SetLcdFilter. |
222 | * |
223 | * @input: |
224 | * library :: |
225 | * A handle to the target library instance. |
226 | * |
227 | * weights :: |
228 | * A pointer to an array; the function copies the first five bytes and |
229 | * uses them to specify the filter weights in 1/256th units. |
230 | * |
231 | * @return: |
232 | * FreeType error code. 0~means success. |
233 | * |
234 | * @note: |
235 | * This function does nothing but returns `FT_Err_Unimplemented_Feature` |
236 | * if the configuration macro `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is |
237 | * not defined in your build of the library. |
238 | * |
239 | * LCD filter weights can also be set per face using @FT_Face_Properties |
240 | * with @FT_PARAM_TAG_LCD_FILTER_WEIGHTS. |
241 | * |
242 | * @since: |
243 | * 2.4.0 |
244 | */ |
245 | FT_EXPORT( FT_Error ) |
246 | FT_Library_SetLcdFilterWeights( FT_Library library, |
247 | unsigned char *weights ); |
248 | |
249 | |
250 | /************************************************************************** |
251 | * |
252 | * @type: |
253 | * FT_LcdFiveTapFilter |
254 | * |
255 | * @description: |
256 | * A typedef for passing the five LCD filter weights to |
257 | * @FT_Face_Properties within an @FT_Parameter structure. |
258 | * |
259 | * @since: |
260 | * 2.8 |
261 | * |
262 | */ |
263 | #define FT_LCD_FILTER_FIVE_TAPS 5 |
264 | |
265 | typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS]; |
266 | |
267 | |
268 | /************************************************************************** |
269 | * |
270 | * @function: |
271 | * FT_Library_SetLcdGeometry |
272 | * |
273 | * @description: |
274 | * This function can be used to modify default positions of color |
275 | * subpixels, which controls Harmony LCD rendering. |
276 | * |
277 | * @input: |
278 | * library :: |
279 | * A handle to the target library instance. |
280 | * |
281 | * sub :: |
282 | * A pointer to an array of 3 vectors in 26.6 fractional pixel format; |
283 | * the function modifies the default values, see the note below. |
284 | * |
285 | * @return: |
286 | * FreeType error code. 0~means success. |
287 | * |
288 | * @note: |
289 | * Subpixel geometry examples: |
290 | * |
291 | * - {{-21, 0}, {0, 0}, {21, 0}} is the default, corresponding to 3 color |
292 | * stripes shifted by a third of a pixel. This could be an RGB panel. |
293 | * |
294 | * - {{21, 0}, {0, 0}, {-21, 0}} looks the same as the default but can |
295 | * specify a BGR panel instead, while keeping the bitmap in the same |
296 | * RGB888 format. |
297 | * |
298 | * - {{0, 21}, {0, 0}, {0, -21}} is the vertical RGB, but the bitmap |
299 | * stays RGB888 as a result. |
300 | * |
301 | * - {{-11, 16}, {-11, -16}, {22, 0}} is a certain PenTile arrangement. |
302 | * |
303 | * This function does nothing and returns `FT_Err_Unimplemented_Feature` |
304 | * in the context of ClearType-style subpixel rendering when |
305 | * `FT_CONFIG_OPTION_SUBPIXEL_RENDERING` is defined in your build of the |
306 | * library. |
307 | * |
308 | * @since: |
309 | * 2.10.0 |
310 | */ |
311 | FT_EXPORT( FT_Error ) |
312 | FT_Library_SetLcdGeometry( FT_Library library, |
313 | FT_Vector sub[3] ); |
314 | |
315 | /* */ |
316 | |
317 | |
318 | FT_END_HEADER |
319 | |
320 | #endif /* FTLCDFIL_H_ */ |
321 | |
322 | |
323 | /* END */ |
324 | |