1 /***************************************************************************/
5 /* FreeType convenience functions to handle glyphs (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007 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 /**** Convenience functions ****/
53 /*************************************************************************/
54 /*************************************************************************/
57 /* documentation is in ftglyph.h */
60 FT_Matrix_Multiply( const FT_Matrix
* a
,
63 FT_Fixed xx
, xy
, yx
, yy
;
69 xx
= FT_MulFix( a
->xx
, b
->xx
) + FT_MulFix( a
->xy
, b
->yx
);
70 xy
= FT_MulFix( a
->xx
, b
->xy
) + FT_MulFix( a
->xy
, b
->yy
);
71 yx
= FT_MulFix( a
->yx
, b
->xx
) + FT_MulFix( a
->yy
, b
->yx
);
72 yy
= FT_MulFix( a
->yx
, b
->xy
) + FT_MulFix( a
->yy
, b
->yy
);
74 b
->xx
= xx
; b
->xy
= xy
;
75 b
->yx
= yx
; b
->yy
= yy
;
79 /* documentation is in ftglyph.h */
81 FT_EXPORT_DEF( FT_Error
)
82 FT_Matrix_Invert( FT_Matrix
* matrix
)
88 return FT_Err_Invalid_Argument
;
90 /* compute discriminant */
91 delta
= FT_MulFix( matrix
->xx
, matrix
->yy
) -
92 FT_MulFix( matrix
->xy
, matrix
->yx
);
95 return FT_Err_Invalid_Argument
; /* matrix can't be inverted */
97 matrix
->xy
= - FT_DivFix( matrix
->xy
, delta
);
98 matrix
->yx
= - FT_DivFix( matrix
->yx
, delta
);
103 matrix
->xx
= FT_DivFix( yy
, delta
);
104 matrix
->yy
= FT_DivFix( xx
, delta
);
110 /*************************************************************************/
111 /*************************************************************************/
113 /**** FT_BitmapGlyph support ****/
115 /*************************************************************************/
116 /*************************************************************************/
118 FT_CALLBACK_DEF( FT_Error
)
119 ft_bitmap_glyph_init( FT_Glyph bitmap_glyph
,
122 FT_BitmapGlyph glyph
= (FT_BitmapGlyph
)bitmap_glyph
;
123 FT_Error error
= FT_Err_Ok
;
124 FT_Library library
= FT_GLYPH( glyph
)->library
;
127 if ( slot
->format
!= FT_GLYPH_FORMAT_BITMAP
)
129 error
= FT_Err_Invalid_Glyph_Format
;
133 glyph
->left
= slot
->bitmap_left
;
134 glyph
->top
= slot
->bitmap_top
;
136 /* do lazy copying whenever possible */
137 if ( slot
->internal
->flags
& FT_GLYPH_OWN_BITMAP
)
139 glyph
->bitmap
= slot
->bitmap
;
140 slot
->internal
->flags
&= ~FT_GLYPH_OWN_BITMAP
;
144 FT_Bitmap_New( &glyph
->bitmap
);
145 error
= FT_Bitmap_Copy( library
, &slot
->bitmap
, &glyph
->bitmap
);
153 FT_CALLBACK_DEF( FT_Error
)
154 ft_bitmap_glyph_copy( FT_Glyph bitmap_source
,
155 FT_Glyph bitmap_target
)
157 FT_Library library
= bitmap_source
->library
;
158 FT_BitmapGlyph source
= (FT_BitmapGlyph
)bitmap_source
;
159 FT_BitmapGlyph target
= (FT_BitmapGlyph
)bitmap_target
;
162 target
->left
= source
->left
;
163 target
->top
= source
->top
;
165 return FT_Bitmap_Copy( library
, &source
->bitmap
, &target
->bitmap
);
169 FT_CALLBACK_DEF( void )
170 ft_bitmap_glyph_done( FT_Glyph bitmap_glyph
)
172 FT_BitmapGlyph glyph
= (FT_BitmapGlyph
)bitmap_glyph
;
173 FT_Library library
= FT_GLYPH( glyph
)->library
;
176 FT_Bitmap_Done( library
, &glyph
->bitmap
);
180 FT_CALLBACK_DEF( void )
181 ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph
,
184 FT_BitmapGlyph glyph
= (FT_BitmapGlyph
)bitmap_glyph
;
187 cbox
->xMin
= glyph
->left
<< 6;
188 cbox
->xMax
= cbox
->xMin
+ ( glyph
->bitmap
.width
<< 6 );
189 cbox
->yMax
= glyph
->top
<< 6;
190 cbox
->yMin
= cbox
->yMax
- ( glyph
->bitmap
.rows
<< 6 );
194 FT_CALLBACK_TABLE_DEF
195 const FT_Glyph_Class ft_bitmap_glyph_class
=
197 sizeof ( FT_BitmapGlyphRec
),
198 FT_GLYPH_FORMAT_BITMAP
,
200 ft_bitmap_glyph_init
,
201 ft_bitmap_glyph_done
,
202 ft_bitmap_glyph_copy
,
203 0, /* FT_Glyph_TransformFunc */
204 ft_bitmap_glyph_bbox
,
205 0 /* FT_Glyph_PrepareFunc */
209 /*************************************************************************/
210 /*************************************************************************/
212 /**** FT_OutlineGlyph support ****/
214 /*************************************************************************/
215 /*************************************************************************/
218 FT_CALLBACK_DEF( FT_Error
)
219 ft_outline_glyph_init( FT_Glyph outline_glyph
,
222 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
223 FT_Error error
= FT_Err_Ok
;
224 FT_Library library
= FT_GLYPH( glyph
)->library
;
225 FT_Outline
* source
= &slot
->outline
;
226 FT_Outline
* target
= &glyph
->outline
;
229 /* check format in glyph slot */
230 if ( slot
->format
!= FT_GLYPH_FORMAT_OUTLINE
)
232 error
= FT_Err_Invalid_Glyph_Format
;
236 /* allocate new outline */
237 error
= FT_Outline_New( library
, source
->n_points
, source
->n_contours
,
242 FT_Outline_Copy( source
, target
);
249 FT_CALLBACK_DEF( void )
250 ft_outline_glyph_done( FT_Glyph outline_glyph
)
252 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
255 FT_Outline_Done( FT_GLYPH( glyph
)->library
, &glyph
->outline
);
259 FT_CALLBACK_DEF( FT_Error
)
260 ft_outline_glyph_copy( FT_Glyph outline_source
,
261 FT_Glyph outline_target
)
263 FT_OutlineGlyph source
= (FT_OutlineGlyph
)outline_source
;
264 FT_OutlineGlyph target
= (FT_OutlineGlyph
)outline_target
;
266 FT_Library library
= FT_GLYPH( source
)->library
;
269 error
= FT_Outline_New( library
, source
->outline
.n_points
,
270 source
->outline
.n_contours
, &target
->outline
);
272 FT_Outline_Copy( &source
->outline
, &target
->outline
);
278 FT_CALLBACK_DEF( void )
279 ft_outline_glyph_transform( FT_Glyph outline_glyph
,
280 const FT_Matrix
* matrix
,
281 const FT_Vector
* delta
)
283 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
287 FT_Outline_Transform( &glyph
->outline
, matrix
);
290 FT_Outline_Translate( &glyph
->outline
, delta
->x
, delta
->y
);
294 FT_CALLBACK_DEF( void )
295 ft_outline_glyph_bbox( FT_Glyph outline_glyph
,
298 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
301 FT_Outline_Get_CBox( &glyph
->outline
, bbox
);
305 FT_CALLBACK_DEF( FT_Error
)
306 ft_outline_glyph_prepare( FT_Glyph outline_glyph
,
309 FT_OutlineGlyph glyph
= (FT_OutlineGlyph
)outline_glyph
;
312 slot
->format
= FT_GLYPH_FORMAT_OUTLINE
;
313 slot
->outline
= glyph
->outline
;
314 slot
->outline
.flags
&= ~FT_OUTLINE_OWNER
;
320 FT_CALLBACK_TABLE_DEF
321 const FT_Glyph_Class ft_outline_glyph_class
=
323 sizeof ( FT_OutlineGlyphRec
),
324 FT_GLYPH_FORMAT_OUTLINE
,
326 ft_outline_glyph_init
,
327 ft_outline_glyph_done
,
328 ft_outline_glyph_copy
,
329 ft_outline_glyph_transform
,
330 ft_outline_glyph_bbox
,
331 ft_outline_glyph_prepare
335 /*************************************************************************/
336 /*************************************************************************/
338 /**** FT_Glyph class and API ****/
340 /*************************************************************************/
341 /*************************************************************************/
344 ft_new_glyph( FT_Library library
,
345 const FT_Glyph_Class
* clazz
,
348 FT_Memory memory
= library
->memory
;
355 if ( !FT_ALLOC( glyph
, clazz
->glyph_size
) )
357 glyph
->library
= library
;
358 glyph
->clazz
= clazz
;
359 glyph
->format
= clazz
->glyph_format
;
368 /* documentation is in ftglyph.h */
370 FT_EXPORT_DEF( FT_Error
)
371 FT_Glyph_Copy( FT_Glyph source
,
376 const FT_Glyph_Class
* clazz
;
381 /* check arguments */
382 if ( !target
|| !source
|| !source
->clazz
)
384 error
= FT_Err_Invalid_Argument
;
388 clazz
= source
->clazz
;
389 error
= ft_new_glyph( source
->library
, clazz
, ©
);
393 copy
->advance
= source
->advance
;
394 copy
->format
= source
->format
;
396 if ( clazz
->glyph_copy
)
397 error
= clazz
->glyph_copy( source
, copy
);
400 FT_Done_Glyph( copy
);
409 /* documentation is in ftglyph.h */
411 FT_EXPORT_DEF( FT_Error
)
412 FT_Get_Glyph( FT_GlyphSlot slot
,
419 const FT_Glyph_Class
* clazz
= 0;
423 return FT_Err_Invalid_Slot_Handle
;
425 library
= slot
->library
;
428 return FT_Err_Invalid_Argument
;
430 /* if it is a bitmap, that's easy :-) */
431 if ( slot
->format
== FT_GLYPH_FORMAT_BITMAP
)
432 clazz
= &ft_bitmap_glyph_class
;
434 /* it it is an outline too */
435 else if ( slot
->format
== FT_GLYPH_FORMAT_OUTLINE
)
436 clazz
= &ft_outline_glyph_class
;
440 /* try to find a renderer that supports the glyph image format */
441 FT_Renderer render
= FT_Lookup_Renderer( library
, slot
->format
, 0 );
445 clazz
= &render
->glyph_class
;
450 error
= FT_Err_Invalid_Glyph_Format
;
454 /* create FT_Glyph object */
455 error
= ft_new_glyph( library
, clazz
, &glyph
);
459 /* copy advance while converting it to 16.16 format */
460 glyph
->advance
.x
= slot
->advance
.x
<< 10;
461 glyph
->advance
.y
= slot
->advance
.y
<< 10;
463 /* now import the image from the glyph slot */
464 error
= clazz
->glyph_init( glyph
, slot
);
466 /* if an error occurred, destroy the glyph */
468 FT_Done_Glyph( glyph
);
477 /* documentation is in ftglyph.h */
479 FT_EXPORT_DEF( FT_Error
)
480 FT_Glyph_Transform( FT_Glyph glyph
,
484 const FT_Glyph_Class
* clazz
;
485 FT_Error error
= FT_Err_Ok
;
488 if ( !glyph
|| !glyph
->clazz
)
489 error
= FT_Err_Invalid_Argument
;
492 clazz
= glyph
->clazz
;
493 if ( clazz
->glyph_transform
)
495 /* transform glyph image */
496 clazz
->glyph_transform( glyph
, matrix
, delta
);
498 /* transform advance vector */
500 FT_Vector_Transform( &glyph
->advance
, matrix
);
503 error
= FT_Err_Invalid_Glyph_Format
;
509 /* documentation is in ftglyph.h */
511 FT_EXPORT_DEF( void )
512 FT_Glyph_Get_CBox( FT_Glyph glyph
,
516 const FT_Glyph_Class
* clazz
;
522 acbox
->xMin
= acbox
->yMin
= acbox
->xMax
= acbox
->yMax
= 0;
524 if ( !glyph
|| !glyph
->clazz
)
528 clazz
= glyph
->clazz
;
529 if ( !clazz
->glyph_bbox
)
533 /* retrieve bbox in 26.6 coordinates */
534 clazz
->glyph_bbox( glyph
, acbox
);
536 /* perform grid fitting if needed */
537 if ( bbox_mode
== FT_GLYPH_BBOX_GRIDFIT
||
538 bbox_mode
== FT_GLYPH_BBOX_PIXELS
)
540 acbox
->xMin
= FT_PIX_FLOOR( acbox
->xMin
);
541 acbox
->yMin
= FT_PIX_FLOOR( acbox
->yMin
);
542 acbox
->xMax
= FT_PIX_CEIL( acbox
->xMax
);
543 acbox
->yMax
= FT_PIX_CEIL( acbox
->yMax
);
546 /* convert to integer pixels if needed */
547 if ( bbox_mode
== FT_GLYPH_BBOX_TRUNCATE
||
548 bbox_mode
== FT_GLYPH_BBOX_PIXELS
)
561 /* documentation is in ftglyph.h */
563 FT_EXPORT_DEF( FT_Error
)
564 FT_Glyph_To_Bitmap( FT_Glyph
* the_glyph
,
565 FT_Render_Mode render_mode
,
569 FT_GlyphSlotRec dummy
;
570 FT_GlyphSlot_InternalRec dummy_internal
;
571 FT_Error error
= FT_Err_Ok
;
573 FT_BitmapGlyph bitmap
= NULL
;
575 const FT_Glyph_Class
* clazz
;
582 /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
583 /* then calling FT_Render_Glyph_Internal() */
589 clazz
= glyph
->clazz
;
591 /* when called with a bitmap glyph, do nothing and return successfully */
592 if ( clazz
== &ft_bitmap_glyph_class
)
595 if ( !clazz
|| !clazz
->glyph_prepare
)
598 FT_MEM_ZERO( &dummy
, sizeof ( dummy
) );
599 FT_MEM_ZERO( &dummy_internal
, sizeof ( dummy_internal
) );
600 dummy
.internal
= &dummy_internal
;
601 dummy
.library
= glyph
->library
;
602 dummy
.format
= clazz
->glyph_format
;
604 /* create result bitmap glyph */
605 error
= ft_new_glyph( glyph
->library
, &ft_bitmap_glyph_class
,
606 (FT_Glyph
*)(void*)&bitmap
);
611 /* if `origin' is set, translate the glyph image */
613 FT_Glyph_Transform( glyph
, 0, origin
);
618 /* prepare dummy slot for rendering */
619 error
= clazz
->glyph_prepare( glyph
, &dummy
);
621 error
= FT_Render_Glyph_Internal( glyph
->library
, &dummy
, render_mode
);
624 if ( !destroy
&& origin
)
631 FT_Glyph_Transform( glyph
, 0, &v
);
638 /* in case of success, copy the bitmap to the glyph bitmap */
639 error
= ft_bitmap_glyph_init( (FT_Glyph
)bitmap
, &dummy
);
644 bitmap
->root
.advance
= glyph
->advance
;
647 FT_Done_Glyph( glyph
);
649 *the_glyph
= FT_GLYPH( bitmap
);
652 if ( error
&& bitmap
)
653 FT_Done_Glyph( FT_GLYPH( bitmap
) );
658 error
= FT_Err_Invalid_Argument
;
663 /* documentation is in ftglyph.h */
665 FT_EXPORT_DEF( void )
666 FT_Done_Glyph( FT_Glyph glyph
)
670 FT_Memory memory
= glyph
->library
->memory
;
671 const FT_Glyph_Class
* clazz
= glyph
->clazz
;
674 if ( clazz
->glyph_done
)
675 clazz
->glyph_done( glyph
);