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]
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-2006, 2009-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 #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
32  ft_smooth_init( FT_Renderer render )
33  {
35 
36 
37  render->clazz->raster_class->raster_reset( render->raster,
38  library->raster_pool,
39  library->raster_pool_size );
40 
41  return 0;
42  }
43 
44 
45  /* sets render-specific mode */
46  static FT_Error
48  FT_ULong mode_tag,
50  {
51  /* we simply pass it to the raster */
52  return render->clazz->raster_class->raster_set_mode( render->raster,
53  mode_tag,
54  data );
55  }
56 
57  /* transform a given glyph image */
58  static FT_Error
60  FT_GlyphSlot slot,
61  const FT_Matrix* matrix,
62  const FT_Vector* delta )
63  {
65 
66 
67  if ( slot->format != render->glyph_format )
68  {
69  error = FT_THROW( Invalid_Argument );
70  goto Exit;
71  }
72 
73  if ( matrix )
74  FT_Outline_Transform( &slot->outline, matrix );
75 
76  if ( delta )
77  FT_Outline_Translate( &slot->outline, delta->x, delta->y );
78 
79  Exit:
80  return error;
81  }
82 
83 
84  /* return the glyph's control box */
85  static void
87  FT_GlyphSlot slot,
88  FT_BBox* cbox )
89  {
90  FT_MEM_ZERO( cbox, sizeof ( *cbox ) );
91 
92  if ( slot->format == render->glyph_format )
93  FT_Outline_Get_CBox( &slot->outline, cbox );
94  }
95 
96 
97  /* convert a slot's glyph image into a bitmap */
98  static FT_Error
99  ft_smooth_render_generic( FT_Renderer render,
100  FT_GlyphSlot slot,
102  const FT_Vector* origin,
103  FT_Render_Mode required_mode )
104  {
105  FT_Error error;
106  FT_Outline* outline = NULL;
107  FT_BBox cbox;
108  FT_Pos width, height, pitch;
109 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
110  FT_Pos height_org, width_org;
111 #endif
112  FT_Bitmap* bitmap;
113  FT_Memory memory;
114  FT_Int hmul = mode == FT_RENDER_MODE_LCD;
115  FT_Int vmul = mode == FT_RENDER_MODE_LCD_V;
116  FT_Pos x_shift, y_shift, x_left, y_top;
117 
119 
120  FT_Bool have_translated_origin = FALSE;
121  FT_Bool have_outline_shifted = FALSE;
122  FT_Bool have_buffer = FALSE;
123 
124 
125  /* check glyph image format */
126  if ( slot->format != render->glyph_format )
127  {
128  error = FT_THROW( Invalid_Argument );
129  goto Exit;
130  }
131 
132  /* check mode */
133  if ( mode != required_mode )
134  {
135  error = FT_THROW( Cannot_Render_Glyph );
136  goto Exit;
137  }
138 
139  outline = &slot->outline;
140 
141  /* translate the outline to the new origin if needed */
142  if ( origin )
143  {
144  FT_Outline_Translate( outline, origin->x, origin->y );
145  have_translated_origin = TRUE;
146  }
147 
148  /* compute the control box, and grid fit it */
149  FT_Outline_Get_CBox( outline, &cbox );
150 
151  cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
152  cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
153  cbox.xMax = FT_PIX_CEIL( cbox.xMax );
154  cbox.yMax = FT_PIX_CEIL( cbox.yMax );
155 
156  if ( cbox.xMin < 0 && cbox.xMax > FT_INT_MAX + cbox.xMin )
157  {
158  FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
159  " xMin = %d, xMax = %d\n",
160  cbox.xMin >> 6, cbox.xMax >> 6 ));
161  error = FT_THROW( Raster_Overflow );
162  goto Exit;
163  }
164  else
165  width = ( cbox.xMax - cbox.xMin ) >> 6;
166 
167  if ( cbox.yMin < 0 && cbox.yMax > FT_INT_MAX + cbox.yMin )
168  {
169  FT_ERROR(( "ft_smooth_render_generic: glyph too large:"
170  " yMin = %d, yMax = %d\n",
171  cbox.yMin >> 6, cbox.yMax >> 6 ));
172  error = FT_THROW( Raster_Overflow );
173  goto Exit;
174  }
175  else
176  height = ( cbox.yMax - cbox.yMin ) >> 6;
177 
178  bitmap = &slot->bitmap;
179  memory = render->root.memory;
180 
181 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
182  width_org = width;
183  height_org = height;
184 #endif
185 
186  /* release old bitmap buffer */
187  if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
188  {
189  FT_FREE( bitmap->buffer );
191  }
192 
193  /* allocate new one */
194  pitch = width;
195  if ( hmul )
196  {
197  width = width * 3;
198  pitch = FT_PAD_CEIL( width, 4 );
199  }
200 
201  if ( vmul )
202  height *= 3;
203 
204  x_shift = (FT_Int) cbox.xMin;
205  y_shift = (FT_Int) cbox.yMin;
206  x_left = (FT_Int)( cbox.xMin >> 6 );
207  y_top = (FT_Int)( cbox.yMax >> 6 );
208 
209 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
210 
211  if ( slot->library->lcd_filter_func )
212  {
213  FT_Int extra = slot->library->lcd_extra;
214 
215 
216  if ( hmul )
217  {
218  x_shift -= 64 * ( extra >> 1 );
219  width += 3 * extra;
220  pitch = FT_PAD_CEIL( width, 4 );
221  x_left -= extra >> 1;
222  }
223 
224  if ( vmul )
225  {
226  y_shift -= 64 * ( extra >> 1 );
227  height += 3 * extra;
228  y_top += extra >> 1;
229  }
230  }
231 
232 #endif
233 
234 #if FT_UINT_MAX > 0xFFFFU
235 
236  /* Required check is (pitch * height < FT_ULONG_MAX), */
237  /* but we care realistic cases only. Always pitch <= width. */
238  if ( width > 0x7FFF || height > 0x7FFF )
239  {
240  FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n",
241  width, height ));
242  error = FT_THROW( Raster_Overflow );
243  goto Exit;
244  }
245 
246 #endif
247 
248  bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
249  bitmap->num_grays = 256;
250  bitmap->width = width;
251  bitmap->rows = height;
252  bitmap->pitch = pitch;
253 
254  /* translate outline to render it into the bitmap */
255  FT_Outline_Translate( outline, -x_shift, -y_shift );
256  have_outline_shifted = TRUE;
257 
258  if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
259  goto Exit;
260  else
261  have_buffer = TRUE;
262 
264 
265  /* set up parameters */
266  params.target = bitmap;
267  params.source = outline;
268  params.flags = FT_RASTER_FLAG_AA;
269 
270 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
271 
272  /* implode outline if needed */
273  {
274  FT_Vector* points = outline->points;
275  FT_Vector* points_end = points + outline->n_points;
276  FT_Vector* vec;
277 
278 
279  if ( hmul )
280  for ( vec = points; vec < points_end; vec++ )
281  vec->x *= 3;
282 
283  if ( vmul )
284  for ( vec = points; vec < points_end; vec++ )
285  vec->y *= 3;
286  }
287 
288  /* render outline into the bitmap */
289  error = render->raster_render( render->raster, &params );
290 
291  /* deflate outline if needed */
292  {
293  FT_Vector* points = outline->points;
294  FT_Vector* points_end = points + outline->n_points;
295  FT_Vector* vec;
296 
297 
298  if ( hmul )
299  for ( vec = points; vec < points_end; vec++ )
300  vec->x /= 3;
301 
302  if ( vmul )
303  for ( vec = points; vec < points_end; vec++ )
304  vec->y /= 3;
305  }
306 
307  if ( error )
308  goto Exit;
309 
310  if ( slot->library->lcd_filter_func )
311  slot->library->lcd_filter_func( bitmap, mode, slot->library );
312 
313 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
314 
315  /* render outline into bitmap */
316  error = render->raster_render( render->raster, &params );
317  if ( error )
318  goto Exit;
319 
320  /* expand it horizontally */
321  if ( hmul )
322  {
323  FT_Byte* line = bitmap->buffer;
324  FT_UInt hh;
325 
326 
327  for ( hh = height_org; hh > 0; hh--, line += pitch )
328  {
329  FT_UInt xx;
330  FT_Byte* end = line + width;
331 
332 
333  for ( xx = width_org; xx > 0; xx-- )
334  {
335  FT_UInt pixel = line[xx-1];
336 
337 
338  end[-3] = (FT_Byte)pixel;
339  end[-2] = (FT_Byte)pixel;
340  end[-1] = (FT_Byte)pixel;
341  end -= 3;
342  }
343  }
344  }
345 
346  /* expand it vertically */
347  if ( vmul )
348  {
349  FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch;
350  FT_Byte* write = bitmap->buffer;
351  FT_UInt hh;
352 
353 
354  for ( hh = height_org; hh > 0; hh-- )
355  {
356  ft_memcpy( write, read, pitch );
357  write += pitch;
358 
359  ft_memcpy( write, read, pitch );
360  write += pitch;
361 
362  ft_memcpy( write, read, pitch );
363  write += pitch;
364  read += pitch;
365  }
366  }
367 
368 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
369 
370  /*
371  * XXX: on 16bit system, we return an error for huge bitmap
372  * to prevent an overflow.
373  */
374  if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX )
375  {
376  error = FT_THROW( Invalid_Pixel_Size );
377  goto Exit;
378  }
379 
380  slot->format = FT_GLYPH_FORMAT_BITMAP;
381  slot->bitmap_left = (FT_Int)x_left;
382  slot->bitmap_top = (FT_Int)y_top;
383 
384  /* everything is fine; don't deallocate buffer */
385  have_buffer = FALSE;
386 
387  error = FT_Err_Ok;
388 
389  Exit:
390  if ( have_outline_shifted )
391  FT_Outline_Translate( outline, x_shift, y_shift );
392  if ( have_translated_origin )
393  FT_Outline_Translate( outline, -origin->x, -origin->y );
394  if ( have_buffer )
395  {
396  FT_FREE( bitmap->buffer );
398  }
399 
400  return error;
401  }
402 
403 
404  /* convert a slot's glyph image into a bitmap */
405  static FT_Error
406  ft_smooth_render( FT_Renderer render,
407  FT_GlyphSlot slot,
408  FT_Render_Mode mode,
409  const FT_Vector* origin )
410  {
411  if ( mode == FT_RENDER_MODE_LIGHT )
412  mode = FT_RENDER_MODE_NORMAL;
413 
414  return ft_smooth_render_generic( render, slot, mode, origin,
416  }
417 
418 
419  /* convert a slot's glyph image into a horizontal LCD bitmap */
420  static FT_Error
422  FT_GlyphSlot slot,
423  FT_Render_Mode mode,
424  const FT_Vector* origin )
425  {
426  FT_Error error;
427 
428  error = ft_smooth_render_generic( render, slot, mode, origin,
430  if ( !error )
432 
433  return error;
434  }
435 
436 
437  /* convert a slot's glyph image into a vertical LCD bitmap */
438  static FT_Error
439  ft_smooth_render_lcd_v( FT_Renderer render,
440  FT_GlyphSlot slot,
441  FT_Render_Mode mode,
442  const FT_Vector* origin )
443  {
444  FT_Error error;
445 
446  error = ft_smooth_render_generic( render, slot, mode, origin,
448  if ( !error )
450 
451  return error;
452  }
453 
454 
455  FT_DEFINE_RENDERER( ft_smooth_renderer_class,
456 
458  sizeof ( FT_RendererRec ),
459 
460  "smooth",
461  0x10000L,
462  0x20000L,
463 
464  0, /* module specific interface */
465 
469  ,
470 
472 
473  (FT_Renderer_RenderFunc) ft_smooth_render,
477 
479  )
480 
481 
482  FT_DEFINE_RENDERER( ft_smooth_lcd_renderer_class,
483 
485  sizeof ( FT_RendererRec ),
486 
487  "smooth-lcd",
488  0x10000L,
489  0x20000L,
490 
491  0, /* module specific interface */
492 
493  (FT_Module_Constructor)ft_smooth_init,
496  ,
497 
499 
501  (FT_Renderer_TransformFunc)ft_smooth_transform,
502  (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox,
503  (FT_Renderer_SetModeFunc) ft_smooth_set_mode,
504 
506  )
507 
508  FT_DEFINE_RENDERER( ft_smooth_lcdv_renderer_class,
509 
511  sizeof ( FT_RendererRec ),
512 
513  "smooth-lcdv",
514  0x10000L,
515  0x20000L,
516 
517  0, /* module specific interface */
518 
519  (FT_Module_Constructor)ft_smooth_init,
522  ,
523 
525 
526  (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v,
527  (FT_Renderer_TransformFunc)ft_smooth_transform,
528  (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox,
529  (FT_Renderer_SetModeFunc) ft_smooth_set_mode,
530 
532  )
533 
534 
535 /* END */
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:260
GLint GLint GLsizei GLsizei height
#define FT_PIX_CEIL(x)
Definition: ftobjs.h:82
int FT_Error
Definition: fttypes.h:296
FT_ULong raster_pool_size
Definition: ftobjs.h:875
FT_Raster_Render_Func raster_render
Definition: ftobjs.h:700
smooth FT_Module_Constructor FT_Renderer_RenderFunc FT_Renderer_TransformFunc ft_smooth_transform
Definition: ftsmooth.c:487
FT_Error(* FT_Module_Constructor)(FT_Module module)
Definition: ftmodapi.h:121
unsigned long FT_ULong
Definition: fttypes.h:249
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:59
GLsizei const GLfloat * points
int write(int fd, const char *buf, int nbytes)
Definition: tif_acorn.c:325
int read(int fd, char *buf, int nbytes)
Definition: tif_acorn.c:331
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:208
#define NULL
Definition: ftobjs.h:61
smooth FT_Module_Constructor FT_GLYPH_FORMAT_OUTLINE
Definition: ftsmooth.c:487
signed int FT_Int
Definition: fttypes.h:216
int rows
Definition: ftimage.h:312
enum FT_Render_Mode_ FT_Render_Mode
return FT_THROW(Missing_Property)
unsigned char * buffer
Definition: ftimage.h:315
voidpf uLong int origin
Definition: ioapi.h:142
const FT_Bitmap * target
Definition: ftimage.h:1106
#define FT_RASTER_FLAG_AA
Definition: ftimage.h:1043
GLint GLint GLsizei width
FT_Int bitmap_top
Definition: freetype.h:1629
FT_Library library
Definition: cffdrivr.c:414
int pitch
Definition: ftimage.h:314
FT_Library library
Definition: freetype.h:1614
smooth FT_Module_Constructor FT_Renderer_RenderFunc FT_Renderer_TransformFunc FT_Renderer_GetCBoxFunc ft_smooth_get_cbox
Definition: ftsmooth.c:487
return FT_Err_Ok
Definition: ftbbox.c:645
FT_Raster raster
Definition: ftobjs.h:699
#define FT_GLYPH_OWN_BITMAP
Definition: ftobjs.h:409
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
void(* FT_Renderer_GetCBoxFunc)(FT_Renderer renderer, FT_GlyphSlot slot, FT_BBox *cbox)
Definition: ftrender.h:101
FT_Outline outline
Definition: freetype.h:1631
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define FT_PAD_CEIL(x, n)
Definition: ftobjs.h:78
unsigned char FT_Byte
Definition: fttypes.h:150
FT_ModuleRec root
Definition: ftobjs.h:694
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:468
FT_Bitmap bitmap
Definition: freetype.h:1627
#define FT_PIX_FLOOR(x)
Definition: ftobjs.h:80
#define FT_FREE(ptr)
Definition: ftmemory.h:286
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:703
FT_Raster_Funcs * raster_class
Definition: ftrender.h:155
FT_Pos yMax
Definition: ftimage.h:119
smooth FT_Module_Constructor FT_Renderer_RenderFunc ft_smooth_render_lcd
Definition: ftsmooth.c:487
FT_Pos xMin
Definition: ftimage.h:118
GLenum mode
smooth FT_Module_Constructor ft_smooth_init
Definition: ftsmooth.c:487
smooth FT_Module_Constructor FT_Renderer_RenderFunc FT_Renderer_TransformFunc FT_Renderer_GetCBoxFunc FT_Renderer_SetModeFunc ft_smooth_set_mode
Definition: ftsmooth.c:487
FT_Raster_ResetFunc raster_reset
Definition: ftimage.h:1292
FT_Error error
Definition: cffdrivr.c:411
FT_Pos x
Definition: ftimage.h:77
FT_DEFINE_RENDERER(ft_smooth_renderer_class, FT_MODULE_RENDERER, sizeof(FT_RendererRec), "smooth", 0x10000L, 0x20000L, 0,(FT_Module_Constructor) ft_smooth_init,(FT_Module_Destructor) 0,(FT_Module_Requester) 0, 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
GLsizei GLsizei GLenum GLenum const GLvoid * data
void * FT_Pointer
Definition: fttypes.h:307
FT_Raster_SetModeFunc raster_set_mode
Definition: ftimage.h:1293
FT_Pos y
Definition: ftimage.h:78
#define FT_MODULE_LIBRARY(x)
Definition: ftobjs.h:485
short num_grays
Definition: ftimage.h:316
FT_Vector * vec
Definition: ftbbox.c:566
#define FALSE
Definition: ftobjs.h:57
FT_Pos xMax
Definition: ftimage.h:119
short n_points
Definition: ftimage.h:386
GLuint GLuint end
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
int width
Definition: ftimage.h:313
FT_Glyph_Format glyph_format
Definition: ftobjs.h:696
if(!abbox) return FT_THROW(Invalid_Argument)
GLenum const GLfloat * params
FT_Error(* FT_Renderer_SetModeFunc)(FT_Renderer renderer, FT_ULong mode_tag, FT_Pointer mode_ptr)
Definition: ftrender.h:107
FT_Byte * raster_pool
Definition: ftobjs.h:873
FT_Int bitmap_left
Definition: freetype.h:1628
FT_Glyph_Format format
Definition: freetype.h:1625
FT_Memory memory
Definition: ftobjs.h:477
unsigned int FT_UInt
Definition: fttypes.h:227
FT_Slot_Internal internal
Definition: freetype.h:1644
char pixel_mode
Definition: ftimage.h:317
#define FT_GRAYS_RASTER_GET
Definition: ftspic.h:29
FT_Error(* FT_Renderer_TransformFunc)(FT_Renderer renderer, FT_GlyphSlot slot, const FT_Matrix *matrix, const FT_Vector *delta)
Definition: ftrender.h:94
FT_MODULE_RENDERER
Definition: ftsmooth.c:484
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:518
#define FT_INT_MAX
Definition: ftstdlib.h:64
smooth FT_Module_Constructor FT_Module_Destructor
Definition: ftsmooth.c:487
smooth FT_Module_Constructor FT_Module_Requester
Definition: ftsmooth.c:487
const void * source
Definition: ftimage.h:1107
FT_Renderer_Class * clazz
Definition: ftobjs.h:695
FT_Pos yMin
Definition: ftimage.h:118
#define ft_memcpy
Definition: ftstdlib.h:81
GLuint GLenum matrix
#define TRUE
Definition: ftobjs.h:53
FT_Vector * points
Definition: ftimage.h:388
FT_Error(* FT_Renderer_RenderFunc)(FT_Renderer renderer, FT_GlyphSlot slot, FT_UInt mode, const FT_Vector *origin)
Definition: ftrender.h:88