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