1 | /***************************************************************************/ |
2 | /* */ |
3 | /* ftinit.c */ |
4 | /* */ |
5 | /* FreeType initialization layer (body). */ |
6 | /* */ |
7 | /* Copyright 1996-2018 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 ) |
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 ) |
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 ) |
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 | /* documentation is in ftmodapi.h */ |
234 | |
235 | FT_EXPORT_DEF( void ) |
236 | FT_Set_Default_Properties( FT_Library library ) |
237 | { |
238 | const char* env; |
239 | const char* p; |
240 | const char* q; |
241 | |
242 | char module_name[MAX_LENGTH + 1]; |
243 | char property_name[MAX_LENGTH + 1]; |
244 | char property_value[MAX_LENGTH + 1]; |
245 | |
246 | int i; |
247 | |
248 | |
249 | env = ft_getenv( "FREETYPE_PROPERTIES" ); |
250 | if ( !env ) |
251 | return; |
252 | |
253 | for ( p = env; *p; p++ ) |
254 | { |
255 | /* skip leading whitespace and separators */ |
256 | if ( *p == ' ' || *p == '\t' ) |
257 | continue; |
258 | |
259 | /* read module name, followed by `:' */ |
260 | q = p; |
261 | for ( i = 0; i < MAX_LENGTH; i++ ) |
262 | { |
263 | if ( !*p || *p == ':' ) |
264 | break; |
265 | module_name[i] = *p++; |
266 | } |
267 | module_name[i] = '\0'; |
268 | |
269 | if ( !*p || *p != ':' || p == q ) |
270 | break; |
271 | |
272 | /* read property name, followed by `=' */ |
273 | q = ++p; |
274 | for ( i = 0; i < MAX_LENGTH; i++ ) |
275 | { |
276 | if ( !*p || *p == '=' ) |
277 | break; |
278 | property_name[i] = *p++; |
279 | } |
280 | property_name[i] = '\0'; |
281 | |
282 | if ( !*p || *p != '=' || p == q ) |
283 | break; |
284 | |
285 | /* read property value, followed by whitespace (if any) */ |
286 | q = ++p; |
287 | for ( i = 0; i < MAX_LENGTH; i++ ) |
288 | { |
289 | if ( !*p || *p == ' ' || *p == '\t' ) |
290 | break; |
291 | property_value[i] = *p++; |
292 | } |
293 | property_value[i] = '\0'; |
294 | |
295 | if ( !( *p == '\0' || *p == ' ' || *p == '\t' ) || p == q ) |
296 | break; |
297 | |
298 | /* we completely ignore errors */ |
299 | ft_property_string_set( library, |
300 | module_name, |
301 | property_name, |
302 | property_value ); |
303 | } |
304 | } |
305 | |
306 | #else |
307 | |
308 | FT_EXPORT_DEF( void ) |
309 | FT_Set_Default_Properties( FT_Library library ) |
310 | { |
311 | FT_UNUSED( library ); |
312 | } |
313 | |
314 | #endif |
315 | |
316 | |
317 | /* documentation is in freetype.h */ |
318 | |
319 | FT_EXPORT_DEF( FT_Error ) |
320 | FT_Init_FreeType( FT_Library *alibrary ) |
321 | { |
322 | FT_Error error; |
323 | FT_Memory memory; |
324 | |
325 | |
326 | /* check of `alibrary' delayed to `FT_New_Library' */ |
327 | |
328 | /* First of all, allocate a new system object -- this function is part */ |
329 | /* of the system-specific component, i.e. `ftsystem.c'. */ |
330 | |
331 | memory = FT_New_Memory(); |
332 | if ( !memory ) |
333 | { |
334 | FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" )); |
335 | return FT_THROW( Unimplemented_Feature ); |
336 | } |
337 | |
338 | /* build a library out of it, then fill it with the set of */ |
339 | /* default drivers. */ |
340 | |
341 | error = FT_New_Library( memory, alibrary ); |
342 | if ( error ) |
343 | FT_Done_Memory( memory ); |
344 | else |
345 | FT_Add_Default_Modules( *alibrary ); |
346 | |
347 | FT_Set_Default_Properties( *alibrary ); |
348 | |
349 | return error; |
350 | } |
351 | |
352 | |
353 | /* documentation is in freetype.h */ |
354 | |
355 | FT_EXPORT_DEF( FT_Error ) |
356 | FT_Done_FreeType( FT_Library library ) |
357 | { |
358 | FT_Memory memory; |
359 | |
360 | |
361 | if ( !library ) |
362 | return FT_THROW( Invalid_Library_Handle ); |
363 | |
364 | memory = library->memory; |
365 | |
366 | /* Discard the library object */ |
367 | FT_Done_Library( library ); |
368 | |
369 | /* discard memory manager */ |
370 | FT_Done_Memory( memory ); |
371 | |
372 | return FT_Err_Ok; |
373 | } |
374 | |
375 | |
376 | /* END */ |
377 | |