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 )
  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     /* 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 )
 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 */