1 /***************************************************************************/
5 /* The FreeType private base classes (body). */
7 /* Copyright 1996-2000 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 /***************************************************************************/
19 #include <freetype/internal/ftobjs.h>
20 #include <freetype/internal/ftlist.h>
21 #include <freetype/internal/ftdebug.h>
22 #include <freetype/internal/ftstream.h>
24 #include <freetype/tttables.h>
26 #include <string.h> /* for strcmp() */
29 /*************************************************************************/
30 /*************************************************************************/
31 /*************************************************************************/
34 /**** M E M O R Y ****/
37 /*************************************************************************/
38 /*************************************************************************/
39 /*************************************************************************/
41 /*************************************************************************/
43 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
44 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
45 /* messages during execution. */
48 #define FT_COMPONENT trace_memory
51 /*************************************************************************/
57 /* Allocates a new block of memory. The returned area is always */
58 /* zero-filled; this is a strong convention in many FreeType parts. */
61 /* memory :: A handle to a given `memory object' which handles */
64 /* size :: The size in bytes of the block to allocate. */
67 /* P :: A pointer to the fresh new block. It should be set to */
68 /* NULL if `size' is 0, or in case of error. */
71 /* FreeType error code. 0 means success. */
73 BASE_FUNC( FT_Error
) FT_Alloc( FT_Memory memory
,
81 *P
= memory
->alloc( memory
, size
);
84 FT_ERROR(( "FT_Alloc:" ));
85 FT_ERROR(( " Out of memory? (%ld requested)\n",
88 return FT_Err_Out_Of_Memory
;
90 MEM_Set( *P
, 0, size
);
95 FT_TRACE7(( "FT_Alloc:" ));
96 FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n",
103 /*************************************************************************/
109 /* Reallocates a block of memory pointed to by `*P' to `Size' bytes */
110 /* from the heap, possibly changing `*P'. */
113 /* memory :: A handle to a given `memory object' which handles */
116 /* current :: The current block size in bytes. */
118 /* size :: The new block size in bytes. */
121 /* P :: A pointer to the fresh new block. It should be set to */
122 /* NULL if `size' is 0, or in case of error. */
125 /* FreeType error code. 0 means success. */
128 /* All callers of FT_Realloc() _must_ provide the current block size */
129 /* as well as the new one. */
131 BASE_FUNC( FT_Error
) FT_Realloc( FT_Memory memory
,
141 /* if the original pointer is NULL, call FT_Alloc() */
143 return FT_Alloc( memory
, size
, P
);
145 /* if the new block if zero-sized, clear the current one */
148 FT_Free( memory
, P
);
152 Q
= memory
->realloc( memory
, current
, size
, *P
);
160 FT_ERROR(( "FT_Realloc:" ));
161 FT_ERROR(( " Failed (current %ld, requested %ld)\n",
163 return FT_Err_Out_Of_Memory
;
167 /*************************************************************************/
173 /* Releases a given block of memory allocated through FT_Alloc(). */
176 /* memory :: A handle to a given `memory object' which handles */
177 /* memory deallocation */
179 /* P :: This is the _address_ of a _pointer_ which points to the */
180 /* allocated block. It is always set to NULL on exit. */
183 /* FreeType error code. 0 means success. */
186 /* If P or *P are NULL, this function should return successfully. */
187 /* This is a strong convention within all of FreeType and its */
190 BASE_FUNC( void ) FT_Free( FT_Memory memory
,
193 FT_TRACE7(( "FT_Free:" ));
194 FT_TRACE7(( " Freeing block 0x%08p, ref 0x%08p\n",
195 P
, P
? *P
: (void*)0 ));
199 memory
->free( memory
, *P
);
205 /*************************************************************************/
206 /*************************************************************************/
207 /*************************************************************************/
210 /**** S T R E A M ****/
213 /*************************************************************************/
214 /*************************************************************************/
215 /*************************************************************************/
218 /*************************************************************************/
221 /* ft_new_input_stream */
224 /* Creates a new input stream object from an FT_Open_Args structure. */
227 /* The function expects a valid `astream' parameter. */
230 FT_Error
ft_new_input_stream( FT_Library library
,
240 return FT_Err_Invalid_Library_Handle
;
243 return FT_Err_Invalid_Argument
;
246 memory
= library
->memory
;
247 if ( ALLOC( stream
, sizeof ( *stream
) ) )
250 stream
->memory
= memory
;
252 /* now, look at the stream flags */
253 if ( args
->flags
& ft_open_memory
)
256 FT_New_Memory_Stream( library
,
261 else if ( args
->flags
& ft_open_pathname
)
263 error
= FT_New_Stream( args
->pathname
, stream
);
264 stream
->pathname
.pointer
= args
->pathname
;
266 else if ( args
->flags
& ft_open_stream
&& args
->stream
)
268 *stream
= *(args
->stream
);
269 stream
->memory
= memory
;
272 error
= FT_Err_Invalid_Argument
;
284 /*************************************************************************/
290 /* Closes and destroys a stream object. */
293 /* stream :: The stream to be closed and destroyed. */
295 FT_EXPORT_FUNC( void ) FT_Done_Stream( FT_Stream stream
)
297 if ( stream
&& stream
->close
)
298 stream
->close( stream
);
303 void ft_done_stream( FT_Stream
* astream
)
305 FT_Stream stream
= *astream
;
306 FT_Memory memory
= stream
->memory
;
310 stream
->close( stream
);
318 #define FT_COMPONENT trace_objs
321 /*************************************************************************/
322 /*************************************************************************/
323 /*************************************************************************/
326 /**** G L Y P H L O A D E R ****/
329 /*************************************************************************/
330 /*************************************************************************/
331 /*************************************************************************/
334 /*************************************************************************/
336 /* The glyph loader is a simple object which is used to load a set of */
337 /* glyphs easily. It is critical for the correct loading of composites. */
339 /* Ideally, one can see it as a stack of abstract `glyph' objects. */
341 /* loader.base Is really the bottom of the stack. It describes a */
342 /* single glyph image made of the juxtaposition of */
343 /* several glyphs (those `in the stack'). */
345 /* loader.current Describes the top of the stack, on which a new */
346 /* glyph can be loaded. */
348 /* Rewind Clears the stack. */
349 /* Prepare Set up `loader.current' for addition of a new glyph */
351 /* Add Add the `current' glyph image to the `base' one, */
352 /* and prepare for another one. */
354 /* The glyph loader is now a base object. Each driver used to */
355 /* re-implement it in one way or the other, which wasted code and */
358 /*************************************************************************/
361 /* create a new glyph loader */
362 BASE_FUNC( FT_Error
) FT_GlyphLoader_New( FT_Memory memory
,
363 FT_GlyphLoader
** aloader
)
365 FT_GlyphLoader
* loader
;
369 if ( !ALLOC( loader
, sizeof ( *loader
) ) )
371 loader
->memory
= memory
;
378 /* rewind the glyph loader - reset counters to 0 */
379 BASE_FUNC( void ) FT_GlyphLoader_Rewind( FT_GlyphLoader
* loader
)
381 FT_GlyphLoad
* base
= &loader
->base
;
382 FT_GlyphLoad
* current
= &loader
->current
;
385 base
->outline
.n_points
= 0;
386 base
->outline
.n_contours
= 0;
387 base
->num_subglyphs
= 0;
393 /* reset the glyph loader, frees all allocated tables */
394 /* and starts from zero */
395 BASE_FUNC( void ) FT_GlyphLoader_Reset( FT_GlyphLoader
* loader
)
397 FT_Memory memory
= loader
->memory
;
400 FREE( loader
->base
.outline
.points
);
401 FREE( loader
->base
.outline
.tags
);
402 FREE( loader
->base
.outline
.contours
);
403 FREE( loader
->base
.extra_points
);
404 FREE( loader
->base
.subglyphs
);
406 loader
->max_points
= 0;
407 loader
->max_contours
= 0;
408 loader
->max_subglyphs
= 0;
410 FT_GlyphLoader_Rewind( loader
);
414 /* delete a glyph loader */
415 BASE_FUNC( void ) FT_GlyphLoader_Done( FT_GlyphLoader
* loader
)
419 FT_Memory memory
= loader
->memory
;
422 FT_GlyphLoader_Reset( loader
);
428 /* re-adjust the `current' outline fields */
430 void FT_GlyphLoader_Adjust_Points( FT_GlyphLoader
* loader
)
432 FT_Outline
* base
= &loader
->base
.outline
;
433 FT_Outline
* current
= &loader
->current
.outline
;
436 current
->points
= base
->points
+ base
->n_points
;
437 current
->tags
= base
->tags
+ base
->n_points
;
438 current
->contours
= base
->contours
+ base
->n_contours
;
440 /* handle extra points table - if any */
441 if ( loader
->use_extra
)
442 loader
->current
.extra_points
=
443 loader
->base
.extra_points
+ base
->n_points
;
447 BASE_FUNC( FT_Error
) FT_GlyphLoader_Create_Extra(
448 FT_GlyphLoader
* loader
)
451 FT_Memory memory
= loader
->memory
;
454 if ( !ALLOC_ARRAY( loader
->base
.extra_points
,
455 loader
->max_points
, FT_Vector
) )
457 loader
->use_extra
= 1;
458 FT_GlyphLoader_Adjust_Points( loader
);
464 /* re-adjust the `current' subglyphs field */
466 void FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader
* loader
)
468 FT_GlyphLoad
* base
= &loader
->base
;
469 FT_GlyphLoad
* current
= &loader
->current
;
472 current
->subglyphs
= base
->subglyphs
+ base
->num_subglyphs
;
476 /* Ensure that we can add `n_points' and `n_contours' to our glyph. this */
477 /* function reallocates its outline tables if necessary. Note that it */
478 /* DOESN'T change the number of points within the loader! */
480 BASE_FUNC( FT_Error
) FT_GlyphLoader_Check_Points(
481 FT_GlyphLoader
* loader
,
485 FT_Memory memory
= loader
->memory
;
486 FT_Error error
= FT_Err_Ok
;
487 FT_Outline
* base
= &loader
->base
.outline
;
488 FT_Outline
* current
= &loader
->current
.outline
;
494 /* check points & tags */
495 new_max
= base
->n_points
+ current
->n_points
+ n_points
;
496 if ( new_max
> loader
->max_points
)
498 new_max
= ( new_max
+ 7 ) & -8;
499 if ( REALLOC_ARRAY( base
->points
, base
->n_points
,
500 new_max
, FT_Vector
) ||
501 REALLOC_ARRAY( base
->tags
, base
->n_points
,
505 if ( loader
->use_extra
&&
506 REALLOC_ARRAY( loader
->base
.extra_points
, base
->n_points
,
507 new_max
, FT_Vector
) )
511 loader
->max_points
= new_max
;
515 new_max
= base
->n_contours
+ current
->n_contours
+
517 if ( new_max
> loader
->max_contours
)
519 new_max
= ( new_max
+ 3 ) & -4;
520 if ( REALLOC_ARRAY( base
->contours
, base
->n_contours
,
521 new_max
, FT_Short
) )
525 loader
->max_contours
= new_max
;
529 FT_GlyphLoader_Adjust_Points( loader
);
536 /* Ensure that we can add `n_subglyphs' to our glyph. this function */
537 /* reallocates its subglyphs table if necessary. Note that it DOES */
538 /* NOT change the number of subglyphs within the loader! */
540 BASE_FUNC( FT_Error
) FT_GlyphLoader_Check_Subglyphs(
541 FT_GlyphLoader
* loader
,
544 FT_Memory memory
= loader
->memory
;
545 FT_Error error
= FT_Err_Ok
;
548 FT_GlyphLoad
* base
= &loader
->base
;
549 FT_GlyphLoad
* current
= &loader
->current
;
552 new_max
= base
->num_subglyphs
+ current
->num_subglyphs
+ n_subs
;
553 if ( new_max
> loader
->max_subglyphs
)
555 new_max
= ( new_max
+ 1 ) & -2;
556 if ( REALLOC_ARRAY( base
->subglyphs
, base
->num_subglyphs
,
557 new_max
, FT_SubGlyph
) )
560 loader
->max_subglyphs
= new_max
;
562 FT_GlyphLoader_Adjust_Subglyphs( loader
);
570 /* prepare loader for the addition of a new glyph on top of the base one */
571 BASE_FUNC( void ) FT_GlyphLoader_Prepare( FT_GlyphLoader
* loader
)
573 FT_GlyphLoad
* current
= &loader
->current
;
576 current
->outline
.n_points
= 0;
577 current
->outline
.n_contours
= 0;
578 current
->num_subglyphs
= 0;
580 FT_GlyphLoader_Adjust_Points ( loader
);
581 FT_GlyphLoader_Adjust_Subglyphs( loader
);
585 /* add current glyph to the base image - and prepare for another */
586 BASE_FUNC( void ) FT_GlyphLoader_Add( FT_GlyphLoader
* loader
)
588 FT_GlyphLoad
* base
= &loader
->base
;
589 FT_GlyphLoad
* current
= &loader
->current
;
591 FT_UInt n_curr_contours
= current
->outline
.n_contours
;
592 FT_UInt n_base_points
= base
->outline
.n_points
;
596 base
->outline
.n_points
+= current
->outline
.n_points
;
597 base
->outline
.n_contours
+= current
->outline
.n_contours
;
598 base
->num_subglyphs
+= current
->num_subglyphs
;
600 /* adjust contours count in newest outline */
601 for ( n
= 0; n
< n_curr_contours
; n
++ )
602 current
->outline
.contours
[n
] += n_base_points
;
604 /* prepare for another new glyph image */
605 FT_GlyphLoader_Prepare( loader
);
609 BASE_FUNC( FT_Error
) FT_GlyphLoader_Copy_Points( FT_GlyphLoader
* target
,
610 FT_GlyphLoader
* source
)
613 FT_UInt num_points
= source
->base
.outline
.n_points
;
614 FT_UInt num_contours
= source
->base
.outline
.n_contours
;
617 error
= FT_GlyphLoader_Check_Points( target
, num_points
, num_contours
);
620 FT_Outline
* out
= &target
->base
.outline
;
621 FT_Outline
* in
= &source
->base
.outline
;
624 MEM_Copy( out
->points
, in
->points
,
625 num_points
* sizeof ( FT_Vector
) );
626 MEM_Copy( out
->tags
, in
->tags
,
627 num_points
* sizeof ( char ) );
628 MEM_Copy( out
->contours
, in
->contours
,
629 num_contours
* sizeof ( short ) );
631 /* do we need to copy the extra points? */
632 if ( target
->use_extra
&& source
->use_extra
)
633 MEM_Copy( target
->base
.extra_points
, source
->base
.extra_points
,
634 num_points
* sizeof ( FT_Vector
) );
636 out
->n_points
= num_points
;
637 out
->n_contours
= num_contours
;
639 FT_GlyphLoader_Adjust_Points( target
);
646 /*************************************************************************/
647 /*************************************************************************/
648 /*************************************************************************/
651 /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/
654 /*************************************************************************/
655 /*************************************************************************/
656 /*************************************************************************/
660 FT_Error
ft_glyphslot_init( FT_GlyphSlot slot
)
662 FT_Driver driver
= slot
->face
->driver
;
663 FT_Driver_Class
* clazz
= driver
->clazz
;
664 FT_Memory memory
= driver
->root
.memory
;
665 FT_Error error
= FT_Err_Ok
;
668 slot
->library
= driver
->root
.library
;
670 if ( FT_DRIVER_USES_OUTLINES( driver
) )
671 error
= FT_GlyphLoader_New( memory
, &slot
->loader
);
673 if ( !error
&& clazz
->init_slot
)
674 error
= clazz
->init_slot( slot
);
681 void ft_glyphslot_clear( FT_GlyphSlot slot
)
683 /* free bitmap if needed */
684 if ( slot
->flags
& ft_glyph_own_bitmap
)
686 FT_Memory memory
= FT_FACE_MEMORY( slot
->face
);
689 FREE( slot
->bitmap
.buffer
);
690 slot
->flags
&= ~ft_glyph_own_bitmap
;
693 /* clear all public fields in the glyph slot */
694 MEM_Set( &slot
->metrics
, 0, sizeof ( slot
->metrics
) );
695 MEM_Set( &slot
->outline
, 0, sizeof ( slot
->outline
) );
696 MEM_Set( &slot
->bitmap
, 0, sizeof ( slot
->bitmap
) );
698 slot
->bitmap_left
= 0;
699 slot
->bitmap_top
= 0;
700 slot
->num_subglyphs
= 0;
702 slot
->control_data
= 0;
703 slot
->control_len
= 0;
705 slot
->format
= ft_glyph_format_none
;
707 slot
->linearHoriAdvance
= 0;
708 slot
->linearVertAdvance
= 0;
713 void ft_glyphslot_done( FT_GlyphSlot slot
)
715 FT_Driver driver
= slot
->face
->driver
;
716 FT_Driver_Class
* clazz
= driver
->clazz
;
717 FT_Memory memory
= driver
->root
.memory
;
720 /* free bitmap buffer if needed */
721 if ( slot
->flags
& ft_glyph_own_bitmap
)
722 FREE( slot
->bitmap
.buffer
);
724 /* free glyph loader */
725 if ( FT_DRIVER_USES_OUTLINES( driver
) )
727 FT_GlyphLoader_Done( slot
->loader
);
731 if ( clazz
->done_slot
)
732 clazz
->done_slot( slot
);
736 /*************************************************************************/
739 /* FT_New_GlyphSlot */
742 /* It is sometimes useful to have more than one glyph slot for a */
743 /* given face object. This function is used to create additional */
744 /* slots. All of them are automatically discarded when the face is */
748 /* face :: A handle to a parent face object. */
751 /* aslot :: A handle to a new glyph slot object. */
754 /* FreeType error code. 0 means success. */
756 FT_EXPORT_FUNC( FT_Error
) FT_New_GlyphSlot( FT_Face face
,
757 FT_GlyphSlot
* aslot
)
761 FT_Driver_Class
* clazz
;
766 if ( !face
|| !aslot
|| !face
->driver
)
767 return FT_Err_Invalid_Argument
;
771 driver
= face
->driver
;
772 clazz
= driver
->clazz
;
773 memory
= driver
->root
.memory
;
775 FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
776 if ( !ALLOC( slot
, clazz
->slot_object_size
) )
780 error
= ft_glyphslot_init( slot
);
783 ft_glyphslot_done( slot
);
792 FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error
));
797 /*************************************************************************/
800 /* FT_Done_GlyphSlot */
803 /* Destroys a given glyph slot. Remember however that all slots are */
804 /* automatically destroyed with its parent. Using this function is */
805 /* not always mandatory. */
808 /* slot :: A handle to a target glyph slot. */
810 FT_EXPORT_FUNC( void ) FT_Done_GlyphSlot( FT_GlyphSlot slot
)
814 FT_Driver driver
= slot
->face
->driver
;
815 FT_Memory memory
= driver
->root
.memory
;
816 FT_GlyphSlot
* parent
;
820 /* Remove slot from its parent face's list */
821 parent
= &slot
->face
->glyph
;
829 ft_glyphslot_done( slot
);
839 /*************************************************************************/
842 /* FT_Set_Transform */
845 /* A function used to set the transformation that is applied to glyph */
846 /* images just before they are converted to bitmaps in a glyph slot */
847 /* when FT_Render_Glyph() is called. */
850 /* face :: A handle to the source face object. */
853 /* matrix :: A pointer to the transformation's 2x2 matrix. Use 0 for */
854 /* the identity matrix. */
855 /* delta :: A pointer to the translation vector. Use 0 for the null */
859 /* The transformation is only applied to scalable image formats after */
860 /* the glyph has been loaded. It means that hinting is unaltered by */
861 /* the transformation and is performed on the character size given in */
862 /* the last call to FT_Set_Char_Sizes() or FT_Set_Pixel_Sizes(). */
864 FT_EXPORT_FUNC( void ) FT_Set_Transform( FT_Face face
,
871 face
->transform_flags
= 0;
875 face
->transform_matrix
.xx
= 0x10000L
;
876 face
->transform_matrix
.xy
= 0;
877 face
->transform_matrix
.yx
= 0;
878 face
->transform_matrix
.yy
= 0x10000L
;
879 matrix
= &face
->transform_matrix
;
882 face
->transform_matrix
= *matrix
;
884 /* set transform_flags bit flag 0 if `matrix' isn't the identity */
885 if ( ( matrix
->xy
| matrix
->yx
) ||
886 matrix
->xx
!= 0x10000L
||
887 matrix
->yy
!= 0x10000L
)
888 face
->transform_flags
|= 1;
892 face
->transform_delta
.x
= 0;
893 face
->transform_delta
.y
= 0;
894 delta
= &face
->transform_delta
;
897 face
->transform_delta
= *delta
;
899 /* set transform_flags bit flag 1 if `delta' isn't the null vector */
900 if ( delta
->x
| delta
->y
)
901 face
->transform_flags
|= 2;
905 static FT_Renderer
ft_lookup_glyph_renderer( FT_GlyphSlot slot
);
908 /*************************************************************************/
914 /* A function used to load a single glyph within a given glyph slot, */
915 /* for a given size. */
918 /* face :: A handle to the target face object where the glyph */
919 /* will be loaded. */
921 /* glyph_index :: The index of the glyph in the font file. */
923 /* load_flags :: A flag indicating what to load for this glyph. The */
924 /* FT_LOAD_XXX constants can be used to control the */
925 /* glyph loading process (e.g., whether the outline */
926 /* should be scaled, whether to load bitmaps or not, */
927 /* whether to hint the outline, etc). */
930 /* FreeType error code. 0 means success. */
933 /* If the glyph image is not a bitmap, and if the bit flag */
934 /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */
935 /* transformed with the information passed to a previous call to */
936 /* FT_Set_Transform. */
938 /* Note that this also transforms the `face.glyph.advance' field, but */
939 /* *not* the values in `face.glyph.metrics'. */
941 FT_EXPORT_FUNC( FT_Error
) FT_Load_Glyph( FT_Face face
,
953 if ( !face
|| !face
->size
|| !face
->glyph
)
954 return FT_Err_Invalid_Face_Handle
;
956 if ( glyph_index
>= (FT_UInt
)face
->num_glyphs
)
957 return FT_Err_Invalid_Argument
;
960 ft_glyphslot_clear( slot
);
962 driver
= face
->driver
;
964 /* when the flag NO_RECURSE is set, we disable hinting and scaling */
965 if ( load_flags
& FT_LOAD_NO_RECURSE
)
966 load_flags
|= FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
;
968 /* do we need to load the glyph through the auto-hinter? */
969 library
= driver
->root
.library
;
970 hinter
= library
->auto_hinter
;
972 !( load_flags
& ( FT_LOAD_NO_SCALE
| FT_LOAD_NO_HINTING
) );
975 if ( FT_DRIVER_HAS_HINTER( driver
) &&
976 !( load_flags
& FT_LOAD_FORCE_AUTOHINT
) )
982 FT_AutoHinter_Interface
* hinting
;
985 hinting
= (FT_AutoHinter_Interface
*)hinter
->clazz
->module_interface
;
986 error
= hinting
->load_glyph( (FT_AutoHinter
)hinter
, slot
, face
->size
,
987 glyph_index
, load_flags
);
990 error
= driver
->clazz
->load_glyph( slot
,
997 /* compute the advance */
998 if ( load_flags
& FT_LOAD_VERTICAL_LAYOUT
)
1000 slot
->advance
.x
= 0;
1001 slot
->advance
.y
= slot
->metrics
.vertAdvance
;
1005 slot
->advance
.x
= slot
->metrics
.horiAdvance
;
1006 slot
->advance
.y
= 0;
1009 /* now, transform the glyph image when needed */
1010 if ( face
->transform_flags
)
1013 FT_Renderer renderer
= ft_lookup_glyph_renderer( slot
);
1017 error
= renderer
->clazz
->transform_glyph( renderer
, slot
,
1018 &face
->transform_matrix
,
1019 &face
->transform_delta
);
1020 /* transform advance */
1021 FT_Vector_Transform( &slot
->advance
, &face
->transform_matrix
);
1024 /* do we need to render the image now? */
1026 slot
->format
!= ft_glyph_format_bitmap
&&
1027 slot
->format
!= ft_glyph_format_composite
&&
1028 load_flags
& FT_LOAD_RENDER
)
1030 error
= FT_Render_Glyph( slot
,
1031 ( load_flags
& FT_LOAD_MONOCHROME
)
1032 ? ft_render_mode_mono
1033 : ft_render_mode_normal
);
1041 /*************************************************************************/
1047 /* A function used to load a single glyph within a given glyph slot, */
1048 /* for a given size, according to its character code. */
1051 /* face :: A handle to a target face object where the glyph */
1052 /* will be loaded. */
1054 /* char_code :: The glyph's character code, according to the */
1055 /* current charmap used in the face. */
1057 /* load_flags :: A flag indicating what to load for this glyph. The */
1058 /* FT_LOAD_XXX constants can be used to control the */
1059 /* glyph loading process (e.g., whether the outline */
1060 /* should be scaled, whether to load bitmaps or not, */
1061 /* whether to hint the outline, etc). */
1064 /* FreeType error code. 0 means success. */
1067 /* If the face has no current charmap, or if the character code */
1068 /* is not defined in the charmap, this function will return an */
1071 /* If the glyph image is not a bitmap, and if the bit flag */
1072 /* FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be */
1073 /* transformed with the information passed to a previous call to */
1074 /* FT_Set_Transform(). */
1076 /* Note that this also transforms the `face.glyph.advance' field, but */
1077 /* *not* the values in `face.glyph.metrics'. */
1079 FT_EXPORT_FUNC( FT_Error
) FT_Load_Char( FT_Face face
,
1083 FT_UInt glyph_index
;
1087 return FT_Err_Invalid_Face_Handle
;
1089 glyph_index
= (FT_UInt
)char_code
;
1090 if ( face
->charmap
)
1091 glyph_index
= FT_Get_Char_Index( face
, char_code
);
1093 return FT_Load_Glyph( face
, glyph_index
, load_flags
);
1097 /* destructor for sizes list */
1099 void destroy_size( FT_Memory memory
,
1103 /* finalize client-specific data */
1104 if ( size
->generic
.finalizer
)
1105 size
->generic
.finalizer( size
);
1107 /* finalize format-specific stuff */
1108 if ( driver
->clazz
->done_size
)
1109 driver
->clazz
->done_size( size
);
1115 /* destructor for faces list */
1117 void destroy_face( FT_Memory memory
,
1121 FT_Driver_Class
* clazz
= driver
->clazz
;
1124 /* discard auto-hinting data */
1125 if ( face
->autohint
.finalizer
)
1126 face
->autohint
.finalizer( face
->autohint
.data
);
1128 /* Discard glyph slots for this face */
1129 /* Beware! FT_Done_GlyphSlot() changes the field `face->slot' */
1130 while ( face
->glyph
)
1131 FT_Done_GlyphSlot( face
->glyph
);
1133 /* Discard all sizes for this face */
1134 FT_List_Finalize( &face
->sizes_list
,
1135 (FT_List_Destructor
)destroy_size
,
1140 /* Now discard client data */
1141 if ( face
->generic
.finalizer
)
1142 face
->generic
.finalizer( face
);
1144 /* finalize format-specific stuff */
1145 if ( clazz
->done_face
)
1146 clazz
->done_face( face
);
1148 /* close the stream for this face if needed */
1149 if ( ( face
->face_flags
& FT_FACE_FLAG_EXTERNAL_STREAM
) == 0 )
1150 ft_done_stream( &face
->stream
);
1158 void Destroy_Driver( FT_Driver driver
)
1160 FT_List_Finalize( &driver
->faces_list
,
1161 (FT_List_Destructor
)destroy_face
,
1162 driver
->root
.memory
,
1165 /* check whether we need to drop the driver's glyph loader */
1166 if ( FT_DRIVER_USES_OUTLINES( driver
) )
1167 FT_GlyphLoader_Done( driver
->glyph_loader
);
1171 /*************************************************************************/
1177 /* This function does some work for FT_Open_Face(). */
1180 FT_Error
open_face( FT_Driver driver
,
1184 FT_Parameter
* params
,
1188 FT_Driver_Class
* clazz
;
1193 clazz
= driver
->clazz
;
1194 memory
= driver
->root
.memory
;
1196 /* allocate the face object and perform basic initialization */
1197 if ( ALLOC( face
, clazz
->face_object_size
) )
1200 face
->driver
= driver
;
1201 face
->memory
= memory
;
1202 face
->stream
= stream
;
1204 error
= clazz
->init_face( stream
,
1217 clazz
->done_face( face
);
1226 /*************************************************************************/
1232 /* Creates a new face object from a given resource and typeface index */
1233 /* using a pathname to the font file. */
1236 /* library :: A handle to the library resource. */
1239 /* pathname :: A path to the font file. */
1241 /* face_index :: The index of the face within the resource. The */
1242 /* first face has index 0. */
1244 /* aface :: A handle to a new face object. */
1247 /* FreeType error code. 0 means success. */
1250 /* Unlike FreeType 1.x, this function automatically creates a glyph */
1251 /* slot for the face object which can be accessed directly through */
1252 /* `face->glyph'. */
1254 /* Note that additional slots can be added to each face with the */
1255 /* FT_New_GlyphSlot() API function. Slots are linked in a single */
1256 /* list through their `next' field. */
1258 /* FT_New_Face() can be used to determine and/or check the font */
1259 /* format of a given font resource. If the `face_index' field is */
1260 /* negative, the function will _not_ return any face handle in */
1261 /* `*face'. Its return value should be 0 if the resource is */
1262 /* recognized, or non-zero if not. */
1264 FT_EXPORT_FUNC( FT_Error
) FT_New_Face( FT_Library library
,
1265 const char* pathname
,
1272 /* test for valid `library' and `aface' delayed to FT_Open_Face() */
1274 return FT_Err_Invalid_Argument
;
1276 args
.flags
= ft_open_pathname
;
1277 args
.pathname
= (char*)pathname
;
1279 return FT_Open_Face( library
, &args
, face_index
, aface
);
1283 /*************************************************************************/
1286 /* FT_New_Memory_Face */
1289 /* Creates a new face object from a given resource and typeface index */
1290 /* using a font file already loaded into memory. */
1293 /* library :: A handle to the library resource. */
1296 /* file_base :: A pointer to the beginning of the font data. */
1298 /* file_size :: The size of the memory chunk used by the font data. */
1300 /* face_index :: The index of the face within the resource. The */
1301 /* first face has index 0. */
1303 /* face :: A handle to a new face object. */
1306 /* FreeType error code. 0 means success. */
1309 /* Unlike FreeType 1.x, this function automatically creates a glyph */
1310 /* slot for the face object which can be accessed directly through */
1311 /* `face->glyph'. */
1313 /* Note that additional slots can be added to each face with the */
1314 /* FT_New_GlyphSlot() API function. Slots are linked in a single */
1315 /* list through their `next' field. */
1317 /* FT_New_Memory_Face() can be used to determine and/or check the */
1318 /* font format of a given font resource. If the `face_index' field */
1319 /* is negative, the function will _not_ return any face handle in */
1320 /* `*face'. Its return value should be 0 if the resource is */
1321 /* recognized, or non-zero if not. */
1323 FT_EXPORT_FUNC( FT_Error
) FT_New_Memory_Face( FT_Library library
,
1332 /* test for valid `library' and `face' delayed to FT_Open_Face() */
1334 return FT_Err_Invalid_Argument
;
1336 args
.flags
= ft_open_memory
;
1337 args
.memory_base
= file_base
;
1338 args
.memory_size
= file_size
;
1340 return FT_Open_Face( library
, &args
, face_index
, face
);
1344 /*************************************************************************/
1350 /* Opens a face object from a given resource and typeface index using */
1351 /* an `FT_Open_Args' structure. If the face object doesn't exist, it */
1352 /* will be created. */
1355 /* library :: A handle to the library resource. */
1358 /* args :: A pointer to an `FT_Open_Args' structure which must */
1359 /* be filled by the caller. */
1361 /* face_index :: The index of the face within the resource. The */
1362 /* first face has index 0. */
1364 /* aface :: A handle to a new face object. */
1367 /* FreeType error code. 0 means success. */
1370 /* Unlike FreeType 1.x, this function automatically creates a glyph */
1371 /* slot for the face object which can be accessed directly through */
1372 /* `face->glyph'. */
1374 /* Note that additional slots can be added to each face with the */
1375 /* FT_New_GlyphSlot() API function. Slots are linked in a single */
1376 /* list through their `next' field. */
1378 /* FT_Open_Face() can be used to determine and/or check the font */
1379 /* format of a given font resource. If the `face_index' field is */
1380 /* negative, the function will _not_ return any face handle in */
1381 /* `*face'. Its return value should be 0 if the resource is */
1382 /* recognized, or non-zero if not. */
1384 FT_EXPORT_FUNC( FT_Error
) FT_Open_Face( FT_Library library
,
1394 FT_ListNode node
= 0;
1397 /* test for valid `library' and `args' delayed to */
1398 /* ft_new_input_stream() */
1401 return FT_Err_Invalid_Argument
;
1405 /* create input stream */
1406 error
= ft_new_input_stream( library
, args
, &stream
);
1410 memory
= library
->memory
;
1412 /* If the font driver is specified in the `args' structure, use */
1413 /* it. Otherwise, we scan the list of registered drivers. */
1414 if ( args
->flags
& ft_open_driver
&& args
->driver
)
1416 driver
= FT_DRIVER( args
->driver
);
1418 /* not all modules are drivers, so check... */
1419 if ( FT_MODULE_IS_DRIVER( driver
) )
1421 FT_Int num_params
= 0;
1422 FT_Parameter
* params
= 0;
1425 if ( args
->flags
& ft_open_params
)
1427 num_params
= args
->num_params
;
1428 params
= args
->params
;
1431 error
= open_face( driver
, stream
, face_index
,
1432 num_params
, params
, &face
);
1437 error
= FT_Err_Invalid_Handle
;
1439 ft_done_stream( &stream
);
1444 /* check each font driver for an appropriate format */
1445 FT_Module
* cur
= library
->modules
;
1446 FT_Module
* limit
= cur
+ library
->num_modules
;
1449 for ( ; cur
< limit
; cur
++ )
1451 /* not all modules are font drivers, so check... */
1452 if ( FT_MODULE_IS_DRIVER( cur
[0] ) )
1454 FT_Int num_params
= 0;
1455 FT_Parameter
* params
= 0;
1458 driver
= FT_DRIVER( cur
[0] );
1460 if ( args
->flags
& ft_open_params
)
1462 num_params
= args
->num_params
;
1463 params
= args
->params
;
1466 error
= open_face( driver
, stream
, face_index
,
1467 num_params
, params
, &face
);
1471 if ( error
!= FT_Err_Unknown_File_Format
)
1476 ft_done_stream( &stream
);
1478 /* no driver is able to handle this format */
1479 error
= FT_Err_Unknown_File_Format
;
1484 FT_TRACE4(( "FT_New_Face: New face object, adding to list\n" ));
1486 /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
1487 if ( args
->flags
& ft_open_stream
&& args
->stream
)
1488 face
->face_flags
|= FT_FACE_FLAG_EXTERNAL_STREAM
;
1490 /* add the face object to its driver's list */
1491 if ( ALLOC( node
, sizeof ( *node
) ) )
1495 /* don't assume driver is the same as face->driver, so use */
1496 /* face->driver instead. */
1497 FT_List_Add( &face
->driver
->faces_list
, node
);
1499 /* now allocate a glyph slot object for the face */
1504 FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
1506 error
= FT_New_GlyphSlot( face
, &slot
);
1513 /* finally, allocate a size object for the face */
1518 FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
1520 error
= FT_New_Size( face
, &size
);
1527 /* initialize transformation for convenience functions */
1528 face
->transform_matrix
.xx
= 0x10000L
;
1529 face
->transform_matrix
.xy
= 0;
1530 face
->transform_matrix
.yx
= 0;
1531 face
->transform_matrix
.yy
= 0x10000L
;
1533 face
->transform_delta
.x
= 0;
1534 face
->transform_delta
.y
= 0;
1540 FT_Done_Face( face
);
1543 FT_TRACE4(( "FT_Open_Face: Return %d\n", error
));
1549 /*************************************************************************/
1552 /* FT_Attach_File */
1555 /* `Attaches' a given font file to an existing face. This is usually */
1556 /* to read additional information for a single face object. For */
1557 /* example, it is used to read the AFM files that come with Type 1 */
1558 /* fonts in order to add kerning data and other metrics. */
1561 /* face :: The target face object. */
1564 /* filepathname :: An 8-bit pathname naming the `metrics' file. */
1567 /* FreeType error code. 0 means success. */
1570 /* If your font file is in memory, or if you want to provide your */
1571 /* own input stream object, use FT_Attach_Stream(). */
1573 /* The meaning of the `attach' action (i.e., what really happens when */
1574 /* the new file is read) is not fixed by FreeType itself. It really */
1575 /* depends on the font format (and thus the font driver). */
1577 /* Client applications are expected to know what they are doing */
1578 /* when invoking this function. Most drivers simply do not implement */
1579 /* file attachments. */
1581 FT_EXPORT_FUNC( FT_Error
) FT_Attach_File( FT_Face face
,
1582 const char* filepathname
)
1587 /* test for valid `face' delayed to FT_Attach_Stream() */
1589 if ( !filepathname
)
1590 return FT_Err_Invalid_Argument
;
1592 open
.flags
= ft_open_pathname
;
1593 open
.pathname
= (char*)filepathname
;
1595 return FT_Attach_Stream( face
, &open
);
1599 /*************************************************************************/
1602 /* FT_Attach_Stream */
1605 /* This function is similar to FT_Attach_File() with the exception */
1606 /* that it reads the attachment from an arbitrary stream. */
1609 /* face :: The target face object. */
1611 /* parameters :: A pointer to an FT_Open_Args structure used to */
1612 /* describe the input stream to FreeType. */
1614 /* FreeType error code. 0 means success. */
1617 /* The meaning of the `attach' (i.e. what really happens when the */
1618 /* new file is read) is not fixed by FreeType itself. It really */
1619 /* depends on the font format (and thus the font driver). */
1621 /* Client applications are expected to know what they are doing */
1622 /* when invoking this function. Most drivers simply do not implement */
1623 /* file attachments. */
1625 FT_EXPORT_FUNC( FT_Error
) FT_Attach_Stream( FT_Face face
,
1626 FT_Open_Args
* parameters
)
1632 FT_Driver_Class
* clazz
;
1635 /* test for valid `parameters' delayed to ft_new_input_stream() */
1638 return FT_Err_Invalid_Face_Handle
;
1640 driver
= face
->driver
;
1642 return FT_Err_Invalid_Driver_Handle
;
1644 error
= ft_new_input_stream( driver
->root
.library
, parameters
, &stream
);
1648 /* we implement FT_Attach_Stream in each driver through the */
1649 /* `attach_file' interface */
1651 error
= FT_Err_Unimplemented_Feature
;
1652 clazz
= driver
->clazz
;
1653 if ( clazz
->attach_file
)
1654 error
= clazz
->attach_file( face
, stream
);
1656 /* close the attached stream */
1657 if ( !parameters
->stream
|| ( parameters
->flags
& ft_open_stream
) )
1658 ft_done_stream( &stream
);
1665 /*************************************************************************/
1671 /* Discards a given face object, as well as all of its child slots */
1675 /* face :: A handle to a target face object. */
1678 /* FreeType error code. 0 means success. */
1680 FT_EXPORT_FUNC( FT_Error
) FT_Done_Face( FT_Face face
)
1688 error
= FT_Err_Invalid_Face_Handle
;
1689 if ( face
&& face
->driver
)
1691 driver
= face
->driver
;
1692 memory
= driver
->root
.memory
;
1694 /* find face in driver's list */
1695 node
= FT_List_Find( &driver
->faces_list
, face
);
1698 /* remove face object from the driver's list */
1699 FT_List_Remove( &driver
->faces_list
, node
);
1702 /* now destroy the object proper */
1703 destroy_face( memory
, face
, driver
);
1711 /*************************************************************************/
1717 /* Creates a new size object from a given face object. */
1720 /* face :: A handle to a parent face object. */
1723 /* asize :: A handle to a new size object. */
1726 /* FreeType error code. 0 means success. */
1728 FT_EXPORT_FUNC( FT_Error
) FT_New_Size( FT_Face face
,
1734 FT_Driver_Class
* clazz
;
1737 FT_ListNode node
= 0;
1741 return FT_Err_Invalid_Face_Handle
;
1744 return FT_Err_Invalid_Size_Handle
;
1746 if ( !face
->driver
)
1747 return FT_Err_Invalid_Driver_Handle
;
1751 driver
= face
->driver
;
1752 clazz
= driver
->clazz
;
1753 memory
= face
->memory
;
1755 /* Allocate new size object and perform basic initialisation */
1756 if ( ALLOC( size
, clazz
->size_object_size
) ||
1757 ALLOC( node
, sizeof ( FT_ListNodeRec
) ) )
1762 if ( clazz
->init_size
)
1763 error
= clazz
->init_size( size
);
1765 /* in case of success, add to the face's list */
1770 FT_List_Add( &face
->sizes_list
, node
);
1784 /*************************************************************************/
1790 /* Discards a given size object. */
1793 /* size :: A handle to a target size object. */
1796 /* FreeType error code. 0 means success. */
1798 FT_EXPORT_FUNC( FT_Error
) FT_Done_Size( FT_Size size
)
1808 return FT_Err_Invalid_Size_Handle
;
1812 return FT_Err_Invalid_Face_Handle
;
1814 driver
= face
->driver
;
1816 return FT_Err_Invalid_Driver_Handle
;
1818 memory
= driver
->root
.memory
;
1821 node
= FT_List_Find( &face
->sizes_list
, size
);
1824 FT_List_Remove( &face
->sizes_list
, node
);
1827 if ( face
->size
== size
)
1830 if ( face
->sizes_list
.head
)
1831 face
->size
= (FT_Size
)(face
->sizes_list
.head
->data
);
1834 destroy_size( memory
, size
, driver
);
1837 error
= FT_Err_Invalid_Size_Handle
;
1844 void ft_recompute_scaled_metrics( FT_Face face
,
1845 FT_Size_Metrics
* metrics
)
1847 /* Compute root ascender, descender, test height, and max_advance */
1849 metrics
->ascender
= ( FT_MulFix( face
->ascender
,
1850 metrics
->y_scale
) + 32 ) & -64;
1852 metrics
->descender
= ( FT_MulFix( face
->descender
,
1853 metrics
->y_scale
) + 32 ) & -64;
1855 metrics
->height
= ( FT_MulFix( face
->height
,
1856 metrics
->y_scale
) + 32 ) & -64;
1858 metrics
->max_advance
= ( FT_MulFix( face
->max_advance_width
,
1859 metrics
->x_scale
) + 32 ) & -64;
1863 /*************************************************************************/
1866 /* FT_Set_Char_Size */
1869 /* Sets the character dimensions of a given face object. The */
1870 /* `char_width' and `char_height' values are used for the width and */
1871 /* height, respectively, expressed in 26.6 fractional points. */
1873 /* If the horizontal or vertical resolution values are zero, a */
1874 /* default value of 72dpi is used. Similarly, if one of the */
1875 /* character dimensions is zero, its value is set equal to the other. */
1878 /* size :: A handle to a target size object. */
1881 /* char_width :: The character width, in 26.6 fractional points. */
1883 /* char_height :: The character height, in 26.6 fractional */
1886 /* horz_resolution :: The horizontal resolution. */
1888 /* vert_resolution :: The vertical resolution. */
1891 /* FreeType error code. 0 means success. */
1894 /* When dealing with fixed-size faces (i.e., non-scalable formats), */
1895 /* use the function FT_Set_Pixel_Sizes(). */
1897 FT_EXPORT_FUNC( FT_Error
) FT_Set_Char_Size( FT_Face face
,
1898 FT_F26Dot6 char_width
,
1899 FT_F26Dot6 char_height
,
1900 FT_UInt horz_resolution
,
1901 FT_UInt vert_resolution
)
1903 FT_Error error
= FT_Err_Ok
;
1906 FT_Driver_Class
* clazz
;
1907 FT_Size_Metrics
* metrics
;
1908 FT_Long dim_x
, dim_y
;
1911 if ( !face
|| !face
->size
|| !face
->driver
)
1912 return FT_Err_Invalid_Face_Handle
;
1914 driver
= face
->driver
;
1915 metrics
= &face
->size
->metrics
;
1918 char_width
= char_height
;
1920 else if ( !char_height
)
1921 char_height
= char_width
;
1923 if ( !horz_resolution
)
1924 horz_resolution
= 72;
1926 if ( !vert_resolution
)
1927 vert_resolution
= 72;
1929 driver
= face
->driver
;
1930 clazz
= driver
->clazz
;
1931 memory
= driver
->root
.memory
;
1933 /* default processing -- this can be overridden by the driver */
1934 if ( char_width
< 1 * 64 )
1935 char_width
= 1 * 64;
1936 if ( char_height
< 1 * 64 )
1937 char_height
= 1 * 64;
1939 /* Compute pixel sizes in 26.6 units */
1940 dim_x
= ( ( ( char_width
* horz_resolution
) / 72 ) + 32 ) & -64;
1941 dim_y
= ( ( ( char_height
* vert_resolution
) / 72 ) + 32 ) & -64;
1943 metrics
->x_ppem
= (FT_UShort
)( dim_x
>> 6 );
1944 metrics
->y_ppem
= (FT_UShort
)( dim_y
>> 6 );
1946 metrics
->x_scale
= 0x10000L
;
1947 metrics
->y_scale
= 0x10000L
;
1949 if ( face
->face_flags
& FT_FACE_FLAG_SCALABLE
)
1951 metrics
->x_scale
= FT_DivFix( dim_x
, face
->units_per_EM
);
1952 metrics
->y_scale
= FT_DivFix( dim_y
, face
->units_per_EM
);
1954 ft_recompute_scaled_metrics( face
, metrics
);
1957 if ( clazz
->set_char_sizes
)
1958 error
= clazz
->set_char_sizes( face
->size
,
1967 /*************************************************************************/
1970 /* FT_Set_Pixel_Sizes */
1973 /* Sets the character dimensions of a given face object. The width */
1974 /* and height are expressed in integer pixels. */
1976 /* If one of the character dimensions is zero, its value is set equal */
1980 /* face :: A handle to the target face object. */
1983 /* pixel_width :: The character width, in integer pixels. */
1985 /* pixel_height :: The character height, in integer pixels. */
1988 /* FreeType error code. 0 means success. */
1990 FT_EXPORT_FUNC( FT_Error
) FT_Set_Pixel_Sizes( FT_Face face
,
1991 FT_UInt pixel_width
,
1992 FT_UInt pixel_height
)
1994 FT_Error error
= FT_Err_Ok
;
1997 FT_Driver_Class
* clazz
;
1998 FT_Size_Metrics
* metrics
= &face
->size
->metrics
;
2001 if ( !face
|| !face
->size
|| !face
->driver
)
2002 return FT_Err_Invalid_Face_Handle
;
2004 driver
= face
->driver
;
2005 clazz
= driver
->clazz
;
2006 memory
= driver
->root
.memory
;
2008 /* default processing -- this can be overridden by the driver */
2009 if ( pixel_width
== 0 )
2010 pixel_width
= pixel_height
;
2012 else if ( pixel_height
== 0 )
2013 pixel_height
= pixel_width
;
2015 if ( pixel_width
< 1 )
2017 if ( pixel_height
< 1 )
2020 metrics
->x_ppem
= pixel_width
;
2021 metrics
->y_ppem
= pixel_height
;
2023 if ( face
->face_flags
& FT_FACE_FLAG_SCALABLE
)
2025 metrics
->x_scale
= FT_DivFix( metrics
->x_ppem
<< 6,
2026 face
->units_per_EM
);
2028 metrics
->y_scale
= FT_DivFix( metrics
->y_ppem
<< 6,
2029 face
->units_per_EM
);
2031 ft_recompute_scaled_metrics( face
, metrics
);
2034 if ( clazz
->set_pixel_sizes
)
2035 error
= clazz
->set_pixel_sizes( face
->size
,
2042 /*************************************************************************/
2045 /* FT_Get_Kerning */
2048 /* Returns the kerning vector between two glyphs of a same face. */
2051 /* face :: A handle to a source face object. */
2053 /* left_glyph :: The index of the left glyph in the kern pair. */
2055 /* right_glyph :: The index of the right glyph in the kern pair. */
2057 /* kern_mode :: See FT_Kerning_Mode() for more information. */
2058 /* Determines the scale/dimension of the returned */
2059 /* kerning vector. */
2062 /* kerning :: The kerning vector. This is in font units for */
2063 /* scalable formats, and in pixels for fixed-sizes */
2067 /* FreeType error code. 0 means success. */
2070 /* Only horizontal layouts (left-to-right & right-to-left) are */
2071 /* supported by this method. Other layouts, or more sophisticated */
2072 /* kernings, are out of the scope of this API function -- they can be */
2073 /* implemented through format-specific interfaces. */
2075 FT_EXPORT_FUNC( FT_Error
) FT_Get_Kerning( FT_Face face
,
2077 FT_UInt right_glyph
,
2079 FT_Vector
* kerning
)
2081 FT_Error error
= FT_Err_Ok
;
2087 return FT_Err_Invalid_Face_Handle
;
2090 return FT_Err_Invalid_Argument
;
2092 driver
= face
->driver
;
2093 memory
= driver
->root
.memory
;
2098 if ( driver
->clazz
->get_kerning
)
2100 error
= driver
->clazz
->get_kerning( face
,
2106 if ( kern_mode
!= ft_kerning_unscaled
)
2108 kerning
->x
= FT_MulFix( kerning
->x
, face
->size
->metrics
.x_scale
);
2109 kerning
->y
= FT_MulFix( kerning
->y
, face
->size
->metrics
.y_scale
);
2111 if ( kern_mode
!= ft_kerning_unfitted
)
2113 kerning
->x
= ( kerning
->x
+ 32 ) & -64;
2114 kerning
->y
= ( kerning
->y
+ 32 ) & -64;
2124 /*************************************************************************/
2127 /* FT_Select_Charmap */
2130 /* Selects a given charmap by its encoding tag (as listed in */
2131 /* `freetype.h'). */
2134 /* face :: A handle to the source face object. */
2136 /* encoding :: A handle to the selected charmap. */
2139 /* FreeType error code. 0 means success. */
2142 /* This function will return an error if no charmap in the face */
2143 /* corresponds to the encoding queried here. */
2145 FT_EXPORT_FUNC( FT_Error
) FT_Select_Charmap( FT_Face face
,
2146 FT_Encoding encoding
)
2153 return FT_Err_Invalid_Face_Handle
;
2155 cur
= face
->charmaps
;
2157 return FT_Err_Invalid_CharMap_Handle
;
2159 limit
= cur
+ face
->num_charmaps
;
2161 for ( ; cur
< limit
; cur
++ )
2163 if ( cur
[0]->encoding
== encoding
)
2165 face
->charmap
= cur
[0];
2170 return FT_Err_Invalid_Argument
;
2174 /*************************************************************************/
2177 /* FT_Set_Charmap */
2180 /* Selects a given charmap for character code to glyph index */
2184 /* face :: A handle to the source face object. */
2185 /* charmap :: A handle to the selected charmap. */
2188 /* FreeType error code. 0 means success. */
2191 /* This function will return an error if the charmap is not part of */
2192 /* the face (i.e., if it is not listed in the face->charmaps[] */
2195 FT_EXPORT_FUNC( FT_Error
) FT_Set_Charmap( FT_Face face
,
2196 FT_CharMap charmap
)
2203 return FT_Err_Invalid_Face_Handle
;
2205 cur
= face
->charmaps
;
2207 return FT_Err_Invalid_CharMap_Handle
;
2209 limit
= cur
+ face
->num_charmaps
;
2211 for ( ; cur
< limit
; cur
++ )
2213 if ( cur
[0] == charmap
)
2215 face
->charmap
= cur
[0];
2219 return FT_Err_Invalid_Argument
;
2223 /*************************************************************************/
2226 /* FT_Get_Char_Index */
2229 /* Returns the glyph index of a given character code. This function */
2230 /* uses a charmap object to do the translation. */
2233 /* face :: A handle to the source face object. */
2235 /* charcode :: The character code. */
2238 /* The glyph index. 0 means `undefined character code'. */
2240 FT_EXPORT_FUNC( FT_UInt
) FT_Get_Char_Index( FT_Face face
,
2248 if ( face
&& face
->charmap
)
2250 driver
= face
->driver
;
2251 result
= driver
->clazz
->get_char_index( face
->charmap
, charcode
);
2257 /*************************************************************************/
2260 /* FT_Get_Glyph_Name */
2263 /* Retrieves the ASCII name of a given glyph in a face. This only */
2264 /* works for those faces where FT_HAS_GLYPH_NAME(face) returns true. */
2267 /* face :: A handle to a source face object. */
2269 /* glyph_index :: The glyph index. */
2271 /* buffer :: A pointer to a target buffer where the name will be */
2274 /* buffer_max :: The maximal number of bytes available in the */
2278 /* FreeType error code. 0 means success. */
2281 /* An error is returned if the face doesn't provide glyph names or if */
2282 /* the glyph index is invalid. In all cases of failure, the first */
2283 /* byte of `buffer' will be set to 0 to indicate an empty name. */
2285 /* The glyph name is truncated to fit within the buffer if it is too */
2286 /* long. The returned string is always zero-terminated. */
2288 /* This function is not compiled within the library if the config */
2289 /* macro FT_CONFIG_OPTION_NO_GLYPH_NAMES is defined in */
2290 /* `include/freetype/config/ftoptions.h' */
2292 FT_EXPORT_FUNC( FT_Error
) FT_Get_Glyph_Name( FT_Face face
,
2293 FT_UInt glyph_index
,
2295 FT_UInt buffer_max
)
2297 FT_Error error
= FT_Err_Invalid_Argument
;
2300 /* clean up buffer */
2301 if ( buffer
&& buffer_max
> 0 )
2302 ((FT_Byte
*)buffer
)[0] = 0;
2305 glyph_index
< (FT_UInt
)face
->num_glyphs
&&
2306 FT_HAS_GLYPH_NAMES( face
) )
2308 /* now, lookup for glyph name */
2309 FT_Driver driver
= face
->driver
;
2310 FT_Module_Class
* clazz
= FT_MODULE_CLASS( driver
);
2313 if ( clazz
->get_interface
)
2315 FT_Glyph_Name_Requester requester
;
2318 requester
= (FT_Glyph_Name_Requester
)clazz
->get_interface(
2319 FT_MODULE( driver
), "glyph_name" );
2321 error
= requester( face
, glyph_index
, buffer
, buffer_max
);
2329 /*************************************************************************/
2332 /* FT_Get_Sfnt_Table */
2335 /* Returns a pointer to a given SFNT table within a face. */
2338 /* face :: A handle to the source face object. */
2339 /* tag :: An index of an SFNT table. */
2342 /* A type-less pointer to the table. This will be 0 in case of */
2343 /* error, or if the corresponding table was not found *OR* loaded */
2344 /* from the file. */
2347 /* The table is owned by the face object, and disappears with it. */
2349 /* This function is only useful to access SFNT tables that are loaded */
2350 /* by the sfnt/truetype/opentype drivers. See the FT_Sfnt_Tag */
2351 /* enumeration in `tttables.h' for a list. */
2353 /* You can load any table with a different function.. XXX */
2355 FT_EXPORT_FUNC( void* ) FT_Get_Sfnt_Table( FT_Face face
,
2359 FT_Get_Sfnt_Table_Func func
;
2363 if ( !face
|| !FT_IS_SFNT( face
) )
2366 driver
= face
->driver
;
2367 func
= (FT_Get_Sfnt_Table_Func
)driver
->root
.clazz
->get_interface(
2368 FT_MODULE( driver
), "get_sfnt" );
2370 table
= func( face
, tag
);
2377 /*************************************************************************/
2378 /*************************************************************************/
2379 /*************************************************************************/
2382 /**** R E N D E R E R S ****/
2385 /*************************************************************************/
2386 /*************************************************************************/
2387 /*************************************************************************/
2389 /* lookup a renderer by glyph format in the library's list */
2390 BASE_FUNC( FT_Renderer
) FT_Lookup_Renderer( FT_Library library
,
2391 FT_Glyph_Format format
,
2395 FT_Renderer result
= 0;
2401 cur
= library
->renderers
.head
;
2406 cur
= (*node
)->next
;
2412 FT_Renderer renderer
= FT_RENDERER( cur
->data
);
2415 if ( renderer
->glyph_format
== format
)
2432 FT_Renderer
ft_lookup_glyph_renderer( FT_GlyphSlot slot
)
2434 FT_Face face
= slot
->face
;
2435 FT_Library library
= FT_FACE_LIBRARY( face
);
2436 FT_Renderer result
= library
->cur_renderer
;
2439 if ( !result
|| result
->glyph_format
!= slot
->format
)
2440 result
= FT_Lookup_Renderer( library
, slot
->format
, 0 );
2447 void ft_set_current_renderer( FT_Library library
)
2449 FT_Renderer renderer
;
2452 renderer
= FT_Lookup_Renderer( library
, ft_glyph_format_outline
, 0 );
2453 library
->cur_renderer
= renderer
;
2458 FT_Error
ft_add_renderer( FT_Module
module )
2460 FT_Library library
= module->library
;
2461 FT_Memory memory
= library
->memory
;
2466 if ( ALLOC( node
, sizeof ( *node
) ) )
2470 FT_Renderer render
= FT_RENDERER( module );
2471 FT_Renderer_Class
* clazz
= (FT_Renderer_Class
*)module->clazz
;
2474 render
->clazz
= clazz
;
2475 render
->glyph_format
= clazz
->glyph_format
;
2477 /* allocate raster object if needed */
2478 if ( clazz
->glyph_format
== ft_glyph_format_outline
&&
2479 clazz
->raster_class
->raster_new
)
2481 error
= clazz
->raster_class
->raster_new( memory
, &render
->raster
);
2485 render
->raster_render
= clazz
->raster_class
->raster_render
;
2486 render
->render
= clazz
->render_glyph
;
2490 node
->data
= module;
2491 FT_List_Add( &library
->renderers
, node
);
2493 ft_set_current_renderer( library
);
2506 void ft_remove_renderer( FT_Module
module )
2508 FT_Library library
= module->library
;
2509 FT_Memory memory
= library
->memory
;
2513 node
= FT_List_Find( &library
->renderers
, module );
2516 FT_Renderer render
= FT_RENDERER( module );
2519 /* release raster object, if any */
2520 if ( render
->raster
)
2521 render
->clazz
->raster_class
->raster_done( render
->raster
);
2523 /* remove from list */
2524 FT_List_Remove( &library
->renderers
, node
);
2527 ft_set_current_renderer( library
);
2532 /*************************************************************************/
2535 /* FT_Get_Renderer */
2538 /* Retrieves the current renderer for a given glyph format. */
2541 /* library :: A handle to the library object. */
2543 /* format :: The glyph format. */
2546 /* A renderer handle. 0 if none found. */
2549 /* An error will be returned if a module already exists by that name, */
2550 /* or if the module requires a version of FreeType that is too great. */
2552 /* To add a new renderer, simply use FT_Add_Module(). To retrieve a */
2553 /* renderer by its name, use FT_Get_Module(). */
2555 FT_EXPORT_FUNC( FT_Renderer
) FT_Get_Renderer( FT_Library library
,
2556 FT_Glyph_Format format
)
2558 /* test for valid `library' delayed to FT_Lookup_Renderer() */
2560 return FT_Lookup_Renderer( library
, format
, 0 );
2564 /*************************************************************************/
2567 /* FT_Set_Renderer */
2570 /* Sets the current renderer to use, and set additional mode. */
2573 /* library :: A handle to the library object. */
2575 /* renderer :: A handle to the renderer object. */
2577 /* num_params :: The number of additional parameters. */
2579 /* parameters :: Additional parameters. */
2582 /* FreeType error code. 0 means success. */
2585 /* In case of success, the renderer will be used to convert glyph */
2586 /* images in the renderer's known format into bitmaps. */
2588 /* This doesn't change the current renderer for other formats. */
2590 FT_EXPORT_DEF( FT_Error
) FT_Set_Renderer( FT_Library library
,
2591 FT_Renderer renderer
,
2593 FT_Parameter
* parameters
)
2596 FT_Error error
= FT_Err_Ok
;
2600 return FT_Err_Invalid_Library_Handle
;
2603 return FT_Err_Invalid_Argument
;
2605 node
= FT_List_Find( &library
->renderers
, renderer
);
2608 error
= FT_Err_Invalid_Argument
;
2612 FT_List_Up( &library
->renderers
, node
);
2614 if ( renderer
->glyph_format
== ft_glyph_format_outline
)
2615 library
->cur_renderer
= renderer
;
2617 if ( num_params
> 0 )
2619 FTRenderer_setMode set_mode
= renderer
->clazz
->set_mode
;
2622 for ( ; num_params
> 0; num_params
-- )
2624 error
= set_mode( renderer
, parameters
->tag
, parameters
->data
);
2636 FT_Error
FT_Render_Glyph_Internal( FT_Library library
,
2638 FT_UInt render_mode
)
2640 FT_Error error
= FT_Err_Ok
;
2641 FT_Renderer renderer
;
2644 /* if it is already a bitmap, no need to do anything */
2645 switch ( slot
->format
)
2647 case ft_glyph_format_bitmap
: /* already a bitmap, don't do anything */
2652 FT_ListNode node
= 0;
2656 /* small shortcut for the very common case */
2657 if ( slot
->format
== ft_glyph_format_outline
)
2659 renderer
= library
->cur_renderer
;
2660 node
= library
->renderers
.head
;
2663 renderer
= FT_Lookup_Renderer( library
, slot
->format
, &node
);
2665 error
= FT_Err_Unimplemented_Feature
;
2668 error
= renderer
->render( renderer
, slot
, render_mode
, 0 );
2669 if ( !error
|| error
!= FT_Err_Cannot_Render_Glyph
)
2672 /* FT_Err_Cannot_Render_Glyph is returned if the render mode */
2673 /* is unsupported by the current renderer for this glyph image */
2676 /* now, look for another renderer that supports the same */
2678 renderer
= FT_Lookup_Renderer( library
, slot
->format
, &node
);
2682 /* if we changed the current renderer for the glyph image format */
2683 /* we need to select it as the next current one */
2684 if ( !error
&& update
&& renderer
)
2685 FT_Set_Renderer( library
, renderer
, 0, 0 );
2693 /*************************************************************************/
2696 /* FT_Render_Glyph */
2699 /* Converts a given glyph image to a bitmap. It does so by */
2700 /* inspecting the glyph image format, find the relevant renderer, and */
2704 /* slot :: A handle to the glyph slot containing the image to */
2707 /* render_mode :: This is the render mode used to render the glyph */
2708 /* image into a bitmap. See FT_Render_Mode for a list */
2709 /* of possible values. */
2712 /* FreeType error code. 0 means success. */
2714 FT_EXPORT_FUNC( FT_Error
) FT_Render_Glyph( FT_GlyphSlot slot
,
2715 FT_UInt render_mode
)
2721 return FT_Err_Invalid_Argument
;
2723 library
= FT_FACE_LIBRARY( slot
->face
);
2725 return FT_Render_Glyph_Internal( library
, slot
, render_mode
);
2729 /*************************************************************************/
2730 /*************************************************************************/
2731 /*************************************************************************/
2734 /**** M O D U L E S ****/
2737 /*************************************************************************/
2738 /*************************************************************************/
2739 /*************************************************************************/
2742 /*************************************************************************/
2745 /* Destroy_Module */
2748 /* Destroys a given module object. For drivers, this also destroys */
2749 /* all child faces. */
2752 /* module :: A handle to the target driver object. */
2755 /* The driver _must_ be LOCKED! */
2758 void Destroy_Module( FT_Module
module )
2760 FT_Memory memory
= module->memory
;
2761 FT_Module_Class
* clazz
= module->clazz
;
2762 FT_Library library
= module->library
;
2765 /* finalize client-data - before anything else */
2766 if ( module->generic
.finalizer
)
2767 module->generic
.finalizer( module );
2769 if ( library
&& library
->auto_hinter
== module )
2770 library
->auto_hinter
= 0;
2772 /* if the module is a renderer */
2773 if ( FT_MODULE_IS_RENDERER( module ) )
2774 ft_remove_renderer( module );
2776 /* if the module is a font driver, add some steps */
2777 if ( FT_MODULE_IS_DRIVER( module ) )
2778 Destroy_Driver( FT_DRIVER( module ) );
2780 /* finalize the module object */
2781 if ( clazz
->module_done
)
2782 clazz
->module_done( module );
2789 /*************************************************************************/
2795 /* Adds a new module to a given library instance. */
2798 /* library :: A handle to the library object. */
2800 /* clazz :: A pointer to class descriptor for the module. */
2803 /* FreeType error code. 0 means success. */
2806 /* An error will be returned if a module already exists by that name, */
2807 /* or if the module requires a version of FreeType that is too great. */
2809 FT_EXPORT_FUNC( FT_Error
) FT_Add_Module( FT_Library library
,
2810 const FT_Module_Class
* clazz
)
2818 #define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \
2822 return FT_Err_Invalid_Library_Handle
;
2825 return FT_Err_Invalid_Argument
;
2827 /* check freetype version */
2828 if ( clazz
->module_requires
> FREETYPE_VER_FIXED
)
2829 return FT_Err_Invalid_Version
;
2831 /* look for a module with the same name in the library's table */
2832 for ( nn
= 0; nn
< library
->num_modules
; nn
++ )
2834 module = library
->modules
[nn
];
2835 if ( strcmp( module->clazz
->module_name
, clazz
->module_name
) == 0 )
2837 /* this installed module has the same name, compare their versions */
2838 if ( clazz
->module_version
<= module->clazz
->module_version
)
2839 return FT_Err_Lower_Module_Version
;
2841 /* remove the module from our list, then exit the loop to replace */
2842 /* it by our new version.. */
2843 FT_Remove_Module( library
, module );
2848 memory
= library
->memory
;
2851 if ( library
->num_modules
>= FT_MAX_MODULES
)
2853 error
= FT_Err_Too_Many_Drivers
;
2857 /* allocate module object */
2858 if ( ALLOC( module,clazz
->module_size
) )
2861 /* base initialization */
2862 module->library
= library
;
2863 module->memory
= memory
;
2864 module->clazz
= (FT_Module_Class
*)clazz
;
2866 /* check whether the module is a renderer - this must be performed */
2867 /* before the normal module initialization */
2868 if ( FT_MODULE_IS_RENDERER( module ) )
2870 /* add to the renderers list */
2871 error
= ft_add_renderer( module );
2876 /* is the module a auto-hinter? */
2877 if ( FT_MODULE_IS_HINTER( module ) )
2878 library
->auto_hinter
= module;
2880 /* if the module is a font driver */
2881 if ( FT_MODULE_IS_DRIVER( module ) )
2883 /* allocate glyph loader if needed */
2884 FT_Driver driver
= FT_DRIVER( module );
2887 driver
->clazz
= (FT_Driver_Class
*)module->clazz
;
2888 if ( FT_DRIVER_USES_OUTLINES( driver
) )
2890 error
= FT_GlyphLoader_New( memory
, &driver
->glyph_loader
);
2896 if ( clazz
->module_init
)
2898 error
= clazz
->module_init( module );
2903 /* add module to the library's table */
2904 library
->modules
[library
->num_modules
++] = module;
2910 if ( FT_MODULE_IS_DRIVER( module ) )
2912 FT_Driver driver
= FT_DRIVER( module );
2915 if ( FT_DRIVER_USES_OUTLINES( driver
) )
2916 FT_GlyphLoader_Done( driver
->glyph_loader
);
2919 if ( FT_MODULE_IS_RENDERER( module ) )
2921 FT_Renderer renderer
= FT_RENDERER( module );
2924 if ( renderer
->raster
)
2925 renderer
->clazz
->raster_class
->raster_done( renderer
->raster
);
2933 /*************************************************************************/
2939 /* Finds a module by its name. */
2942 /* library :: A handle to the library object. */
2944 /* module_name :: The module's name (as an ASCII string). */
2947 /* A module handle. 0 if none was found. */
2950 /* You should better be familiar with FreeType internals to know */
2951 /* which module to look for :-) */
2953 FT_EXPORT_FUNC( FT_Module
) FT_Get_Module( FT_Library library
,
2954 const char* module_name
)
2956 FT_Module result
= 0;
2961 if ( !library
|| !module_name
)
2964 cur
= library
->modules
;
2965 limit
= cur
+ library
->num_modules
;
2967 for ( ; cur
< limit
; cur
++ )
2968 if ( strcmp( cur
[0]->clazz
->module_name
, module_name
) == 0 )
2978 /*************************************************************************/
2981 /* FT_Get_Module_Interface */
2984 /* Finds a module and returns its specific interface as a typeless */
2988 /* library :: A handle to the library object. */
2990 /* module_name :: The module's name (as an ASCII string). */
2993 /* A module-specific interface if available, 0 otherwise. */
2996 /* You should better be familiar with FreeType internals to know */
2997 /* which module to look for, and what its interface is :-) */
2999 BASE_FUNC( const void* ) FT_Get_Module_Interface( FT_Library library
,
3000 const char* mod_name
)
3005 /* test for valid `library' delayed to FT_Get_Module() */
3007 module = FT_Get_Module( library
, mod_name
);
3009 return module ? module->clazz
->module_interface
: 0;
3013 /*************************************************************************/
3016 /* FT_Remove_Module */
3019 /* Removes a given module from a library instance. */
3022 /* library :: A handle to a library object. */
3024 /* module :: A handle to a module object. */
3027 /* FreeType error code. 0 means success. */
3030 /* The module object is destroyed by the function in case of success. */
3032 FT_EXPORT_FUNC( FT_Error
) FT_Remove_Module( FT_Library library
,
3035 /* try to find the module from the table, then remove it from there */
3038 return FT_Err_Invalid_Library_Handle
;
3042 FT_Module
* cur
= library
->modules
;
3043 FT_Module
* limit
= cur
+ library
->num_modules
;
3046 for ( ; cur
< limit
; cur
++ )
3048 if ( cur
[0] == module )
3050 /* remove it from the table */
3051 library
->num_modules
--;
3053 while ( cur
< limit
)
3060 /* destroy the module */
3061 Destroy_Module( module );
3067 return FT_Err_Invalid_Driver_Handle
;
3071 /*************************************************************************/
3072 /*************************************************************************/
3073 /*************************************************************************/
3076 /**** L I B R A R Y ****/
3079 /*************************************************************************/
3080 /*************************************************************************/
3081 /*************************************************************************/
3084 /*************************************************************************/
3087 /* FT_New_Library */
3090 /* This function is used to create a new FreeType library instance */
3091 /* from a given memory object. It is thus possible to use libraries */
3092 /* with distinct memory allocators within the same program. */
3095 /* memory :: A handle to the original memory object. */
3098 /* alibrary :: A pointer to handle of a new library object. */
3101 /* FreeType error code. 0 means success. */
3103 FT_EXPORT_FUNC( FT_Error
) FT_New_Library( FT_Memory memory
,
3104 FT_Library
* alibrary
)
3106 FT_Library library
= 0;
3111 return FT_Err_Invalid_Argument
;
3113 /* first of all, allocate the library object */
3114 if ( ALLOC( library
, sizeof ( *library
) ) )
3117 library
->memory
= memory
;
3119 /* allocate the render pool */
3120 library
->raster_pool_size
= FT_RENDER_POOL_SIZE
;
3121 if ( ALLOC( library
->raster_pool
, FT_RENDER_POOL_SIZE
) )
3125 *alibrary
= library
;
3135 /*************************************************************************/
3138 /* FT_Done_Library */
3141 /* Discards a given library object. This closes all drivers and */
3142 /* discards all resource objects. */
3145 /* library :: A handle to the target library. */
3148 /* FreeType error code. 0 means success. */
3150 FT_EXPORT_FUNC( FT_Error
) FT_Done_Library( FT_Library library
)
3157 return FT_Err_Invalid_Library_Handle
;
3159 memory
= library
->memory
;
3161 /* Discard client-data */
3162 if ( library
->generic
.finalizer
)
3163 library
->generic
.finalizer( library
);
3165 /* Close all modules in the library */
3166 for ( n
= 0; n
< library
->num_modules
; n
++ )
3168 FT_Module
module = library
->modules
[n
];
3173 Destroy_Module( module );
3174 library
->modules
[n
] = 0;
3178 /* Destroy raster objects */
3179 FREE( library
->raster_pool
);
3180 library
->raster_pool_size
= 0;
3187 /*************************************************************************/
3190 /* FT_Set_Debug_Hook */
3193 /* Sets a debug hook function for debugging the interpreter of a font */
3197 /* library :: A handle to the library object. */
3199 /* hook_index :: The index of the debug hook. You should use the */
3200 /* values defined in ftobjs.h, e.g. */
3201 /* FT_DEBUG_HOOK_TRUETYPE */
3203 /* debug_hook :: The function used to debug the interpreter. */
3206 /* Currently, four debug hook slots are available, but only two (for */
3207 /* the TrueType and the Type 1 interpreter) are defined. */
3209 FT_EXPORT_FUNC( void ) FT_Set_Debug_Hook( FT_Library library
,
3211 FT_DebugHook_Func debug_hook
)
3213 if ( library
&& debug_hook
&&
3215 ( sizeof ( library
->debug_hooks
) / sizeof ( void* ) ) )
3216 library
->debug_hooks
[hook_index
] = debug_hook
;
3220 /*************************************************************************/
3223 /* FT_Done_FreeType */
3226 /* Destroys a given FreeType library object and all of its childs, */
3227 /* including resources, drivers, faces, sizes, etc. */
3230 /* library :: A handle to the target library object. */
3233 /* FreeType error code. 0 means success. */
3235 FT_EXPORT_FUNC( FT_Error
) FT_Done_FreeType( FT_Library library
)
3237 /* test for valid `library' delayed to FT_Done_Library() */
3239 /* Discard the library object */
3240 FT_Done_Library( library
);