1/***************************************************************************/
2/*                                                                         */
3/*  ftinit.c                                                               */
4/*                                                                         */
5/*    FreeType initialization layer (body).                                */
6/*                                                                         */
7/*  Copyright 1996-2002, 2005, 2007, 2009, 2012-2014 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  /*                                                                       */
20  /*  The purpose of this file is to implement the following two           */
21  /*  functions:                                                           */
22  /*                                                                       */
23  /*  FT_Add_Default_Modules():                                            */
24  /*     This function is used to add the set of default modules to a      */
25  /*     fresh new library object.  The set is taken from the header file  */
26  /*     `config/ftmodule.h'.  See the document `FreeType 2.0 Build        */
27  /*     System' for more information.                                     */
28  /*                                                                       */
29  /*  FT_Init_FreeType():                                                  */
30  /*     This function creates a system object for the current platform,   */
31  /*     builds a library out of it, then calls FT_Default_Drivers().      */
32  /*                                                                       */
33  /*  Note that even if FT_Init_FreeType() uses the implementation of the  */
34  /*  system object defined at build time, client applications are still   */
35  /*  able to provide their own `ftsystem.c'.                              */
36  /*                                                                       */
37  /*************************************************************************/
38
39
40#include <ft2build.h>
41#include FT_CONFIG_CONFIG_H
42#include FT_INTERNAL_OBJECTS_H
43#include FT_INTERNAL_DEBUG_H
44#include FT_MODULE_H
45#include "basepic.h"
46
47
48  /*************************************************************************/
49  /*                                                                       */
50  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
51  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
52  /* messages during execution.                                            */
53  /*                                                                       */
54#undef  FT_COMPONENT
55#define FT_COMPONENT  trace_init
56
57
58#ifndef FT_CONFIG_OPTION_PIC
59
60
61#undef  FT_USE_MODULE
62#ifdef __cplusplus
63#define FT_USE_MODULE( type, x )  extern "C" const type  x;
64#else
65#define FT_USE_MODULE( type, x )  extern const type  x;
66#endif
67
68#include FT_CONFIG_MODULES_H
69
70#undef  FT_USE_MODULE
71#define FT_USE_MODULE( type, x )  (const FT_Module_Class*)&(x),
72
73  static
74  const FT_Module_Class*  const ft_default_modules[] =
75  {
76#include FT_CONFIG_MODULES_H
77    0
78  };
79
80
81#else /* FT_CONFIG_OPTION_PIC */
82
83
84#ifdef __cplusplus
85#define FT_EXTERNC  extern "C"
86#else
87#define FT_EXTERNC  extern
88#endif
89
90  /* declare the module's class creation/destruction functions */
91#undef  FT_USE_MODULE
92#define FT_USE_MODULE( type, x )                            \
93  FT_EXTERNC FT_Error                                       \
94  FT_Create_Class_ ## x( FT_Library         library,        \
95                         FT_Module_Class*  *output_class ); \
96  FT_EXTERNC void                                           \
97  FT_Destroy_Class_ ## x( FT_Library        library,        \
98                          FT_Module_Class*  clazz );
99
100#include FT_CONFIG_MODULES_H
101
102  /* count all module classes */
103#undef  FT_USE_MODULE
104#define FT_USE_MODULE( type, x )  MODULE_CLASS_ ## x,
105
106  enum
107  {
108#include FT_CONFIG_MODULES_H
109    FT_NUM_MODULE_CLASSES
110  };
111
112  /* destroy all module classes */
113#undef  FT_USE_MODULE
114#define FT_USE_MODULE( type, x )                   \
115  if ( classes[i] )                                \
116  {                                                \
117    FT_Destroy_Class_ ## x( library, classes[i] ); \
118  }                                                \
119  i++;
120
121
122  FT_BASE_DEF( void )
123  ft_destroy_default_module_classes( FT_Library  library )
124  {
125    FT_Module_Class*  *classes;
126    FT_Memory          memory;
127    FT_UInt            i;
128    BasePIC*           pic_container = (BasePIC*)library->pic_container.base;
129
130
131    if ( !pic_container->default_module_classes )
132      return;
133
134    memory  = library->memory;
135    classes = pic_container->default_module_classes;
136    i       = 0;
137
138#include FT_CONFIG_MODULES_H
139
140    FT_FREE( classes );
141    pic_container->default_module_classes = 0;
142  }
143
144
145  /* initialize all module classes and the pointer table */
146#undef  FT_USE_MODULE
147#define FT_USE_MODULE( type, x )                     \
148  error = FT_Create_Class_ ## x( library, &clazz );  \
149  if ( error )                                       \
150    goto Exit;                                       \
151  classes[i++] = clazz;
152
153
154  FT_BASE_DEF( FT_Error )
155  ft_create_default_module_classes( FT_Library  library )
156  {
157    FT_Error           error;
158    FT_Memory          memory;
159    FT_Module_Class*  *classes = NULL;
160    FT_Module_Class*   clazz;
161    FT_UInt            i;
162    BasePIC*           pic_container = (BasePIC*)library->pic_container.base;
163
164
165    memory = library->memory;
166
167    pic_container->default_module_classes = 0;
168
169    if ( FT_ALLOC( classes, sizeof ( FT_Module_Class* ) *
170                              ( FT_NUM_MODULE_CLASSES + 1 ) ) )
171      return error;
172
173    /* initialize all pointers to 0, especially the last one */
174    for ( i = 0; i < FT_NUM_MODULE_CLASSES; i++ )
175      classes[i] = 0;
176    classes[FT_NUM_MODULE_CLASSES] = 0;
177
178    i = 0;
179
180#include FT_CONFIG_MODULES_H
181
182  Exit:
183    if ( error )
184      ft_destroy_default_module_classes( library );
185    else
186      pic_container->default_module_classes = classes;
187
188    return error;
189  }
190
191
192#endif /* FT_CONFIG_OPTION_PIC */
193
194
195  /* documentation is in ftmodapi.h */
196
197  FT_EXPORT_DEF( void )
198  FT_Add_Default_Modules( FT_Library  library )
199  {
200    FT_Error                       error;
201    const FT_Module_Class* const*  cur;
202
203
204    /* FT_DEFAULT_MODULES_GET dereferences `library' in PIC mode */
205#ifdef FT_CONFIG_OPTION_PIC
206    if ( !library )
207      return;
208#endif
209
210    /* GCC 4.6 warns the type difference:
211     *   FT_Module_Class** != const FT_Module_Class* const*
212     */
213    cur = (const FT_Module_Class* const*)FT_DEFAULT_MODULES_GET;
214
215    /* test for valid `library' delayed to FT_Add_Module() */
216    while ( *cur )
217    {
218      error = FT_Add_Module( library, *cur );
219      /* notify errors, but don't stop */
220      if ( error )
221        FT_TRACE0(( "FT_Add_Default_Module:"
222                    " Cannot install `%s', error = 0x%x\n",
223                    (*cur)->module_name, error ));
224      cur++;
225    }
226  }
227
228
229  /* documentation is in freetype.h */
230
231  FT_EXPORT_DEF( FT_Error )
232  FT_Init_FreeType( FT_Library  *alibrary )
233  {
234    FT_Error   error;
235    FT_Memory  memory;
236
237
238    /* check of `alibrary' delayed to `FT_New_Library' */
239
240    /* First of all, allocate a new system object -- this function is part */
241    /* of the system-specific component, i.e. `ftsystem.c'.                */
242
243    memory = FT_New_Memory();
244    if ( !memory )
245    {
246      FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" ));
247      return FT_THROW( Unimplemented_Feature );
248    }
249
250    /* build a library out of it, then fill it with the set of */
251    /* default drivers.                                        */
252
253    error = FT_New_Library( memory, alibrary );
254    if ( error )
255      FT_Done_Memory( memory );
256    else
257      FT_Add_Default_Modules( *alibrary );
258
259    return error;
260  }
261
262
263  /* documentation is in freetype.h */
264
265  FT_EXPORT_DEF( FT_Error )
266  FT_Done_FreeType( FT_Library  library )
267  {
268    FT_Memory  memory;
269
270
271    if ( !library )
272      return FT_THROW( Invalid_Library_Handle );
273
274    memory = library->memory;
275
276    /* Discard the library object */
277    FT_Done_Library( library );
278
279    /* discard memory manager */
280    FT_Done_Memory( memory );
281
282    return FT_Err_Ok;
283  }
284
285
286/* END */
287