Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenftlcdfil.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* ftlcdfil.c */ 00004 /* */ 00005 /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ 00006 /* */ 00007 /* Copyright 2006, 2008, 2009, 2010 by */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 00019 #include <ft2build.h> 00020 #include FT_LCD_FILTER_H 00021 #include FT_IMAGE_H 00022 #include FT_INTERNAL_OBJECTS_H 00023 00024 00025 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING 00026 00027 /* define USE_LEGACY to implement the legacy filter */ 00028 #define USE_LEGACY 00029 00030 /* FIR filter used by the default and light filters */ 00031 static void 00032 _ft_lcd_filter_fir( FT_Bitmap* bitmap, 00033 FT_Render_Mode mode, 00034 FT_Library library ) 00035 { 00036 FT_Byte* weights = library->lcd_weights; 00037 FT_UInt width = (FT_UInt)bitmap->width; 00038 FT_UInt height = (FT_UInt)bitmap->rows; 00039 00040 00041 /* horizontal in-place FIR filter */ 00042 if ( mode == FT_RENDER_MODE_LCD && width >= 4 ) 00043 { 00044 FT_Byte* line = bitmap->buffer; 00045 00046 00047 for ( ; height > 0; height--, line += bitmap->pitch ) 00048 { 00049 FT_UInt fir[5]; 00050 FT_UInt val1, xx; 00051 00052 00053 val1 = line[0]; 00054 fir[0] = weights[2] * val1; 00055 fir[1] = weights[3] * val1; 00056 fir[2] = weights[4] * val1; 00057 fir[3] = 0; 00058 fir[4] = 0; 00059 00060 val1 = line[1]; 00061 fir[0] += weights[1] * val1; 00062 fir[1] += weights[2] * val1; 00063 fir[2] += weights[3] * val1; 00064 fir[3] += weights[4] * val1; 00065 00066 for ( xx = 2; xx < width; xx++ ) 00067 { 00068 FT_UInt val, pix; 00069 00070 00071 val = line[xx]; 00072 pix = fir[0] + weights[0] * val; 00073 fir[0] = fir[1] + weights[1] * val; 00074 fir[1] = fir[2] + weights[2] * val; 00075 fir[2] = fir[3] + weights[3] * val; 00076 fir[3] = weights[4] * val; 00077 00078 pix >>= 8; 00079 pix |= -( pix >> 8 ); 00080 line[xx - 2] = (FT_Byte)pix; 00081 } 00082 00083 { 00084 FT_UInt pix; 00085 00086 00087 pix = fir[0] >> 8; 00088 pix |= -( pix >> 8 ); 00089 line[xx - 2] = (FT_Byte)pix; 00090 00091 pix = fir[1] >> 8; 00092 pix |= -( pix >> 8 ); 00093 line[xx - 1] = (FT_Byte)pix; 00094 } 00095 } 00096 } 00097 00098 /* vertical in-place FIR filter */ 00099 else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 ) 00100 { 00101 FT_Byte* column = bitmap->buffer; 00102 FT_Int pitch = bitmap->pitch; 00103 00104 00105 for ( ; width > 0; width--, column++ ) 00106 { 00107 FT_Byte* col = column; 00108 FT_UInt fir[5]; 00109 FT_UInt val1, yy; 00110 00111 00112 val1 = col[0]; 00113 fir[0] = weights[2] * val1; 00114 fir[1] = weights[3] * val1; 00115 fir[2] = weights[4] * val1; 00116 fir[3] = 0; 00117 fir[4] = 0; 00118 col += pitch; 00119 00120 val1 = col[0]; 00121 fir[0] += weights[1] * val1; 00122 fir[1] += weights[2] * val1; 00123 fir[2] += weights[3] * val1; 00124 fir[3] += weights[4] * val1; 00125 col += pitch; 00126 00127 for ( yy = 2; yy < height; yy++ ) 00128 { 00129 FT_UInt val, pix; 00130 00131 00132 val = col[0]; 00133 pix = fir[0] + weights[0] * val; 00134 fir[0] = fir[1] + weights[1] * val; 00135 fir[1] = fir[2] + weights[2] * val; 00136 fir[2] = fir[3] + weights[3] * val; 00137 fir[3] = weights[4] * val; 00138 00139 pix >>= 8; 00140 pix |= -( pix >> 8 ); 00141 col[-2 * pitch] = (FT_Byte)pix; 00142 col += pitch; 00143 } 00144 00145 { 00146 FT_UInt pix; 00147 00148 00149 pix = fir[0] >> 8; 00150 pix |= -( pix >> 8 ); 00151 col[-2 * pitch] = (FT_Byte)pix; 00152 00153 pix = fir[1] >> 8; 00154 pix |= -( pix >> 8 ); 00155 col[-pitch] = (FT_Byte)pix; 00156 } 00157 } 00158 } 00159 } 00160 00161 00162 #ifdef USE_LEGACY 00163 00164 /* intra-pixel filter used by the legacy filter */ 00165 static void 00166 _ft_lcd_filter_legacy( FT_Bitmap* bitmap, 00167 FT_Render_Mode mode, 00168 FT_Library library ) 00169 { 00170 FT_UInt width = (FT_UInt)bitmap->width; 00171 FT_UInt height = (FT_UInt)bitmap->rows; 00172 FT_Int pitch = bitmap->pitch; 00173 00174 static const int filters[3][3] = 00175 { 00176 { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 }, 00177 { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 }, 00178 { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 } 00179 }; 00180 00181 FT_UNUSED( library ); 00182 00183 00184 /* horizontal in-place intra-pixel filter */ 00185 if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) 00186 { 00187 FT_Byte* line = bitmap->buffer; 00188 00189 00190 for ( ; height > 0; height--, line += pitch ) 00191 { 00192 FT_UInt xx; 00193 00194 00195 for ( xx = 0; xx < width; xx += 3 ) 00196 { 00197 FT_UInt r = 0; 00198 FT_UInt g = 0; 00199 FT_UInt b = 0; 00200 FT_UInt p; 00201 00202 00203 p = line[xx]; 00204 r += filters[0][0] * p; 00205 g += filters[0][1] * p; 00206 b += filters[0][2] * p; 00207 00208 p = line[xx + 1]; 00209 r += filters[1][0] * p; 00210 g += filters[1][1] * p; 00211 b += filters[1][2] * p; 00212 00213 p = line[xx + 2]; 00214 r += filters[2][0] * p; 00215 g += filters[2][1] * p; 00216 b += filters[2][2] * p; 00217 00218 line[xx] = (FT_Byte)( r / 65536 ); 00219 line[xx + 1] = (FT_Byte)( g / 65536 ); 00220 line[xx + 2] = (FT_Byte)( b / 65536 ); 00221 } 00222 } 00223 } 00224 else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 ) 00225 { 00226 FT_Byte* column = bitmap->buffer; 00227 00228 00229 for ( ; width > 0; width--, column++ ) 00230 { 00231 FT_Byte* col = column; 00232 FT_Byte* col_end = col + height * pitch; 00233 00234 00235 for ( ; col < col_end; col += 3 * pitch ) 00236 { 00237 FT_UInt r = 0; 00238 FT_UInt g = 0; 00239 FT_UInt b = 0; 00240 FT_UInt p; 00241 00242 00243 p = col[0]; 00244 r += filters[0][0] * p; 00245 g += filters[0][1] * p; 00246 b += filters[0][2] * p; 00247 00248 p = col[pitch]; 00249 r += filters[1][0] * p; 00250 g += filters[1][1] * p; 00251 b += filters[1][2] * p; 00252 00253 p = col[pitch * 2]; 00254 r += filters[2][0] * p; 00255 g += filters[2][1] * p; 00256 b += filters[2][2] * p; 00257 00258 col[0] = (FT_Byte)( r / 65536 ); 00259 col[pitch] = (FT_Byte)( g / 65536 ); 00260 col[2 * pitch] = (FT_Byte)( b / 65536 ); 00261 } 00262 } 00263 } 00264 } 00265 00266 #endif /* USE_LEGACY */ 00267 00268 00269 FT_EXPORT_DEF( FT_Error ) 00270 FT_Library_SetLcdFilterWeights( FT_Library library, 00271 unsigned char *weights ) 00272 { 00273 if ( !library || !weights ) 00274 return FT_Err_Invalid_Argument; 00275 00276 ft_memcpy( library->lcd_weights, weights, 5 ); 00277 00278 return FT_Err_Ok; 00279 } 00280 00281 00282 FT_EXPORT_DEF( FT_Error ) 00283 FT_Library_SetLcdFilter( FT_Library library, 00284 FT_LcdFilter filter ) 00285 { 00286 static const FT_Byte light_filter[5] = 00287 { 0x00, 0x55, 0x56, 0x55, 0x00 }; 00288 /* the values here sum up to a value larger than 256, */ 00289 /* providing a cheap gamma correction */ 00290 static const FT_Byte default_filter[5] = 00291 { 0x10, 0x40, 0x70, 0x40, 0x10 }; 00292 00293 00294 if ( !library ) 00295 return FT_Err_Invalid_Argument; 00296 00297 switch ( filter ) 00298 { 00299 case FT_LCD_FILTER_NONE: 00300 library->lcd_filter_func = NULL; 00301 library->lcd_extra = 0; 00302 break; 00303 00304 case FT_LCD_FILTER_DEFAULT: 00305 #if defined( FT_FORCE_LEGACY_LCD_FILTER ) 00306 00307 library->lcd_filter_func = _ft_lcd_filter_legacy; 00308 library->lcd_extra = 0; 00309 00310 #elif defined( FT_FORCE_LIGHT_LCD_FILTER ) 00311 00312 ft_memcpy( library->lcd_weights, light_filter, 5 ); 00313 library->lcd_filter_func = _ft_lcd_filter_fir; 00314 library->lcd_extra = 2; 00315 00316 #else 00317 00318 ft_memcpy( library->lcd_weights, default_filter, 5 ); 00319 library->lcd_filter_func = _ft_lcd_filter_fir; 00320 library->lcd_extra = 2; 00321 00322 #endif 00323 00324 break; 00325 00326 case FT_LCD_FILTER_LIGHT: 00327 ft_memcpy( library->lcd_weights, light_filter, 5 ); 00328 library->lcd_filter_func = _ft_lcd_filter_fir; 00329 library->lcd_extra = 2; 00330 break; 00331 00332 #ifdef USE_LEGACY 00333 00334 case FT_LCD_FILTER_LEGACY: 00335 library->lcd_filter_func = _ft_lcd_filter_legacy; 00336 library->lcd_extra = 0; 00337 break; 00338 00339 #endif 00340 00341 default: 00342 return FT_Err_Invalid_Argument; 00343 } 00344 00345 library->lcd_filter = filter; 00346 00347 return FT_Err_Ok; 00348 } 00349 00350 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ 00351 00352 FT_EXPORT_DEF( FT_Error ) 00353 FT_Library_SetLcdFilterWeights( FT_Library library, 00354 unsigned char *weights ) 00355 { 00356 FT_UNUSED( library ); 00357 FT_UNUSED( weights ); 00358 00359 return FT_Err_Unimplemented_Feature; 00360 } 00361 00362 00363 FT_EXPORT_DEF( FT_Error ) 00364 FT_Library_SetLcdFilter( FT_Library library, 00365 FT_LcdFilter filter ) 00366 { 00367 FT_UNUSED( library ); 00368 FT_UNUSED( filter ); 00369 00370 return FT_Err_Unimplemented_Feature; 00371 } 00372 00373 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ 00374 00375 00376 /* END */ Generated on Sun May 27 2012 04:33:35 for ReactOS by
1.7.6.1
|