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
39 /*************************************************************************/
41 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
42 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
43 /* messages during execution. */
46 #define FT_COMPONENT trace_glyph
49 /*************************************************************************/
50 /*************************************************************************/
52 /**** FT_BitmapGlyph support ****/
54 /*************************************************************************/
55 /*************************************************************************/
57 FT_CALLBACK_DEF( FT_Error
)
58 ft_bitmap_glyph_init( FT_Glyph bitmap_glyph
,
61 FT_BitmapGlyph glyph
= (FT_BitmapGlyph
)bitmap_glyph
;
62 FT_Error error
= FT_Err_Ok
;
63 FT_Library library
= FT_GLYPH( glyph
)->library
;
66 if ( slot
->format
!= FT_GLYPH_FORMAT_BITMAP
)
68 error
= FT_Err_Invalid_Glyph_Format
;
72 glyph
->left
= slot
->bitmap_left
;
73 glyph
->top
= slot
->bitmap_top
;
75 /* do lazy copying whenever possible */
76 if ( slot
->internal
->flags
& FT_GLYPH_OWN_BITMAP
)
78 glyph
->bitmap
= slot
->bitmap
;
79 slot
->internal
->flags
&= ~FT_GLYPH_OWN_BITMAP
;
83 FT_Bitmap_New( &glyph
->bitmap
);
84 error
= FT_Bitmap_Copy( library
, &slot
->bitmap
, &glyph
->bitmap
);
92 FT_CALLBACK_DEF( FT_Error
)
93 ft_bitmap_glyph_copy( FT_Glyph bitmap_source
,
94 FT_Glyph bitmap_target
)
96 FT_Library library
= bitmap_source
->library
;
97 FT_BitmapGlyph source
= (FT_BitmapGlyph
)bitmap_source
;
98 FT_BitmapGlyph target
= (FT_BitmapGlyph
)bitmap_target
;
101 target
->left
= source
->left
;
102 target
->top
= source
->top
;
104 return FT_Bitmap_Copy( library
, &source
->bitmap
, &target
->bitmap
);
108 FT_CALLBACK_DEF( void )
109 ft_bitmap_glyph_done( FT_Glyph bitmap_glyph
)
111 FT_BitmapGlyph glyph
= (FT_BitmapGlyph
)bitmap_glyph
;
112 FT_Library library
= FT_GLYPH( glyph
)->library
;
115 FT_Bitmap_Done( library
, &glyph
->bitmap
);
119 FT_CALLBACK_DEF( void )
120 ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph
,
123 FT_BitmapGlyph glyph
= (FT_BitmapGlyph
)bitmap_glyph
;
126 cbox
->xMin
= glyph
->left
<< 6;
127 cbox
->xMax
= cbox
->xMin
+ ( glyph
->bitmap
.width
<< 6 );
128 cbox
->yMax
= glyph
->top
<< 6;
129 cbox
->yMin
= cbox
->yMax
- ( glyph
->bitmap
.rows
<< 6 );
133 FT_DEFINE_GLYPH(ft_bitmap_glyph_class
,
134 sizeof ( FT_BitmapGlyphRec
),
135 FT_GLYPH_FORMAT_BITMAP
,
137 ft_bitmap_glyph_init
,
138 ft_bitmap_glyph_done
,
139 ft_bitmap_glyph_copy
,
140 0, /* FT_Glyph_TransformFunc */
141 ft_bitmap_glyph_bbox
,
142 0 /* FT_Glyph_PrepareFunc */
146 /*************************************************************************/
147 /*************************************************************************/
149 /**** FT_OutlineGlyph support ****/
151 /*************************************************************************/
152 /*************************************************************************/
155 FT_CALLBACK_DEF( FT_Error
)
156 ft_outline_glyph_init( FT_Glyph outline_glyph
,
159 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
160 FT_Error error
= FT_Err_Ok
;
161 FT_Library library
= FT_GLYPH( glyph
)->library
;
162 FT_Outline
* source
= &slot
->outline
;
163 FT_Outline
* target
= &glyph
->outline
;
166 /* check format in glyph slot */
167 if ( slot
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
169 error
= FT_Err_Invalid_Glyph_Format
;
173 /* allocate new outline */
174 error
= FT_Outline_New( library
, source
->n_points
, source
->n_contours
,
179 FT_Outline_Copy( source
, target
);
186 FT_CALLBACK_DEF( void )
187 ft_outline_glyph_done( FT_Glyph outline_glyph
)
189 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
192 FT_Outline_Done( FT_GLYPH( glyph
)->library
, &glyph
->outline
);
196 FT_CALLBACK_DEF( FT_Error
)
197 ft_outline_glyph_copy( FT_Glyph outline_source
,
198 FT_Glyph outline_target
)
200 FT_OutlineGlyph source
= (FT_OutlineGlyph
)outline_source
;
201 FT_OutlineGlyph target
= (FT_OutlineGlyph
)outline_target
;
203 FT_Library library
= FT_GLYPH( source
)->library
;
206 error
= FT_Outline_New( library
, source
->outline
.n_points
,
207 source
->outline
.n_contours
, &target
->outline
);
209 FT_Outline_Copy( &source
->outline
, &target
->outline
);
215 FT_CALLBACK_DEF( void )
216 ft_outline_glyph_transform( FT_Glyph outline_glyph
,
217 const FT_Matrix
* matrix
,
218 const FT_Vector
* delta
)
220 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
224 FT_Outline_Transform( &glyph
->outline
, matrix
);
227 FT_Outline_Translate( &glyph
->outline
, delta
->x
, delta
->y
);
231 FT_CALLBACK_DEF( void )
232 ft_outline_glyph_bbox( FT_Glyph outline_glyph
,
235 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
238 FT_Outline_Get_CBox( &glyph
->outline
, bbox
);
242 FT_CALLBACK_DEF( FT_Error
)
243 ft_outline_glyph_prepare( FT_Glyph outline_glyph
,
246 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
249 slot
->format
= FT_GLYPH_FORMAT_OUTLINE
;
250 slot
->outline
= glyph
->outline
;
251 slot
->outline
.flags
&= ~FT_OUTLINE_OWNER
;
257 FT_DEFINE_GLYPH( ft_outline_glyph_class
,
258 sizeof ( FT_OutlineGlyphRec
),
259 FT_GLYPH_FORMAT_OUTLINE
,
261 ft_outline_glyph_init
,
262 ft_outline_glyph_done
,
263 ft_outline_glyph_copy
,
264 ft_outline_glyph_transform
,
265 ft_outline_glyph_bbox
,
266 ft_outline_glyph_prepare
270 /*************************************************************************/
271 /*************************************************************************/
273 /**** FT_Glyph class and API ****/
275 /*************************************************************************/
276 /*************************************************************************/
279 ft_new_glyph( FT_Library library
,
280 const FT_Glyph_Class
* clazz
,
283 FT_Memory memory
= library
->memory
;
290 if ( !FT_ALLOC( glyph
, clazz
->glyph_size
) )
292 glyph
->library
= library
;
293 glyph
->clazz
= clazz
;
294 glyph
->format
= clazz
->glyph_format
;
303 /* documentation is in ftglyph.h */
305 FT_EXPORT_DEF( FT_Error
)
306 FT_Glyph_Copy( FT_Glyph source
,
311 const FT_Glyph_Class
* clazz
;
314 /* check arguments */
317 error
= FT_Err_Invalid_Argument
;
323 if ( !source
|| !source
->clazz
)
325 error
= FT_Err_Invalid_Argument
;
329 clazz
= source
->clazz
;
330 error
= ft_new_glyph( source
->library
, clazz
, ©
);
334 copy
->advance
= source
->advance
;
335 copy
->format
= source
->format
;
337 if ( clazz
->glyph_copy
)
338 error
= clazz
->glyph_copy( source
, copy
);
341 FT_Done_Glyph( copy
);
350 /* documentation is in ftglyph.h */
352 FT_EXPORT_DEF( FT_Error
)
353 FT_Get_Glyph( FT_GlyphSlot slot
,
360 const FT_Glyph_Class
* clazz
= 0;
364 return FT_Err_Invalid_Slot_Handle
;
366 library
= slot
->library
;
369 return FT_Err_Invalid_Argument
;
371 /* if it is a bitmap, that's easy :-) */
372 if ( slot
->format
== FT_GLYPH_FORMAT_BITMAP
)
373 clazz
= FT_BITMAP_GLYPH_CLASS_GET
;
375 /* if it is an outline */
376 else if ( slot
->format
== FT_GLYPH_FORMAT_OUTLINE
)
377 clazz
= FT_OUTLINE_GLYPH_CLASS_GET
;
381 /* try to find a renderer that supports the glyph image format */
382 FT_Renderer render
= FT_Lookup_Renderer( library
, slot
->format
, 0 );
386 clazz
= &render
->glyph_class
;
391 error
= FT_Err_Invalid_Glyph_Format
;
395 /* create FT_Glyph object */
396 error
= ft_new_glyph( library
, clazz
, &glyph
);
400 /* copy advance while converting it to 16.16 format */
401 glyph
->advance
.x
= slot
->advance
.x
<< 10;
402 glyph
->advance
.y
= slot
->advance
.y
<< 10;
404 /* now import the image from the glyph slot */
405 error
= clazz
->glyph_init( glyph
, slot
);
407 /* if an error occurred, destroy the glyph */
409 FT_Done_Glyph( glyph
);
418 /* documentation is in ftglyph.h */
420 FT_EXPORT_DEF( FT_Error
)
421 FT_Glyph_Transform( FT_Glyph glyph
,
425 const FT_Glyph_Class
* clazz
;
426 FT_Error error
= FT_Err_Ok
;
429 if ( !glyph
|| !glyph
->clazz
)
430 error
= FT_Err_Invalid_Argument
;
433 clazz
= glyph
->clazz
;
434 if ( clazz
->glyph_transform
)
436 /* transform glyph image */
437 clazz
->glyph_transform( glyph
, matrix
, delta
);
439 /* transform advance vector */
441 FT_Vector_Transform( &glyph
->advance
, matrix
);
444 error
= FT_Err_Invalid_Glyph_Format
;
450 /* documentation is in ftglyph.h */
452 FT_EXPORT_DEF( void )
453 FT_Glyph_Get_CBox( FT_Glyph glyph
,
457 const FT_Glyph_Class
* clazz
;
463 acbox
->xMin
= acbox
->yMin
= acbox
->xMax
= acbox
->yMax
= 0;
465 if ( !glyph
|| !glyph
->clazz
)
469 clazz
= glyph
->clazz
;
470 if ( !clazz
->glyph_bbox
)
474 /* retrieve bbox in 26.6 coordinates */
475 clazz
->glyph_bbox( glyph
, acbox
);
477 /* perform grid fitting if needed */
478 if ( bbox_mode
== FT_GLYPH_BBOX_GRIDFIT
||
479 bbox_mode
== FT_GLYPH_BBOX_PIXELS
)
481 acbox
->xMin
= FT_PIX_FLOOR( acbox
->xMin
);
482 acbox
->yMin
= FT_PIX_FLOOR( acbox
->yMin
);
483 acbox
->xMax
= FT_PIX_CEIL( acbox
->xMax
);
484 acbox
->yMax
= FT_PIX_CEIL( acbox
->yMax
);
487 /* convert to integer pixels if needed */
488 if ( bbox_mode
== FT_GLYPH_BBOX_TRUNCATE
||
489 bbox_mode
== FT_GLYPH_BBOX_PIXELS
)
502 /* documentation is in ftglyph.h */
504 FT_EXPORT_DEF( FT_Error
)
505 FT_Glyph_To_Bitmap( FT_Glyph
* the_glyph
,
506 FT_Render_Mode render_mode
,
510 FT_GlyphSlotRec dummy
;
511 FT_GlyphSlot_InternalRec dummy_internal
;
512 FT_Error error
= FT_Err_Ok
;
514 FT_BitmapGlyph bitmap
= NULL
;
516 const FT_Glyph_Class
* clazz
;
518 #ifdef FT_CONFIG_OPTION_PIC
519 FT_Library library
= FT_GLYPH( glyph
)->library
;
527 /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
528 /* then calling FT_Render_Glyph_Internal() */
534 clazz
= glyph
->clazz
;
536 /* when called with a bitmap glyph, do nothing and return successfully */
537 if ( clazz
== FT_BITMAP_GLYPH_CLASS_GET
)
540 if ( !clazz
|| !clazz
->glyph_prepare
)
543 FT_MEM_ZERO( &dummy
, sizeof ( dummy
) );
544 FT_MEM_ZERO( &dummy_internal
, sizeof ( dummy_internal
) );
545 dummy
.internal
= &dummy_internal
;
546 dummy
.library
= glyph
->library
;
547 dummy
.format
= clazz
->glyph_format
;
549 /* create result bitmap glyph */
550 error
= ft_new_glyph( glyph
->library
, FT_BITMAP_GLYPH_CLASS_GET
,
551 (FT_Glyph
*)(void*)&bitmap
);
556 /* if `origin' is set, translate the glyph image */
558 FT_Glyph_Transform( glyph
, 0, origin
);
563 /* prepare dummy slot for rendering */
564 error
= clazz
->glyph_prepare( glyph
, &dummy
);
566 error
= FT_Render_Glyph_Internal( glyph
->library
, &dummy
, render_mode
);
569 if ( !destroy
&& origin
)
576 FT_Glyph_Transform( glyph
, 0, &v
);
583 /* in case of success, copy the bitmap to the glyph bitmap */
584 error
= ft_bitmap_glyph_init( (FT_Glyph
)bitmap
, &dummy
);
589 bitmap
->root
.advance
= glyph
->advance
;
592 FT_Done_Glyph( glyph
);
594 *the_glyph
= FT_GLYPH( bitmap
);
597 if ( error
&& bitmap
)
598 FT_Done_Glyph( FT_GLYPH( bitmap
) );
603 error
= FT_Err_Invalid_Argument
;
608 /* documentation is in ftglyph.h */
610 FT_EXPORT_DEF( void )
611 FT_Done_Glyph( FT_Glyph glyph
)
615 FT_Memory memory
= glyph
->library
->memory
;
616 const FT_Glyph_Class
* clazz
= glyph
->clazz
;
619 if ( clazz
->glyph_done
)
620 clazz
->glyph_done( glyph
);