Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
ftlcdfil.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftlcdfil.c */
4 /* */
5 /* FreeType API for color filtering of subpixel bitmap glyphs (body). */
6 /* */
7 /* Copyright 2006, 2008-2010, 2013 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_INTERNAL_DEBUG_H
21 
22 #include FT_LCD_FILTER_H
23 #include FT_IMAGE_H
24 #include FT_INTERNAL_OBJECTS_H
25 
26 
27 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
28 
29 /* define USE_LEGACY to implement the legacy filter */
30 #define USE_LEGACY
31 
32  /* FIR filter used by the default and light filters */
33  static void
34  _ft_lcd_filter_fir( FT_Bitmap* bitmap,
37  {
38  FT_Byte* weights = library->lcd_weights;
39  FT_UInt width = (FT_UInt)bitmap->width;
40  FT_UInt height = (FT_UInt)bitmap->rows;
41 
42 
43  /* horizontal in-place FIR filter */
44  if ( mode == FT_RENDER_MODE_LCD && width >= 4 )
45  {
46  FT_Byte* line = bitmap->buffer;
47 
48 
49  for ( ; height > 0; height--, line += bitmap->pitch )
50  {
51  FT_UInt fir[5];
52  FT_UInt val1, xx;
53 
54 
55  val1 = line[0];
56  fir[0] = weights[2] * val1;
57  fir[1] = weights[3] * val1;
58  fir[2] = weights[4] * val1;
59  fir[3] = 0;
60  fir[4] = 0;
61 
62  val1 = line[1];
63  fir[0] += weights[1] * val1;
64  fir[1] += weights[2] * val1;
65  fir[2] += weights[3] * val1;
66  fir[3] += weights[4] * val1;
67 
68  for ( xx = 2; xx < width; xx++ )
69  {
70  FT_UInt val, pix;
71 
72 
73  val = line[xx];
74  pix = fir[0] + weights[0] * val;
75  fir[0] = fir[1] + weights[1] * val;
76  fir[1] = fir[2] + weights[2] * val;
77  fir[2] = fir[3] + weights[3] * val;
78  fir[3] = weights[4] * val;
79 
80  pix >>= 8;
81  pix |= -( pix >> 8 );
82  line[xx - 2] = (FT_Byte)pix;
83  }
84 
85  {
86  FT_UInt pix;
87 
88 
89  pix = fir[0] >> 8;
90  pix |= -( pix >> 8 );
91  line[xx - 2] = (FT_Byte)pix;
92 
93  pix = fir[1] >> 8;
94  pix |= -( pix >> 8 );
95  line[xx - 1] = (FT_Byte)pix;
96  }
97  }
98  }
99 
100  /* vertical in-place FIR filter */
101  else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 )
102  {
103  FT_Byte* column = bitmap->buffer;
104  FT_Int pitch = bitmap->pitch;
105 
106 
107  for ( ; width > 0; width--, column++ )
108  {
109  FT_Byte* col = column;
110  FT_UInt fir[5];
111  FT_UInt val1, yy;
112 
113 
114  val1 = col[0];
115  fir[0] = weights[2] * val1;
116  fir[1] = weights[3] * val1;
117  fir[2] = weights[4] * val1;
118  fir[3] = 0;
119  fir[4] = 0;
120  col += pitch;
121 
122  val1 = col[0];
123  fir[0] += weights[1] * val1;
124  fir[1] += weights[2] * val1;
125  fir[2] += weights[3] * val1;
126  fir[3] += weights[4] * val1;
127  col += pitch;
128 
129  for ( yy = 2; yy < height; yy++ )
130  {
131  FT_UInt val, pix;
132 
133 
134  val = col[0];
135  pix = fir[0] + weights[0] * val;
136  fir[0] = fir[1] + weights[1] * val;
137  fir[1] = fir[2] + weights[2] * val;
138  fir[2] = fir[3] + weights[3] * val;
139  fir[3] = weights[4] * val;
140 
141  pix >>= 8;
142  pix |= -( pix >> 8 );
143  col[-2 * pitch] = (FT_Byte)pix;
144  col += pitch;
145  }
146 
147  {
148  FT_UInt pix;
149 
150 
151  pix = fir[0] >> 8;
152  pix |= -( pix >> 8 );
153  col[-2 * pitch] = (FT_Byte)pix;
154 
155  pix = fir[1] >> 8;
156  pix |= -( pix >> 8 );
157  col[-pitch] = (FT_Byte)pix;
158  }
159  }
160  }
161  }
162 
163 
164 #ifdef USE_LEGACY
165 
166  /* intra-pixel filter used by the legacy filter */
167  static void
168  _ft_lcd_filter_legacy( FT_Bitmap* bitmap,
169  FT_Render_Mode mode,
170  FT_Library library )
171  {
172  FT_UInt width = (FT_UInt)bitmap->width;
173  FT_UInt height = (FT_UInt)bitmap->rows;
174  FT_Int pitch = bitmap->pitch;
175 
176  static const int filters[3][3] =
177  {
178  { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 },
179  { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 },
180  { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 }
181  };
182 
183  FT_UNUSED( library );
184 
185 
186  /* horizontal in-place intra-pixel filter */
187  if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
188  {
189  FT_Byte* line = bitmap->buffer;
190 
191 
192  for ( ; height > 0; height--, line += pitch )
193  {
194  FT_UInt xx;
195 
196 
197  for ( xx = 0; xx < width; xx += 3 )
198  {
199  FT_UInt r = 0;
200  FT_UInt g = 0;
201  FT_UInt b = 0;
202  FT_UInt p;
203 
204 
205  p = line[xx];
206  r += filters[0][0] * p;
207  g += filters[0][1] * p;
208  b += filters[0][2] * p;
209 
210  p = line[xx + 1];
211  r += filters[1][0] * p;
212  g += filters[1][1] * p;
213  b += filters[1][2] * p;
214 
215  p = line[xx + 2];
216  r += filters[2][0] * p;
217  g += filters[2][1] * p;
218  b += filters[2][2] * p;
219 
220  line[xx] = (FT_Byte)( r / 65536 );
221  line[xx + 1] = (FT_Byte)( g / 65536 );
222  line[xx + 2] = (FT_Byte)( b / 65536 );
223  }
224  }
225  }
226  else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
227  {
228  FT_Byte* column = bitmap->buffer;
229 
230 
231  for ( ; width > 0; width--, column++ )
232  {
233  FT_Byte* col = column;
234  FT_Byte* col_end = col + height * pitch;
235 
236 
237  for ( ; col < col_end; col += 3 * pitch )
238  {
239  FT_UInt r = 0;
240  FT_UInt g = 0;
241  FT_UInt b = 0;
242  FT_UInt p;
243 
244 
245  p = col[0];
246  r += filters[0][0] * p;
247  g += filters[0][1] * p;
248  b += filters[0][2] * p;
249 
250  p = col[pitch];
251  r += filters[1][0] * p;
252  g += filters[1][1] * p;
253  b += filters[1][2] * p;
254 
255  p = col[pitch * 2];
256  r += filters[2][0] * p;
257  g += filters[2][1] * p;
258  b += filters[2][2] * p;
259 
260  col[0] = (FT_Byte)( r / 65536 );
261  col[pitch] = (FT_Byte)( g / 65536 );
262  col[2 * pitch] = (FT_Byte)( b / 65536 );
263  }
264  }
265  }
266  }
267 
268 #endif /* USE_LEGACY */
269 
270 
273  unsigned char *weights )
274  {
275  if ( !library || !weights )
276  return FT_THROW( Invalid_Argument );
277 
278  ft_memcpy( library->lcd_weights, weights, 5 );
279 
280  return FT_Err_Ok;
281  }
282 
283 
287  {
288  static const FT_Byte light_filter[5] =
289  { 0x00, 0x55, 0x56, 0x55, 0x00 };
290  /* the values here sum up to a value larger than 256, */
291  /* providing a cheap gamma correction */
292  static const FT_Byte default_filter[5] =
293  { 0x10, 0x40, 0x70, 0x40, 0x10 };
294 
295 
296  if ( !library )
297  return FT_THROW( Invalid_Argument );
298 
299  switch ( filter )
300  {
301  case FT_LCD_FILTER_NONE:
302  library->lcd_filter_func = NULL;
303  library->lcd_extra = 0;
304  break;
305 
307 #if defined( FT_FORCE_LEGACY_LCD_FILTER )
308 
309  library->lcd_filter_func = _ft_lcd_filter_legacy;
310  library->lcd_extra = 0;
311 
312 #elif defined( FT_FORCE_LIGHT_LCD_FILTER )
313 
314  ft_memcpy( library->lcd_weights, light_filter, 5 );
315  library->lcd_filter_func = _ft_lcd_filter_fir;
316  library->lcd_extra = 2;
317 
318 #else
319 
320  ft_memcpy( library->lcd_weights, default_filter, 5 );
321  library->lcd_filter_func = _ft_lcd_filter_fir;
322  library->lcd_extra = 2;
323 
324 #endif
325 
326  break;
327 
328  case FT_LCD_FILTER_LIGHT:
329  ft_memcpy( library->lcd_weights, light_filter, 5 );
330  library->lcd_filter_func = _ft_lcd_filter_fir;
331  library->lcd_extra = 2;
332  break;
333 
334 #ifdef USE_LEGACY
335 
337  library->lcd_filter_func = _ft_lcd_filter_legacy;
338  library->lcd_extra = 0;
339  break;
340 
341 #endif
342 
343  default:
344  return FT_THROW( Invalid_Argument );
345  }
346 
347  library->lcd_filter = filter;
348 
349  return FT_Err_Ok;
350  }
351 
352 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
353 
356  unsigned char *weights )
357  {
358  FT_UNUSED( library );
359  FT_UNUSED( weights );
360 
361  return FT_THROW( Unimplemented_Feature );
362  }
363 
364 
367  FT_LcdFilter filter )
368  {
369  FT_UNUSED( library );
370  FT_UNUSED( filter );
371 
372  return FT_THROW( Unimplemented_Feature );
373  }
374 
375 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
376 
377 
378 /* END */
GLint GLint GLsizei GLsizei height
int FT_Error
Definition: fttypes.h:296
const GLbyte * weights
GLfloat GLfloat p
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
int rows
Definition: ftimage.h:312
enum FT_Render_Mode_ FT_Render_Mode
FT_Library_SetLcdFilterWeights(FT_Library library, unsigned char *weights)
Definition: ftlcdfil.c:355
return FT_THROW(Missing_Property)
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
unsigned char * buffer
Definition: ftimage.h:315
GLint GLint GLsizei width
FT_Library library
Definition: cffdrivr.c:414
int pitch
Definition: ftimage.h:314
return FT_Err_Ok
Definition: ftbbox.c:645
GLboolean GLboolean GLboolean b
unsigned char FT_Byte
Definition: fttypes.h:150
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:32
GLenum mode
int int filters
Definition: png.h:1717
GLdouble GLdouble GLdouble r
GLuint GLfloat * val
int width
Definition: ftimage.h:313
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
unsigned int FT_UInt
Definition: fttypes.h:227
FT_BEGIN_HEADER enum FT_LcdFilter_ FT_LcdFilter
GLboolean GLboolean g
GLenum GLenum GLvoid GLvoid * column
FT_Library_SetLcdFilter(FT_Library library, FT_LcdFilter filter)
Definition: ftlcdfil.c:366
#define ft_memcpy
Definition: ftstdlib.h:81