[FREETYPE] Update to v2.7.0. CORE-11639
[reactos.git] / reactos / sdk / lib / 3rdparty / freetype / src / base / ftinit.c
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 )
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 /*
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
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
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 )
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 )
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 */