1 | /**************************************************************************** |
2 | * |
3 | * ftinit.c |
4 | * |
5 | * FreeType initialization layer (body). |
6 | * |
7 | * Copyright (C) 1996-2023 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 <freetype/internal/ftobjs.h> |
43 | #include <freetype/internal/ftdebug.h> |
44 | #include <freetype/ftmodapi.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 ) |
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 ) |
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 ) |
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 ) |
199 | FT_Init_FreeType( FT_Library *alibrary ) |
200 | { |
201 | FT_Error error; |
202 | FT_Memory memory; |
203 | |
204 | |
205 | #ifdef FT_DEBUG_LOGGING |
206 | ft_logging_init(); |
207 | #endif |
208 | |
209 | /* check of `alibrary' delayed to `FT_New_Library' */ |
210 | |
211 | /* First of all, allocate a new system object -- this function is part */ |
212 | /* of the system-specific component, i.e. `ftsystem.c'. */ |
213 | |
214 | memory = FT_New_Memory(); |
215 | if ( !memory ) |
216 | { |
217 | FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" )); |
218 | return FT_THROW( Unimplemented_Feature ); |
219 | } |
220 | |
221 | /* build a library out of it, then fill it with the set of */ |
222 | /* default drivers. */ |
223 | |
224 | error = FT_New_Library( memory, alibrary ); |
225 | if ( error ) |
226 | FT_Done_Memory( memory ); |
227 | else |
228 | FT_Add_Default_Modules( *alibrary ); |
229 | |
230 | FT_Set_Default_Properties( *alibrary ); |
231 | |
232 | return error; |
233 | } |
234 | |
235 | |
236 | /* documentation is in freetype.h */ |
237 | |
238 | FT_EXPORT_DEF( FT_Error ) |
239 | FT_Done_FreeType( FT_Library library ) |
240 | { |
241 | FT_Memory memory; |
242 | |
243 | |
244 | if ( !library ) |
245 | return FT_THROW( Invalid_Library_Handle ); |
246 | |
247 | memory = library->memory; |
248 | |
249 | /* Discard the library object */ |
250 | FT_Done_Library( library ); |
251 | |
252 | /* discard memory manager */ |
253 | FT_Done_Memory( memory ); |
254 | |
255 | #ifdef FT_DEBUG_LOGGING |
256 | ft_logging_deinit(); |
257 | #endif |
258 | |
259 | return FT_Err_Ok; |
260 | } |
261 | |
262 | |
263 | /* END */ |
264 | |