PageRenderTime 43ms CodeModel.GetById 19ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/compiler/android-ndk/jni/freetype/src/base/ftlcdfil.c

http://ftk.googlecode.com/
C | 351 lines | 240 code | 86 blank | 25 comment | 25 complexity | 57e2736c0dd1af97073bfda34ebc40a7 MD5 | raw file
  1/***************************************************************************/
  2/*                                                                         */
  3/*  ftlcdfil.c                                                             */
  4/*                                                                         */
  5/*    FreeType API for color filtering of subpixel bitmap glyphs (body).   */
  6/*                                                                         */
  7/*  Copyright 2006, 2008, 2009 by                                          */
  8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9/*                                                                         */
 10/*  This file is part of the FreeType project, and may only be used,       */
 11/*  modified, and distributed under the terms of the FreeType project      */
 12/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
 13/*  this file you indicate that you have read the license and              */
 14/*  understand and accept it fully.                                        */
 15/*                                                                         */
 16/***************************************************************************/
 17
 18
 19#include <ft2build.h>
 20#include FT_LCD_FILTER_H
 21#include FT_IMAGE_H
 22#include FT_INTERNAL_OBJECTS_H
 23
 24
 25#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
 26
 27/* define USE_LEGACY to implement the legacy filter */
 28#define  USE_LEGACY
 29
 30  /* FIR filter used by the default and light filters */
 31  static void
 32  _ft_lcd_filter_fir( FT_Bitmap*      bitmap,
 33                      FT_Render_Mode  mode,
 34                      FT_Library      library )
 35  {
 36    FT_Byte*  weights = library->lcd_weights;
 37    FT_UInt   width   = (FT_UInt)bitmap->width;
 38    FT_UInt   height  = (FT_UInt)bitmap->rows;
 39
 40
 41    /* horizontal in-place FIR filter */
 42    if ( mode == FT_RENDER_MODE_LCD && width >= 4 )
 43    {
 44      FT_Byte*  line = bitmap->buffer;
 45
 46
 47      for ( ; height > 0; height--, line += bitmap->pitch )
 48      {
 49        FT_UInt  fir[5];
 50        FT_UInt  val1, xx;
 51
 52
 53        val1   = line[0];
 54        fir[0] = weights[2] * val1;
 55        fir[1] = weights[3] * val1;
 56        fir[2] = weights[4] * val1;
 57        fir[3] = 0;
 58        fir[4] = 0;
 59
 60        val1    = line[1];
 61        fir[0] += weights[1] * val1;
 62        fir[1] += weights[2] * val1;
 63        fir[2] += weights[3] * val1;
 64        fir[3] += weights[4] * val1;
 65
 66        for ( xx = 2; xx < width; xx++ )
 67        {
 68          FT_UInt  val, pix;
 69
 70
 71          val    = line[xx];
 72          pix    = fir[0] + weights[0] * val;
 73          fir[0] = fir[1] + weights[1] * val;
 74          fir[1] = fir[2] + weights[2] * val;
 75          fir[2] = fir[3] + weights[3] * val;
 76          fir[3] =          weights[4] * val;
 77
 78          pix        >>= 8;
 79          pix         |= -( pix >> 8 );
 80          line[xx - 2] = (FT_Byte)pix;
 81        }
 82
 83        {
 84          FT_UInt  pix;
 85
 86
 87          pix          = fir[0] >> 8;
 88          pix         |= -( pix >> 8 );
 89          line[xx - 2] = (FT_Byte)pix;
 90
 91          pix          = fir[1] >> 8;
 92          pix         |= -( pix >> 8 );
 93          line[xx - 1] = (FT_Byte)pix;
 94        }
 95      }
 96    }
 97
 98    /* vertical in-place FIR filter */
 99    else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 )
