1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftinit.c                                                               */
4 /*                                                                         */
5 /*    FreeType initialization layer (body).                                */
6 /*                                                                         */
7 /*  Copyright 1996-2016 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   /*     `freetype/config/ftmodule.h'.  See the document `FreeType 2.0     */
27   /*     Build 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 )
ft_destroy_default_module_classes(FT_Library library)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 = NULL;
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 )
ft_create_default_module_classes(FT_Library library)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 = NULL;
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] = NULL;
176     classes[FT_NUM_MODULE_CLASSES] = NULL;
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 )
FT_Add_Default_Modules(FT_Library library)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 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
230 
231 #define MAX_LENGTH  128
232 
233   /*
234    * Set default properties derived from the `FREETYPE_PROPERTIES'
235    * environment variable.
236    *
237    * `FREETYPE_PROPERTIES' has the following syntax form (broken here into
238    * multiple lines for better readability)
239    *
240    *   <optional whitespace>
241    *   <module-name1> ':'
242    *   <property-name1> '=' <property-value1>
243    *   <whitespace>
244    *   <module-name2> ':'
245    *   <property-name2> '=' <property-value2>
246    *   ...
247    *
248    * Example:
249    *
250    *   FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
251    *                       cff:no-stem-darkening=1 \
252    *                       autofitter:warping=1
253    *
254    */
255 
256   static void
ft_set_default_properties(FT_Library library)257   ft_set_default_properties( FT_Library  library )
258   {
259     const char*  env;
260     const char*  p;
261     const char*  q;
262 
263     char  module_name[MAX_LENGTH + 1];
264     char  property_name[MAX_LENGTH + 1];
265     char  property_value[MAX_LENGTH + 1];
266 
267     int  i;
268 
269 
270     env = ft_getenv( "FREETYPE_PROPERTIES" );
271     if ( !env )
272       return;
273 
274     for ( p = env; *p; p++ )
275     {
276       /* skip leading whitespace and separators */
277       if ( *p == ' ' || *p == '\t' )
278         continue;
279 
280       /* read module name, followed by `:' */
281       q = p;
282       for ( i = 0; i < MAX_LENGTH; i++ )
283       {
284         if ( !*p || *p == ':' )
285           break;
286         module_name[i] = *p++;
287       }
288       module_name[i] = '\0';
289 
290       if ( !*p || *p != ':' || p == q )
291         break;
292 
293       /* read property name, followed by `=' */
294       q = ++p;
295       for ( i = 0; i < MAX_LENGTH; i++ )
296       {
297         if ( !*p || *p == '=' )
298           break;
299         property_name[i] = *p++;
300       }
301       property_name[i] = '\0';
302 
303       if ( !*p || *p != '=' || p == q )
304         break;
305 
306       /* read property value, followed by whitespace (if any) */
307       q = ++p;
308       for ( i = 0; i < MAX_LENGTH; i++ )
309       {
310         if ( !*p || *p == ' ' || *p == '\t' )
311           break;
312         property_value[i] = *p++;
313       }
314       property_value[i] = '\0';
315 
316       if ( !( *p == '\0' || *p == ' ' || *p == '\t' ) || p == q )
317         break;
318 
319       /* we completely ignore errors */
320       ft_property_string_set( library,
321                               module_name,
322                               property_name,
323                               property_value );
324     }
325   }
326 
327 #else
328 
329   static void
ft_set_default_properties(FT_Library library)330   ft_set_default_properties( FT_Library  library )
331   {
332     FT_UNUSED( library );
333   }
334 
335 #endif
336 
337 
338   /* documentation is in freetype.h */
339 
340   FT_EXPORT_DEF( FT_Error )
FT_Init_FreeType(FT_Library * alibrary)341   FT_Init_FreeType( FT_Library  *alibrary )
342   {
343     FT_Error   error;
344     FT_Memory  memory;
345 
346 
347     /* check of `alibrary' delayed to `FT_New_Library' */
348 
349     /* First of all, allocate a new system object -- this function is part */
350     /* of the system-specific component, i.e. `ftsystem.c'.                */
351 
352     memory = FT_New_Memory();
353     if ( !memory )
354     {
355       FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" ));
356       return FT_THROW( Unimplemented_Feature );
357     }
358 
359     /* build a library out of it, then fill it with the set of */
360     /* default drivers.                                        */
361 
362     error = FT_New_Library( memory, alibrary );
363     if ( error )
364       FT_Done_Memory( memory );
365     else
366       FT_Add_Default_Modules( *alibrary );
367 
368     ft_set_default_properties( *alibrary );
369 
370     return error;
371   }
372 
373 
374   /* documentation is in freetype.h */
375 
376   FT_EXPORT_DEF( FT_Error )
FT_Done_FreeType(FT_Library library)377   FT_Done_FreeType( FT_Library  library )
378   {
379     FT_Memory  memory;
380 
381 
382     if ( !library )
383       return FT_THROW( Invalid_Library_Handle );
384 
385     memory = library->memory;
386 
387     /* Discard the library object */
388     FT_Done_Library( library );
389 
390     /* discard memory manager */
391     FT_Done_Memory( memory );
392 
393     return FT_Err_Ok;
394   }
395 
396 
397 /* END */
398