1 /****************************************************************************
2  *
3  * ftinit.c
4  *
5  *   FreeType initialization layer (body).
6  *
7  * Copyright (C) 1996-2019 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 
46 
47   /**************************************************************************
48    *
49    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
50    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
51    * messages during execution.
52    */
53 #undef  FT_COMPONENT
54 #define FT_COMPONENT  init
55 
56 
57 #undef  FT_USE_MODULE
58 #ifdef __cplusplus
59 #define FT_USE_MODULE( type, x )  extern "C" const type  x;
60 #else
61 #define FT_USE_MODULE( type, x )  extern const type  x;
62 #endif
63 
64 #include FT_CONFIG_MODULES_H
65 
66 #undef  FT_USE_MODULE
67 #define FT_USE_MODULE( type, x )  (const FT_Module_Class*)&(x),
68 
69   static
70   const FT_Module_Class*  const ft_default_modules[] =
71   {
72 #include FT_CONFIG_MODULES_H
73     0
74   };
75 
76 
77   /* documentation is in ftmodapi.h */
78 
79   FT_EXPORT_DEF( void )
FT_Add_Default_Modules(FT_Library library)80   FT_Add_Default_Modules( FT_Library  library )
81   {
82     FT_Error                       error;
83     const FT_Module_Class* const*  cur;
84 
85 
86     /* GCC 4.6 warns the type difference:
87      *   FT_Module_Class** != const FT_Module_Class* const*
88      */
89     cur = (const FT_Module_Class* const*)ft_default_modules;
90 
91     /* test for valid `library' delayed to FT_Add_Module() */
92     while ( *cur )
93     {
94       error = FT_Add_Module( library, *cur );
95       /* notify errors, but don't stop */
96       if ( error )
97         FT_TRACE0(( "FT_Add_Default_Module:"
98                     " Cannot install `%s', error = 0x%x\n",
99                     (*cur)->module_name, error ));
100       cur++;
101     }
102   }
103 
104 
105 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
106 
107 #define MAX_LENGTH  128
108 
109   /* documentation is in ftmodapi.h */
110 
111   FT_EXPORT_DEF( void )
FT_Set_Default_Properties(FT_Library library)112   FT_Set_Default_Properties( FT_Library  library )
113   {
114     const char*  env;
115     const char*  p;
116     const char*  q;
117 
118     char  module_name[MAX_LENGTH + 1];
119     char  property_name[MAX_LENGTH + 1];
120     char  property_value[MAX_LENGTH + 1];
121 
122     int  i;
123 
124 
125     env = ft_getenv( "FREETYPE_PROPERTIES" );
126     if ( !env )
127       return;
128 
129     for ( p = env; *p; p++ )
130     {
131       /* skip leading whitespace and separators */
132       if ( *p == ' ' || *p == '\t' )
133         continue;
134 
135       /* read module name, followed by `:' */
136       q = p;
137       for ( i = 0; i < MAX_LENGTH; i++ )
138       {
139         if ( !*p || *p == ':' )
140           break;
141         module_name[i] = *p++;
142       }
143       module_name[i] = '\0';
144 
145       if ( !*p || *p != ':' || p == q )
146         break;
147 
148       /* read property name, followed by `=' */
149       q = ++p;
150       for ( i = 0; i < MAX_LENGTH; i++ )
151       {
152         if ( !*p || *p == '=' )
153           break;
154         property_name[i] = *p++;
155       }
156       property_name[i] = '\0';
157 
158       if ( !*p || *p != '=' || p == q )
159         break;
160 
161       /* read property value, followed by whitespace (if any) */
162       q = ++p;
163       for ( i = 0; i < MAX_LENGTH; i++ )
164       {
165         if ( !*p || *p == ' ' || *p == '\t' )
166           break;
167         property_value[i] = *p++;
168       }
169       property_value[i] = '\0';
170 
171       if ( !( *p == '\0' || *p == ' ' || *p == '\t' ) || p == q )
172         break;
173 
174       /* we completely ignore errors */
175       ft_property_string_set( library,
176                               module_name,
177                               property_name,
178                               property_value );
179 
180       if ( !*p )
181         break;
182     }
183   }
184 
185 #else
186 
187   FT_EXPORT_DEF( void )
FT_Set_Default_Properties(FT_Library library)188   FT_Set_Default_Properties( FT_Library  library )
189   {
190     FT_UNUSED( library );
191   }
192 
193 #endif
194 
195 
196   /* documentation is in freetype.h */
197 
198   FT_EXPORT_DEF( FT_Error )
FT_Init_FreeType(FT_Library * alibrary)199   FT_Init_FreeType( FT_Library  *alibrary )
200   {
201     FT_Error   error;
202     FT_Memory  memory;
203 
204 
205     /* check of `alibrary' delayed to `FT_New_Library' */
206 
207     /* First of all, allocate a new system object -- this function is part */
208     /* of the system-specific component, i.e. `ftsystem.c'.                */
209 
210     memory = FT_New_Memory();
211     if ( !memory )
212     {
213       FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" ));
214       return FT_THROW( Unimplemented_Feature );
215     }
216 
217     /* build a library out of it, then fill it with the set of */
218     /* default drivers.                                        */
219 
220     error = FT_New_Library( memory, alibrary );
221     if ( error )
222       FT_Done_Memory( memory );
223     else
224       FT_Add_Default_Modules( *alibrary );
225 
226     FT_Set_Default_Properties( *alibrary );
227 
228     return error;
229   }
230 
231 
232   /* documentation is in freetype.h */
233 
234   FT_EXPORT_DEF( FT_Error )
FT_Done_FreeType(FT_Library library)235   FT_Done_FreeType( FT_Library  library )
236   {
237     FT_Memory  memory;
238 
239 
240     if ( !library )
241       return FT_THROW( Invalid_Library_Handle );
242 
243     memory = library->memory;
244 
245     /* Discard the library object */
246     FT_Done_Library( library );
247 
248     /* discard memory manager */
249     FT_Done_Memory( memory );
250 
251     return FT_Err_Ok;
252   }
253 
254 
255 /* END */
256