:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / win32k / freetype / src / base / ftobjs.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftobjs.c                                                               */
4 /*                                                                         */
5 /*    The FreeType private base classes (body).                            */
6 /*                                                                         */
7 /*  Copyright 1996-2000 by                                                 */
8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 /*                                                                         */
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.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17
18
19 #include <freetype/internal/ftobjs.h>
20 #include <freetype/internal/ftlist.h>
21 #include <freetype/internal/ftdebug.h>
22 #include <freetype/internal/ftstream.h>
23
24 #include <freetype/tttables.h>
25
26 #include <string.h>     /* for strcmp() */
27
28
29   /*************************************************************************/
30   /*************************************************************************/
31   /*************************************************************************/
32   /****                                                                 ****/
33   /****                                                                 ****/
34   /****                           M E M O R Y                           ****/
35   /****                                                                 ****/
36   /****                                                                 ****/
37   /*************************************************************************/
38   /*************************************************************************/
39   /*************************************************************************/
40
41   /*************************************************************************/
42   /*                                                                       */
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.                                            */
46   /*                                                                       */
47 #undef  FT_COMPONENT
48 #define FT_COMPONENT  trace_memory
49
50
51   /*************************************************************************/
52   /*                                                                       */
53   /* <Function>                                                            */
54   /*    FT_Alloc                                                           */
55   /*                                                                       */
56   /* <Description>                                                         */
57   /*    Allocates a new block of memory.  The returned area is always      */
58   /*    zero-filled; this is a strong convention in many FreeType parts.   */
59   /*                                                                       */
60   /* <Input>                                                               */
61   /*    memory :: A handle to a given `memory object' which handles        */
62   /*              allocation.                                              */
63   /*                                                                       */
64   /*    size   :: The size in bytes of the block to allocate.              */
65   /*                                                                       */
66   /* <Output>                                                              */
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.                */
69   /*                                                                       */
70   /* <Return>                                                              */
71   /*    FreeType error code.  0 means success.                             */
72   /*                                                                       */
73   BASE_FUNC( FT_Error )  FT_Alloc( FT_Memory  memory,
74                                    FT_Long    size,
75                                    void**     P )
76   {
77     FT_Assert( P != 0 );
78
79     if ( size > 0 )
80     {
81       *P = memory->alloc( memory, size );
82       if ( !*P )
83       {
84         FT_ERROR(( "FT_Alloc:" ));
85         FT_ERROR(( " Out of memory? (%ld requested)\n",
86                    size ));
87
88         return FT_Err_Out_Of_Memory;
89       }
90       MEM_Set( *P, 0, size );
91     }
92     else
93       *P = NULL;
94
95     FT_TRACE7(( "FT_Alloc:" ));
96     FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n",
97                 size, *P, P ));
98
99     return FT_Err_Ok;
100   }
101
102
103   /*************************************************************************/
104   /*                                                                       */
105   /* <Function>                                                            */
106   /*    FT_Realloc                                                         */
107   /*                                                                       */
108   /* <Description>                                                         */
109   /*    Reallocates a block of memory pointed to by `*P' to `Size' bytes   */
110   /*    from the heap, possibly changing `*P'.                             */
111   /*                                                                       */
112   /* <Input>                                                               */
113   /*    memory  :: A handle to a given `memory object' which handles       */
114   /*               reallocation.                                           */
115   /*                                                                       */
116   /*    current :: The current block size in bytes.                        */
117   /*                                                                       */
118   /*    size    :: The new block size in bytes.                            */
119   /*                                                                       */
120   /* <InOut>                                                               */
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.               */
123   /*                                                                       */
124   /* <Return>                                                              */
125   /*    FreeType error code.  0 means success.                             */
126   /*                                                                       */
127   /* <Note>                                                                */
128   /*    All callers of FT_Realloc() _must_ provide the current block size  */
129   /*    as well as the new one.                                            */
130   /*                                                                       */
131   BASE_FUNC( FT_Error )  FT_Realloc( FT_Memory  memory,
132                                      FT_Long    current,
133                                      FT_Long    size,
134                                      void**     P )
135   {
136     void*  Q;
137
138
139     FT_Assert( P != 0 );
140
141     /* if the original pointer is NULL, call FT_Alloc() */
142     if ( !*P )
143       return FT_Alloc( memory, size, P );
144
145     /* if the new block if zero-sized, clear the current one */
146     if ( size <= 0 )
147     {
148       FT_Free( memory, P );
149       return FT_Err_Ok;
150     }
151
152     Q = memory->realloc( memory, current, size, *P );
153     if ( !Q )
154       goto Fail;
155
156     *P = Q;
157     return FT_Err_Ok;
158
159   Fail:
160     FT_ERROR(( "FT_Realloc:" ));
161     FT_ERROR(( " Failed (current %ld, requested %ld)\n",
162                current, size ));
163     return FT_Err_Out_Of_Memory;
164   }
165
166
167   /*************************************************************************/
168   /*                                                                       */
169   /* <Function>                                                            */
170   /*    FT_Free                                                            */
171   /*                                                                       */
172   /* <Description>                                                         */
173   /*    Releases a given block of memory allocated through FT_Alloc().     */
174   /*                                                                       */
175   /* <Input>                                                               */
176   /*    memory :: A handle to a given `memory object' which handles        */
177   /*              memory deallocation                                      */
178   /*                                                                       */
179   /*    P      :: This is the _address_ of a _pointer_ which points to the */
180   /*              allocated block.  It is always set to NULL on exit.      */
181   /*                                                                       */
182   /* <Return>                                                              */
183   /*    FreeType error code.  0 means success.                             */
184   /*                                                                       */
185   /* <Note>                                                                */
186   /*    If P or *P are NULL, this function should return successfully.     */
187   /*    This is a strong convention within all of FreeType and its         */
188   /*    drivers.                                                           */
189   /*                                                                       */
190   BASE_FUNC( void )  FT_Free( FT_Memory  memory,
191                               void**     P )
192   {
193     FT_TRACE7(( "FT_Free:" ));
194     FT_TRACE7(( " Freeing block 0x%08p, ref 0x%08p\n",
195                 P, P ? *P : (void*)0 ));
196
197     if ( P && *P )
198     {
199       memory->free( memory, *P );
200       *P = 0;
201     }
202   }
203
204
205   /*************************************************************************/
206   /*************************************************************************/
207   /*************************************************************************/
208   /****                                                                 ****/
209   /****                                                                 ****/
210   /****                           S T R E A M                           ****/
211   /****                                                                 ****/
212   /****                                                                 ****/
213   /*************************************************************************/
214   /*************************************************************************/
215   /*************************************************************************/
216
217
218   /*************************************************************************/
219   /*                                                                       */
220   /* <Function>                                                            */
221   /*    ft_new_input_stream                                                */
222   /*                                                                       */
223   /* <Description>                                                         */
224   /*    Creates a new input stream object from an FT_Open_Args structure.  */
225   /*                                                                       */
226   /* <Note>                                                                */
227   /*    The function expects a valid `astream' parameter.                  */
228   /*                                                                       */
229   static
230   FT_Error  ft_new_input_stream( FT_Library     library,
231                                  FT_Open_Args*  args,
232                                  FT_Stream*     astream )
233   {
234     FT_Error   error;
235     FT_Memory  memory;
236     FT_Stream  stream;
237
238
239     if ( !library )
240       return FT_Err_Invalid_Library_Handle;
241
242     if ( !args )
243       return FT_Err_Invalid_Argument;
244
245     *astream = 0;
246     memory   = library->memory;
247     if ( ALLOC( stream, sizeof ( *stream ) ) )
248       goto Exit;
249
250     stream->memory = memory;
251
252     /* now, look at the stream flags */
253     if ( args->flags & ft_open_memory )
254     {
255       error = 0;
256       FT_New_Memory_Stream( library,
257                             args->memory_base,
258                             args->memory_size,
259                             stream );
260     }
261     else if ( args->flags & ft_open_pathname )
262     {
263       error = FT_New_Stream( args->pathname, stream );
264       stream->pathname.pointer = args->pathname;
265     }
266     else if ( args->flags & ft_open_stream && args->stream )
267     {
268       *stream        = *(args->stream);
269       stream->memory = memory;
270     }
271     else
272       error = FT_Err_Invalid_Argument;
273
274     if ( error )
275       FREE( stream );
276
277     *astream = stream;
278
279   Exit:
280     return error;
281   }
282
283
284   /*************************************************************************/
285   /*                                                                       */
286   /* <Function>                                                            */
287   /*    FT_Done_Stream                                                     */
288   /*                                                                       */
289   /* <Description>                                                         */
290   /*    Closes and destroys a stream object.                               */
291   /*                                                                       */
292   /* <Input>                                                               */
293   /*    stream :: The stream to be closed and destroyed.                   */
294   /*                                                                       */
295   FT_EXPORT_FUNC( void )  FT_Done_Stream( FT_Stream  stream )
296   {
297     if ( stream && stream->close )
298       stream->close( stream );
299   }
300
301
302   static
303   void  ft_done_stream( FT_Stream*  astream )
304   {
305     FT_Stream  stream = *astream;
306     FT_Memory  memory = stream->memory;
307
308
309     if ( stream->close )
310       stream->close( stream );
311
312     FREE( stream );
313     *astream = 0;
314   }
315
316
317 #undef  FT_COMPONENT
318 #define FT_COMPONENT  trace_objs
319
320
321   /*************************************************************************/
322   /*************************************************************************/
323   /*************************************************************************/
324   /****                                                                 ****/
325   /****                                                                 ****/
326   /****                     G L Y P H   L O A D E R                     ****/
327   /****                                                                 ****/
328   /****                                                                 ****/
329   /*************************************************************************/
330   /*************************************************************************/
331   /*************************************************************************/
332
333
334   /*************************************************************************/
335   /*                                                                       */
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. */
338   /*                                                                       */
339   /* Ideally, one can see it as a stack of abstract `glyph' objects.       */
340   /*                                                                       */
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').              */
344   /*                                                                       */
345   /*   loader.current  Describes the top of the stack, on which a new      */
346   /*                   glyph can be loaded.                                */
347   /*                                                                       */
348   /*   Rewind          Clears the stack.                                   */
349   /*   Prepare         Set up `loader.current' for addition of a new glyph */
350   /*                   image.                                              */
351   /*   Add             Add the `current' glyph image to the `base' one,    */
352   /*                   and prepare for another one.                        */
353   /*                                                                       */
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        */
356   /* energy.                                                               */
357   /*                                                                       */
358   /*************************************************************************/
359
360
361   /* create a new glyph loader */
362   BASE_FUNC( FT_Error )  FT_GlyphLoader_New( FT_Memory         memory,
363                                              FT_GlyphLoader**  aloader )
364   {
365     FT_GlyphLoader*  loader;
366     FT_Error         error;
367
368
369     if ( !ALLOC( loader, sizeof ( *loader ) ) )
370     {
371       loader->memory = memory;
372       *aloader       = loader;
373     }
374     return error;
375   }
376
377
378   /* rewind the glyph loader - reset counters to 0 */
379   BASE_FUNC( void )  FT_GlyphLoader_Rewind( FT_GlyphLoader*  loader )
380   {
381     FT_GlyphLoad*  base    = &loader->base;
382     FT_GlyphLoad*  current = &loader->current;
383
384
385     base->outline.n_points   = 0;
386     base->outline.n_contours = 0;
387     base->num_subglyphs      = 0;
388
389     *current = *base;
390   }
391
392
393   /* reset the glyph loader, frees all allocated tables */
394   /* and starts from zero                               */
395   BASE_FUNC( void )  FT_GlyphLoader_Reset( FT_GlyphLoader*  loader )
396   {
397     FT_Memory memory = loader->memory;
398
399
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 );
405
406     loader->max_points    = 0;
407     loader->max_contours  = 0;
408     loader->max_subglyphs = 0;
409
410     FT_GlyphLoader_Rewind( loader );
411   }
412
413
414   /* delete a glyph loader */
415   BASE_FUNC( void )  FT_GlyphLoader_Done( FT_GlyphLoader*  loader )
416   {
417     if ( loader )
418     {
419       FT_Memory memory = loader->memory;
420
421
422       FT_GlyphLoader_Reset( loader );
423       FREE( loader );
424     }
425   }
426
427
428   /* re-adjust the `current' outline fields */
429   static
430   void  FT_GlyphLoader_Adjust_Points( FT_GlyphLoader*  loader )
431   {
432     FT_Outline*  base    = &loader->base.outline;
433     FT_Outline*  current = &loader->current.outline;
434
435
436     current->points   = base->points   + base->n_points;
437     current->tags     = base->tags     + base->n_points;
438     current->contours = base->contours + base->n_contours;
439
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;
444   }
445
446
447   BASE_FUNC( FT_Error )  FT_GlyphLoader_Create_Extra(
448                            FT_GlyphLoader*  loader )
449   {
450     FT_Error   error;
451     FT_Memory  memory = loader->memory;
452
453
454     if ( !ALLOC_ARRAY( loader->base.extra_points,
455                        loader->max_points, FT_Vector ) )
456     {
457       loader->use_extra = 1;
458       FT_GlyphLoader_Adjust_Points( loader );
459     }
460     return error;
461   }
462
463
464   /* re-adjust the `current' subglyphs field */
465   static
466   void  FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader*  loader )
467   {
468     FT_GlyphLoad* base    = &loader->base;
469     FT_GlyphLoad* current = &loader->current;
470
471
472     current->subglyphs = base->subglyphs + base->num_subglyphs;
473   }
474
475
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!                */
479   /*                                                                       */
480   BASE_FUNC( FT_Error ) FT_GlyphLoader_Check_Points(
481                           FT_GlyphLoader*  loader,
482                           FT_UInt          n_points,
483                           FT_UInt          n_contours )
484   {
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;
489     FT_Bool      adjust  = 1;
490
491     FT_UInt      new_max;
492
493
494     /* check points & tags */
495     new_max = base->n_points + current->n_points + n_points;
496     if ( new_max > loader->max_points )
497     {
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,
502                           new_max, FT_Byte   )          )
503        goto Exit;
504
505       if ( loader->use_extra &&
506            REALLOC_ARRAY( loader->base.extra_points, base->n_points,
507                           new_max, FT_Vector ) )
508        goto Exit;
509
510       adjust = 1;
511       loader->max_points = new_max;
512     }
513
514     /* check contours */
515     new_max = base->n_contours + current->n_contours +
516               n_contours;
517     if ( new_max > loader->max_contours )
518     {
519       new_max = ( new_max + 3 ) & -4;
520       if ( REALLOC_ARRAY( base->contours, base->n_contours,
521                           new_max, FT_Short ) )
522         goto Exit;
523
524       adjust = 1;
525       loader->max_contours = new_max;
526     }
527
528     if ( adjust )
529       FT_GlyphLoader_Adjust_Points( loader );
530
531   Exit:
532     return error;
533   }
534
535
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!            */
539   /*                                                                  */
540   BASE_FUNC( FT_Error )  FT_GlyphLoader_Check_Subglyphs(
541                            FT_GlyphLoader*  loader,
542                            FT_UInt          n_subs )
543   {
544     FT_Memory  memory = loader->memory;
545     FT_Error   error  = FT_Err_Ok;
546     FT_UInt    new_max;
547
548     FT_GlyphLoad*  base    = &loader->base;
549     FT_GlyphLoad*  current = &loader->current;
550
551
552     new_max = base->num_subglyphs + current->num_subglyphs + n_subs;
553     if ( new_max > loader->max_subglyphs )
554     {
555       new_max = ( new_max + 1 ) & -2;
556       if ( REALLOC_ARRAY( base->subglyphs, base->num_subglyphs,
557                           new_max, FT_SubGlyph ) )
558         goto Exit;
559
560       loader->max_subglyphs = new_max;
561
562       FT_GlyphLoader_Adjust_Subglyphs( loader );
563     }
564
565   Exit:
566     return error;
567   }
568
569
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 )
572   {
573     FT_GlyphLoad*  current = &loader->current;
574
575
576     current->outline.n_points   = 0;
577     current->outline.n_contours = 0;
578     current->num_subglyphs      = 0;
579
580     FT_GlyphLoader_Adjust_Points   ( loader );
581     FT_GlyphLoader_Adjust_Subglyphs( loader );
582   }
583
584
585   /* add current glyph to the base image - and prepare for another */
586   BASE_FUNC( void )  FT_GlyphLoader_Add( FT_GlyphLoader*  loader )
587   {
588     FT_GlyphLoad*  base    = &loader->base;
589     FT_GlyphLoad*  current = &loader->current;
590
591     FT_UInt        n_curr_contours = current->outline.n_contours;
592     FT_UInt        n_base_points   = base->outline.n_points;
593     FT_UInt        n;
594
595
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;
599
600     /* adjust contours count in newest outline */
601     for ( n = 0; n < n_curr_contours; n++ )
602       current->outline.contours[n] += n_base_points;
603
604     /* prepare for another new glyph image */
605     FT_GlyphLoader_Prepare( loader );
606   }
607
608
609   BASE_FUNC( FT_Error )  FT_GlyphLoader_Copy_Points( FT_GlyphLoader*  target,
610                                                      FT_GlyphLoader*  source )
611   {
612     FT_Error  error;
613     FT_UInt   num_points   = source->base.outline.n_points;
614     FT_UInt   num_contours = source->base.outline.n_contours;
615
616
617     error = FT_GlyphLoader_Check_Points( target, num_points, num_contours );
618     if ( !error )
619     {
620       FT_Outline*  out = &target->base.outline;
621       FT_Outline*  in  = &source->base.outline;
622
623
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 ) );
630
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 ) );
635
636       out->n_points   = num_points;
637       out->n_contours = num_contours;
638
639       FT_GlyphLoader_Adjust_Points( target );
640     }
641
642     return error;
643   }
644
645
646   /*************************************************************************/
647   /*************************************************************************/
648   /*************************************************************************/
649   /****                                                                 ****/
650   /****                                                                 ****/
651   /****               FACE, SIZE & GLYPH SLOT OBJECTS                   ****/
652   /****                                                                 ****/
653   /****                                                                 ****/
654   /*************************************************************************/
655   /*************************************************************************/
656   /*************************************************************************/
657
658
659   static
660   FT_Error  ft_glyphslot_init( FT_GlyphSlot  slot )
661   {
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;
666
667
668     slot->library = driver->root.library;
669
670     if ( FT_DRIVER_USES_OUTLINES( driver ) )
671       error = FT_GlyphLoader_New( memory, &slot->loader );
672
673     if ( !error && clazz->init_slot )
674       error = clazz->init_slot( slot );
675
676     return error;
677   }
678
679
680   static
681   void  ft_glyphslot_clear( FT_GlyphSlot  slot )
682   {
683     /* free bitmap if needed */
684     if ( slot->flags & ft_glyph_own_bitmap )
685     {
686       FT_Memory  memory = FT_FACE_MEMORY( slot->face );
687
688
689       FREE( slot->bitmap.buffer );
690       slot->flags &= ~ft_glyph_own_bitmap;
691     }
692
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 )  );
697
698     slot->bitmap_left   = 0;
699     slot->bitmap_top    = 0;
700     slot->num_subglyphs = 0;
701     slot->subglyphs     = 0;
702     slot->control_data  = 0;
703     slot->control_len   = 0;
704     slot->other         = 0;
705     slot->format        = ft_glyph_format_none;
706
707     slot->linearHoriAdvance = 0;
708     slot->linearVertAdvance = 0;
709   }
710
711
712   static
713   void  ft_glyphslot_done( FT_GlyphSlot  slot )
714   {
715     FT_Driver         driver = slot->face->driver;
716     FT_Driver_Class*  clazz  = driver->clazz;
717     FT_Memory         memory = driver->root.memory;
718
719
720     /* free bitmap buffer if needed */
721     if ( slot->flags & ft_glyph_own_bitmap )
722       FREE( slot->bitmap.buffer );
723
724     /* free glyph loader */
725     if ( FT_DRIVER_USES_OUTLINES( driver ) )
726     {
727       FT_GlyphLoader_Done( slot->loader );
728       slot->loader = 0;
729     }
730
731     if ( clazz->done_slot )
732       clazz->done_slot( slot );
733   }
734
735
736   /*************************************************************************/
737   /*                                                                       */
738   /* <Function>                                                            */
739   /*    FT_New_GlyphSlot                                                   */
740   /*                                                                       */
741   /* <Description>                                                         */
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   */
745   /*    destroyed.                                                         */
746   /*                                                                       */
747   /* <Input>                                                               */
748   /*    face  :: A handle to a parent face object.                         */
749   /*                                                                       */
750   /* <Output>                                                              */
751   /*    aslot :: A handle to a new glyph slot object.                      */
752   /*                                                                       */
753   /* <Return>                                                              */
754   /*    FreeType error code.  0 means success.                             */
755   /*                                                                       */
756   FT_EXPORT_FUNC( FT_Error )  FT_New_GlyphSlot( FT_Face        face,
757                                                 FT_GlyphSlot*  aslot )
758   {
759     FT_Error          error;
760     FT_Driver         driver;
761     FT_Driver_Class*  clazz;
762     FT_Memory         memory;
763     FT_GlyphSlot      slot;
764
765
766     if ( !face || !aslot || !face->driver )
767       return FT_Err_Invalid_Argument;
768
769     *aslot = 0;
770
771     driver = face->driver;
772     clazz  = driver->clazz;
773     memory = driver->root.memory;
774
775     FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
776     if ( !ALLOC( slot, clazz->slot_object_size ) )
777     {
778       slot->face = face;
779
780       error = ft_glyphslot_init( slot );
781       if ( error )
782       {
783         ft_glyphslot_done( slot );
784         FREE( slot );
785         goto Exit;
786       }
787
788       *aslot = slot;
789     }
790
791   Exit:
792     FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
793     return error;
794   }
795
796
797   /*************************************************************************/
798   /*                                                                       */
799   /* <Function>                                                            */
800   /*    FT_Done_GlyphSlot                                                  */
801   /*                                                                       */
802   /* <Description>                                                         */
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.                                              */
806   /*                                                                       */
807   /* <Input>                                                               */
808   /*    slot :: A handle to a target glyph slot.                           */
809   /*                                                                       */
810   FT_EXPORT_FUNC( void )  FT_Done_GlyphSlot( FT_GlyphSlot  slot )
811   {
812     if ( slot )
813     {
814       FT_Driver         driver = slot->face->driver;
815       FT_Memory         memory = driver->root.memory;
816       FT_GlyphSlot*     parent;
817       FT_GlyphSlot      cur;
818
819
820       /* Remove slot from its parent face's list */
821       parent = &slot->face->glyph;
822       cur    = *parent;
823
824       while ( cur )
825       {
826         if ( cur == slot )
827         {
828           *parent = cur->next;
829           ft_glyphslot_done( slot );
830           FREE( slot );
831           break;
832         }
833         cur = cur->next;
834       }
835     }
836   }
837
838
839   /*************************************************************************/
840   /*                                                                       */
841   /* <Function>                                                            */
842   /*    FT_Set_Transform                                                   */
843   /*                                                                       */
844   /* <Description>                                                         */
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.                                  */
848   /*                                                                       */
849   /* <InOut>                                                               */
850   /*    face   :: A handle to the source face object.                      */
851   /*                                                                       */
852   /* <Input>                                                               */
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 */
856   /*              vector.                                                  */
857   /*                                                                       */
858   /* <Note>                                                                */
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().      */
863   /*                                                                       */
864   FT_EXPORT_FUNC( void )  FT_Set_Transform( FT_Face     face,
865                                             FT_Matrix*  matrix,
866                                             FT_Vector*  delta )
867   {
868     if ( !face )
869       return;
870
871     face->transform_flags = 0;
872
873     if ( !matrix )
874     {
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;
880     }
881     else
882       face->transform_matrix = *matrix;
883
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;
889
890     if ( !delta )
891     {
892       face->transform_delta.x = 0;
893       face->transform_delta.y = 0;
894       delta = &face->transform_delta;
895     }
896     else
897       face->transform_delta = *delta;
898
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;
902   }
903
904
905   static FT_Renderer  ft_lookup_glyph_renderer( FT_GlyphSlot  slot );
906
907
908   /*************************************************************************/
909   /*                                                                       */
910   /* <Function>                                                            */
911   /*    FT_Load_Glyph                                                      */
912   /*                                                                       */
913   /* <Description>                                                         */
914   /*    A function used to load a single glyph within a given glyph slot,  */
915   /*    for a given size.                                                  */
916   /*                                                                       */
917   /* <Input>                                                               */
918   /*    face        :: A handle to the target face object where the glyph  */
919   /*                   will be loaded.                                     */
920   /*                                                                       */
921   /*    glyph_index :: The index of the glyph in the font file.            */
922   /*                                                                       */
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).                  */
928   /*                                                                       */
929   /* <Return>                                                              */
930   /*    FreeType error code.  0 means success.                             */
931   /*                                                                       */
932   /* <Note>                                                                */
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.                                                  */
937   /*                                                                       */
938   /*    Note that this also transforms the `face.glyph.advance' field, but */
939   /*    *not* the values in `face.glyph.metrics'.                          */
940   /*                                                                       */
941   FT_EXPORT_FUNC( FT_Error )  FT_Load_Glyph( FT_Face  face,
942                                              FT_UInt  glyph_index,
943                                              FT_Int   load_flags )
944   {
945     FT_Error      error;
946     FT_Driver     driver;
947     FT_GlyphSlot  slot;
948     FT_Library    library;
949     FT_Bool       autohint;
950     FT_Module     hinter;
951
952
953     if ( !face || !face->size || !face->glyph )
954       return FT_Err_Invalid_Face_Handle;
955
956     if ( glyph_index >= (FT_UInt)face->num_glyphs )
957       return FT_Err_Invalid_Argument;
958
959     slot = face->glyph;
960     ft_glyphslot_clear( slot );
961
962     driver = face->driver;
963
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;
967
968     /* do we need to load the glyph through the auto-hinter? */
969     library  = driver->root.library;
970     hinter   = library->auto_hinter;
971     autohint = hinter &&
972                !( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) );
973     if ( autohint )
974     {
975       if ( FT_DRIVER_HAS_HINTER( driver ) &&
976            !( load_flags & FT_LOAD_FORCE_AUTOHINT ) )
977         autohint = 0;
978     }
979
980     if ( autohint )
981     {
982       FT_AutoHinter_Interface*  hinting;
983
984
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 );
988     }
989     else
990       error = driver->clazz->load_glyph( slot,
991                                          face->size,
992                                          glyph_index,
993                                          load_flags );
994     if ( error )
995       goto Exit;
996
997     /* compute the advance */
998     if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
999     {
1000       slot->advance.x = 0;
1001       slot->advance.y = slot->metrics.vertAdvance;
1002     }
1003     else
1004     {
1005       slot->advance.x = slot->metrics.horiAdvance;
1006       slot->advance.y = 0;
1007     }
1008
1009     /* now, transform the glyph image when needed */
1010     if ( face->transform_flags )
1011     {
1012       /* get renderer */
1013       FT_Renderer  renderer = ft_lookup_glyph_renderer( slot );
1014
1015
1016       if ( renderer )
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 );
1022     }
1023
1024     /* do we need to render the image now? */
1025     if ( !error                                    &&
1026          slot->format != ft_glyph_format_bitmap    &&
1027          slot->format != ft_glyph_format_composite &&
1028          load_flags & FT_LOAD_RENDER )
1029     {
1030       error = FT_Render_Glyph( slot,
1031                                ( load_flags & FT_LOAD_MONOCHROME )
1032                                   ? ft_render_mode_mono
1033                                   : ft_render_mode_normal );
1034     }
1035
1036   Exit:
1037     return error;
1038   }
1039
1040
1041   /*************************************************************************/
1042   /*                                                                       */
1043   /* <Function>                                                            */
1044   /*    FT_Load_Char                                                       */
1045   /*                                                                       */
1046   /* <Description>                                                         */
1047   /*    A function used to load a single glyph within a given glyph slot,  */
1048   /*    for a given size, according to its character code.                 */
1049   /*                                                                       */
1050   /* <Input>                                                               */
1051   /*    face        :: A handle to a target face object where the glyph    */
1052   /*                   will be loaded.                                     */
1053   /*                                                                       */
1054   /*    char_code   :: The glyph's character code, according to the        */
1055   /*                   current charmap used in the face.                   */
1056   /*                                                                       */
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).                  */
1062   /*                                                                       */
1063   /* <Return>                                                              */
1064   /*    FreeType error code.  0 means success.                             */
1065   /*                                                                       */
1066   /* <Note>                                                                */
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        */
1069   /*    error.                                                             */
1070   /*                                                                       */
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().                                                */
1075   /*                                                                       */
1076   /*    Note that this also transforms the `face.glyph.advance' field, but */
1077   /*    *not* the values in `face.glyph.metrics'.                          */
1078   /*                                                                       */
1079   FT_EXPORT_FUNC( FT_Error )  FT_Load_Char( FT_Face   face,
1080                                             FT_ULong  char_code,
1081                                             FT_Int    load_flags )
1082   {
1083     FT_UInt  glyph_index;
1084
1085
1086     if ( !face )
1087       return FT_Err_Invalid_Face_Handle;
1088
1089     glyph_index = (FT_UInt)char_code;
1090     if ( face->charmap )
1091       glyph_index = FT_Get_Char_Index( face, char_code );
1092
1093     return FT_Load_Glyph( face, glyph_index, load_flags );
1094   }
1095
1096
1097   /* destructor for sizes list */
1098   static
1099   void  destroy_size( FT_Memory  memory,
1100                       FT_Size    size,
1101                       FT_Driver  driver )
1102   {
1103     /* finalize client-specific data */
1104     if ( size->generic.finalizer )
1105       size->generic.finalizer( size );
1106
1107     /* finalize format-specific stuff */
1108     if ( driver->clazz->done_size )
1109       driver->clazz->done_size( size );
1110
1111     FREE( size );
1112   }
1113
1114
1115   /* destructor for faces list */
1116   static
1117   void  destroy_face( FT_Memory  memory,
1118                       FT_Face    face,
1119                       FT_Driver  driver )
1120   {
1121     FT_Driver_Class*  clazz = driver->clazz;
1122
1123
1124     /* discard auto-hinting data */
1125     if ( face->autohint.finalizer )
1126       face->autohint.finalizer( face->autohint.data );
1127       
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 );
1132
1133     /* Discard all sizes for this face */
1134     FT_List_Finalize( &face->sizes_list,
1135                      (FT_List_Destructor)destroy_size,
1136                      memory,
1137                      driver );
1138     face->size = 0;
1139
1140     /* Now discard client data */
1141     if ( face->generic.finalizer )
1142       face->generic.finalizer( face );
1143
1144     /* finalize format-specific stuff */
1145     if ( clazz->done_face )
1146       clazz->done_face( face );
1147
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 );
1151
1152     /* get rid of it */
1153     FREE( face );
1154   }
1155
1156
1157   static
1158   void  Destroy_Driver( FT_Driver  driver )
1159   {
1160     FT_List_Finalize( &driver->faces_list,
1161                       (FT_List_Destructor)destroy_face,
1162                       driver->root.memory,
1163                       driver );
1164
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 );
1168   }
1169
1170
1171   /*************************************************************************/
1172   /*                                                                       */
1173   /* <Function>                                                            */
1174   /*    open_face                                                          */
1175   /*                                                                       */
1176   /* <Description>                                                         */
1177   /*    This function does some work for FT_Open_Face().                   */
1178   /*                                                                       */
1179   static
1180   FT_Error  open_face( FT_Driver      driver,
1181                        FT_Stream      stream,
1182                        FT_Long        face_index,
1183                        FT_Int         num_params,
1184                        FT_Parameter*  params,
1185                        FT_Face*       aface )
1186   {
1187     FT_Memory         memory;
1188     FT_Driver_Class*  clazz;
1189     FT_Face           face = 0;
1190     FT_Error          error;
1191
1192
1193     clazz  = driver->clazz;
1194     memory = driver->root.memory;
1195
1196     /* allocate the face object and perform basic initialization */
1197     if ( ALLOC( face, clazz->face_object_size ) )
1198       goto Fail;
1199
1200     face->driver = driver;
1201     face->memory = memory;
1202     face->stream = stream;
1203
1204     error = clazz->init_face( stream,
1205                               face,
1206                               face_index,
1207                               num_params,
1208                               params );
1209     if ( error )
1210       goto Fail;
1211
1212     *aface = face;
1213
1214   Fail:
1215     if ( error )
1216     {
1217       clazz->done_face( face );
1218       FREE( face );
1219       *aface = 0;
1220     }
1221
1222     return error;
1223   }
1224
1225
1226   /*************************************************************************/
1227   /*                                                                       */
1228   /* <Function>                                                            */
1229   /*    FT_New_Face                                                        */
1230   /*                                                                       */
1231   /* <Description>                                                         */
1232   /*    Creates a new face object from a given resource and typeface index */
1233   /*    using a pathname to the font file.                                 */
1234   /*                                                                       */
1235   /* <InOut>                                                               */
1236   /*    library    :: A handle to the library resource.                    */
1237   /*                                                                       */
1238   /* <Input>                                                               */
1239   /*    pathname   :: A path to the font file.                             */
1240   /*                                                                       */
1241   /*    face_index :: The index of the face within the resource.  The      */
1242   /*                  first face has index 0.                              */
1243   /* <Output>                                                              */
1244   /*    aface      :: A handle to a new face object.                       */
1245   /*                                                                       */
1246   /* <Return>                                                              */
1247   /*    FreeType error code.  0 means success.                             */
1248   /*                                                                       */
1249   /* <Note>                                                                */
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'.                                                     */
1253   /*                                                                       */
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.                                   */
1257   /*                                                                       */
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.                                    */
1263   /*                                                                       */
1264   FT_EXPORT_FUNC( FT_Error )  FT_New_Face( FT_Library   library,
1265                                            const char*  pathname,
1266                                            FT_Long      face_index,
1267                                            FT_Face*     aface )
1268   {
1269     FT_Open_Args  args;
1270
1271
1272     /* test for valid `library' and `aface' delayed to FT_Open_Face() */
1273     if ( !pathname )
1274       return FT_Err_Invalid_Argument;
1275
1276     args.flags    = ft_open_pathname;
1277     args.pathname = (char*)pathname;
1278
1279     return FT_Open_Face( library, &args, face_index, aface );
1280   }
1281
1282
1283   /*************************************************************************/
1284   /*                                                                       */
1285   /* <Function>                                                            */
1286   /*    FT_New_Memory_Face                                                 */
1287   /*                                                                       */
1288   /* <Description>                                                         */
1289   /*    Creates a new face object from a given resource and typeface index */
1290   /*    using a font file already loaded into memory.                      */
1291   /*                                                                       */
1292   /* <InOut>                                                               */
1293   /*    library    :: A handle to the library resource.                    */
1294   /*                                                                       */
1295   /* <Input>                                                               */
1296   /*    file_base  :: A pointer to the beginning of the font data.         */
1297   /*                                                                       */
1298   /*    file_size  :: The size of the memory chunk used by the font data.  */
1299   /*                                                                       */
1300   /*    face_index :: The index of the face within the resource.  The      */
1301   /*                  first face has index 0.                              */
1302   /* <Output>                                                              */
1303   /*    face       :: A handle to a new face object.                       */
1304   /*                                                                       */
1305   /* <Return>                                                              */
1306   /*    FreeType error code.  0 means success.                             */
1307   /*                                                                       */
1308   /* <Note>                                                                */
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'.                                                     */
1312   /*                                                                       */
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.                                   */
1316   /*                                                                       */
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.                                    */
1322   /*                                                                       */
1323   FT_EXPORT_FUNC( FT_Error )  FT_New_Memory_Face( FT_Library  library,
1324                                                   FT_Byte*    file_base,
1325                                                   FT_Long     file_size,
1326                                                   FT_Long     face_index,
1327                                                   FT_Face*    face )
1328   {
1329     FT_Open_Args  args;
1330
1331
1332     /* test for valid `library' and `face' delayed to FT_Open_Face() */
1333     if ( !file_base )
1334       return FT_Err_Invalid_Argument;
1335
1336     args.flags       = ft_open_memory;
1337     args.memory_base = file_base;
1338     args.memory_size = file_size;
1339
1340     return FT_Open_Face( library, &args, face_index, face );
1341   }
1342
1343
1344   /*************************************************************************/
1345   /*                                                                       */
1346   /* <Function>                                                            */
1347   /*    FT_Open_Face                                                       */
1348   /*                                                                       */
1349   /* <Description>                                                         */
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.                                                   */
1353   /*                                                                       */
1354   /* <InOut>                                                               */
1355   /*    library    :: A handle to the library resource.                    */
1356   /*                                                                       */
1357   /* <Input>                                                               */
1358   /*    args       :: A pointer to an `FT_Open_Args' structure which must  */
1359   /*                  be filled by the caller.                             */
1360   /*                                                                       */
1361   /*    face_index :: The index of the face within the resource.  The      */
1362   /*                  first face has index 0.                              */
1363   /* <Output>                                                              */
1364   /*    aface      :: A handle to a new face object.                       */
1365   /*                                                                       */
1366   /* <Return>                                                              */
1367   /*    FreeType error code.  0 means success.                             */
1368   /*                                                                       */
1369   /* <Note>                                                                */
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'.                                                     */
1373   /*                                                                       */
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.                                   */
1377   /*                                                                       */
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.                                    */
1383   /*                                                                       */
1384   FT_EXPORT_FUNC( FT_Error )  FT_Open_Face( FT_Library     library,
1385                                             FT_Open_Args*  args,
1386                                             FT_Long        face_index,
1387                                             FT_Face*       aface )
1388   {
1389     FT_Error     error;
1390     FT_Driver    driver;
1391     FT_Memory    memory;
1392     FT_Stream    stream;
1393     FT_Face      face = 0;
1394     FT_ListNode  node = 0;
1395
1396
1397     /* test for valid `library' and `args' delayed to */
1398     /* ft_new_input_stream()                          */
1399
1400     if ( !aface )
1401       return FT_Err_Invalid_Argument;
1402
1403     *aface = 0;
1404
1405     /* create input stream */
1406     error = ft_new_input_stream( library, args, &stream );
1407     if ( error )
1408       goto Exit;
1409
1410     memory = library->memory;
1411
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 )
1415     {
1416       driver = FT_DRIVER( args->driver );
1417
1418       /* not all modules are drivers, so check... */
1419       if ( FT_MODULE_IS_DRIVER( driver ) )
1420       {
1421         FT_Int         num_params = 0;
1422         FT_Parameter*  params     = 0;
1423
1424
1425         if ( args->flags & ft_open_params )
1426         {
1427           num_params = args->num_params;
1428           params     = args->params;
1429         }
1430
1431         error = open_face( driver, stream, face_index,
1432                            num_params, params, &face );
1433         if ( !error )
1434           goto Success;
1435       }
1436       else
1437         error = FT_Err_Invalid_Handle;
1438
1439       ft_done_stream( &stream );
1440       goto Fail;
1441     }
1442     else
1443     {
1444       /* check each font driver for an appropriate format */
1445       FT_Module*  cur   = library->modules;
1446       FT_Module*  limit = cur + library->num_modules;
1447
1448
1449       for ( ; cur < limit; cur++ )
1450       {
1451         /* not all modules are font drivers, so check... */
1452         if ( FT_MODULE_IS_DRIVER( cur[0] ) )
1453         {
1454           FT_Int         num_params = 0;
1455           FT_Parameter*  params     = 0;
1456
1457
1458           driver = FT_DRIVER( cur[0] );
1459
1460           if ( args->flags & ft_open_params )
1461           {
1462             num_params = args->num_params;
1463             params     = args->params;
1464           }
1465
1466           error = open_face( driver, stream, face_index,
1467                              num_params, params, &face );
1468           if ( !error )
1469             goto Success;
1470
1471           if ( error != FT_Err_Unknown_File_Format )
1472             goto Fail;
1473         }
1474       }
1475
1476       ft_done_stream( &stream );
1477
1478       /* no driver is able to handle this format */
1479       error = FT_Err_Unknown_File_Format;
1480       goto Fail;
1481     }
1482
1483   Success:
1484     FT_TRACE4(( "FT_New_Face: New face object, adding to list\n" ));
1485
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;
1489
1490     /* add the face object to its driver's list */
1491     if ( ALLOC( node, sizeof ( *node ) ) )
1492       goto Fail;
1493
1494     node->data = face;
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 );
1498
1499     /* now allocate a glyph slot object for the face */
1500     {
1501       FT_GlyphSlot  slot;
1502
1503
1504       FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
1505
1506       error = FT_New_GlyphSlot( face, &slot );
1507       if ( error )
1508         goto Fail;
1509
1510       face->glyph = slot;
1511     }
1512
1513     /* finally, allocate a size object for the face */
1514     {
1515       FT_Size  size;
1516
1517
1518       FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
1519
1520       error = FT_New_Size( face, &size );
1521       if ( error )
1522         goto Fail;
1523
1524       face->size = size;
1525     }
1526
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;
1532
1533     face->transform_delta.x = 0;
1534     face->transform_delta.y = 0;
1535
1536     *aface = face;
1537     goto Exit;
1538
1539   Fail:
1540     FT_Done_Face( face );
1541
1542   Exit:
1543     FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
1544
1545     return error;
1546   }
1547
1548
1549   /*************************************************************************/
1550   /*                                                                       */
1551   /* <Function>                                                            */
1552   /*    FT_Attach_File                                                     */
1553   /*                                                                       */
1554   /* <Description>                                                         */
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.              */
1559   /*                                                                       */
1560   /* <InOut>                                                               */
1561   /*    face         :: The target face object.                            */
1562   /*                                                                       */
1563   /* <Input>                                                               */
1564   /*    filepathname :: An 8-bit pathname naming the `metrics' file.       */
1565   /*                                                                       */
1566   /* <Return>                                                              */
1567   /*    FreeType error code.  0 means success.                             */
1568   /*                                                                       */
1569   /* <Note>                                                                */
1570   /*    If your font file is in memory, or if you want to provide your     */
1571   /*    own input stream object, use FT_Attach_Stream().                   */
1572   /*                                                                       */
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).             */
1576   /*                                                                       */
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.                                                  */
1580   /*                                                                       */
1581   FT_EXPORT_FUNC( FT_Error )  FT_Attach_File( FT_Face      face,
1582                                               const char*  filepathname )
1583   {
1584     FT_Open_Args  open;
1585
1586
1587     /* test for valid `face' delayed to FT_Attach_Stream() */
1588
1589     if ( !filepathname )
1590       return FT_Err_Invalid_Argument;
1591
1592     open.flags    = ft_open_pathname;
1593     open.pathname = (char*)filepathname;
1594
1595     return FT_Attach_Stream( face, &open );
1596   }
1597
1598
1599   /*************************************************************************/
1600   /*                                                                       */
1601   /* <Function>                                                            */
1602   /*    FT_Attach_Stream                                                   */
1603   /*                                                                       */
1604   /* <Description>                                                         */
1605   /*    This function is similar to FT_Attach_File() with the exception    */
1606   /*    that it reads the attachment from an arbitrary stream.             */
1607   /*                                                                       */
1608   /* <Input>                                                               */
1609   /*    face       :: The target face object.                              */
1610   /*                                                                       */
1611   /*    parameters :: A pointer to an FT_Open_Args structure used to       */
1612   /*                  describe the input stream to FreeType.               */
1613   /* <Return>                                                              */
1614   /*    FreeType error code.  0 means success.                             */
1615   /*                                                                       */
1616   /* <Note>                                                                */
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).             */
1620   /*                                                                       */
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.                                                  */
1624   /*                                                                       */
1625   FT_EXPORT_FUNC( FT_Error )  FT_Attach_Stream( FT_Face        face,
1626                                                 FT_Open_Args*  parameters )
1627   {
1628     FT_Stream  stream;
1629     FT_Error   error;
1630     FT_Driver  driver;
1631
1632     FT_Driver_Class*  clazz;
1633
1634
1635     /* test for valid `parameters' delayed to ft_new_input_stream() */
1636
1637     if ( !face )
1638       return FT_Err_Invalid_Face_Handle;
1639
1640     driver = face->driver;
1641     if ( !driver )
1642       return FT_Err_Invalid_Driver_Handle;
1643
1644     error = ft_new_input_stream( driver->root.library, parameters, &stream );
1645     if ( error )
1646       goto Exit;
1647
1648     /* we implement FT_Attach_Stream in each driver through the */
1649     /* `attach_file' interface                                  */
1650
1651     error = FT_Err_Unimplemented_Feature;
1652     clazz = driver->clazz;
1653     if ( clazz->attach_file )
1654       error = clazz->attach_file( face, stream );
1655
1656     /* close the attached stream */
1657     if ( !parameters->stream || ( parameters->flags & ft_open_stream ) )
1658       ft_done_stream( &stream );
1659
1660   Exit:
1661     return error;
1662   }
1663
1664
1665   /*************************************************************************/
1666   /*                                                                       */
1667   /* <Function>                                                            */
1668   /*    FT_Done_Face                                                       */
1669   /*                                                                       */
1670   /* <Description>                                                         */
1671   /*    Discards a given face object, as well as all of its child slots    */
1672   /*    and sizes.                                                         */
1673   /*                                                                       */
1674   /* <Input>                                                               */
1675   /*    face :: A handle to a target face object.                          */
1676   /*                                                                       */
1677   /* <Return>                                                              */
1678   /*    FreeType error code.  0 means success.                             */
1679   /*                                                                       */
1680   FT_EXPORT_FUNC( FT_Error )  FT_Done_Face( FT_Face  face )
1681   {
1682     FT_Error     error;
1683     FT_Driver    driver;
1684     FT_Memory    memory;
1685     FT_ListNode  node;
1686
1687
1688     error = FT_Err_Invalid_Face_Handle;
1689     if ( face && face->driver )
1690     {
1691       driver = face->driver;
1692       memory = driver->root.memory;
1693
1694       /* find face in driver's list */
1695       node = FT_List_Find( &driver->faces_list, face );
1696       if ( node )
1697       {
1698         /* remove face object from the driver's list */
1699         FT_List_Remove( &driver->faces_list, node );
1700         FREE( node );
1701
1702         /* now destroy the object proper */
1703         destroy_face( memory, face, driver );
1704         error = FT_Err_Ok;
1705       }
1706     }
1707     return error;
1708   }
1709
1710
1711   /*************************************************************************/
1712   /*                                                                       */
1713   /* <Function>                                                            */
1714   /*    FT_New_Size                                                        */
1715   /*                                                                       */
1716   /* <Description>                                                         */
1717   /*    Creates a new size object from a given face object.                */
1718   /*                                                                       */
1719   /* <Input>                                                               */
1720   /*    face :: A handle to a parent face object.                          */
1721   /*                                                                       */
1722   /* <Output>                                                              */
1723   /*    asize :: A handle to a new size object.                            */
1724   /*                                                                       */
1725   /* <Return>                                                              */
1726   /*    FreeType error code.  0 means success.                             */
1727   /*                                                                       */
1728   FT_EXPORT_FUNC( FT_Error )  FT_New_Size( FT_Face   face,
1729                                            FT_Size*  asize )
1730   {
1731     FT_Error          error;
1732     FT_Memory         memory;
1733     FT_Driver         driver;
1734     FT_Driver_Class*  clazz;
1735
1736     FT_Size           size = 0;
1737     FT_ListNode       node = 0;
1738
1739
1740     if ( !face )
1741       return FT_Err_Invalid_Face_Handle;
1742
1743     if ( !asize )
1744       return FT_Err_Invalid_Size_Handle;
1745
1746     if ( !face->driver )
1747       return FT_Err_Invalid_Driver_Handle;
1748
1749     *asize = 0;
1750
1751     driver = face->driver;
1752     clazz  = driver->clazz;
1753     memory = face->memory;
1754
1755     /* Allocate new size object and perform basic initialisation */
1756     if ( ALLOC( size, clazz->size_object_size ) ||
1757          ALLOC( node, sizeof ( FT_ListNodeRec ) ) )
1758       goto Exit;
1759
1760     size->face = face;
1761
1762     if ( clazz->init_size )
1763       error = clazz->init_size( size );
1764
1765     /* in case of success, add to the face's list */
1766     if ( !error )
1767     {
1768       *asize     = size;
1769       node->data = size;
1770       FT_List_Add( &face->sizes_list, node );
1771     }
1772
1773   Exit:
1774     if ( error )
1775     {
1776       FREE( node );
1777       FREE( size );
1778     }
1779
1780     return error;
1781   }
1782
1783
1784   /*************************************************************************/
1785   /*                                                                       */
1786   /* <Function>                                                            */
1787   /*    FT_Done_Size                                                       */
1788   /*                                                                       */
1789   /* <Description>                                                         */
1790   /*    Discards a given size object.                                      */
1791   /*                                                                       */
1792   /* <Input>                                                               */
1793   /*    size :: A handle to a target size object.                          */
1794   /*                                                                       */
1795   /* <Return>                                                              */
1796   /*    FreeType error code.  0 means success.                             */
1797   /*                                                                       */
1798   FT_EXPORT_FUNC( FT_Error )  FT_Done_Size( FT_Size  size )
1799   {
1800     FT_Error     error;
1801     FT_Driver    driver;
1802     FT_Memory    memory;
1803     FT_Face      face;
1804     FT_ListNode  node;
1805
1806
1807     if ( !size )
1808       return FT_Err_Invalid_Size_Handle;
1809
1810     face = size->face;
1811     if ( !face )
1812       return FT_Err_Invalid_Face_Handle;
1813
1814     driver = face->driver;
1815     if ( !driver )
1816       return FT_Err_Invalid_Driver_Handle;
1817
1818     memory = driver->root.memory;
1819
1820     error = FT_Err_Ok;
1821     node  = FT_List_Find( &face->sizes_list, size );
1822     if ( node )
1823     {
1824       FT_List_Remove( &face->sizes_list, node );
1825       FREE( node );
1826
1827       if ( face->size == size )
1828       {
1829         face->size = 0;
1830         if ( face->sizes_list.head )
1831           face->size = (FT_Size)(face->sizes_list.head->data);
1832       }
1833
1834       destroy_size( memory, size, driver );
1835     }
1836     else
1837       error = FT_Err_Invalid_Size_Handle;
1838
1839     return FT_Err_Ok;
1840   }
1841
1842
1843   static
1844   void  ft_recompute_scaled_metrics( FT_Face           face,
1845                                      FT_Size_Metrics*  metrics )
1846   {
1847     /* Compute root ascender, descender, test height, and max_advance */
1848
1849     metrics->ascender    = ( FT_MulFix( face->ascender,
1850                                         metrics->y_scale ) + 32 ) & -64;
1851
1852     metrics->descender   = ( FT_MulFix( face->descender,
1853                                         metrics->y_scale ) + 32 ) & -64;
1854
1855     metrics->height      = ( FT_MulFix( face->height,
1856                                         metrics->y_scale ) + 32 ) & -64;
1857
1858     metrics->max_advance = ( FT_MulFix( face->max_advance_width,
1859                                         metrics->x_scale ) + 32 ) & -64;
1860   }
1861
1862
1863   /*************************************************************************/
1864   /*                                                                       */
1865   /* <Function>                                                            */
1866   /*    FT_Set_Char_Size                                                   */
1867   /*                                                                       */
1868   /* <Description>                                                         */
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.         */
1872   /*                                                                       */
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. */
1876   /*                                                                       */
1877   /* <InOut>                                                               */
1878   /*    size            :: A handle to a target size object.               */
1879   /*                                                                       */
1880   /* <Input>                                                               */
1881   /*    char_width      :: The character width, in 26.6 fractional points. */
1882   /*                                                                       */
1883   /*    char_height     :: The character height, in 26.6 fractional        */
1884   /*                       points.                                         */
1885   /*                                                                       */
1886   /*    horz_resolution :: The horizontal resolution.                      */
1887   /*                                                                       */
1888   /*    vert_resolution :: The vertical resolution.                        */
1889   /*                                                                       */
1890   /* <Return>                                                              */
1891   /*    FreeType error code.  0 means success.                             */
1892   /*                                                                       */
1893   /* <Note>                                                                */
1894   /*    When dealing with fixed-size faces (i.e., non-scalable formats),   */
1895   /*    use the function FT_Set_Pixel_Sizes().                             */
1896   /*                                                                       */
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 )
1902   {
1903     FT_Error          error = FT_Err_Ok;
1904     FT_Driver         driver;
1905     FT_Memory         memory;
1906     FT_Driver_Class*  clazz;
1907     FT_Size_Metrics*  metrics;
1908     FT_Long           dim_x, dim_y;
1909
1910
1911     if ( !face || !face->size || !face->driver )
1912       return FT_Err_Invalid_Face_Handle;
1913
1914     driver  = face->driver;
1915     metrics = &face->size->metrics;
1916
1917     if ( !char_width )
1918       char_width = char_height;
1919
1920     else if ( !char_height )
1921       char_height = char_width;
1922
1923     if ( !horz_resolution )
1924       horz_resolution = 72;
1925
1926     if ( !vert_resolution )
1927       vert_resolution = 72;
1928
1929     driver = face->driver;
1930     clazz  = driver->clazz;
1931     memory = driver->root.memory;
1932
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;
1938
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;
1942
1943     metrics->x_ppem  = (FT_UShort)( dim_x >> 6 );
1944     metrics->y_ppem  = (FT_UShort)( dim_y >> 6 );
1945
1946     metrics->x_scale = 0x10000L;
1947     metrics->y_scale = 0x10000L;
1948
1949     if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
1950     {
1951       metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM );
1952       metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM );
1953
1954       ft_recompute_scaled_metrics( face, metrics );
1955     }
1956
1957     if ( clazz->set_char_sizes )
1958       error = clazz->set_char_sizes( face->size,
1959                                      char_width,
1960                                      char_height,
1961                                      horz_resolution,
1962                                      vert_resolution );
1963     return error;
1964   }
1965
1966
1967   /*************************************************************************/
1968   /*                                                                       */
1969   /* <Function>                                                            */
1970   /*    FT_Set_Pixel_Sizes                                                 */
1971   /*                                                                       */
1972   /* <Description>                                                         */
1973   /*    Sets the character dimensions of a given face object.  The width   */
1974   /*    and height are expressed in integer pixels.                        */
1975   /*                                                                       */
1976   /*    If one of the character dimensions is zero, its value is set equal */
1977   /*    to the other.                                                      */
1978   /*                                                                       */
1979   /* <InOut>                                                               */
1980   /*    face         :: A handle to the target face object.                */
1981   /*                                                                       */
1982   /* <Input>                                                               */
1983   /*    pixel_width  :: The character width, in integer pixels.            */
1984   /*                                                                       */
1985   /*    pixel_height :: The character height, in integer pixels.           */
1986   /*                                                                       */
1987   /* <Return>                                                              */
1988   /*    FreeType error code.  0 means success.                             */
1989   /*                                                                       */
1990   FT_EXPORT_FUNC( FT_Error )  FT_Set_Pixel_Sizes( FT_Face  face,
1991                                                   FT_UInt  pixel_width,
1992                                                   FT_UInt  pixel_height )
1993   {
1994     FT_Error          error = FT_Err_Ok;
1995     FT_Driver         driver;
1996     FT_Memory         memory;
1997     FT_Driver_Class*  clazz;
1998     FT_Size_Metrics*  metrics = &face->size->metrics;
1999
2000
2001     if ( !face || !face->size || !face->driver )
2002       return FT_Err_Invalid_Face_Handle;
2003
2004     driver = face->driver;
2005     clazz  = driver->clazz;
2006     memory = driver->root.memory;
2007
2008     /* default processing -- this can be overridden by the driver */
2009     if ( pixel_width == 0 )
2010       pixel_width = pixel_height;
2011
2012     else if ( pixel_height == 0 )
2013       pixel_height = pixel_width;
2014
2015     if ( pixel_width  < 1 )
2016       pixel_width  = 1;
2017     if ( pixel_height < 1 )
2018       pixel_height = 1;
2019
2020     metrics->x_ppem = pixel_width;
2021     metrics->y_ppem = pixel_height;
2022
2023     if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
2024     {
2025       metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
2026                                     face->units_per_EM );
2027
2028       metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
2029                                     face->units_per_EM );
2030
2031       ft_recompute_scaled_metrics( face, metrics );
2032     }
2033
2034     if ( clazz->set_pixel_sizes )
2035       error = clazz->set_pixel_sizes( face->size,
2036                                       pixel_width,
2037                                       pixel_height );
2038     return error;
2039   }
2040
2041
2042   /*************************************************************************/
2043   /*                                                                       */
2044   /* <Function>                                                            */
2045   /*    FT_Get_Kerning                                                     */
2046   /*                                                                       */
2047   /* <Description>                                                         */
2048   /*    Returns the kerning vector between two glyphs of a same face.      */
2049   /*                                                                       */
2050   /* <Input>                                                               */
2051   /*    face        :: A handle to a source face object.                   */
2052   /*                                                                       */
2053   /*    left_glyph  :: The index of the left glyph in the kern pair.       */
2054   /*                                                                       */
2055   /*    right_glyph :: The index of the right glyph in the kern pair.      */
2056   /*                                                                       */
2057   /*    kern_mode   :: See FT_Kerning_Mode() for more information.         */
2058   /*                   Determines the scale/dimension of the returned      */
2059   /*                   kerning vector.                                     */
2060   /*                                                                       */
2061   /* <Output>                                                              */
2062   /*    kerning     :: The kerning vector.  This is in font units for      */
2063   /*                   scalable formats, and in pixels for fixed-sizes     */
2064   /*                   formats.                                            */
2065   /*                                                                       */
2066   /* <Return>                                                              */
2067   /*    FreeType error code.  0 means success.                             */
2068   /*                                                                       */
2069   /* <Note>                                                                */
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.                    */
2074   /*                                                                       */
2075   FT_EXPORT_FUNC( FT_Error )  FT_Get_Kerning( FT_Face     face,
2076                                               FT_UInt     left_glyph,
2077                                               FT_UInt     right_glyph,
2078                                               FT_UInt     kern_mode,
2079                                               FT_Vector*  kerning )
2080   {
2081     FT_Error   error = FT_Err_Ok;
2082     FT_Driver  driver;
2083     FT_Memory  memory;
2084
2085
2086     if ( !face )
2087       return FT_Err_Invalid_Face_Handle;
2088
2089     if ( !kerning )
2090       return FT_Err_Invalid_Argument;
2091
2092     driver = face->driver;
2093     memory = driver->root.memory;
2094
2095     kerning->x = 0;
2096     kerning->y = 0;
2097
2098     if ( driver->clazz->get_kerning )
2099     {
2100       error = driver->clazz->get_kerning( face,
2101                                           left_glyph,
2102                                           right_glyph,
2103                                           kerning );
2104       if ( !error )
2105       {
2106         if ( kern_mode != ft_kerning_unscaled )
2107         {
2108           kerning->x = FT_MulFix( kerning->x, face->size->metrics.x_scale );
2109           kerning->y = FT_MulFix( kerning->y, face->size->metrics.y_scale );
2110
2111           if ( kern_mode != ft_kerning_unfitted )
2112           {
2113             kerning->x = ( kerning->x + 32 ) & -64;
2114             kerning->y = ( kerning->y + 32 ) & -64;
2115           }
2116         }
2117       }
2118     }
2119
2120     return error;
2121   }
2122
2123
2124   /*************************************************************************/
2125   /*                                                                       */
2126   /* <Function>                                                            */
2127   /*    FT_Select_Charmap                                                  */
2128   /*                                                                       */
2129   /* <Description>                                                         */
2130   /*    Selects a given charmap by its encoding tag (as listed in          */
2131   /*    `freetype.h').                                                     */
2132   /*                                                                       */
2133   /* <Input>                                                               */
2134   /*    face     :: A handle to the source face object.                    */
2135   /*                                                                       */
2136   /*    encoding :: A handle to the selected charmap.                      */
2137   /*                                                                       */
2138   /* <Return>                                                              */
2139   /*    FreeType error code.  0 means success.                             */
2140   /*                                                                       */
2141   /* <Note>                                                                */
2142   /*    This function will return an error if no charmap in the face       */
2143   /*    corresponds to the encoding queried here.                          */
2144   /*                                                                       */
2145   FT_EXPORT_FUNC( FT_Error )  FT_Select_Charmap( FT_Face      face,
2146                                                  FT_Encoding  encoding )
2147   {
2148     FT_CharMap*  cur;
2149     FT_CharMap*  limit;
2150
2151
2152     if ( !face )
2153       return FT_Err_Invalid_Face_Handle;
2154
2155     cur = face->charmaps;
2156     if ( !cur )
2157       return FT_Err_Invalid_CharMap_Handle;
2158
2159     limit = cur + face->num_charmaps;
2160
2161     for ( ; cur < limit; cur++ )
2162     {
2163       if ( cur[0]->encoding == encoding )
2164       {
2165         face->charmap = cur[0];
2166         return 0;
2167       }
2168     }
2169
2170     return FT_Err_Invalid_Argument;
2171   }
2172
2173
2174   /*************************************************************************/
2175   /*                                                                       */
2176   /* <Function>                                                            */
2177   /*    FT_Set_Charmap                                                     */
2178   /*                                                                       */
2179   /* <Description>                                                         */
2180   /*    Selects a given charmap for character code to glyph index          */
2181   /*    decoding.                                                          */
2182   /*                                                                       */
2183   /* <Input>                                                               */
2184   /*    face     :: A handle to the source face object.                    */
2185   /*    charmap  :: A handle to the selected charmap.                      */
2186   /*                                                                       */
2187   /* <Return>                                                              */
2188   /*    FreeType error code.  0 means success.                             */
2189   /*                                                                       */
2190   /* <Note>                                                                */
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[]        */
2193   /*    table).                                                            */
2194   /*                                                                       */
2195   FT_EXPORT_FUNC( FT_Error )  FT_Set_Charmap( FT_Face     face,
2196                                               FT_CharMap  charmap )
2197   {
2198     FT_CharMap*  cur;
2199     FT_CharMap*  limit;
2200
2201
2202     if ( !face )
2203       return FT_Err_Invalid_Face_Handle;
2204
2205     cur = face->charmaps;
2206     if ( !cur )
2207       return FT_Err_Invalid_CharMap_Handle;
2208
2209     limit = cur + face->num_charmaps;
2210
2211     for ( ; cur < limit; cur++ )
2212     {
2213       if ( cur[0] == charmap )
2214       {
2215         face->charmap = cur[0];
2216         return 0;
2217       }
2218     }
2219     return FT_Err_Invalid_Argument;
2220   }
2221
2222
2223   /*************************************************************************/
2224   /*                                                                       */
2225   /* <Function>                                                            */
2226   /*    FT_Get_Char_Index                                                  */
2227   /*                                                                       */
2228   /* <Description>                                                         */
2229   /*    Returns the glyph index of a given character code.  This function  */
2230   /*    uses a charmap object to do the translation.                       */
2231   /*                                                                       */
2232   /* <Input>                                                               */
2233   /*    face     :: A handle to the source face object.                    */
2234   /*                                                                       */
2235   /*    charcode :: The character code.                                    */
2236   /*                                                                       */
2237   /* <Return>                                                              */
2238   /*    The glyph index.  0 means `undefined character code'.              */
2239   /*                                                                       */
2240   FT_EXPORT_FUNC( FT_UInt )  FT_Get_Char_Index( FT_Face   face,
2241                                                 FT_ULong  charcode )
2242   {
2243     FT_UInt    result;
2244     FT_Driver  driver;
2245
2246
2247     result = 0;
2248     if ( face && face->charmap )
2249     {
2250       driver = face->driver;
2251       result = driver->clazz->get_char_index( face->charmap, charcode );
2252     }
2253     return result;
2254   }
2255
2256
2257   /*************************************************************************/
2258   /*                                                                       */
2259   /* <Function>                                                            */
2260   /*    FT_Get_Glyph_Name                                                  */
2261   /*                                                                       */
2262   /* <Description>                                                         */
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.  */
2265   /*                                                                       */
2266   /* <Input>                                                               */
2267   /*    face        :: A handle to a source face object.                   */
2268   /*                                                                       */
2269   /*    glyph_index :: The glyph index.                                    */
2270   /*                                                                       */
2271   /*    buffer      :: A pointer to a target buffer where the name will be */
2272   /*                   copied to.                                          */
2273   /*                                                                       */
2274   /*    buffer_max  :: The maximal number of bytes available in the        */
2275   /*                   buffer.                                             */
2276   /*                                                                       */
2277   /* <Return>                                                              */
2278   /*    FreeType error code.  0 means success.                             */
2279   /*                                                                       */
2280   /* <Note>                                                                */
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.       */
2284   /*                                                                       */
2285   /*    The glyph name is truncated to fit within the buffer if it is too  */
2286   /*    long.  The returned string is always zero-terminated.              */
2287   /*                                                                       */
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'                              */
2291   /*                                                                       */
2292   FT_EXPORT_FUNC( FT_Error )  FT_Get_Glyph_Name( FT_Face     face,
2293                                                  FT_UInt     glyph_index,
2294                                                  FT_Pointer  buffer,
2295                                                  FT_UInt     buffer_max )
2296   {
2297     FT_Error  error = FT_Err_Invalid_Argument;
2298     
2299
2300     /* clean up buffer */
2301     if ( buffer && buffer_max > 0 )
2302       ((FT_Byte*)buffer)[0] = 0;
2303       
2304     if ( face                                    &&
2305          glyph_index < (FT_UInt)face->num_glyphs &&
2306          FT_HAS_GLYPH_NAMES( face )              )
2307     {
2308       /* now, lookup for glyph name */
2309       FT_Driver        driver = face->driver;
2310       FT_Module_Class* clazz  = FT_MODULE_CLASS( driver );
2311
2312
2313       if ( clazz->get_interface )
2314       {
2315         FT_Glyph_Name_Requester  requester;
2316         
2317
2318         requester = (FT_Glyph_Name_Requester)clazz->get_interface(
2319                       FT_MODULE( driver ), "glyph_name" );
2320         if ( requester )
2321           error = requester( face, glyph_index, buffer, buffer_max );
2322       }
2323     }
2324
2325     return error;
2326   }                                                 
2327
2328
2329   /*************************************************************************/
2330   /*                                                                       */
2331   /* <Function>                                                            */
2332   /*    FT_Get_Sfnt_Table                                                  */
2333   /*                                                                       */
2334   /* <Description>                                                         */
2335   /*    Returns a pointer to a given SFNT table within a face.             */
2336   /*                                                                       */
2337   /* <Input>                                                               */
2338   /*    face :: A handle to the source face object.                        */
2339   /*    tag  :: An index of an SFNT table.                                 */
2340   /*                                                                       */
2341   /* <Return>                                                              */
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.                                                     */
2345   /*                                                                       */
2346   /* <Note>                                                                */
2347   /*    The table is owned by the face object, and disappears with it.     */
2348   /*                                                                       */
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.                            */
2352   /*                                                                       */
2353   /*    You can load any table with a different function.. XXX             */
2354   /*                                                                       */
2355   FT_EXPORT_FUNC( void* )  FT_Get_Sfnt_Table( FT_Face      face,
2356                                               FT_Sfnt_Tag  tag )
2357   {
2358     void*                   table = 0;
2359     FT_Get_Sfnt_Table_Func  func;
2360     FT_Driver               driver;
2361
2362
2363     if ( !face || !FT_IS_SFNT( face ) )
2364       goto Exit;
2365
2366     driver = face->driver;
2367     func = (FT_Get_Sfnt_Table_Func)driver->root.clazz->get_interface(
2368                                      FT_MODULE( driver ), "get_sfnt" );
2369     if ( func )
2370       table = func( face, tag );
2371
2372   Exit:
2373     return table;
2374   }
2375
2376
2377   /*************************************************************************/
2378   /*************************************************************************/
2379   /*************************************************************************/
2380   /****                                                                 ****/
2381   /****                                                                 ****/
2382   /****                        R E N D E R E R S                        ****/
2383   /****                                                                 ****/
2384   /****                                                                 ****/
2385   /*************************************************************************/
2386   /*************************************************************************/
2387   /*************************************************************************/
2388
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,
2392                                                 FT_ListNode*     node )
2393   {
2394     FT_ListNode   cur;
2395     FT_Renderer   result = 0;
2396
2397
2398     if ( !library )
2399       goto Exit;
2400
2401     cur = library->renderers.head;
2402
2403     if ( node )
2404     {
2405       if ( *node )
2406         cur = (*node)->next;
2407       *node = 0;
2408     }
2409
2410     while ( cur )
2411     {
2412       FT_Renderer  renderer = FT_RENDERER( cur->data );
2413
2414
2415       if ( renderer->glyph_format == format )
2416       {
2417         if ( node )
2418           *node = cur;
2419
2420         result = renderer;
2421         break;
2422       }
2423       cur = cur->next;
2424     }
2425
2426   Exit:
2427     return result;
2428   }
2429
2430
2431   static
2432   FT_Renderer  ft_lookup_glyph_renderer( FT_GlyphSlot  slot )
2433   {
2434     FT_Face      face    = slot->face;
2435     FT_Library   library = FT_FACE_LIBRARY( face );
2436     FT_Renderer  result  = library->cur_renderer;
2437
2438
2439     if ( !result || result->glyph_format != slot->format )
2440       result = FT_Lookup_Renderer( library, slot->format, 0 );
2441
2442     return result;
2443   }
2444
2445
2446   static
2447   void  ft_set_current_renderer( FT_Library  library )
2448   {
2449     FT_Renderer  renderer;
2450
2451
2452     renderer = FT_Lookup_Renderer( library, ft_glyph_format_outline, 0 );
2453     library->cur_renderer = renderer;
2454   }
2455
2456
2457   static
2458   FT_Error  ft_add_renderer( FT_Module  module )
2459   {
2460     FT_Library   library = module->library;
2461     FT_Memory    memory  = library->memory;
2462     FT_Error     error;
2463     FT_ListNode  node;
2464
2465
2466     if ( ALLOC( node, sizeof ( *node ) ) )
2467       goto Exit;
2468
2469     {
2470       FT_Renderer         render = FT_RENDERER( module );
2471       FT_Renderer_Class*  clazz  = (FT_Renderer_Class*)module->clazz;
2472
2473
2474       render->clazz        = clazz;
2475       render->glyph_format = clazz->glyph_format;
2476
2477       /* allocate raster object if needed */
2478       if ( clazz->glyph_format == ft_glyph_format_outline &&
2479            clazz->raster_class->raster_new )
2480       {
2481         error = clazz->raster_class->raster_new( memory, &render->raster );
2482         if ( error )
2483           goto Fail;
2484
2485         render->raster_render = clazz->raster_class->raster_render;
2486         render->render        = clazz->render_glyph;
2487       }
2488
2489       /* add to list */
2490       node->data = module;
2491       FT_List_Add( &library->renderers, node );
2492
2493       ft_set_current_renderer( library );
2494     }
2495
2496   Fail:
2497     if ( error )
2498       FREE( node );
2499
2500   Exit:
2501     return error;
2502   }
2503
2504
2505   static
2506   void  ft_remove_renderer( FT_Module  module )
2507   {
2508     FT_Library   library = module->library;
2509     FT_Memory    memory  = library->memory;
2510     FT_ListNode  node;
2511
2512
2513     node = FT_List_Find( &library->renderers, module );
2514     if ( node )
2515     {
2516       FT_Renderer  render = FT_RENDERER( module );
2517
2518
2519       /* release raster object, if any */
2520       if ( render->raster )
2521         render->clazz->raster_class->raster_done( render->raster );
2522
2523       /* remove from list */
2524       FT_List_Remove( &library->renderers, node );
2525       FREE( node );
2526
2527       ft_set_current_renderer( library );
2528     }
2529   }
2530
2531
2532   /*************************************************************************/
2533   /*                                                                       */
2534   /* <Function>                                                            */
2535   /*    FT_Get_Renderer                                                    */
2536   /*                                                                       */
2537   /* <Description>                                                         */
2538   /*    Retrieves the current renderer for a given glyph format.           */
2539   /*                                                                       */
2540   /* <Input>                                                               */
2541   /*    library :: A handle to the library object.                         */
2542   /*                                                                       */
2543   /*    format  :: The glyph format.                                       */
2544   /*                                                                       */
2545   /* <Return>                                                              */
2546   /*    A renderer handle.  0 if none found.                               */
2547   /*                                                                       */
2548   /* <Note>                                                                */
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. */
2551   /*                                                                       */
2552   /*    To add a new renderer, simply use FT_Add_Module().  To retrieve a  */
2553   /*    renderer by its name, use FT_Get_Module().                         */
2554   /*                                                                       */
2555   FT_EXPORT_FUNC( FT_Renderer )  FT_Get_Renderer( FT_Library       library,
2556                                                   FT_Glyph_Format  format )
2557   {
2558     /* test for valid `library' delayed to FT_Lookup_Renderer() */
2559
2560     return  FT_Lookup_Renderer( library, format, 0 );
2561   }
2562
2563
2564   /*************************************************************************/
2565   /*                                                                       */
2566   /* <Function>                                                            */
2567   /*    FT_Set_Renderer                                                    */
2568   /*                                                                       */
2569   /* <Description>                                                         */
2570   /*    Sets the current renderer to use, and set additional mode.         */
2571   /*                                                                       */
2572   /* <Input>                                                               */
2573   /*    library    :: A handle to the library object.                      */
2574   /*                                                                       */
2575   /*    renderer   :: A handle to the renderer object.                     */
2576   /*                                                                       */
2577   /*    num_params :: The number of additional parameters.                 */
2578   /*                                                                       */
2579   /*    parameters :: Additional parameters.                               */
2580   /*                                                                       */
2581   /* <Return>                                                              */
2582   /*    FreeType error code.  0 means success.                             */
2583   /*                                                                       */
2584   /* <Note>                                                                */
2585   /*    In case of success, the renderer will be used to convert glyph     */
2586   /*    images in the renderer's known format into bitmaps.                */
2587   /*                                                                       */
2588   /*    This doesn't change the current renderer for other formats.        */
2589   /*                                                                       */
2590   FT_EXPORT_DEF( FT_Error )  FT_Set_Renderer( FT_Library     library,
2591                                               FT_Renderer    renderer,
2592                                               FT_UInt        num_params,
2593                                               FT_Parameter*  parameters )
2594   {
2595     FT_ListNode  node;
2596     FT_Error     error = FT_Err_Ok;
2597
2598
2599     if ( !library )
2600       return FT_Err_Invalid_Library_Handle;
2601
2602     if ( !renderer )
2603       return FT_Err_Invalid_Argument;
2604
2605     node = FT_List_Find( &library->renderers, renderer );
2606     if ( !node )
2607     {
2608       error = FT_Err_Invalid_Argument;
2609       goto Exit;
2610     }
2611
2612     FT_List_Up( &library->renderers, node );
2613
2614     if ( renderer->glyph_format == ft_glyph_format_outline )
2615       library->cur_renderer = renderer;
2616
2617     if ( num_params > 0 )
2618     {
2619       FTRenderer_setMode  set_mode = renderer->clazz->set_mode;
2620
2621
2622       for ( ; num_params > 0; num_params-- )
2623       {
2624         error = set_mode( renderer, parameters->tag, parameters->data );
2625         if ( error )
2626           break;
2627       }
2628     }
2629
2630   Exit:
2631     return error;
2632   }
2633
2634
2635   LOCAL_FUNC
2636   FT_Error  FT_Render_Glyph_Internal( FT_Library    library,
2637                                       FT_GlyphSlot  slot,
2638                                       FT_UInt       render_mode )
2639   {
2640     FT_Error     error = FT_Err_Ok;
2641     FT_Renderer  renderer;
2642
2643
2644     /* if it is already a bitmap, no need to do anything */
2645     switch ( slot->format )
2646     {
2647     case ft_glyph_format_bitmap:   /* already a bitmap, don't do anything */
2648       break;
2649
2650     default:
2651       {
2652         FT_ListNode  node   = 0;
2653         FT_Bool      update = 0;
2654
2655
2656         /* small shortcut for the very common case */
2657         if ( slot->format == ft_glyph_format_outline )
2658         {
2659           renderer = library->cur_renderer;
2660           node     = library->renderers.head;
2661         }
2662         else
2663           renderer = FT_Lookup_Renderer( library, slot->format, &node );
2664
2665         error = FT_Err_Unimplemented_Feature;
2666         while ( renderer )
2667         {
2668           error = renderer->render( renderer, slot, render_mode, 0 );
2669           if ( !error || error != FT_Err_Cannot_Render_Glyph )
2670             break;
2671
2672           /* FT_Err_Cannot_Render_Glyph is returned if the render mode   */
2673           /* is unsupported by the current renderer for this glyph image */
2674           /* format.                                                     */
2675
2676           /* now, look for another renderer that supports the same */
2677           /* format.                                               */
2678           renderer = FT_Lookup_Renderer( library, slot->format, &node );
2679           update   = 1;
2680         }
2681
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 );
2686       }
2687     }
2688
2689     return error;
2690   }
2691
2692
2693   /*************************************************************************/
2694   /*                                                                       */
2695   /* <Function>                                                            */
2696   /*    FT_Render_Glyph                                                    */
2697   /*                                                                       */
2698   /* <Description>                                                         */
2699   /*    Converts a given glyph image to a bitmap.  It does so by           */
2700   /*    inspecting the glyph image format, find the relevant renderer, and */
2701   /*    invoke it.                                                         */
2702   /*                                                                       */
2703   /* <Input>                                                               */
2704   /*    slot        :: A handle to the glyph slot containing the image to  */
2705   /*                   convert.                                            */
2706   /*                                                                       */
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.                                 */
2710   /*                                                                       */
2711   /* <Return>                                                              */
2712   /*    FreeType error code.  0 means success.                             */
2713   /*                                                                       */
2714   FT_EXPORT_FUNC( FT_Error )  FT_Render_Glyph( FT_GlyphSlot  slot,
2715                                                FT_UInt       render_mode )
2716   {
2717     FT_Library   library;
2718
2719
2720     if ( !slot )
2721       return FT_Err_Invalid_Argument;
2722
2723     library = FT_FACE_LIBRARY( slot->face );
2724
2725     return FT_Render_Glyph_Internal( library, slot, render_mode );
2726   }
2727
2728
2729   /*************************************************************************/
2730   /*************************************************************************/
2731   /*************************************************************************/
2732   /****                                                                 ****/
2733   /****                                                                 ****/
2734   /****                         M O D U L E S                           ****/
2735   /****                                                                 ****/
2736   /****                                                                 ****/
2737   /*************************************************************************/
2738   /*************************************************************************/
2739   /*************************************************************************/
2740
2741
2742   /*************************************************************************/
2743   /*                                                                       */
2744   /* <Function>                                                            */
2745   /*    Destroy_Module                                                     */
2746   /*                                                                       */
2747   /* <Description>                                                         */
2748   /*    Destroys a given module object.  For drivers, this also destroys   */
2749   /*    all child faces.                                                   */
2750   /*                                                                       */
2751   /* <InOut>                                                               */
2752   /*     module :: A handle to the target driver object.                   */
2753   /*                                                                       */
2754   /* <Note>                                                                */
2755   /*     The driver _must_ be LOCKED!                                      */
2756   /*                                                                       */
2757   static
2758   void  Destroy_Module( FT_Module  module )
2759   {
2760     FT_Memory         memory  = module->memory;
2761     FT_Module_Class*  clazz   = module->clazz;
2762     FT_Library        library = module->library;
2763
2764
2765     /* finalize client-data - before anything else */
2766     if ( module->generic.finalizer )
2767       module->generic.finalizer( module );
2768
2769     if ( library && library->auto_hinter == module )
2770       library->auto_hinter = 0;
2771
2772     /* if the module is a renderer */
2773     if ( FT_MODULE_IS_RENDERER( module ) )
2774       ft_remove_renderer( module );
2775
2776     /* if the module is a font driver, add some steps */
2777     if ( FT_MODULE_IS_DRIVER( module ) )
2778       Destroy_Driver( FT_DRIVER( module ) );
2779
2780     /* finalize the module object */
2781     if ( clazz->module_done )
2782       clazz->module_done( module );
2783
2784     /* discard it */
2785     FREE( module );
2786   }
2787
2788
2789   /*************************************************************************/
2790   /*                                                                       */
2791   /* <Function>                                                            */
2792   /*    FT_Add_Module                                                      */
2793   /*                                                                       */
2794   /* <Description>                                                         */
2795   /*    Adds a new module to a given library instance.                     */
2796   /*                                                                       */
2797   /* <Input>                                                               */
2798   /*    library :: A handle to the library object.                         */
2799   /*                                                                       */
2800   /*    clazz   :: A pointer to class descriptor for the module.           */
2801   /*                                                                       */
2802   /* <Return>                                                              */
2803   /*    FreeType error code.  0 means success.                             */
2804   /*                                                                       */
2805   /* <Note>                                                                */
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. */
2808   /*                                                                       */
2809   FT_EXPORT_FUNC( FT_Error )  FT_Add_Module( FT_Library              library,
2810                                              const FT_Module_Class*  clazz )
2811   {
2812     FT_Error   error;
2813     FT_Memory  memory;
2814     FT_Module  module;
2815     FT_UInt    nn;
2816
2817
2818 #define FREETYPE_VER_FIXED  ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \
2819                                 FREETYPE_MINOR                  )
2820
2821     if ( !library )
2822       return FT_Err_Invalid_Library_Handle;
2823
2824     if ( !clazz )
2825       return FT_Err_Invalid_Argument;
2826
2827     /* check freetype version */
2828     if ( clazz->module_requires > FREETYPE_VER_FIXED )
2829       return FT_Err_Invalid_Version;
2830
2831     /* look for a module with the same name in the library's table */
2832     for ( nn = 0; nn < library->num_modules; nn++ )
2833     {
2834       module = library->modules[nn];
2835       if ( strcmp( module->clazz->module_name, clazz->module_name ) == 0 )
2836       {
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;
2840
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 );
2844         break;
2845       }
2846     }
2847
2848     memory = library->memory;
2849     error  = FT_Err_Ok;
2850
2851     if ( library->num_modules >= FT_MAX_MODULES )
2852     {
2853       error = FT_Err_Too_Many_Drivers;
2854       goto Exit;
2855     }
2856
2857     /* allocate module object */
2858     if ( ALLOC( module,clazz->module_size ) )
2859       goto Exit;
2860
2861     /* base initialization */
2862     module->library = library;
2863     module->memory  = memory;
2864     module->clazz   = (FT_Module_Class*)clazz;
2865
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 ) )
2869     {
2870       /* add to the renderers list */
2871       error = ft_add_renderer( module );
2872       if ( error )
2873         goto Fail;
2874     }
2875
2876     /* is the module a auto-hinter? */
2877     if ( FT_MODULE_IS_HINTER( module ) )
2878       library->auto_hinter = module;
2879
2880     /* if the module is a font driver */
2881     if ( FT_MODULE_IS_DRIVER( module ) )
2882     {
2883       /* allocate glyph loader if needed */
2884       FT_Driver   driver = FT_DRIVER( module );
2885
2886
2887       driver->clazz = (FT_Driver_Class*)module->clazz;
2888       if ( FT_DRIVER_USES_OUTLINES( driver ) )
2889       {
2890         error = FT_GlyphLoader_New( memory, &driver->glyph_loader );
2891         if ( error )
2892           goto Fail;
2893       }
2894     }
2895
2896     if ( clazz->module_init )
2897     {
2898       error = clazz->module_init( module );
2899       if ( error )
2900         goto Fail;
2901     }
2902
2903     /* add module to the library's table */
2904     library->modules[library->num_modules++] = module;
2905
2906   Exit:
2907     return error;
2908
2909   Fail:
2910     if ( FT_MODULE_IS_DRIVER( module ) )
2911     {
2912       FT_Driver  driver = FT_DRIVER( module );
2913
2914
2915       if ( FT_DRIVER_USES_OUTLINES( driver ) )
2916         FT_GlyphLoader_Done( driver->glyph_loader );
2917     }
2918
2919     if ( FT_MODULE_IS_RENDERER( module ) )
2920     {
2921       FT_Renderer  renderer = FT_RENDERER( module );
2922
2923
2924       if ( renderer->raster )
2925         renderer->clazz->raster_class->raster_done( renderer->raster );
2926     }
2927
2928     FREE( module );
2929     goto Exit;
2930   }
2931
2932
2933   /*************************************************************************/
2934   /*                                                                       */
2935   /* <Function>                                                            */
2936   /*    FT_Get_Module                                                      */
2937   /*                                                                       */
2938   /* <Description>                                                         */
2939   /*    Finds a module by its name.                                        */
2940   /*                                                                       */
2941   /* <Input>                                                               */
2942   /*    library     :: A handle to the library object.                     */
2943   /*                                                                       */
2944   /*    module_name :: The module's name (as an ASCII string).             */
2945   /*                                                                       */
2946   /* <Return>                                                              */
2947   /*    A module handle.  0 if none was found.                             */
2948   /*                                                                       */
2949   /* <Note>                                                                */
2950   /*    You should better be familiar with FreeType internals to know      */
2951   /*    which module to look for :-)                                       */
2952   /*                                                                       */
2953   FT_EXPORT_FUNC( FT_Module ) FT_Get_Module( FT_Library   library,
2954                                              const char*  module_name )
2955   {
2956     FT_Module   result = 0;
2957     FT_Module*  cur;
2958     FT_Module*  limit;
2959
2960
2961     if ( !library || !module_name )
2962       return result;
2963
2964     cur   = library->modules;
2965     limit = cur + library->num_modules;
2966
2967     for ( ; cur < limit; cur++ )
2968       if ( strcmp( cur[0]->clazz->module_name, module_name ) == 0 )
2969       {
2970         result = cur[0];
2971         break;
2972       }
2973
2974     return result;
2975   }
2976
2977
2978   /*************************************************************************/
2979   /*                                                                       */
2980   /* <Function>                                                            */
2981   /*    FT_Get_Module_Interface                                            */
2982   /*                                                                       */
2983   /* <Description>                                                         */
2984   /*    Finds a module and returns its specific interface as a typeless    */
2985   /*    pointer.                                                           */
2986   /*                                                                       */
2987   /* <Input>                                                               */
2988   /*    library     :: A handle to the library object.                     */
2989   /*                                                                       */
2990   /*    module_name :: The module's name (as an ASCII string).             */
2991   /*                                                                       */
2992   /* <Return>                                                              */
2993   /*    A module-specific interface if available, 0 otherwise.             */
2994   /*                                                                       */
2995   /* <Note>                                                                */
2996   /*    You should better be familiar with FreeType internals to know      */
2997   /*    which module to look for, and what its interface is :-)            */
2998   /*                                                                       */
2999   BASE_FUNC( const void* )  FT_Get_Module_Interface( FT_Library   library,
3000                                                      const char*  mod_name )
3001   {
3002     FT_Module  module;
3003
3004
3005     /* test for valid `library' delayed to FT_Get_Module() */
3006
3007     module = FT_Get_Module( library, mod_name );
3008
3009     return module ? module->clazz->module_interface : 0;
3010   }
3011
3012
3013   /*************************************************************************/
3014   /*                                                                       */
3015   /* <Function>                                                            */
3016   /*    FT_Remove_Module                                                   */
3017   /*                                                                       */
3018   /* <Description>                                                         */
3019   /*    Removes a given module from a library instance.                    */
3020   /*                                                                       */
3021   /* <Input>                                                               */
3022   /*    library :: A handle to a library object.                           */
3023   /*                                                                       */
3024   /*    module  :: A handle to a module object.                            */
3025   /*                                                                       */
3026   /* <Return>                                                              */
3027   /*    FreeType error code.  0 means success.                             */
3028   /*                                                                       */
3029   /* <Note>                                                                */
3030   /*    The module object is destroyed by the function in case of success. */
3031   /*                                                                       */
3032   FT_EXPORT_FUNC( FT_Error )  FT_Remove_Module( FT_Library  library,
3033                                                 FT_Module   module )
3034   {
3035     /* try to find the module from the table, then remove it from there */
3036
3037     if ( !library )
3038       return FT_Err_Invalid_Library_Handle;
3039
3040     if ( module )
3041     {
3042       FT_Module*  cur   = library->modules;
3043       FT_Module*  limit = cur + library->num_modules;
3044
3045
3046       for ( ; cur < limit; cur++ )
3047       {
3048         if ( cur[0] == module )
3049         {
3050           /* remove it from the table */
3051           library->num_modules--;
3052           limit--;
3053           while ( cur < limit )
3054           {
3055             cur[0] = cur[1];
3056             cur++;
3057           }
3058           limit[0] = 0;
3059
3060           /* destroy the module */
3061           Destroy_Module( module );
3062
3063           return FT_Err_Ok;
3064         }
3065       }
3066     }
3067     return FT_Err_Invalid_Driver_Handle;
3068   }
3069
3070
3071   /*************************************************************************/
3072   /*************************************************************************/
3073   /*************************************************************************/
3074   /****                                                                 ****/
3075   /****                                                                 ****/
3076   /****                         L I B R A R Y                           ****/
3077   /****                                                                 ****/
3078   /****                                                                 ****/
3079   /*************************************************************************/
3080   /*************************************************************************/
3081   /*************************************************************************/
3082
3083
3084   /*************************************************************************/
3085   /*                                                                       */
3086   /* <Function>                                                            */
3087   /*    FT_New_Library                                                     */
3088   /*                                                                       */
3089   /* <Description>                                                         */
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.           */
3093   /*                                                                       */
3094   /* <Input>                                                               */
3095   /*    memory   :: A handle to the original memory object.                */
3096   /*                                                                       */
3097   /* <Output>                                                              */
3098   /*    alibrary :: A pointer to handle of a new library object.           */
3099   /*                                                                       */
3100   /* <Return>                                                              */
3101   /*    FreeType error code.  0 means success.                             */
3102   /*                                                                       */
3103   FT_EXPORT_FUNC( FT_Error )  FT_New_Library( FT_Memory    memory,
3104                                               FT_Library*  alibrary )
3105   {
3106     FT_Library  library = 0;
3107     FT_Error    error;
3108
3109
3110     if ( !memory )
3111       return FT_Err_Invalid_Argument;
3112
3113     /* first of all, allocate the library object */
3114     if ( ALLOC( library, sizeof ( *library ) ) )
3115       return error;
3116
3117     library->memory = memory;
3118
3119     /* allocate the render pool */
3120     library->raster_pool_size = FT_RENDER_POOL_SIZE;
3121     if ( ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
3122       goto Fail;
3123
3124     /* That's ok now */
3125     *alibrary = library;
3126
3127     return FT_Err_Ok;
3128
3129   Fail:
3130     FREE( library );
3131     return error;
3132   }
3133
3134
3135   /*************************************************************************/
3136   /*                                                                       */
3137   /* <Function>                                                            */
3138   /*    FT_Done_Library                                                    */
3139   /*                                                                       */
3140   /* <Description>                                                         */
3141   /*    Discards a given library object.  This closes all drivers and      */
3142   /*    discards all resource objects.                                     */
3143   /*                                                                       */
3144   /* <Input>                                                               */
3145   /*    library :: A handle to the target library.                         */
3146   /*                                                                       */
3147   /* <Return>                                                              */
3148   /*    FreeType error code.  0 means success.                             */
3149   /*                                                                       */
3150   FT_EXPORT_FUNC( FT_Error )  FT_Done_Library( FT_Library  library )
3151   {
3152     FT_Memory  memory;
3153     FT_UInt    n;
3154
3155
3156     if ( !library )
3157       return FT_Err_Invalid_Library_Handle;
3158
3159     memory = library->memory;
3160
3161     /* Discard client-data */
3162     if ( library->generic.finalizer )
3163       library->generic.finalizer( library );
3164
3165     /* Close all modules in the library */
3166     for ( n = 0; n < library->num_modules; n++ )
3167     {
3168       FT_Module  module = library->modules[n];
3169
3170
3171       if ( module )
3172       {
3173         Destroy_Module( module );
3174         library->modules[n] = 0;
3175       }
3176     }
3177
3178     /* Destroy raster objects */
3179     FREE( library->raster_pool );
3180     library->raster_pool_size = 0;
3181
3182     FREE( library );
3183     return FT_Err_Ok;
3184   }
3185
3186
3187   /*************************************************************************/
3188   /*                                                                       */
3189   /* <Function>                                                            */
3190   /*    FT_Set_Debug_Hook                                                  */
3191   /*                                                                       */
3192   /* <Description>                                                         */
3193   /*    Sets a debug hook function for debugging the interpreter of a font */
3194   /*    format.                                                            */
3195   /*                                                                       */
3196   /* <Input>                                                               */
3197   /*    library    :: A handle to the library object.                      */
3198   /*                                                                       */
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                               */
3202   /*                                                                       */
3203   /*    debug_hook :: The function used to debug the interpreter.          */
3204   /*                                                                       */
3205   /* <Note>                                                                */
3206   /*    Currently, four debug hook slots are available, but only two (for  */
3207   /*    the TrueType and the Type 1 interpreter) are defined.              */
3208   /*                                                                       */
3209   FT_EXPORT_FUNC( void )  FT_Set_Debug_Hook( FT_Library         library,
3210                                              FT_UInt            hook_index,
3211                                              FT_DebugHook_Func  debug_hook )
3212   {
3213     if ( library && debug_hook &&
3214          hook_index <
3215            ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )
3216       library->debug_hooks[hook_index] = debug_hook;
3217   }
3218
3219
3220   /*************************************************************************/
3221   /*                                                                       */
3222   /* <Function>                                                            */
3223   /*    FT_Done_FreeType                                                   */
3224   /*                                                                       */
3225   /* <Description>                                                         */
3226   /*    Destroys a given FreeType library object and all of its childs,    */
3227   /*    including resources, drivers, faces, sizes, etc.                   */
3228   /*                                                                       */
3229   /* <Input>                                                               */
3230   /*    library :: A handle to the target library object.                  */
3231   /*                                                                       */
3232   /* <Return>                                                              */
3233   /*    FreeType error code.  0 means success.                             */
3234   /*                                                                       */
3235   FT_EXPORT_FUNC( FT_Error )  FT_Done_FreeType( FT_Library  library )
3236   {
3237     /* test for valid `library' delayed to FT_Done_Library() */
3238
3239     /* Discard the library object */
3240     FT_Done_Library( library );
3241
3242     return FT_Err_Ok;
3243   }
3244
3245
3246 /* END */