source: trunk/poppler/freetype2/src/base/ftlcdfil.c @ 165

Last change on this file since 165 was 165, checked in by Eugene Romanenko, 15 years ago

update to latest freetype cvs, (closes #76)

File size: 9.3 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  ftlcdfil.c                                                             */
4/*                                                                         */
5/*    FreeType API for color filtering of subpixel bitmap glyphs (body).   */
6/*                                                                         */
7/*  Copyright 2006 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  /* FIR filter used by the default and light filters */
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 FIR 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( 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    static const FT_Byte  default_filter[5] =
276                            { 0x10, 0x40, 0x70, 0x40, 0x10 };
277
278
279    if ( library == NULL )
280      return FT_Err_Invalid_Argument;
281
282    switch ( filter )
283    {
284    case FT_LCD_FILTER_NONE:
285      library->lcd_filter_func = NULL;
286      library->lcd_extra       = 0;
287      break;
288
289    case FT_LCD_FILTER_DEFAULT:
290#if defined( FT_FORCE_LEGACY_LCD_FILTER )
291
292      library->lcd_filter_func = _ft_lcd_filter_legacy;
293      library->lcd_extra       = 0;
294
295#elif defined( FT_FORCE_LIGHT_LCD_FILTER )
296
297      memcpy( library->lcd_weights, default_filter, 5 );
298      library->lcd_filter_func = _ft_lcd_filter_fir;
299      library->lcd_extra       = 2;
300
301#else
302
303      memcpy( library->lcd_weights, default_filter, 5 );
304      library->lcd_filter_func = _ft_lcd_filter_fir;
305      library->lcd_extra       = 2;
306
307#endif
308
309      break;
310
311    case FT_LCD_FILTER_LIGHT:
312      memcpy( library->lcd_weights, light_filter, 5 );
313      library->lcd_filter_func = _ft_lcd_filter_fir;
314      library->lcd_extra       = 2;
315      break;
316
317#ifdef USE_LEGACY
318
319    case FT_LCD_FILTER_LEGACY:
320      library->lcd_filter_func = _ft_lcd_filter_legacy;
321      library->lcd_extra       = 0;
322      break;
323
324#endif
325
326    default:
327      return FT_Err_Invalid_Argument;
328    }
329
330    library->lcd_filter = filter;
331    return 0;
332  }
333
334#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
335
336  FT_EXPORT( FT_Error )
337  FT_Library_SetLcdFilter( FT_Library    library,
338                           FT_LcdFilter  filter )
339  {
340    FT_UNUSED( library );
341    FT_UNUSED( filter );
342
343    return FT_Err_Unimplemented_Feature;
344  }
345
346#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
347
348
349/* END */
Note: See TracBrowser for help on using the repository browser.