100    {
101      FT_Byte*  column = bitmap->buffer;
102      FT_Int    pitch  = bitmap->pitch;
103
104
105      for ( ; width > 0; width--, column++ )
106      {
107        FT_Byte*  col = column;
108        FT_UInt   fir[5];
109        FT_UInt   val1, yy;
110
111
112        val1   = col[0];
113        fir[0] = weights[2] * val1;
114        fir[1] = weights[3] * val1;
115        fir[2] = weights[4] * val1;
116        fir[3] = 0;
117        fir[4] = 0;
118        col   += pitch;
119
120        val1    = col[0];
121        fir[0] += weights[1] * val1;
122        fir[1] += weights[2] * val1;
123        fir[2] += weights[3] * val1;
124        fir[3] += weights[4] * val1;
125        col    += pitch;
126
127        for ( yy = 2; yy < height; yy++ )
128        {
129          FT_UInt  val, pix;
130
131
132          val    = col[0];
133          pix    = fir[0] + weights[0] * val;
134          fir[0] = fir[1] + weights[1] * val;
135          fir[1] = fir[2] + weights[2] * val;
136          fir[2] = fir[3] + weights[3] * val;
137          fir[3] =          weights[4] * val;
138
139          pix           >>= 8;
140          pix            |= -( pix >> 8 );
141          col[-2 * pitch] = (FT_Byte)pix;
142          col            += pitch;
143        }
144
145        {
146          FT_UInt  pix;
147
148
149          pix             = fir[0] >> 8;
150          pix            |= -( pix >> 8 );
151          col[-2 * pitch] = (FT_Byte)pix;
152
153          pix         = fir[1] >> 8;
154          pix        |= -( pix >> 8 );
155          col[-pitch] = (FT_Byte)pix;
156        }
157      }
158    }
159  }
160
161
162#ifdef USE_LEGACY
163
164  /* intra-pixel filter used by the legacy filter */
165  static void
166  _ft_lcd_filter_legacy( FT_Bitmap*      bitmap,
167                         FT_Render_Mode  mode,
168                         FT_Library      library )
169  {
170    FT_UInt  width  = (FT_UInt)bitmap->width;
171    FT_UInt  height = (FT_UInt)bitmap->rows;
172    FT_Int   pitch  = bitmap->pitch;
173
174    static const int  filters[3][3] =
175    {
176      { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 },
177      { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 },
178      { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 }
179    };
180
181    FT_UNUSED( library );
182
183
184    /* horizontal in-place intra-pixel filter */
185    if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
186    {
187      FT_Byte*  line = bitmap->buffer;
188
189
190      for ( ; height > 0; height--, line += pitch )
191      {
192        FT_UInt  xx;
193
194
195        for ( xx = 0; xx < width; xx += 3 )
196        {
197          FT_UInt  r = 0;
198          FT_UInt  g = 0;
199          FT_UInt  b = 0;
200          FT_UInt  p;
201
202
203          p  = line[xx];
204          r += filters[0][0] * p;
205          g += filters[0][1] * p;
206          b += filters[0][2] * p;
207
208          p  = line[xx + 1];
209          r += filters[1][0] * p;
210          g += filters[1][1] * p;
211          b += filters[1][2] * p;
212
213          p  = line[xx + 2];
214          r += filters[2][0] * p;
215          g += filters[2][1] * p;
216          b += filters[2][2] * p;
217
218          line[xx]     = (FT_Byte)( r / 65536 );
219          line[xx + 1] = (FT_Byte)( g / 65536 );
220          line[xx + 2] = (FT_Byte)( b / 65536 );
221        }
222      }
223    }
224    else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
225    {
226      FT_Byte*  column = bitmap->buffer;
227
228
229      for ( ; width > 0; width--, column++ )
230      {
231        FT_Byte*  col     = column;
232        FT_Byte*  col_end = col + height * pitch;
233
234
235        for ( ; col < col_end; col += 3 * pitch )
236        {
237          FT_UInt  r = 0;
238          FT_UInt  g = 0;
239          FT_UInt  b = 0;
240          FT_UInt  p;
241
242
243          p  = col[0];
244          r += filters[0][0] * p;
245          g += filters[0][1] * p;
246          b += filters[0][2] * p;
247
248          p  = col[pitch];
249          r += filters[1][0] * p;
250          g += filters[1][1] * p;
251          b += filters[1][2] * p;
252
253          p  = col[pitch * 2];
254          r += filters[2][0] * p;
255          g += filters[2][1] * p;
256          b += filters[2][2] * p;
257
258          col[0]         = (FT_Byte)( r / 65536 );
259          col[pitch]     = (FT_Byte)( g / 65536 );
260          col[2 * pitch] = (FT_Byte)( b / 65536 );
261        }
262      }
263    }
264  }
265
266#endif /* USE_LEGACY */
267
268
269  FT_EXPORT_DEF( FT_Error )
270  FT_Library_SetLcdFilter( FT_Library     library,
271                           FT_LcdFilter   filter )
272  {
273    static const FT_Byte  light_filter[5] =
274                            { 0, 85, 86, 85, 0 };
275    /* the values here sum up to a value larger than 256, */
276    /* providing a cheap gamma correction                 */
277    static const FT_Byte  default_filter[5] =
278                            { 0x10, 0x40, 0x70, 0x40, 0x10 };
279
280
281    if ( library == NULL )
282      return FT_Err_Invalid_Argument;
283
284    switch ( filter )
285    {
286    case FT_LCD_FILTER_NONE:
287      library->lcd_filter_func = NULL;
288      library->lcd_extra       = 0;
289      break;
290
291    case FT_LCD_FILTER_DEFAULT:
292#if defined( FT_FORCE_LEGACY_LCD_FILTER )
293
294      library->lcd_filter_func = _ft_lcd_filter_legacy;
295      library->lcd_extra       = 0;
296
297#elif defined( FT_FORCE_LIGHT_LCD_FILTER )
298
299      ft_memcpy( library->lcd_weights, light_filter, 5 );
300      library->lcd_filter_func = _ft_lcd_filter_fir;
301      library->lcd_extra       = 2;
302
303#else
304
305      ft_memcpy( library->lcd_weights, default_filter, 5 );
306      library->lcd_filter_func = _ft_lcd_filter_fir;
307      library->lcd_extra       = 2;
308
309#endif
310
311      break;
312
313    case FT_LCD_FILTER_LIGHT:
314      ft_memcpy( library->lcd_weights, light_filter, 5 );
315      library->lcd_filter_func = _ft_lcd_filter_fir;
316      library->lcd_extra       = 2;
317      break;
318
319#ifdef USE_LEGACY
320
321    case FT_LCD_FILTER_LEGACY:
322      library->lcd_filter_func = _ft_lcd_filter_legacy;
323      library->lcd_extra       = 0;
324      break;
325
326#endif
327
328    default:
329      return FT_Err_Invalid_Argument;
330    }
331
332    library->lcd_filter = filter;
333    return 0;
334  }
335
336#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
337
338  FT_EXPORT_DEF( FT_Error )
339  FT_Library_SetLcdFilter( FT_Library    library,
340                           FT_LcdFilter  filter )
341  {
342    FT_UNUSED( library );
343    FT_UNUSED( filter );
344
345    return FT_Err_Unimplemented_Feature;
346  }
347
348#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
349
350
351/* END */