ReactOS  0.4.13-dev-651-g5dbc677
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-2018 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 #define FT_SHIFTCLAMP( x ) ( x >>= 8, (FT_Byte)( x > 255 ? 255 : x ) )
33 
34 
35  /* add padding according to filter weights */
36  FT_BASE_DEF (void)
38  FT_Pos* Max,
40  {
41  FT_Byte* lcd_weights;
42  FT_Bitmap_LcdFilterFunc lcd_filter_func;
43 
44 
45  /* Per-face LCD filtering takes priority if set up. */
46  if ( slot->face && slot->face->internal->lcd_filter_func )
47  {
48  lcd_weights = slot->face->internal->lcd_weights;
49  lcd_filter_func = slot->face->internal->lcd_filter_func;
50  }
51  else
52  {
53  lcd_weights = slot->library->lcd_weights;
54  lcd_filter_func = slot->library->lcd_filter_func;
55  }
56 
57  if ( lcd_filter_func == ft_lcd_filter_fir )
58  {
59  *Min -= lcd_weights[0] ? 43 :
60  lcd_weights[1] ? 22 : 0;
61  *Max += lcd_weights[4] ? 43 :
62  lcd_weights[3] ? 22 : 0;
63  }
64  }
65 
66 
67  /* FIR filter used by the default and light filters */
68  FT_BASE_DEF( void )
69  ft_lcd_filter_fir( FT_Bitmap* bitmap,
72  {
74  FT_UInt height = (FT_UInt)bitmap->rows;
75  FT_Int pitch = bitmap->pitch;
76  FT_Byte* origin = bitmap->buffer;
77 
78 
79  /* take care of bitmap flow */
80  if ( pitch > 0 )
81  origin += pitch * (FT_Int)( height - 1 );
82 
83  /* horizontal in-place FIR filter */
84  if ( mode == FT_RENDER_MODE_LCD && width >= 2 )
85  {
86  FT_Byte* line = origin;
87 
88 
89  /* `fir' must be at least 32 bit wide, since the sum of */
90  /* the values in `weights' can exceed 0xFF */
91 
92  for ( ; height > 0; height--, line -= pitch )
93  {
94  FT_UInt fir[5];
95  FT_UInt val, xx;
96 
97 
98  val = line[0];
99  fir[2] = weights[2] * val;
100  fir[3] = weights[3] * val;
101  fir[4] = weights[4] * val;
102 
103  val = line[1];
104  fir[1] = fir[2] + weights[1] * val;
105  fir[2] = fir[3] + weights[2] * val;
106  fir[3] = fir[4] + weights[3] * val;
107  fir[4] = weights[4] * val;
108 
109  for ( xx = 2; xx < width; xx++ )
110  {
111  val = line[xx];
112  fir[0] = fir[1] + weights[0] * val;
113  fir[1] = fir[2] + weights[1] * val;
114  fir[2] = fir[3] + weights[2] * val;
115  fir[3] = fir[4] + weights[3] * val;
116  fir[4] = weights[4] * val;
117 
118  line[xx - 2] = FT_SHIFTCLAMP( fir[0] );
119  }
120 
121  line[xx - 2] = FT_SHIFTCLAMP( fir[1] );
122  line[xx - 1] = FT_SHIFTCLAMP( fir[2] );
123  }
124  }
125 
126  /* vertical in-place FIR filter */
127  else if ( mode == FT_RENDER_MODE_LCD_V && height >= 2 )
128  {
129  FT_Byte* column = origin;
130 
131 
132  for ( ; width > 0; width--, column++ )
133  {
134  FT_Byte* col = column;
135  FT_UInt fir[5];
136  FT_UInt val, yy;
137 
138 
139  val = col[0];
140  fir[2] = weights[2] * val;
141  fir[3] = weights[3] * val;
142  fir[4] = weights[4] * val;
143  col -= pitch;
144 
145  val = col[0];
146  fir[1] = fir[2] + weights[1] * val;
147  fir[2] = fir[3] + weights[2] * val;
148  fir[3] = fir[4] + weights[3] * val;
149  fir[4] = weights[4] * val;
150  col -= pitch;
151 
152  for ( yy = 2; yy < height; yy++, col -= pitch )
153  {
154  val = col[0];
155  fir[0] = fir[1] + weights[0] * val;
156  fir[1] = fir[2] + weights[1] * val;
157  fir[2] = fir[3] + weights[2] * val;
158  fir[3] = fir[4] + weights[3] * val;
159  fir[4] = weights[4] * val;
160 
161  col[pitch * 2] = FT_SHIFTCLAMP( fir[0] );
162  }
163 
164  col[pitch * 2] = FT_SHIFTCLAMP( fir[1] );
165  col[pitch] = FT_SHIFTCLAMP( fir[2] );
166  }
167  }
168  }
169 
170 
171 #ifdef USE_LEGACY
172 
173  /* intra-pixel filter used by the legacy filter */
174  static void
175  _ft_lcd_filter_legacy( FT_Bitmap* bitmap,
177  FT_Byte* weights )
178  {
180  FT_UInt height = (FT_UInt)bitmap->rows;
181  FT_Int pitch = bitmap->pitch;
182  FT_Byte* origin = bitmap->buffer;
183 
184  static const unsigned int filters[3][3] =
185  {
186  { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 },
187  { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 },
188  { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 }
189  };
190 
191  FT_UNUSED( weights );
192 
193 
194  /* take care of bitmap flow */
195  if ( pitch > 0 )
196  origin += pitch * (FT_Int)( height - 1 );
197 
198  /* horizontal in-place intra-pixel filter */
199  if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
200  {
201  FT_Byte* line = origin;
202 
203 
204  for ( ; height > 0; height--, line -= pitch )
205  {
206  FT_UInt xx;
207 
208 
209  for ( xx = 0; xx < width; xx += 3 )
210  {
211  FT_UInt r, g, b;
212  FT_UInt p;
213 
214 
215  p = line[xx];
216  r = filters[0][0] * p;
217  g = filters[0][1] * p;
218  b = filters[0][2] * p;
219 
220  p = line[xx + 1];
221  r += filters[1][0] * p;
222  g += filters[1][1] * p;
223  b += filters[1][2] * p;
224 
225  p = line[xx + 2];
226  r += filters[2][0] * p;
227  g += filters[2][1] * p;
228  b += filters[2][2] * p;
229 
230  line[xx] = (FT_Byte)( r / 65536 );
231  line[xx + 1] = (FT_Byte)( g / 65536 );
232  line[xx + 2] = (FT_Byte)( b / 65536 );
233  }
234  }
235  }
236  else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
237  {
238  FT_Byte* column = origin;
239 
240 
241  for ( ; width > 0; width--, column++ )
242  {
243  FT_Byte* col = column - 2 * pitch;
244 
245 
246  for ( ; height > 0; height -= 3, col -= 3 * pitch )
247  {
248  FT_UInt r, g, b;
249  FT_UInt p;
250 
251 
252  p = col[0];
253  r = filters[0][0] * p;
254  g = filters[0][1] * p;
255  b = filters[0][2] * p;
256 
257  p = col[pitch];
258  r += filters[1][0] * p;
259  g += filters[1][1] * p;
260  b += filters[1][2] * p;
261 
262  p = col[pitch * 2];
263  r += filters[2][0] * p;
264  g += filters[2][1] * p;
265  b += filters[2][2] * p;
266 
267  col[0] = (FT_Byte)( r / 65536 );
268  col[pitch] = (FT_Byte)( g / 65536 );
269  col[pitch * 2] = (FT_Byte)( b / 65536 );
270  }
271  }
272  }
273  }
274 
275 #endif /* USE_LEGACY */
276 
277 
280  unsigned char *weights )
281  {
282  if ( !library )
283  return FT_THROW( Invalid_Library_Handle );
284 
285  if ( !weights )
286  return FT_THROW( Invalid_Argument );
287 
289  library->lcd_filter_func = ft_lcd_filter_fir;
290 
291  return FT_Err_Ok;
292  }
293 
294 
298  {
299  static const FT_LcdFiveTapFilter default_weights =
300  { 0x08, 0x4d, 0x56, 0x4d, 0x08 };
301  static const FT_LcdFiveTapFilter light_weights =
302  { 0x00, 0x55, 0x56, 0x55, 0x00 };
303 
304 
305  if ( !library )
306  return FT_THROW( Invalid_Library_Handle );
307 
308  switch ( filter )
309  {
310  case FT_LCD_FILTER_NONE:
311  library->lcd_filter_func = NULL;
312  break;
313 
315  ft_memcpy( library->lcd_weights,
316  default_weights,
318  library->lcd_filter_func = ft_lcd_filter_fir;
319  break;
320 
321  case FT_LCD_FILTER_LIGHT:
322  ft_memcpy( library->lcd_weights,
323  light_weights,
325  library->lcd_filter_func = ft_lcd_filter_fir;
326  break;
327 
328 #ifdef USE_LEGACY
329 
332  library->lcd_filter_func = _ft_lcd_filter_legacy;
333  break;
334 
335 #endif
336 
337  default:
338  return FT_THROW( Invalid_Argument );
339  }
340 
341  return FT_Err_Ok;
342  }
343 
344 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
345 
346  /* add padding according to accommodate outline shifts */
347  FT_BASE_DEF (void)
349  FT_Pos* Max,
351  {
352  FT_UNUSED( slot );
353 
354  *Min -= 21;
355  *Max += 21;
356  }
357 
358 
361  unsigned char *weights )
362  {
363  FT_UNUSED( library );
364  FT_UNUSED( weights );
365 
366  return FT_THROW( Unimplemented_Feature );
367  }
368 
369 
373  {
374  FT_UNUSED( library );
375  FT_UNUSED( filter );
376 
377  return FT_THROW( Unimplemented_Feature );
378  }
379 
380 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
381 
382 
383 /* END */
int FT_Error
Definition: fttypes.h:300
GLint GLint GLsizei width
Definition: gl.h:1546
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
uint32 width
Definition: uimain.c:91
signed int FT_Int
Definition: fttypes.h:220
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
enum FT_Render_Mode_ FT_Render_Mode
FT_Library_SetLcdFilterWeights(FT_Library library, unsigned char *weights)
Definition: ftlcdfil.c:360
voidpf uLong int origin
Definition: ioapi.h:142
FT_Library library
Definition: cffdrivr.c:654
return FT_Err_Ok
Definition: ftbbox.c:511
#define FT_LCD_FILTER_FIVE_TAPS
Definition: ftlcdfil.h:296
unsigned char FT_Byte
Definition: fttypes.h:154
#define FT_THROW(e)
Definition: ftdebug.h:213
#define Max(a, b)
Definition: cdprocs.h:70
smooth NULL
Definition: ftsmooth.c:416
Definition: parser.c:48
#define b
Definition: ke_i.h:79
GLuint GLfloat * val
Definition: glext.h:7180
Definition: uimain.c:88
GLboolean GLboolean g
Definition: glext.h:6204
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
int xx
Definition: npserver.c:29
#define Min(a, b)
Definition: cdprocs.h:66
ft_lcd_padding(FT_Pos *Min, FT_Pos *Max, FT_GlyphSlot slot)
Definition: ftlcdfil.c:348
FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS]
Definition: ftlcdfil.h:298
GLenum mode
Definition: glext.h:6217
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
Definition: vfat.h:184
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:483
unsigned int FT_UInt
Definition: fttypes.h:231
FT_BEGIN_HEADER enum FT_LcdFilter_ FT_LcdFilter
#define FT_BASE_DEF(x)
Definition: ftconfig.h:419
FT_Library_SetLcdFilter(FT_Library library, FT_LcdFilter filter)
Definition: ftlcdfil.c:371
const GLbyte * weights
Definition: glext.h:6523
GLenum GLenum GLvoid GLvoid * column
Definition: glext.h:5664
GLfloat GLfloat p
Definition: glext.h:8902
#define ft_memcpy
Definition: ftstdlib.h:82
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005