1 /***************************************************************************/
5 /* FreeType convenience functions to handle glyphs (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007, 2008 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 /***************************************************************************/
18 /*************************************************************************/
20 /* This file contains the definition of several convenience functions */
21 /* that can be used by client applications to easily retrieve glyph */
22 /* bitmaps and outlines from a given face. */
24 /* These functions should be optional if you are writing a font server */
25 /* or text layout engine on top of FreeType. However, they are pretty */
26 /* handy for many other simple uses of the library. */
28 /*************************************************************************/
35 #include FT_INTERNAL_OBJECTS_H
38 /*************************************************************************/
40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
42 /* messages during execution. */
45 #define FT_COMPONENT trace_glyph
48 /*************************************************************************/
49 /*************************************************************************/
51 /**** FT_BitmapGlyph support ****/
53 /*************************************************************************/
54 /*************************************************************************/
56 FT_CALLBACK_DEF( FT_Error
)
57 ft_bitmap_glyph_init( FT_Glyph bitmap_glyph
,
60 FT_BitmapGlyph glyph
= (FT_BitmapGlyph
)bitmap_glyph
;
61 FT_Error error
= FT_Err_Ok
;
62 FT_Library library
= FT_GLYPH( glyph
)->library
;
65 if ( slot
->format
!= FT_GLYPH_FORMAT_BITMAP
)
67 error
= FT_Err_Invalid_Glyph_Format
;
71 glyph
->left
= slot
->bitmap_left
;
72 glyph
->top
= slot
->bitmap_top
;
74 /* do lazy copying whenever possible */
75 if ( slot
->internal
->flags
& FT_GLYPH_OWN_BITMAP
)
77 glyph
->bitmap
= slot
->bitmap
;
78 slot
->internal
->flags
&= ~FT_GLYPH_OWN_BITMAP
;
82 FT_Bitmap_New( &glyph
->bitmap
);
83 error
= FT_Bitmap_Copy( library
, &slot
->bitmap
, &glyph
->bitmap
);
91 FT_CALLBACK_DEF( FT_Error
)
92 ft_bitmap_glyph_copy( FT_Glyph bitmap_source
,
93 FT_Glyph bitmap_target
)
95 FT_Library library
= bitmap_source
->library
;
96 FT_BitmapGlyph source
= (FT_BitmapGlyph
)bitmap_source
;
97 FT_BitmapGlyph target
= (FT_BitmapGlyph
)bitmap_target
;
100 target
->left
= source
->left
;
101 target
->top
= source
->top
;
103 return FT_Bitmap_Copy( library
, &source
->bitmap
, &target
->bitmap
);
107 FT_CALLBACK_DEF( void )
108 ft_bitmap_glyph_done( FT_Glyph bitmap_glyph
)
110 FT_BitmapGlyph glyph
= (FT_BitmapGlyph
)bitmap_glyph
;
111 FT_Library library
= FT_GLYPH( glyph
)->library
;
114 FT_Bitmap_Done( library
, &glyph
->bitmap
);
118 FT_CALLBACK_DEF( void )
119 ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph
,
122 FT_BitmapGlyph glyph
= (FT_BitmapGlyph
)bitmap_glyph
;
125 cbox
->xMin
= glyph
->left
<< 6;
126 cbox
->xMax
= cbox
->xMin
+ ( glyph
->bitmap
.width
<< 6 );
127 cbox
->yMax
= glyph
->top
<< 6;
128 cbox
->yMin
= cbox
->yMax
- ( glyph
->bitmap
.rows
<< 6 );
132 FT_CALLBACK_TABLE_DEF
133 const FT_Glyph_Class ft_bitmap_glyph_class
=
135 sizeof ( FT_BitmapGlyphRec
),
136 FT_GLYPH_FORMAT_BITMAP
,
138 ft_bitmap_glyph_init
,
139 ft_bitmap_glyph_done
,
140 ft_bitmap_glyph_copy
,
141 0, /* FT_Glyph_TransformFunc */
142 ft_bitmap_glyph_bbox
,
143 0 /* FT_Glyph_PrepareFunc */
147 /*************************************************************************/
148 /*************************************************************************/
150 /**** FT_OutlineGlyph support ****/
152 /*************************************************************************/
153 /*************************************************************************/
156 FT_CALLBACK_DEF( FT_Error
)
157 ft_outline_glyph_init( FT_Glyph outline_glyph
,
160 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
161 FT_Error error
= FT_Err_Ok
;
162 FT_Library library
= FT_GLYPH( glyph
)->library
;
163 FT_Outline
* source
= &slot
->outline
;
164 FT_Outline
* target
= &glyph
->outline
;
167 /* check format in glyph slot */
168 if ( slot
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
170 error
= FT_Err_Invalid_Glyph_Format
;
174 /* allocate new outline */
175 error
= FT_Outline_New( library
, source
->n_points
, source
->n_contours
,
180 FT_Outline_Copy( source
, target
);
187 FT_CALLBACK_DEF( void )
188 ft_outline_glyph_done( FT_Glyph outline_glyph
)
190 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
193 FT_Outline_Done( FT_GLYPH( glyph
)->library
, &glyph
->outline
);
197 FT_CALLBACK_DEF( FT_Error
)
198 ft_outline_glyph_copy( FT_Glyph outline_source
,
199 FT_Glyph outline_target
)
201 FT_OutlineGlyph source
= (FT_OutlineGlyph
)outline_source
;
202 FT_OutlineGlyph target
= (FT_OutlineGlyph
)outline_target
;
204 FT_Library library
= FT_GLYPH( source
)->library
;
207 error
= FT_Outline_New( library
, source
->outline
.n_points
,
208 source
->outline
.n_contours
, &target
->outline
);
210 FT_Outline_Copy( &source
->outline
, &target
->outline
);
216 FT_CALLBACK_DEF( void )
217 ft_outline_glyph_transform( FT_Glyph outline_glyph
,
218 const FT_Matrix
* matrix
,
219 const FT_Vector
* delta
)
221 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
225 FT_Outline_Transform( &glyph
->outline
, matrix
);
228 FT_Outline_Translate( &glyph
->outline
, delta
->x
, delta
->y
);
232 FT_CALLBACK_DEF( void )
233 ft_outline_glyph_bbox( FT_Glyph outline_glyph
,
236 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
239 FT_Outline_Get_CBox( &glyph
->outline
, bbox
);
243 FT_CALLBACK_DEF( FT_Error
)
244 ft_outline_glyph_prepare( FT_Glyph outline_glyph
,
247 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
250 slot
->format
= FT_GLYPH_FORMAT_OUTLINE
;
251 slot
->outline
= glyph
->outline
;
252 slot
->outline
.flags
&= ~FT_OUTLINE_OWNER
;
258 FT_CALLBACK_TABLE_DEF
259 const FT_Glyph_Class ft_outline_glyph_class
=
261 sizeof ( FT_OutlineGlyphRec
),
262 FT_GLYPH_FORMAT_OUTLINE
,
264 ft_outline_glyph_init
,
265 ft_outline_glyph_done
,
266 ft_outline_glyph_copy
,
267 ft_outline_glyph_transform
,
268 ft_outline_glyph_bbox
,
269 ft_outline_glyph_prepare
273 /*************************************************************************/
274 /*************************************************************************/
276 /**** FT_Glyph class and API ****/
278 /*************************************************************************/
279 /*************************************************************************/
282 ft_new_glyph( FT_Library library
,
283 const FT_Glyph_Class
* clazz
,
286 FT_Memory memory
= library
->memory
;
293 if ( !FT_ALLOC( glyph
, clazz
->glyph_size
) )
295 glyph
->library
= library
;
296 glyph
->clazz
= clazz
;
297 glyph
->format
= clazz
->glyph_format
;
306 /* documentation is in ftglyph.h */
308 FT_EXPORT_DEF( FT_Error
)
309 FT_Glyph_Copy( FT_Glyph source
,
314 const FT_Glyph_Class
* clazz
;
317 /* check arguments */
320 error
= FT_Err_Invalid_Argument
;
326 if ( !source
|| !source
->clazz
)
328 error
= FT_Err_Invalid_Argument
;
332 clazz
= source
->clazz
;
333 error
= ft_new_glyph( source
->library
, clazz
, ©
);
337 copy
->advance
= source
->advance
;
338 copy
->format
= source
->format
;
340 if ( clazz
->glyph_copy
)
341 error
= clazz
->glyph_copy( source
, copy
);
344 FT_Done_Glyph( copy
);
353 /* documentation is in ftglyph.h */
355 FT_EXPORT_DEF( FT_Error
)
356 FT_Get_Glyph( FT_GlyphSlot slot
,
363 const FT_Glyph_Class
* clazz
= 0;
367 return FT_Err_Invalid_Slot_Handle
;
369 library
= slot
->library
;
372 return FT_Err_Invalid_Argument
;
374 /* if it is a bitmap, that's easy :-) */
375 if ( slot
->format
== FT_GLYPH_FORMAT_BITMAP
)
376 clazz
= &ft_bitmap_glyph_class
;
378 /* it it is an outline too */
379 else if ( slot
->format
== FT_GLYPH_FORMAT_OUTLINE
)
380 clazz
= &ft_outline_glyph_class
;
384 /* try to find a renderer that supports the glyph image format */
385 FT_Renderer render
= FT_Lookup_Renderer( library
, slot
->format
, 0 );
389 clazz
= &render
->glyph_class
;
394 error
= FT_Err_Invalid_Glyph_Format
;
398 /* create FT_Glyph object */
399 error
= ft_new_glyph( library
, clazz
, &glyph
);
403 /* copy advance while converting it to 16.16 format */
404 glyph
->advance
.x
= slot
->advance
.x
<< 10;
405 glyph
->advance
.y
= slot
->advance
.y
<< 10;
407 /* now import the image from the glyph slot */
408 error
= clazz
->glyph_init( glyph
, slot
);
410 /* if an error occurred, destroy the glyph */
412 FT_Done_Glyph( glyph
);
421 /* documentation is in ftglyph.h */
423 FT_EXPORT_DEF( FT_Error
)
424 FT_Glyph_Transform( FT_Glyph glyph
,
428 const FT_Glyph_Class
* clazz
;
429 FT_Error error
= FT_Err_Ok
;
432 if ( !glyph
|| !glyph
->clazz
)
433 error
= FT_Err_Invalid_Argument
;
436 clazz
= glyph
->clazz
;
437 if ( clazz
->glyph_transform
)
439 /* transform glyph image */
440 clazz
->glyph_transform( glyph
, matrix
, delta
);
442 /* transform advance vector */
444 FT_Vector_Transform( &glyph
->advance
, matrix
);
447 error
= FT_Err_Invalid_Glyph_Format
;
453 /* documentation is in ftglyph.h */
455 FT_EXPORT_DEF( void )
456 FT_Glyph_Get_CBox( FT_Glyph glyph
,
460 const FT_Glyph_Class
* clazz
;
466 acbox
->xMin
= acbox
->yMin
= acbox
->xMax
= acbox
->yMax
= 0;
468 if ( !glyph
|| !glyph
->clazz
)
472 clazz
= glyph
->clazz
;
473 if ( !clazz
->glyph_bbox
)
477 /* retrieve bbox in 26.6 coordinates */
478 clazz
->glyph_bbox( glyph
, acbox
);
480 /* perform grid fitting if needed */
481 if ( bbox_mode
== FT_GLYPH_BBOX_GRIDFIT
||
482 bbox_mode
== FT_GLYPH_BBOX_PIXELS
)
484 acbox
->xMin
= FT_PIX_FLOOR( acbox
->xMin
);
485 acbox
->yMin
= FT_PIX_FLOOR( acbox
->yMin
);
486 acbox
->xMax
= FT_PIX_CEIL( acbox
->xMax
);
487 acbox
->yMax
= FT_PIX_CEIL( acbox
->yMax
);
490 /* convert to integer pixels if needed */
491 if ( bbox_mode
== FT_GLYPH_BBOX_TRUNCATE
||
492 bbox_mode
== FT_GLYPH_BBOX_PIXELS
)
505 /* documentation is in ftglyph.h */
507 FT_EXPORT_DEF( FT_Error
)
508 FT_Glyph_To_Bitmap( FT_Glyph
* the_glyph
,
509 FT_Render_Mode render_mode
,
513 FT_GlyphSlotRec dummy
;
514 FT_GlyphSlot_InternalRec dummy_internal
;
515 FT_Error error
= FT_Err_Ok
;
517 FT_BitmapGlyph bitmap
= NULL
;
519 const FT_Glyph_Class
* clazz
;
526 /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
527 /* then calling FT_Render_Glyph_Internal() */
533 clazz
= glyph
->clazz
;
535 /* when called with a bitmap glyph, do nothing and return successfully */
536 if ( clazz
== &ft_bitmap_glyph_class
)
539 if ( !clazz
|| !clazz
->glyph_prepare
)
542 FT_MEM_ZERO( &dummy
, sizeof ( dummy
) );
543 FT_MEM_ZERO( &dummy_internal
, sizeof ( dummy_internal
) );
544 dummy
.internal
= &dummy_internal
;
545 dummy
.library
= glyph
->library
;
546 dummy
.format
= clazz
->glyph_format
;
548 /* create result bitmap glyph */
549 error
= ft_new_glyph( glyph
->library
, &ft_bitmap_glyph_class
,
550 (FT_Glyph
*)(void*)&bitmap
);
555 /* if `origin' is set, translate the glyph image */
557 FT_Glyph_Transform( glyph
, 0, origin
);
562 /* prepare dummy slot for rendering */
563 error
= clazz
->glyph_prepare( glyph
, &dummy
);
565 error
= FT_Render_Glyph_Internal( glyph
->library
, &dummy
, render_mode
);
568 if ( !destroy
&& origin
)
575 FT_Glyph_Transform( glyph
, 0, &v
);
582 /* in case of success, copy the bitmap to the glyph bitmap */
583 error
= ft_bitmap_glyph_init( (FT_Glyph
)bitmap
, &dummy
);
588 bitmap
->root
.advance
= glyph
->advance
;
591 FT_Done_Glyph( glyph
);
593 *the_glyph
= FT_GLYPH( bitmap
);
596 if ( error
&& bitmap
)
597 FT_Done_Glyph( FT_GLYPH( bitmap
) );
602 error
= FT_Err_Invalid_Argument
;
607 /* documentation is in ftglyph.h */
609 FT_EXPORT_DEF( void )
610 FT_Done_Glyph( FT_Glyph glyph
)
614 FT_Memory memory
= glyph
->library
->memory
;
615 const FT_Glyph_Class
* clazz
= glyph
->clazz
;
618 if ( clazz
->glyph_done
)
619 clazz
->glyph_done( glyph
);