1 /***************************************************************************/
5 /* Anti-aliasing renderer interface (body). */
7 /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_OBJECTS_H
30 /* initialize renderer -- init its raster */
32 ft_smooth_init( FT_Renderer render
)
34 FT_Library library
= FT_MODULE_LIBRARY( render
);
37 render
->clazz
->raster_class
->raster_reset( render
->raster
,
39 library
->raster_pool_size
);
45 /* sets render-specific mode */
47 ft_smooth_set_mode( FT_Renderer render
,
51 /* we simply pass it to the raster */
52 return render
->clazz
->raster_class
->raster_set_mode( render
->raster
,
57 /* transform a given glyph image */
59 ft_smooth_transform( FT_Renderer render
,
61 const FT_Matrix
* matrix
,
62 const FT_Vector
* delta
)
64 FT_Error error
= Smooth_Err_Ok
;
67 if ( slot
->format
!= render
->glyph_format
)
69 error
= Smooth_Err_Invalid_Argument
;
74 FT_Outline_Transform( &slot
->outline
, matrix
);
77 FT_Outline_Translate( &slot
->outline
, delta
->x
, delta
->y
);
84 /* return the glyph's control box */
86 ft_smooth_get_cbox( FT_Renderer render
,
90 FT_MEM_ZERO( cbox
, sizeof ( *cbox
) );
92 if ( slot
->format
== render
->glyph_format
)
93 FT_Outline_Get_CBox( &slot
->outline
, cbox
);
97 /* convert a slot's glyph image into a bitmap */
99 ft_smooth_render_generic( FT_Renderer render
,
102 const FT_Vector
* origin
,
103 FT_Render_Mode required_mode
)
106 FT_Outline
* outline
= NULL
;
108 FT_UInt width
, height
, height_org
, width_org
, pitch
;
111 FT_Int hmul
= mode
== FT_RENDER_MODE_LCD
;
112 FT_Int vmul
= mode
== FT_RENDER_MODE_LCD_V
;
113 FT_Pos x_shift
, y_shift
, x_left
, y_top
;
115 FT_Raster_Params params
;
118 /* check glyph image format */
119 if ( slot
->format
!= render
->glyph_format
)
121 error
= Smooth_Err_Invalid_Argument
;
126 if ( mode
!= required_mode
)
127 return Smooth_Err_Cannot_Render_Glyph
;
129 outline
= &slot
->outline
;
131 /* translate the outline to the new origin if needed */
133 FT_Outline_Translate( outline
, origin
->x
, origin
->y
);
135 /* compute the control box, and grid fit it */
136 FT_Outline_Get_CBox( outline
, &cbox
);
138 cbox
.xMin
= FT_PIX_FLOOR( cbox
.xMin
);
139 cbox
.yMin
= FT_PIX_FLOOR( cbox
.yMin
);
140 cbox
.xMax
= FT_PIX_CEIL( cbox
.xMax
);
141 cbox
.yMax
= FT_PIX_CEIL( cbox
.yMax
);
143 width
= (FT_UInt
)( ( cbox
.xMax
- cbox
.xMin
) >> 6 );
144 height
= (FT_UInt
)( ( cbox
.yMax
- cbox
.yMin
) >> 6 );
145 bitmap
= &slot
->bitmap
;
146 memory
= render
->root
.memory
;
151 /* release old bitmap buffer */
152 if ( slot
->internal
->flags
& FT_GLYPH_OWN_BITMAP
)
154 FT_FREE( bitmap
->buffer
);
155 slot
->internal
->flags
&= ~FT_GLYPH_OWN_BITMAP
;
158 /* allocate new one */
163 pitch
= FT_PAD_CEIL( width
, 4 );
169 x_shift
= (FT_Int
) cbox
.xMin
;
170 y_shift
= (FT_Int
) cbox
.yMin
;
171 x_left
= (FT_Int
)( cbox
.xMin
>> 6 );
172 y_top
= (FT_Int
)( cbox
.yMax
>> 6 );
174 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
176 if ( slot
->library
->lcd_filter_func
)
178 FT_Int extra
= slot
->library
->lcd_extra
;
183 x_shift
-= 64 * ( extra
>> 1 );
185 pitch
= FT_PAD_CEIL( width
, 4 );
186 x_left
-= extra
>> 1;
191 y_shift
-= 64 * ( extra
>> 1 );
199 #if FT_UINT_MAX > 0xFFFFU
201 /* Required check is ( pitch * height < FT_ULONG_MAX ), */
202 /* but we care realistic cases only. Always pitch <= width. */
203 if ( width
> 0xFFFFU
|| height
> 0xFFFFU
)
205 FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n",
207 return Smooth_Err_Raster_Overflow
;
212 bitmap
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
213 bitmap
->num_grays
= 256;
214 bitmap
->width
= width
;
215 bitmap
->rows
= height
;
216 bitmap
->pitch
= pitch
;
218 /* translate outline to render it into the bitmap */
219 FT_Outline_Translate( outline
, -x_shift
, -y_shift
);
221 if ( FT_ALLOC( bitmap
->buffer
, (FT_ULong
)pitch
* height
) )
224 slot
->internal
->flags
|= FT_GLYPH_OWN_BITMAP
;
226 /* set up parameters */
227 params
.target
= bitmap
;
228 params
.source
= outline
;
229 params
.flags
= FT_RASTER_FLAG_AA
;
231 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
233 /* implode outline if needed */
235 FT_Vector
* points
= outline
->points
;
236 FT_Vector
* points_end
= points
+ outline
->n_points
;
241 for ( vec
= points
; vec
< points_end
; vec
++ )
245 for ( vec
= points
; vec
< points_end
; vec
++ )
249 /* render outline into the bitmap */
250 error
= render
->raster_render( render
->raster
, ¶ms
);
252 /* deflate outline if needed */
254 FT_Vector
* points
= outline
->points
;
255 FT_Vector
* points_end
= points
+ outline
->n_points
;
260 for ( vec
= points
; vec
< points_end
; vec
++ )
264 for ( vec
= points
; vec
< points_end
; vec
++ )
268 if ( slot
->library
->lcd_filter_func
)
269 slot
->library
->lcd_filter_func( bitmap
, mode
, slot
->library
);
271 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
273 /* render outline into bitmap */
274 error
= render
->raster_render( render
->raster
, ¶ms
);
276 /* expand it horizontally */
279 FT_Byte
* line
= bitmap
->buffer
;
283 for ( hh
= height_org
; hh
> 0; hh
--, line
+= pitch
)
286 FT_Byte
* end
= line
+ width
;
289 for ( xx
= width_org
; xx
> 0; xx
-- )
291 FT_UInt pixel
= line
[xx
-1];
294 end
[-3] = (FT_Byte
)pixel
;
295 end
[-2] = (FT_Byte
)pixel
;
296 end
[-1] = (FT_Byte
)pixel
;
302 /* expand it vertically */
305 FT_Byte
* read
= bitmap
->buffer
+ ( height
- height_org
) * pitch
;
306 FT_Byte
* write
= bitmap
->buffer
;
310 for ( hh
= height_org
; hh
> 0; hh
-- )
312 ft_memcpy( write
, read
, pitch
);
315 ft_memcpy( write
, read
, pitch
);
318 ft_memcpy( write
, read
, pitch
);
324 #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
326 FT_Outline_Translate( outline
, x_shift
, y_shift
);
329 * XXX: on 16bit system, we return an error for huge bitmap
330 * to prevent an overflow.
332 if ( x_left
> FT_INT_MAX
|| y_top
> FT_INT_MAX
)
333 return Smooth_Err_Invalid_Pixel_Size
;
338 slot
->format
= FT_GLYPH_FORMAT_BITMAP
;
339 slot
->bitmap_left
= (FT_Int
)x_left
;
340 slot
->bitmap_top
= (FT_Int
)y_top
;
343 if ( outline
&& origin
)
344 FT_Outline_Translate( outline
, -origin
->x
, -origin
->y
);
350 /* convert a slot's glyph image into a bitmap */
352 ft_smooth_render( FT_Renderer render
,
355 const FT_Vector
* origin
)
357 if ( mode
== FT_RENDER_MODE_LIGHT
)
358 mode
= FT_RENDER_MODE_NORMAL
;
360 return ft_smooth_render_generic( render
, slot
, mode
, origin
,
361 FT_RENDER_MODE_NORMAL
);
365 /* convert a slot's glyph image into a horizontal LCD bitmap */
367 ft_smooth_render_lcd( FT_Renderer render
,
370 const FT_Vector
* origin
)
374 error
= ft_smooth_render_generic( render
, slot
, mode
, origin
,
375 FT_RENDER_MODE_LCD
);
377 slot
->bitmap
.pixel_mode
= FT_PIXEL_MODE_LCD
;
383 /* convert a slot's glyph image into a vertical LCD bitmap */
385 ft_smooth_render_lcd_v( FT_Renderer render
,
388 const FT_Vector
* origin
)
392 error
= ft_smooth_render_generic( render
, slot
, mode
, origin
,
393 FT_RENDER_MODE_LCD_V
);
395 slot
->bitmap
.pixel_mode
= FT_PIXEL_MODE_LCD_V
;
401 FT_DEFINE_RENDERER(ft_smooth_renderer_class
,
404 sizeof( FT_RendererRec
),
410 0, /* module specific interface */
412 (FT_Module_Constructor
)ft_smooth_init
,
413 (FT_Module_Destructor
) 0,
414 (FT_Module_Requester
) 0
417 FT_GLYPH_FORMAT_OUTLINE
,
419 (FT_Renderer_RenderFunc
) ft_smooth_render
,
420 (FT_Renderer_TransformFunc
)ft_smooth_transform
,
421 (FT_Renderer_GetCBoxFunc
) ft_smooth_get_cbox
,
422 (FT_Renderer_SetModeFunc
) ft_smooth_set_mode
,
424 (FT_Raster_Funcs
*) &FT_GRAYS_RASTER_GET
428 FT_DEFINE_RENDERER(ft_smooth_lcd_renderer_class
,
431 sizeof( FT_RendererRec
),
437 0, /* module specific interface */
439 (FT_Module_Constructor
)ft_smooth_init
,
440 (FT_Module_Destructor
) 0,
441 (FT_Module_Requester
) 0
444 FT_GLYPH_FORMAT_OUTLINE
,
446 (FT_Renderer_RenderFunc
) ft_smooth_render_lcd
,
447 (FT_Renderer_TransformFunc
)ft_smooth_transform
,
448 (FT_Renderer_GetCBoxFunc
) ft_smooth_get_cbox
,
449 (FT_Renderer_SetModeFunc
) ft_smooth_set_mode
,
451 (FT_Raster_Funcs
*) &FT_GRAYS_RASTER_GET
454 FT_DEFINE_RENDERER(ft_smooth_lcdv_renderer_class
,
457 sizeof( FT_RendererRec
),
463 0, /* module specific interface */
465 (FT_Module_Constructor
)ft_smooth_init
,
466 (FT_Module_Destructor
) 0,
467 (FT_Module_Requester
) 0
470 FT_GLYPH_FORMAT_OUTLINE
,
472 (FT_Renderer_RenderFunc
) ft_smooth_render_lcd_v
,
473 (FT_Renderer_TransformFunc
)ft_smooth_transform
,
474 (FT_Renderer_GetCBoxFunc
) ft_smooth_get_cbox
,
475 (FT_Renderer_SetModeFunc
) ft_smooth_set_mode
,
477 (FT_Raster_Funcs
*) &FT_GRAYS_RASTER_GET