ReactOS  0.4.12-dev-36-g472787f
ftsmooth.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftsmooth.c */
4 /* */
5 /* Anti-aliasing renderer interface (body). */
6 /* */
7 /* Copyright 2000-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 #include FT_INTERNAL_OBJECTS_H
22 #include FT_OUTLINE_H
23 #include "ftsmooth.h"
24 #include "ftgrays.h"
25 #include "ftspic.h"
26 
27 #include "ftsmerrs.h"
28 
29 
30  /* initialize renderer -- init its raster */
31  static FT_Error
33  {
34  render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
35 
36  return 0;
37  }
38 
39 
40  /* sets render-specific mode */
41  static FT_Error
43  FT_ULong mode_tag,
45  {
46  /* we simply pass it to the raster */
47  return render->clazz->raster_class->raster_set_mode( render->raster,
48  mode_tag,
49  data );
50  }
51 
52  /* transform a given glyph image */
53  static FT_Error
56  const FT_Matrix* matrix,
57  const FT_Vector* delta )
58  {
60 
61 
62  if ( slot->format != render->glyph_format )
63  {
64  error = FT_THROW( Invalid_Argument );
65  goto Exit;
66  }
67 
68  if ( matrix )
69  FT_Outline_Transform( &slot->outline, matrix );
70 
71  if ( delta )
72  FT_Outline_Translate( &slot->outline, delta->x, delta->y );
73 
74  Exit:
75  return error;
76  }
77 
78 
79  /* return the glyph's control box */
80  static void
83  FT_BBox* cbox )
84  {
85  FT_ZERO( cbox );
86 
87  if ( slot->format == render->glyph_format )
88  FT_Outline_Get_CBox( &slot->outline, cbox );
89  }
90 
91 
92  /* convert a slot's glyph image into a bitmap */
93  static FT_Error
97  const FT_Vector* origin,
98  FT_Render_Mode required_mode )
99  {
101  FT_Outline* outline = &slot->outline;
102  FT_Bitmap* bitmap = &slot->bitmap;
103  FT_Memory memory = render->root.memory;
104  FT_Pos x_shift = 0;
105  FT_Pos y_shift = 0;
106  FT_Int hmul = ( mode == FT_RENDER_MODE_LCD );
107  FT_Int vmul = ( mode == FT_RENDER_MODE_LCD_V );
108 
110 
111 
112  /* check glyph image format */
113  if ( slot->format != render->glyph_format )
114  {
115  error = FT_THROW( Invalid_Argument );
116  goto Exit;
117  }
118 
119  /* check mode */
120  if ( mode != required_mode )
121  {
122  error = FT_THROW( Cannot_Render_Glyph );
123  goto Exit;
124  }
125 
126  /* release old bitmap buffer */
127  if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
128  {
129  FT_FREE( bitmap->buffer );
131  }
132 
133  ft_glyphslot_preset_bitmap( slot, mode, origin );
134 
135  /* allocate new one */
136  if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
137  goto Exit;
138 
140 
141  x_shift = 64 * -slot->bitmap_left;
142  y_shift = 64 * -slot->bitmap_top;
143  if ( bitmap->pixel_mode == FT_PIXEL_MODE_LCD_V )
144  y_shift += 64 * (FT_Int)bitmap->rows / 3;
145  else
146  y_shift += 64 * (FT_Int)bitmap->rows;
147 
148  if ( origin )
149  {
150  x_shift += origin->x;
151  y_shift += origin->y;
152  }
153 
154  /* translate outline to render it into the bitmap */
155  if ( x_shift || y_shift )
156  FT_Outline_Translate( outline, x_shift, y_shift );
157 
158  /* set up parameters */
159  params.target = bitmap;
160  params.source = outline;
161  params.flags = FT_RASTER_FLAG_AA;
162 
163 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
164 
165  /* implode outline if needed */
166  {
167  FT_Vector* points = outline->points;
168  FT_Vector* points_end = points + outline->n_points;
169  FT_Vector* vec;
170 
171 
172  if ( hmul )
173  for ( vec = points; vec < points_end; vec++ )
174  vec->x *= 3;
175 
176  if ( vmul )
177  for ( vec = points; vec < points_end; vec++ )
178  vec->y *= 3;
179  }
180 
181  /* render outline into the bitmap */
182  error = render->raster_render( render->raster, &params );
183 
184  /* deflate outline if needed */
185  {
186  FT_Vector* points = outline->points;
187  FT_Vector* points_end = points + outline->n_points;
188  FT_Vector* vec;
189 
190 
191  if ( hmul )
192  for ( vec = points; vec < points_end; vec++ )
193  vec->x /= 3;
194 
195  if ( vmul )
196  for ( vec = points; vec < points_end; vec++ )
197  vec->y /= 3;
198  }
199 
200  if ( error )
201  goto Exit;
202 
203  /* finally apply filtering */
204  if ( hmul || vmul )
205  {
206  FT_Byte* lcd_weights;
207  FT_Bitmap_LcdFilterFunc lcd_filter_func;
208 
209 
210  /* Per-face LCD filtering takes priority if set up. */
211  if ( slot->face && slot->face->internal->lcd_filter_func )
212  {
213  lcd_weights = slot->face->internal->lcd_weights;
214  lcd_filter_func = slot->face->internal->lcd_filter_func;
215  }
216  else
217  {
218  lcd_weights = slot->library->lcd_weights;
219  lcd_filter_func = slot->library->lcd_filter_func;
220  }
221 
222  if ( lcd_filter_func )
223  lcd_filter_func( bitmap, mode, lcd_weights );
224  }
225 
226 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
227 
228  if ( hmul ) /* lcd */
229  {
230  FT_Byte* line;
231  FT_Byte* temp = NULL;
232  FT_UInt i, j;
233 
234  unsigned int height = bitmap->rows;
235  unsigned int width = bitmap->width;
236  int pitch = bitmap->pitch;
237 
238 
239  /* Render 3 separate monochrome bitmaps, shifting the outline */
240  /* by 1/3 pixel. */
241  width /= 3;
242 
243  bitmap->buffer += width;
244 
245  error = render->raster_render( render->raster, &params );
246  if ( error )
247  goto Exit;
248 
249  FT_Outline_Translate( outline, -21, 0 );
250  x_shift -= 21;
251  bitmap->buffer += width;
252 
253  error = render->raster_render( render->raster, &params );
254  if ( error )
255  goto Exit;
256 
257  FT_Outline_Translate( outline, 42, 0 );
258  x_shift += 42;
259  bitmap->buffer -= 2 * width;
260 
261  error = render->raster_render( render->raster, &params );
262  if ( error )
263  goto Exit;
264 
265  /* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD. */
266  /* XXX: It is more efficient to render every third byte above. */
267 
268  if ( FT_ALLOC( temp, (FT_ULong)pitch ) )
269  goto Exit;
270 
271  for ( i = 0; i < height; i++ )
272  {
273  line = bitmap->buffer + i * (FT_ULong)pitch;
274  for ( j = 0; j < width; j++ )
275  {
276  temp[3 * j ] = line[j];
277  temp[3 * j + 1] = line[j + width];
278  temp[3 * j + 2] = line[j + width + width];
279  }
280  FT_MEM_COPY( line, temp, pitch );
281  }
282 
283  FT_FREE( temp );
284  }
285  else if ( vmul ) /* lcd_v */
286  {
287  int pitch = bitmap->pitch;
288 
289 
290  /* Render 3 separate monochrome bitmaps, shifting the outline */
291  /* by 1/3 pixel. Triple the pitch to render on each third row. */
292  bitmap->pitch *= 3;
293  bitmap->rows /= 3;
294 
295  bitmap->buffer += pitch;
296 
297  error = render->raster_render( render->raster, &params );
298  if ( error )
299  goto Exit;
300 
301  FT_Outline_Translate( outline, 0, 21 );
302  y_shift += 21;
303  bitmap->buffer += pitch;
304 
305  error = render->raster_render( render->raster, &params );
306  if ( error )
307  goto Exit;
308 
309  FT_Outline_Translate( outline, 0, -42 );
310  y_shift -= 42;
311  bitmap->buffer -= 2 * pitch;
312 
313  error = render->raster_render( render->raster, &params );
314  if ( error )
315  goto Exit;
316 
317  bitmap->pitch /= 3;
318  bitmap->rows *= 3;
319  }
320  else /* grayscale */
321  error = render->raster_render( render->raster, &params );
322 
323 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
324 
325  Exit:
326  if ( !error )
327  {
328  /* everything is fine; the glyph is now officially a bitmap */
329  slot->format = FT_GLYPH_FORMAT_BITMAP;
330  }
331  else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
332  {
333  FT_FREE( bitmap->buffer );
335  }
336 
337  if ( x_shift || y_shift )
338  FT_Outline_Translate( outline, -x_shift, -y_shift );
339 
340  return error;
341  }
342 
343 
344  /* convert a slot's glyph image into a bitmap */
345  static FT_Error
349  const FT_Vector* origin )
350  {
351  if ( mode == FT_RENDER_MODE_LIGHT )
352  mode = FT_RENDER_MODE_NORMAL;
353 
354  return ft_smooth_render_generic( render, slot, mode, origin,
356  }
357 
358 
359  /* convert a slot's glyph image into a horizontal LCD bitmap */
360  static FT_Error
364  const FT_Vector* origin )
365  {
366  return ft_smooth_render_generic( render, slot, mode, origin,
368  }
369 
370 
371  /* convert a slot's glyph image into a vertical LCD bitmap */
372  static FT_Error
376  const FT_Vector* origin )
377  {
378  return ft_smooth_render_generic( render, slot, mode, origin,
380  }
381 
382 
384  ft_smooth_renderer_class,
385 
387  sizeof ( FT_RendererRec ),
388 
389  "smooth",
390  0x10000L,
391  0x20000L,
392 
393  NULL, /* module specific interface */
394 
395  (FT_Module_Constructor)ft_smooth_init, /* module_init */
396  (FT_Module_Destructor) NULL, /* module_done */
397  (FT_Module_Requester) NULL, /* get_interface */
398 
400 
401  (FT_Renderer_RenderFunc) ft_smooth_render, /* render_glyph */
402  (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */
403  (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */
405 
406  (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */
407  )
408 
409 
411  ft_smooth_lcd_renderer_class,
412 
414  sizeof ( FT_RendererRec ),
415 
416  "smooth-lcd",
417  0x10000L,
418  0x20000L,
419 
420  NULL, /* module specific interface */
421 
422  (FT_Module_Constructor)ft_smooth_init, /* module_init */
423  (FT_Module_Destructor) NULL, /* module_done */
424  (FT_Module_Requester) NULL, /* get_interface */
425 
427 
428  (FT_Renderer_RenderFunc) ft_smooth_render_lcd, /* render_glyph */
429  (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */
430  (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */
432 
433  (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */
434  )
435 
436 
438  ft_smooth_lcdv_renderer_class,
439 
441  sizeof ( FT_RendererRec ),
442 
443  "smooth-lcdv",
444  0x10000L,
445  0x20000L,
446 
447  NULL, /* module specific interface */
448 
449  (FT_Module_Constructor)ft_smooth_init, /* module_init */
450  (FT_Module_Destructor) NULL, /* module_done */
451  (FT_Module_Requester) NULL, /* get_interface */
452 
454 
455  (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, /* render_glyph */
456  (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */
457  (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */
458  (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */
459 
460  (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */
461  )
462 
463 
464 /* END */
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:303
int FT_Error
Definition: fttypes.h:300
FT_Face_Internal internal
Definition: freetype.h:1120
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
FT_Pos y
Definition: ftimage.h:77
FT_Raster_SetModeFunc raster_set_mode
Definition: ftimage.h:1186
FT_Error(* FT_Module_Constructor)(FT_Module module)
Definition: ftmodapi.h:152
unsigned long FT_ULong
Definition: fttypes.h:253
FT_Memory memory
Definition: ftobjs.h:537
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
unsigned char pixel_mode
Definition: ftimage.h:268
unsigned int rows
Definition: ftimage.h:263
#define error(str)
Definition: mkdosfs.c:1605
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_Renderer_RenderFunc FT_Renderer_TransformFunc FT_Renderer_GetCBoxFunc ft_smooth_get_cbox
Definition: ftsmooth.c:416
FT_Pos x
Definition: ftimage.h:76
const void * source
Definition: ftimage.h:1000
signed int FT_Int
Definition: fttypes.h:220
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_Renderer_RenderFunc FT_Renderer_TransformFunc ft_smooth_transform
Definition: ftsmooth.c:416
GLuint GLenum matrix
Definition: glext.h:9407
enum FT_Render_Mode_ FT_Render_Mode
unsigned char * buffer
Definition: ftimage.h:266
voidpf uLong int origin
Definition: ioapi.h:142
#define FT_RASTER_FLAG_AA
Definition: ftimage.h:941
FT_Glyph_Format glyph_format
Definition: ftobjs.h:775
return FT_Err_Ok
Definition: ftbbox.c:511
static char memory[1024 *256]
Definition: process.c:116
#define FT_GLYPH_OWN_BITMAP
Definition: ftobjs.h:463
static FT_Error ft_smooth_render(FT_Renderer render, FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector *origin)
Definition: ftsmooth.c:346
void(* FT_Renderer_GetCBoxFunc)(FT_Renderer renderer, FT_GlyphSlot slot, FT_BBox *cbox)
Definition: ftrender.h:102
static FT_Error ft_smooth_render_generic(FT_Renderer render, FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector *origin, FT_Render_Mode required_mode)
Definition: ftsmooth.c:94
FT_Raster_ResetFunc raster_reset
Definition: ftimage.h:1185
FT_Vector * points
Definition: ftimage.h:339
FT_Renderer_Class * clazz
Definition: ftobjs.h:774
GLenum GLclampf GLint i
Definition: glfuncs.h:14
GLenum const GLfloat * params
Definition: glext.h:5645
unsigned char FT_Byte
Definition: fttypes.h:154
#define FT_THROW(e)
Definition: ftdebug.h:213
FT_Module_Interface(* FT_Module_Requester)(FT_Module module, const char *name)
Definition: ftmodapi.h:184
FT_Raster_Funcs * raster_class
Definition: ftrender.h:156
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:478
smooth NULL
Definition: ftsmooth.c:416
FT_Int bitmap_left
Definition: freetype.h:1924
#define FT_FREE(ptr)
Definition: ftmemory.h:329
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:711
FT_Int bitmap_top
Definition: freetype.h:1925
smooth FT_Module_Constructor ft_smooth_init
Definition: ftsmooth.c:416
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_Renderer_RenderFunc FT_Renderer_TransformFunc FT_Renderer_GetCBoxFunc FT_Renderer_SetModeFunc ft_smooth_set_mode
Definition: ftsmooth.c:416
Definition: uimain.c:88
#define FT_ZERO(p)
Definition: ftmemory.h:237
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_GLYPH_FORMAT_OUTLINE
Definition: ftsmooth.c:416
if(!(yy_init))
Definition: macro.lex.yy.c:717
static void Exit(void)
Definition: sock.c:1331
static void render(void)
Definition: ssstars.c:272
FT_DEFINE_RENDERER(ft_smooth_renderer_class, FT_MODULE_RENDERER, sizeof(FT_RendererRec), "smooth", 0x10000L, 0x20000L, NULL,(FT_Module_Constructor) ft_smooth_init,(FT_Module_Destructor) NULL,(FT_Module_Requester) NULL, FT_GLYPH_FORMAT_OUTLINE,(FT_Renderer_RenderFunc) ft_smooth_render,(FT_Renderer_TransformFunc) ft_smooth_transform,(FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox,(FT_Renderer_SetModeFunc) ft_smooth_set_mode,(FT_Raster_Funcs *)&FT_GRAYS_RASTER_GET) FT_DEFINE_RENDERER(ft_smooth_lcd_renderer_class
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
FT_Vector * vec
Definition: ftbbox.c:448
GLsizei const GLfloat * points
Definition: glext.h:8112
char line[200]
Definition: main.c:97
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_Renderer_RenderFunc ft_smooth_render_lcd
Definition: ftsmooth.c:416
FT_Outline outline
Definition: freetype.h:1927
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
static stack_node_t temp
Definition: rpn.c:18
FT_Bitmap bitmap
Definition: freetype.h:1923
static FT_Error ft_smooth_render_lcd_v(FT_Renderer render, FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector *origin)
Definition: ftsmooth.c:373
Definition: mesh.c:5329
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
Definition: vfat.h:189
FT_Glyph_Format format
Definition: freetype.h:1921
FT_Error(* FT_Renderer_SetModeFunc)(FT_Renderer renderer, FT_ULong mode_tag, FT_Pointer mode_ptr)
Definition: ftrender.h:108
ft_glyphslot_preset_bitmap(FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector *origin)
Definition: ftobjs.c:334
short n_points
Definition: ftimage.h:337
unsigned int FT_UInt
Definition: fttypes.h:231
FT_Library library
Definition: freetype.h:1910
void(* FT_Module_Destructor)(FT_Module module)
Definition: ftmodapi.h:167
const FT_Bitmap * target
Definition: ftimage.h:999
#define FT_ALLOC_MULT(ptr, count, item_size)
Definition: ftmemory.h:309
#define FT_GRAYS_RASTER_GET
Definition: ftspic.h:30
FT_Raster_Render_Func raster_render
Definition: ftobjs.h:779
int pitch
Definition: ftimage.h:265
FT_Error(* FT_Renderer_TransformFunc)(FT_Renderer renderer, FT_GlyphSlot slot, const FT_Matrix *matrix, const FT_Vector *delta)
Definition: ftrender.h:95
FT_MODULE_RENDERER
Definition: ftsmooth.c:413
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:528
FT_Slot_Internal internal
Definition: freetype.h:1940
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:228
static HBITMAP bitmap
Definition: clipboard.c:1344
FT_ModuleRec root
Definition: ftobjs.h:773
FT_Error(* FT_Renderer_RenderFunc)(FT_Renderer renderer, FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector *origin)
Definition: ftrender.h:89
FT_Raster raster
Definition: ftobjs.h:778
unsigned int width
Definition: ftimage.h:264