misc/libfreetype/include/freetype/internal/ftserv.h
changeset 9431 0f5961910e27
parent 9357 a501f5ec7b34
parent 9429 7a97a554ac80
child 9433 f0a8ac191839
equal deleted inserted replaced
9357:a501f5ec7b34 9431:0f5961910e27
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  ftserv.h                                                               */
       
     4 /*                                                                         */
       
     5 /*    The FreeType services (specification only).                          */
       
     6 /*                                                                         */
       
     7 /*  Copyright 2003, 2004, 2005, 2006, 2007 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   /*  Each module can export one or more `services'.  Each service is      */
       
    21   /*  identified by a constant string and modeled by a pointer; the latter */
       
    22   /*  generally corresponds to a structure containing function pointers.   */
       
    23   /*                                                                       */
       
    24   /*  Note that a service's data cannot be a mere function pointer because */
       
    25   /*  in C it is possible that function pointers might be implemented      */
       
    26   /*  differently than data pointers (e.g. 48 bits instead of 32).         */
       
    27   /*                                                                       */
       
    28   /*************************************************************************/
       
    29 
       
    30 
       
    31 #ifndef __FTSERV_H__
       
    32 #define __FTSERV_H__
       
    33 
       
    34 
       
    35 FT_BEGIN_HEADER
       
    36 
       
    37 #if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
       
    38 
       
    39   /* we disable the warning `conditional expression is constant' here */
       
    40   /* in order to compile cleanly with the maximum level of warnings   */
       
    41 #pragma warning( disable : 4127 )
       
    42 
       
    43 #endif /* _MSC_VER */
       
    44 
       
    45   /*
       
    46    * @macro:
       
    47    *   FT_FACE_FIND_SERVICE
       
    48    *
       
    49    * @description:
       
    50    *   This macro is used to look up a service from a face's driver module.
       
    51    *
       
    52    * @input:
       
    53    *   face ::
       
    54    *     The source face handle.
       
    55    *
       
    56    *   id ::
       
    57    *     A string describing the service as defined in the service's
       
    58    *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
       
    59    *     `multi-masters').  It is automatically prefixed with
       
    60    *     `FT_SERVICE_ID_'.
       
    61    *
       
    62    * @output:
       
    63    *   ptr ::
       
    64    *     A variable that receives the service pointer.  Will be NULL
       
    65    *     if not found.
       
    66    */
       
    67 #ifdef __cplusplus
       
    68 
       
    69 #define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
       
    70   FT_BEGIN_STMNT                                                            \
       
    71     FT_Module    module = FT_MODULE( FT_FACE( face )->driver );             \
       
    72     FT_Pointer   _tmp_  = NULL;                                             \
       
    73     FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                              \
       
    74                                                                             \
       
    75                                                                             \
       
    76     if ( module->clazz->get_interface )                                     \
       
    77       _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
       
    78     *_pptr_ = _tmp_;                                                        \
       
    79   FT_END_STMNT
       
    80 
       
    81 #else /* !C++ */
       
    82 
       
    83 #define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
       
    84   FT_BEGIN_STMNT                                                            \
       
    85     FT_Module   module = FT_MODULE( FT_FACE( face )->driver );              \
       
    86     FT_Pointer  _tmp_  = NULL;                                              \
       
    87                                                                             \
       
    88     if ( module->clazz->get_interface )                                     \
       
    89       _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
       
    90     ptr = _tmp_;                                                            \
       
    91   FT_END_STMNT
       
    92 
       
    93 #endif /* !C++ */
       
    94 
       
    95   /*
       
    96    * @macro:
       
    97    *   FT_FACE_FIND_GLOBAL_SERVICE
       
    98    *
       
    99    * @description:
       
   100    *   This macro is used to look up a service from all modules.
       
   101    *
       
   102    * @input:
       
   103    *   face ::
       
   104    *     The source face handle.
       
   105    *
       
   106    *   id ::
       
   107    *     A string describing the service as defined in the service's
       
   108    *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
       
   109    *     `multi-masters').  It is automatically prefixed with
       
   110    *     `FT_SERVICE_ID_'.
       
   111    *
       
   112    * @output:
       
   113    *   ptr ::
       
   114    *     A variable that receives the service pointer.  Will be NULL
       
   115    *     if not found.
       
   116    */
       
   117 #ifdef __cplusplus
       
   118 
       
   119 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
       
   120   FT_BEGIN_STMNT                                                   \
       
   121     FT_Module    module = FT_MODULE( FT_FACE( face )->driver );    \
       
   122     FT_Pointer   _tmp_;                                            \
       
   123     FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                     \
       
   124                                                                    \
       
   125                                                                    \
       
   126     _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
       
   127     *_pptr_ = _tmp_;                                               \
       
   128   FT_END_STMNT
       
   129 
       
   130 #else /* !C++ */
       
   131 
       
   132 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
       
   133   FT_BEGIN_STMNT                                                   \
       
   134     FT_Module   module = FT_MODULE( FT_FACE( face )->driver );     \
       
   135     FT_Pointer  _tmp_;                                             \
       
   136                                                                    \
       
   137                                                                    \
       
   138     _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
       
   139     ptr   = _tmp_;                                                 \
       
   140   FT_END_STMNT
       
   141 
       
   142 #endif /* !C++ */
       
   143 
       
   144 
       
   145   /*************************************************************************/
       
   146   /*************************************************************************/
       
   147   /*****                                                               *****/
       
   148   /*****         S E R V I C E   D E S C R I P T O R S                 *****/
       
   149   /*****                                                               *****/
       
   150   /*************************************************************************/
       
   151   /*************************************************************************/
       
   152 
       
   153   /*
       
   154    *  The following structure is used to _describe_ a given service
       
   155    *  to the library.  This is useful to build simple static service lists.
       
   156    */
       
   157   typedef struct  FT_ServiceDescRec_
       
   158   {
       
   159     const char*  serv_id;     /* service name         */
       
   160     const void*  serv_data;   /* service pointer/data */
       
   161 
       
   162   } FT_ServiceDescRec;
       
   163 
       
   164   typedef const FT_ServiceDescRec*  FT_ServiceDesc;
       
   165 
       
   166   /*************************************************************************/
       
   167   /*                                                                       */
       
   168   /* <Macro>                                                               */
       
   169   /*    FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6             */
       
   170   /*                                                                       */
       
   171   /* <Description>                                                         */
       
   172   /*    Used to initialize an array of FT_ServiceDescRec structs.          */
       
   173   /*                                                                       */
       
   174   /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */
       
   175   /*    to called with a pointer where the allocated array is returned.    */
       
   176   /*    And when it is no longer needed a Destroy function needs           */
       
   177   /*    to be called to release that allocation.                           */
       
   178   /*                                                                       */
       
   179   /*    These functions should be manyally called from the pic_init and    */
       
   180   /*    pic_free functions of your module (see FT_DEFINE_MODULE)           */
       
   181   /*                                                                       */
       
   182   /*    When FT_CONFIG_OPTION_PIC is not defined the array will be         */
       
   183   /*    allocated in the global scope (or the scope where the macro        */
       
   184   /*    is used).                                                          */
       
   185   /*                                                                       */
       
   186 #ifndef FT_CONFIG_OPTION_PIC
       
   187 
       
   188 #define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1)            \
       
   189   static const FT_ServiceDescRec class_[] =                                  \
       
   190   {                                                                          \
       
   191   {serv_id_1, serv_data_1},                                                  \
       
   192   {NULL, NULL}                                                               \
       
   193   };
       
   194 #define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1,            \
       
   195         serv_id_2, serv_data_2)                                              \
       
   196   static const FT_ServiceDescRec class_[] =                                  \
       
   197   {                                                                          \
       
   198   {serv_id_1, serv_data_1},                                                  \
       
   199   {serv_id_2, serv_data_2},                                                  \
       
   200   {NULL, NULL}                                                               \
       
   201   };
       
   202 #define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1,            \
       
   203         serv_id_2, serv_data_2, serv_id_3, serv_data_3)                      \
       
   204   static const FT_ServiceDescRec class_[] =                                  \
       
   205   {                                                                          \
       
   206   {serv_id_1, serv_data_1},                                                  \
       
   207   {serv_id_2, serv_data_2},                                                  \
       
   208   {serv_id_3, serv_data_3},                                                  \
       
   209   {NULL, NULL}                                                               \
       
   210   };
       
   211 #define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1,            \
       
   212         serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
       
   213         serv_id_4, serv_data_4)                                              \
       
   214   static const FT_ServiceDescRec class_[] =                                  \
       
   215   {                                                                          \
       
   216   {serv_id_1, serv_data_1},                                                  \
       
   217   {serv_id_2, serv_data_2},                                                  \
       
   218   {serv_id_3, serv_data_3},                                                  \
       
   219   {serv_id_4, serv_data_4},                                                  \
       
   220   {NULL, NULL}                                                               \
       
   221   };
       
   222 #define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1,            \
       
   223         serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
       
   224         serv_id_4, serv_data_4, serv_id_5, serv_data_5)                      \
       
   225   static const FT_ServiceDescRec class_[] =                                  \
       
   226   {                                                                          \
       
   227   {serv_id_1, serv_data_1},                                                  \
       
   228   {serv_id_2, serv_data_2},                                                  \
       
   229   {serv_id_3, serv_data_3},                                                  \
       
   230   {serv_id_4, serv_data_4},                                                  \
       
   231   {serv_id_5, serv_data_5},                                                  \
       
   232   {NULL, NULL}                                                               \
       
   233   };
       
   234 #define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1,            \
       
   235         serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
       
   236         serv_id_4, serv_data_4, serv_id_5, serv_data_5,                      \
       
   237         serv_id_6, serv_data_6)                                              \
       
   238   static const FT_ServiceDescRec class_[] =                                  \
       
   239   {                                                                          \
       
   240   {serv_id_1, serv_data_1},                                                  \
       
   241   {serv_id_2, serv_data_2},                                                  \
       
   242   {serv_id_3, serv_data_3},                                                  \
       
   243   {serv_id_4, serv_data_4},                                                  \
       
   244   {serv_id_5, serv_data_5},                                                  \
       
   245   {serv_id_6, serv_data_6},                                                  \
       
   246   {NULL, NULL}                                                               \
       
   247   };
       
   248 
       
   249 #else /* FT_CONFIG_OPTION_PIC */ 
       
   250 
       
   251 #define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1)            \
       
   252   void                                                                       \
       
   253   FT_Destroy_Class_##class_( FT_Library library,                             \
       
   254                              FT_ServiceDescRec* clazz )                      \
       
   255   {                                                                          \
       
   256     FT_Memory memory = library->memory;                                      \
       
   257     if ( clazz )                                                             \
       
   258       FT_FREE( clazz );                                                      \
       
   259   }                                                                          \
       
   260                                                                              \
       
   261   FT_Error                                                                   \
       
   262   FT_Create_Class_##class_( FT_Library library,                              \
       
   263                             FT_ServiceDescRec** output_class)                \
       
   264   {                                                                          \
       
   265     FT_ServiceDescRec*  clazz;                                               \
       
   266     FT_Error          error;                                                 \
       
   267     FT_Memory memory = library->memory;                                      \
       
   268                                                                              \
       
   269     if ( FT_ALLOC( clazz, sizeof(*clazz)*2 ) )                               \
       
   270       return error;                                                          \
       
   271     clazz[0].serv_id = serv_id_1;                                            \
       
   272     clazz[0].serv_data = serv_data_1;                                        \
       
   273     clazz[1].serv_id = NULL;                                                 \
       
   274     clazz[1].serv_data = NULL;                                               \
       
   275     *output_class = clazz;                                                   \
       
   276     return FT_Err_Ok;                                                        \
       
   277   } 
       
   278 
       
   279 #define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1,            \
       
   280         serv_id_2, serv_data_2)                                              \
       
   281   void                                                                       \
       
   282   FT_Destroy_Class_##class_( FT_Library library,                             \
       
   283                              FT_ServiceDescRec* clazz )                      \
       
   284   {                                                                          \
       
   285     FT_Memory memory = library->memory;                                      \
       
   286     if ( clazz )                                                             \
       
   287       FT_FREE( clazz );                                                      \
       
   288   }                                                                          \
       
   289                                                                              \
       
   290   FT_Error                                                                   \
       
   291   FT_Create_Class_##class_( FT_Library library,                              \
       
   292                             FT_ServiceDescRec** output_class)                \
       
   293   {                                                                          \
       
   294     FT_ServiceDescRec*  clazz;                                               \
       
   295     FT_Error          error;                                                 \
       
   296     FT_Memory memory = library->memory;                                      \
       
   297                                                                              \
       
   298     if ( FT_ALLOC( clazz, sizeof(*clazz)*3 ) )                               \
       
   299       return error;                                                          \
       
   300     clazz[0].serv_id = serv_id_1;                                            \
       
   301     clazz[0].serv_data = serv_data_1;                                        \
       
   302     clazz[1].serv_id = serv_id_2;                                            \
       
   303     clazz[1].serv_data = serv_data_2;                                        \
       
   304     clazz[2].serv_id = NULL;                                                 \
       
   305     clazz[2].serv_data = NULL;                                               \
       
   306     *output_class = clazz;                                                   \
       
   307     return FT_Err_Ok;                                                        \
       
   308   } 
       
   309 
       
   310 #define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1,            \
       
   311         serv_id_2, serv_data_2, serv_id_3, serv_data_3)                      \
       
   312   void                                                                       \
       
   313   FT_Destroy_Class_##class_( FT_Library library,                             \
       
   314                              FT_ServiceDescRec* clazz )                      \
       
   315   {                                                                          \
       
   316     FT_Memory memory = library->memory;                                      \
       
   317     if ( clazz )                                                             \
       
   318       FT_FREE( clazz );                                                      \
       
   319   }                                                                          \
       
   320                                                                              \
       
   321   FT_Error                                                                   \
       
   322   FT_Create_Class_##class_( FT_Library library,                              \
       
   323                             FT_ServiceDescRec** output_class)                \
       
   324   {                                                                          \
       
   325     FT_ServiceDescRec*  clazz;                                               \
       
   326     FT_Error          error;                                                 \
       
   327     FT_Memory memory = library->memory;                                      \
       
   328                                                                              \
       
   329     if ( FT_ALLOC( clazz, sizeof(*clazz)*4 ) )                               \
       
   330       return error;                                                          \
       
   331     clazz[0].serv_id = serv_id_1;                                            \
       
   332     clazz[0].serv_data = serv_data_1;                                        \
       
   333     clazz[1].serv_id = serv_id_2;                                            \
       
   334     clazz[1].serv_data = serv_data_2;                                        \
       
   335     clazz[2].serv_id = serv_id_3;                                            \
       
   336     clazz[2].serv_data = serv_data_3;                                        \
       
   337     clazz[3].serv_id = NULL;                                                 \
       
   338     clazz[3].serv_data = NULL;                                               \
       
   339     *output_class = clazz;                                                   \
       
   340     return FT_Err_Ok;                                                        \
       
   341   } 
       
   342 
       
   343 #define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1,            \
       
   344         serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
       
   345         serv_id_4, serv_data_4)                                              \
       
   346   void                                                                       \
       
   347   FT_Destroy_Class_##class_( FT_Library library,                             \
       
   348                              FT_ServiceDescRec* clazz )                      \
       
   349   {                                                                          \
       
   350     FT_Memory memory = library->memory;                                      \
       
   351     if ( clazz )                                                             \
       
   352       FT_FREE( clazz );                                                      \
       
   353   }                                                                          \
       
   354                                                                              \
       
   355   FT_Error                                                                   \
       
   356   FT_Create_Class_##class_( FT_Library library,                              \
       
   357                             FT_ServiceDescRec** output_class)                \
       
   358   {                                                                          \
       
   359     FT_ServiceDescRec*  clazz;                                               \
       
   360     FT_Error          error;                                                 \
       
   361     FT_Memory memory = library->memory;                                      \
       
   362                                                                              \
       
   363     if ( FT_ALLOC( clazz, sizeof(*clazz)*5 ) )                               \
       
   364       return error;                                                          \
       
   365     clazz[0].serv_id = serv_id_1;                                            \
       
   366     clazz[0].serv_data = serv_data_1;                                        \
       
   367     clazz[1].serv_id = serv_id_2;                                            \
       
   368     clazz[1].serv_data = serv_data_2;                                        \
       
   369     clazz[2].serv_id = serv_id_3;                                            \
       
   370     clazz[2].serv_data = serv_data_3;                                        \
       
   371     clazz[3].serv_id = serv_id_4;                                            \
       
   372     clazz[3].serv_data = serv_data_4;                                        \
       
   373     clazz[4].serv_id = NULL;                                                 \
       
   374     clazz[4].serv_data = NULL;                                               \
       
   375     *output_class = clazz;                                                   \
       
   376     return FT_Err_Ok;                                                        \
       
   377   } 
       
   378 
       
   379 #define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1,            \
       
   380         serv_id_2, serv_data_2, serv_id_3, serv_data_3, serv_id_4,           \
       
   381         serv_data_4, serv_id_5, serv_data_5)                                 \
       
   382   void                                                                       \
       
   383   FT_Destroy_Class_##class_( FT_Library library,                             \
       
   384                              FT_ServiceDescRec* clazz )                      \
       
   385   {                                                                          \
       
   386     FT_Memory memory = library->memory;                                      \
       
   387     if ( clazz )                                                             \
       
   388       FT_FREE( clazz );                                                      \
       
   389   }                                                                          \
       
   390                                                                              \
       
   391   FT_Error                                                                   \
       
   392   FT_Create_Class_##class_( FT_Library library,                              \
       
   393                             FT_ServiceDescRec** output_class)                \
       
   394   {                                                                          \
       
   395     FT_ServiceDescRec*  clazz;                                               \
       
   396     FT_Error          error;                                                 \
       
   397     FT_Memory memory = library->memory;                                      \
       
   398                                                                              \
       
   399     if ( FT_ALLOC( clazz, sizeof(*clazz)*6 ) )                               \
       
   400       return error;                                                          \
       
   401     clazz[0].serv_id = serv_id_1;                                            \
       
   402     clazz[0].serv_data = serv_data_1;                                        \
       
   403     clazz[1].serv_id = serv_id_2;                                            \
       
   404     clazz[1].serv_data = serv_data_2;                                        \
       
   405     clazz[2].serv_id = serv_id_3;                                            \
       
   406     clazz[2].serv_data = serv_data_3;                                        \
       
   407     clazz[3].serv_id = serv_id_4;                                            \
       
   408     clazz[3].serv_data = serv_data_4;                                        \
       
   409     clazz[4].serv_id = serv_id_5;                                            \
       
   410     clazz[4].serv_data = serv_data_5;                                        \
       
   411     clazz[5].serv_id = NULL;                                                 \
       
   412     clazz[5].serv_data = NULL;                                               \
       
   413     *output_class = clazz;                                                   \
       
   414     return FT_Err_Ok;                                                        \
       
   415   } 
       
   416 
       
   417 #define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1,            \
       
   418         serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
       
   419         serv_id_4, serv_data_4, serv_id_5, serv_data_5,                      \
       
   420         serv_id_6, serv_data_6)                                              \
       
   421   void                                                                       \
       
   422   FT_Destroy_Class_##class_( FT_Library library,                             \
       
   423                              FT_ServiceDescRec* clazz )                      \
       
   424   {                                                                          \
       
   425     FT_Memory memory = library->memory;                                      \
       
   426     if ( clazz )                                                             \
       
   427       FT_FREE( clazz );                                                      \
       
   428   }                                                                          \
       
   429                                                                              \
       
   430   FT_Error                                                                   \
       
   431   FT_Create_Class_##class_( FT_Library library,                              \
       
   432                             FT_ServiceDescRec** output_class)                \
       
   433   {                                                                          \
       
   434     FT_ServiceDescRec*  clazz;                                               \
       
   435     FT_Error          error;                                                 \
       
   436     FT_Memory memory = library->memory;                                      \
       
   437                                                                              \
       
   438     if ( FT_ALLOC( clazz, sizeof(*clazz)*7 ) )                               \
       
   439       return error;                                                          \
       
   440     clazz[0].serv_id = serv_id_1;                                            \
       
   441     clazz[0].serv_data = serv_data_1;                                        \
       
   442     clazz[1].serv_id = serv_id_2;                                            \
       
   443     clazz[1].serv_data = serv_data_2;                                        \
       
   444     clazz[2].serv_id = serv_id_3;                                            \
       
   445     clazz[2].serv_data = serv_data_3;                                        \
       
   446     clazz[3].serv_id = serv_id_4;                                            \
       
   447     clazz[3].serv_data = serv_data_4;                                        \
       
   448     clazz[4].serv_id = serv_id_5;                                            \
       
   449     clazz[4].serv_data = serv_data_5;                                        \
       
   450     clazz[5].serv_id = serv_id_6;                                            \
       
   451     clazz[5].serv_data = serv_data_6;                                        \
       
   452     clazz[6].serv_id = NULL;                                                 \
       
   453     clazz[6].serv_data = NULL;                                               \
       
   454     *output_class = clazz;                                                   \
       
   455     return FT_Err_Ok;                                                        \
       
   456   } 
       
   457 #endif /* FT_CONFIG_OPTION_PIC */ 
       
   458 
       
   459   /*
       
   460    *  Parse a list of FT_ServiceDescRec descriptors and look for
       
   461    *  a specific service by ID.  Note that the last element in the
       
   462    *  array must be { NULL, NULL }, and that the function should
       
   463    *  return NULL if the service isn't available.
       
   464    *
       
   465    *  This function can be used by modules to implement their
       
   466    *  `get_service' method.
       
   467    */
       
   468   FT_BASE( FT_Pointer )
       
   469   ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
       
   470                           const char*     service_id );
       
   471 
       
   472 
       
   473   /*************************************************************************/
       
   474   /*************************************************************************/
       
   475   /*****                                                               *****/
       
   476   /*****             S E R V I C E S   C A C H E                       *****/
       
   477   /*****                                                               *****/
       
   478   /*************************************************************************/
       
   479   /*************************************************************************/
       
   480 
       
   481   /*
       
   482    *  This structure is used to store a cache for several frequently used
       
   483    *  services.  It is the type of `face->internal->services'.  You
       
   484    *  should only use FT_FACE_LOOKUP_SERVICE to access it.
       
   485    *
       
   486    *  All fields should have the type FT_Pointer to relax compilation
       
   487    *  dependencies.  We assume the developer isn't completely stupid.
       
   488    *
       
   489    *  Each field must be named `service_XXXX' where `XXX' corresponds to
       
   490    *  the correct FT_SERVICE_ID_XXXX macro.  See the definition of
       
   491    *  FT_FACE_LOOKUP_SERVICE below how this is implemented.
       
   492    *
       
   493    */
       
   494   typedef struct  FT_ServiceCacheRec_
       
   495   {
       
   496     FT_Pointer  service_POSTSCRIPT_FONT_NAME;
       
   497     FT_Pointer  service_MULTI_MASTERS;
       
   498     FT_Pointer  service_GLYPH_DICT;
       
   499     FT_Pointer  service_PFR_METRICS;
       
   500     FT_Pointer  service_WINFNT;
       
   501 
       
   502   } FT_ServiceCacheRec, *FT_ServiceCache;
       
   503 
       
   504 
       
   505   /*
       
   506    *  A magic number used within the services cache.
       
   507    */
       
   508 #define FT_SERVICE_UNAVAILABLE  ((FT_Pointer)-2)  /* magic number */
       
   509 
       
   510 
       
   511   /*
       
   512    * @macro:
       
   513    *   FT_FACE_LOOKUP_SERVICE
       
   514    *
       
   515    * @description:
       
   516    *   This macro is used to lookup a service from a face's driver module
       
   517    *   using its cache.
       
   518    *
       
   519    * @input:
       
   520    *   face::
       
   521    *     The source face handle containing the cache.
       
   522    *
       
   523    *   field ::
       
   524    *     The field name in the cache.
       
   525    *
       
   526    *   id ::
       
   527    *     The service ID.
       
   528    *
       
   529    * @output:
       
   530    *   ptr ::
       
   531    *     A variable receiving the service data.  NULL if not available.
       
   532    */
       
   533 #ifdef __cplusplus
       
   534 
       
   535 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
       
   536   FT_BEGIN_STMNT                                               \
       
   537     FT_Pointer   svc;                                          \
       
   538     FT_Pointer*  Pptr = (FT_Pointer*)&(ptr);                   \
       
   539                                                                \
       
   540                                                                \
       
   541     svc = FT_FACE( face )->internal->services. service_ ## id; \
       
   542     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
       
   543       svc = NULL;                                              \
       
   544     else if ( svc == NULL )                                    \
       
   545     {                                                          \
       
   546       FT_FACE_FIND_SERVICE( face, svc, id );                   \
       
   547                                                                \
       
   548       FT_FACE( face )->internal->services. service_ ## id =    \
       
   549         (FT_Pointer)( svc != NULL ? svc                        \
       
   550                                   : FT_SERVICE_UNAVAILABLE );  \
       
   551     }                                                          \
       
   552     *Pptr = svc;                                               \
       
   553   FT_END_STMNT
       
   554 
       
   555 #else /* !C++ */
       
   556 
       
   557 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
       
   558   FT_BEGIN_STMNT                                               \
       
   559     FT_Pointer  svc;                                           \
       
   560                                                                \
       
   561                                                                \
       
   562     svc = FT_FACE( face )->internal->services. service_ ## id; \
       
   563     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
       
   564       svc = NULL;                                              \
       
   565     else if ( svc == NULL )                                    \
       
   566     {                                                          \
       
   567       FT_FACE_FIND_SERVICE( face, svc, id );                   \
       
   568                                                                \
       
   569       FT_FACE( face )->internal->services. service_ ## id =    \
       
   570         (FT_Pointer)( svc != NULL ? svc                        \
       
   571                                   : FT_SERVICE_UNAVAILABLE );  \
       
   572     }                                                          \
       
   573     ptr = svc;                                                 \
       
   574   FT_END_STMNT
       
   575 
       
   576 #endif /* !C++ */
       
   577 
       
   578   /*
       
   579    *  A macro used to define new service structure types.
       
   580    */
       
   581 
       
   582 #define FT_DEFINE_SERVICE( name )            \
       
   583   typedef struct FT_Service_ ## name ## Rec_ \
       
   584     FT_Service_ ## name ## Rec ;             \
       
   585   typedef struct FT_Service_ ## name ## Rec_ \
       
   586     const * FT_Service_ ## name ;            \
       
   587   struct FT_Service_ ## name ## Rec_
       
   588 
       
   589   /* */
       
   590 
       
   591   /*
       
   592    *  The header files containing the services.
       
   593    */
       
   594 
       
   595 #define FT_SERVICE_BDF_H                <freetype/internal/services/svbdf.h>
       
   596 #define FT_SERVICE_CID_H                <freetype/internal/services/svcid.h>
       
   597 #define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
       
   598 #define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
       
   599 #define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
       
   600 #define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
       
   601 #define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
       
   602 #define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
       
   603 #define FT_SERVICE_POSTSCRIPT_CMAPS_H   <freetype/internal/services/svpscmap.h>
       
   604 #define FT_SERVICE_POSTSCRIPT_INFO_H    <freetype/internal/services/svpsinfo.h>
       
   605 #define FT_SERVICE_POSTSCRIPT_NAME_H    <freetype/internal/services/svpostnm.h>
       
   606 #define FT_SERVICE_SFNT_H               <freetype/internal/services/svsfnt.h>
       
   607 #define FT_SERVICE_TRUETYPE_ENGINE_H    <freetype/internal/services/svtteng.h>
       
   608 #define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>
       
   609 #define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>
       
   610 #define FT_SERVICE_XFREE86_NAME_H       <freetype/internal/services/svxf86nm.h>
       
   611 #define FT_SERVICE_TRUETYPE_GLYF_H      <freetype/internal/services/svttglyf.h>
       
   612 
       
   613  /* */
       
   614 
       
   615 FT_END_HEADER
       
   616 
       
   617 #endif /* __FTSERV_H__ */
       
   618 
       
   619 
       
   620 /* END */