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 );