Home | History | Annotate | Download | only in internal
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  ftserv.h                                                               */
      4 /*                                                                         */
      5 /*    The FreeType services (specification only).                          */
      6 /*                                                                         */
      7 /*  Copyright 2003-2017 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   /*
     38    * @macro:
     39    *   FT_FACE_FIND_SERVICE
     40    *
     41    * @description:
     42    *   This macro is used to look up a service from a face's driver module.
     43    *
     44    * @input:
     45    *   face ::
     46    *     The source face handle.
     47    *
     48    *   id ::
     49    *     A string describing the service as defined in the service's
     50    *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
     51    *     `multi-masters').  It is automatically prefixed with
     52    *     `FT_SERVICE_ID_'.
     53    *
     54    * @output:
     55    *   ptr ::
     56    *     A variable that receives the service pointer.  Will be NULL
     57    *     if not found.
     58    */
     59 #ifdef __cplusplus
     60 
     61 #define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
     62   FT_BEGIN_STMNT                                                            \
     63     FT_Module    module = FT_MODULE( FT_FACE( face )->driver );             \
     64     FT_Pointer   _tmp_  = NULL;                                             \
     65     FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                              \
     66                                                                             \
     67                                                                             \
     68     if ( module->clazz->get_interface )                                     \
     69       _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
     70     *_pptr_ = _tmp_;                                                        \
     71   FT_END_STMNT
     72 
     73 #else /* !C++ */
     74 
     75 #define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
     76   FT_BEGIN_STMNT                                                            \
     77     FT_Module   module = FT_MODULE( FT_FACE( face )->driver );              \
     78     FT_Pointer  _tmp_  = NULL;                                              \
     79                                                                             \
     80     if ( module->clazz->get_interface )                                     \
     81       _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
     82     ptr = _tmp_;                                                            \
     83   FT_END_STMNT
     84 
     85 #endif /* !C++ */
     86 
     87 
     88   /*
     89    * @macro:
     90    *   FT_FACE_FIND_GLOBAL_SERVICE
     91    *
     92    * @description:
     93    *   This macro is used to look up a service from all modules.
     94    *
     95    * @input:
     96    *   face ::
     97    *     The source face handle.
     98    *
     99    *   id ::
    100    *     A string describing the service as defined in the service's
    101    *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
    102    *     `multi-masters').  It is automatically prefixed with
    103    *     `FT_SERVICE_ID_'.
    104    *
    105    * @output:
    106    *   ptr ::
    107    *     A variable that receives the service pointer.  Will be NULL
    108    *     if not found.
    109    */
    110 #ifdef __cplusplus
    111 
    112 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )                  \
    113   FT_BEGIN_STMNT                                                      \
    114     FT_Module    module = FT_MODULE( FT_FACE( face )->driver );       \
    115     FT_Pointer   _tmp_;                                               \
    116     FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                        \
    117                                                                       \
    118                                                                       \
    119     _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
    120     *_pptr_ = _tmp_;                                                  \
    121   FT_END_STMNT
    122 
    123 #else /* !C++ */
    124 
    125 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )                  \
    126   FT_BEGIN_STMNT                                                      \
    127     FT_Module   module = FT_MODULE( FT_FACE( face )->driver );        \
    128     FT_Pointer  _tmp_;                                                \
    129                                                                       \
    130                                                                       \
    131     _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
    132     ptr   = _tmp_;                                                    \
    133   FT_END_STMNT
    134 
    135 #endif /* !C++ */
    136 
    137 
    138   /*************************************************************************/
    139   /*************************************************************************/
    140   /*****                                                               *****/
    141   /*****         S E R V I C E   D E S C R I P T O R S                 *****/
    142   /*****                                                               *****/
    143   /*************************************************************************/
    144   /*************************************************************************/
    145 
    146   /*
    147    *  The following structure is used to _describe_ a given service
    148    *  to the library.  This is useful to build simple static service lists.
    149    */
    150   typedef struct  FT_ServiceDescRec_
    151   {
    152     const char*  serv_id;     /* service name         */
    153     const void*  serv_data;   /* service pointer/data */
    154 
    155   } FT_ServiceDescRec;
    156 
    157   typedef const FT_ServiceDescRec*  FT_ServiceDesc;
    158 
    159 
    160   /*************************************************************************/
    161   /*                                                                       */
    162   /* <Macro>                                                               */
    163   /*    FT_DEFINE_SERVICEDESCREC1                                          */
    164   /*    FT_DEFINE_SERVICEDESCREC2                                          */
    165   /*    FT_DEFINE_SERVICEDESCREC3                                          */
    166   /*    FT_DEFINE_SERVICEDESCREC4                                          */
    167   /*    FT_DEFINE_SERVICEDESCREC5                                          */
    168   /*    FT_DEFINE_SERVICEDESCREC6                                          */
    169   /*    FT_DEFINE_SERVICEDESCREC7                                          */
    170   /*    FT_DEFINE_SERVICEDESCREC8                                          */
    171   /*                                                                       */
    172   /* <Description>                                                         */
    173   /*    Used to initialize an array of FT_ServiceDescRec structures.       */
    174   /*                                                                       */
    175   /*    When FT_CONFIG_OPTION_PIC is defined a `create' function needs to  */
    176   /*    be called with a pointer to return an allocated array.  As soon as */
    177   /*    it is no longer needed, a `destroy' function needs to be called to */
    178   /*    release that allocation.                                           */
    179   /*                                                                       */
    180   /*    These functions should be manually called from the `pic_init' and  */
    181   /*    `pic_free' functions of your module (see FT_DEFINE_MODULE).        */
    182   /*                                                                       */
    183   /*    When FT_CONFIG_OPTION_PIC is not defined the array will be         */
    184   /*    allocated in the global scope (or the scope where the macro is     */
    185   /*    used).                                                             */
    186   /*                                                                       */
    187 #ifndef FT_CONFIG_OPTION_PIC
    188 
    189 #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
    190                                    serv_id_1, serv_data_1 )                 \
    191   static const FT_ServiceDescRec  class_[] =                                \
    192   {                                                                         \
    193     { serv_id_1, serv_data_1 },                                             \
    194     { NULL, NULL }                                                          \
    195   };
    196 
    197 #define FT_DEFINE_SERVICEDESCREC2( class_,                                  \
    198                                    serv_id_1, serv_data_1,                  \
    199                                    serv_id_2, serv_data_2 )                 \
    200   static const FT_ServiceDescRec  class_[] =                                \
    201   {                                                                         \
    202     { serv_id_1, serv_data_1 },                                             \
    203     { serv_id_2, serv_data_2 },                                             \
    204     { NULL, NULL }                                                          \
    205   };
    206 
    207 #define FT_DEFINE_SERVICEDESCREC3( class_,                                  \
    208                                    serv_id_1, serv_data_1,                  \
    209                                    serv_id_2, serv_data_2,                  \
    210                                    serv_id_3, serv_data_3 )                 \
    211   static const FT_ServiceDescRec  class_[] =                                \
    212   {                                                                         \
    213     { serv_id_1, serv_data_1 },                                             \
    214     { serv_id_2, serv_data_2 },                                             \
    215     { serv_id_3, serv_data_3 },                                             \
    216     { NULL, NULL }                                                          \
    217   };
    218 
    219 #define FT_DEFINE_SERVICEDESCREC4( class_,                                  \
    220                                    serv_id_1, serv_data_1,                  \
    221                                    serv_id_2, serv_data_2,                  \
    222                                    serv_id_3, serv_data_3,                  \
    223                                    serv_id_4, serv_data_4 )                 \
    224   static const FT_ServiceDescRec  class_[] =                                \
    225   {                                                                         \
    226     { serv_id_1, serv_data_1 },                                             \
    227     { serv_id_2, serv_data_2 },                                             \
    228     { serv_id_3, serv_data_3 },                                             \
    229     { serv_id_4, serv_data_4 },                                             \
    230     { NULL, NULL }                                                          \
    231   };
    232 
    233 #define FT_DEFINE_SERVICEDESCREC5( class_,                                  \
    234                                    serv_id_1, serv_data_1,                  \
    235                                    serv_id_2, serv_data_2,                  \
    236                                    serv_id_3, serv_data_3,                  \
    237                                    serv_id_4, serv_data_4,                  \
    238                                    serv_id_5, serv_data_5 )                 \
    239   static const FT_ServiceDescRec  class_[] =                                \
    240   {                                                                         \
    241     { serv_id_1, serv_data_1 },                                             \
    242     { serv_id_2, serv_data_2 },                                             \
    243     { serv_id_3, serv_data_3 },                                             \
    244     { serv_id_4, serv_data_4 },                                             \
    245     { serv_id_5, serv_data_5 },                                             \
    246     { NULL, NULL }                                                          \
    247   };
    248 
    249 #define FT_DEFINE_SERVICEDESCREC6( class_,                                  \
    250                                    serv_id_1, serv_data_1,                  \
    251                                    serv_id_2, serv_data_2,                  \
    252                                    serv_id_3, serv_data_3,                  \
    253                                    serv_id_4, serv_data_4,                  \
    254                                    serv_id_5, serv_data_5,                  \
    255                                    serv_id_6, serv_data_6 )                 \
    256   static const FT_ServiceDescRec  class_[] =                                \
    257   {                                                                         \
    258     { serv_id_1, serv_data_1 },                                             \
    259     { serv_id_2, serv_data_2 },                                             \
    260     { serv_id_3, serv_data_3 },                                             \
    261     { serv_id_4, serv_data_4 },                                             \
    262     { serv_id_5, serv_data_5 },                                             \
    263     { serv_id_6, serv_data_6 },                                             \
    264     { NULL, NULL }                                                          \
    265   };
    266 
    267 #define FT_DEFINE_SERVICEDESCREC7( class_,                                  \
    268                                    serv_id_1, serv_data_1,                  \
    269                                    serv_id_2, serv_data_2,                  \
    270                                    serv_id_3, serv_data_3,                  \
    271                                    serv_id_4, serv_data_4,                  \
    272                                    serv_id_5, serv_data_5,                  \
    273                                    serv_id_6, serv_data_6,                  \
    274                                    serv_id_7, serv_data_7 )                 \
    275   static const FT_ServiceDescRec  class_[] =                                \
    276   {                                                                         \
    277     { serv_id_1, serv_data_1 },                                             \
    278     { serv_id_2, serv_data_2 },                                             \
    279     { serv_id_3, serv_data_3 },                                             \
    280     { serv_id_4, serv_data_4 },                                             \
    281     { serv_id_5, serv_data_5 },                                             \
    282     { serv_id_6, serv_data_6 },                                             \
    283     { serv_id_7, serv_data_7 },                                             \
    284     { NULL, NULL }                                                          \
    285   };
    286 
    287 #define FT_DEFINE_SERVICEDESCREC8( class_,                                  \
    288                                    serv_id_1, serv_data_1,                  \
    289                                    serv_id_2, serv_data_2,                  \
    290                                    serv_id_3, serv_data_3,                  \
    291                                    serv_id_4, serv_data_4,                  \
    292                                    serv_id_5, serv_data_5,                  \
    293                                    serv_id_6, serv_data_6,                  \
    294                                    serv_id_7, serv_data_7,                  \
    295                                    serv_id_8, serv_data_8 )                 \
    296   static const FT_ServiceDescRec  class_[] =                                \
    297   {                                                                         \
    298     { serv_id_1, serv_data_1 },                                             \
    299     { serv_id_2, serv_data_2 },                                             \
    300     { serv_id_3, serv_data_3 },                                             \
    301     { serv_id_4, serv_data_4 },                                             \
    302     { serv_id_5, serv_data_5 },                                             \
    303     { serv_id_6, serv_data_6 },                                             \
    304     { serv_id_7, serv_data_7 },                                             \
    305     { serv_id_8, serv_data_8 },                                             \
    306     { NULL, NULL }                                                          \
    307   };
    308 
    309 #define FT_DEFINE_SERVICEDESCREC9( class_,                                  \
    310                                    serv_id_1, serv_data_1,                  \
    311                                    serv_id_2, serv_data_2,                  \
    312                                    serv_id_3, serv_data_3,                  \
    313                                    serv_id_4, serv_data_4,                  \
    314                                    serv_id_5, serv_data_5,                  \
    315                                    serv_id_6, serv_data_6,                  \
    316                                    serv_id_7, serv_data_7,                  \
    317                                    serv_id_8, serv_data_8,                  \
    318                                    serv_id_9, serv_data_9 )                 \
    319   static const FT_ServiceDescRec  class_[] =                                \
    320   {                                                                         \
    321     { serv_id_1, serv_data_1 },                                             \
    322     { serv_id_2, serv_data_2 },                                             \
    323     { serv_id_3, serv_data_3 },                                             \
    324     { serv_id_4, serv_data_4 },                                             \
    325     { serv_id_5, serv_data_5 },                                             \
    326     { serv_id_6, serv_data_6 },                                             \
    327     { serv_id_7, serv_data_7 },                                             \
    328     { serv_id_8, serv_data_8 },                                             \
    329     { serv_id_9, serv_data_9 },                                             \
    330     { NULL, NULL }                                                          \
    331   };
    332 
    333 #else /* FT_CONFIG_OPTION_PIC */
    334 
    335 #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
    336                                    serv_id_1, serv_data_1 )                 \
    337   void                                                                      \
    338   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
    339                                FT_ServiceDescRec*  clazz )                  \
    340   {                                                                         \
    341     FT_Memory  memory = library->memory;                                    \
    342                                                                             \
    343                                                                             \
    344     if ( clazz )                                                            \
    345       FT_FREE( clazz );                                                     \
    346   }                                                                         \
    347                                                                             \
    348   FT_Error                                                                  \
    349   FT_Create_Class_ ## class_( FT_Library           library,                 \
    350                               FT_ServiceDescRec**  output_class )           \
    351   {                                                                         \
    352     FT_ServiceDescRec*  clazz  = NULL;                                      \
    353     FT_Error            error;                                              \
    354     FT_Memory           memory = library->memory;                           \
    355                                                                             \
    356                                                                             \
    357     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 2 ) )                         \
    358       return error;                                                         \
    359                                                                             \
    360     clazz[0].serv_id   = serv_id_1;                                         \
    361     clazz[0].serv_data = serv_data_1;                                       \
    362     clazz[1].serv_id   = NULL;                                              \
    363     clazz[1].serv_data = NULL;                                              \
    364                                                                             \
    365     *output_class = clazz;                                                  \
    366                                                                             \
    367     return FT_Err_Ok;                                                       \
    368   }
    369 
    370 #define FT_DEFINE_SERVICEDESCREC2( class_,                                  \
    371                                    serv_id_1, serv_data_1,                  \
    372                                    serv_id_2, serv_data_2 )                 \
    373   void                                                                      \
    374   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
    375                                FT_ServiceDescRec*  clazz )                  \
    376   {                                                                         \
    377     FT_Memory  memory = library->memory;                                    \
    378                                                                             \
    379                                                                             \
    380     if ( clazz )                                                            \
    381       FT_FREE( clazz );                                                     \
    382   }                                                                         \
    383                                                                             \
    384   FT_Error                                                                  \
    385   FT_Create_Class_ ## class_( FT_Library           library,                 \
    386                               FT_ServiceDescRec**  output_class )           \
    387   {                                                                         \
    388     FT_ServiceDescRec*  clazz  = NULL;                                      \
    389     FT_Error            error;                                              \
    390     FT_Memory           memory = library->memory;                           \
    391                                                                             \
    392                                                                             \
    393     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 3 ) )                         \
    394       return error;                                                         \
    395                                                                             \
    396     clazz[0].serv_id   = serv_id_1;                                         \
    397     clazz[0].serv_data = serv_data_1;                                       \
    398     clazz[1].serv_id   = serv_id_2;                                         \
    399     clazz[1].serv_data = serv_data_2;                                       \
    400     clazz[2].serv_id   = NULL;                                              \
    401     clazz[2].serv_data = NULL;                                              \
    402                                                                             \
    403     *output_class = clazz;                                                  \
    404                                                                             \
    405     return FT_Err_Ok;                                                       \
    406   }
    407 
    408 #define FT_DEFINE_SERVICEDESCREC3( class_,                                  \
    409                                    serv_id_1, serv_data_1,                  \
    410                                    serv_id_2, serv_data_2,                  \
    411                                    serv_id_3, serv_data_3 )                 \
    412   void                                                                      \
    413   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
    414                                FT_ServiceDescRec*  clazz )                  \
    415   {                                                                         \
    416     FT_Memory  memory = library->memory;                                    \
    417                                                                             \
    418                                                                             \
    419     if ( clazz )                                                            \
    420       FT_FREE( clazz );                                                     \
    421   }                                                                         \
    422                                                                             \
    423   FT_Error                                                                  \
    424   FT_Create_Class_ ## class_( FT_Library           library,                 \
    425                               FT_ServiceDescRec**  output_class )           \
    426   {                                                                         \
    427     FT_ServiceDescRec*  clazz  = NULL;                                      \
    428     FT_Error            error;                                              \
    429     FT_Memory           memory = library->memory;                           \
    430                                                                             \
    431                                                                             \
    432     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 4 ) )                         \
    433       return error;                                                         \
    434                                                                             \
    435     clazz[0].serv_id   = serv_id_1;                                         \
    436     clazz[0].serv_data = serv_data_1;                                       \
    437     clazz[1].serv_id   = serv_id_2;                                         \
    438     clazz[1].serv_data = serv_data_2;                                       \
    439     clazz[2].serv_id   = serv_id_3;                                         \
    440     clazz[2].serv_data = serv_data_3;                                       \
    441     clazz[3].serv_id   = NULL;                                              \
    442     clazz[3].serv_data = NULL;                                              \
    443                                                                             \
    444     *output_class = clazz;                                                  \
    445                                                                             \
    446     return FT_Err_Ok;                                                       \
    447   }
    448 
    449 #define FT_DEFINE_SERVICEDESCREC4( class_,                                  \
    450                                    serv_id_1, serv_data_1,                  \
    451                                    serv_id_2, serv_data_2,                  \
    452                                    serv_id_3, serv_data_3,                  \
    453                                    serv_id_4, serv_data_4 )                 \
    454   void                                                                      \
    455   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
    456                                FT_ServiceDescRec*  clazz )                  \
    457   {                                                                         \
    458     FT_Memory  memory = library->memory;                                    \
    459                                                                             \
    460                                                                             \
    461     if ( clazz )                                                            \
    462       FT_FREE( clazz );                                                     \
    463   }                                                                         \
    464                                                                             \
    465   FT_Error                                                                  \
    466   FT_Create_Class_ ## class_( FT_Library           library,                 \
    467                               FT_ServiceDescRec**  output_class )           \
    468   {                                                                         \
    469     FT_ServiceDescRec*  clazz  = NULL;                                      \
    470     FT_Error            error;                                              \
    471     FT_Memory           memory = library->memory;                           \
    472                                                                             \
    473                                                                             \
    474     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 5 ) )                         \
    475       return error;                                                         \
    476                                                                             \
    477     clazz[0].serv_id   = serv_id_1;                                         \
    478     clazz[0].serv_data = serv_data_1;                                       \
    479     clazz[1].serv_id   = serv_id_2;                                         \
    480     clazz[1].serv_data = serv_data_2;                                       \
    481     clazz[2].serv_id   = serv_id_3;                                         \
    482     clazz[2].serv_data = serv_data_3;                                       \
    483     clazz[3].serv_id   = serv_id_4;                                         \
    484     clazz[3].serv_data = serv_data_4;                                       \
    485     clazz[4].serv_id   = NULL;                                              \
    486     clazz[4].serv_data = NULL;                                              \
    487                                                                             \
    488     *output_class = clazz;                                                  \
    489                                                                             \
    490     return FT_Err_Ok;                                                       \
    491   }
    492 
    493 #define FT_DEFINE_SERVICEDESCREC5( class_,                                  \
    494                                    serv_id_1, serv_data_1,                  \
    495                                    serv_id_2, serv_data_2,                  \
    496                                    serv_id_3, serv_data_3,                  \
    497                                    serv_id_4, serv_data_4,                  \
    498                                    serv_id_5, serv_data_5 )                 \
    499   void                                                                      \
    500   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
    501                                FT_ServiceDescRec*  clazz )                  \
    502   {                                                                         \
    503     FT_Memory  memory = library->memory;                                    \
    504                                                                             \
    505                                                                             \
    506     if ( clazz )                                                            \
    507       FT_FREE( clazz );                                                     \
    508   }                                                                         \
    509                                                                             \
    510   FT_Error                                                                  \
    511   FT_Create_Class_ ## class_( FT_Library           library,                 \
    512                               FT_ServiceDescRec**  output_class )           \
    513   {                                                                         \
    514     FT_ServiceDescRec*  clazz  = NULL;                                      \
    515     FT_Error            error;                                              \
    516     FT_Memory           memory = library->memory;                           \
    517                                                                             \
    518                                                                             \
    519     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 6 ) )                         \
    520       return error;                                                         \
    521                                                                             \
    522     clazz[0].serv_id   = serv_id_1;                                         \
    523     clazz[0].serv_data = serv_data_1;                                       \
    524     clazz[1].serv_id   = serv_id_2;                                         \
    525     clazz[1].serv_data = serv_data_2;                                       \
    526     clazz[2].serv_id   = serv_id_3;                                         \
    527     clazz[2].serv_data = serv_data_3;                                       \
    528     clazz[3].serv_id   = serv_id_4;                                         \
    529     clazz[3].serv_data = serv_data_4;                                       \
    530     clazz[4].serv_id   = serv_id_5;                                         \
    531     clazz[4].serv_data = serv_data_5;                                       \
    532     clazz[5].serv_id   = NULL;                                              \
    533     clazz[5].serv_data = NULL;                                              \
    534                                                                             \
    535     *output_class = clazz;                                                  \
    536                                                                             \
    537     return FT_Err_Ok;                                                       \
    538   }
    539 
    540 #define FT_DEFINE_SERVICEDESCREC6( class_,                                  \
    541                                    serv_id_1, serv_data_1,                  \
    542                                    serv_id_2, serv_data_2,                  \
    543                                    serv_id_3, serv_data_3,                  \
    544                                    serv_id_4, serv_data_4,                  \
    545                                    serv_id_5, serv_data_5,                  \
    546                                    serv_id_6, serv_data_6 )                 \
    547   void                                                                      \
    548   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
    549                                FT_ServiceDescRec*  clazz )                  \
    550   {                                                                         \
    551     FT_Memory  memory = library->memory;                                    \
    552                                                                             \
    553                                                                             \
    554     if ( clazz )                                                            \
    555       FT_FREE( clazz );                                                     \
    556   }                                                                         \
    557                                                                             \
    558   FT_Error                                                                  \
    559   FT_Create_Class_ ## class_( FT_Library           library,                 \
    560                               FT_ServiceDescRec**  output_class)            \
    561   {                                                                         \
    562     FT_ServiceDescRec*  clazz  = NULL;                                      \
    563     FT_Error            error;                                              \
    564     FT_Memory           memory = library->memory;                           \
    565                                                                             \
    566                                                                             \
    567     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 7 ) )                         \
    568       return error;                                                         \
    569                                                                             \
    570     clazz[0].serv_id   = serv_id_1;                                         \
    571     clazz[0].serv_data = serv_data_1;                                       \
    572     clazz[1].serv_id   = serv_id_2;                                         \
    573     clazz[1].serv_data = serv_data_2;                                       \
    574     clazz[2].serv_id   = serv_id_3;                                         \
    575     clazz[2].serv_data = serv_data_3;                                       \
    576     clazz[3].serv_id   = serv_id_4;                                         \
    577     clazz[3].serv_data = serv_data_4;                                       \
    578     clazz[4].serv_id   = serv_id_5;                                         \
    579     clazz[4].serv_data = serv_data_5;                                       \
    580     clazz[5].serv_id   = serv_id_6;                                         \
    581     clazz[5].serv_data = serv_data_6;                                       \
    582     clazz[6].serv_id   = NULL;                                              \
    583     clazz[6].serv_data = NULL;                                              \
    584                                                                             \
    585     *output_class = clazz;                                                  \
    586                                                                             \
    587     return FT_Err_Ok;                                                       \
    588   }
    589 
    590 #define FT_DEFINE_SERVICEDESCREC7( class_,                                  \
    591                                    serv_id_1, serv_data_1,                  \
    592                                    serv_id_2, serv_data_2,                  \
    593                                    serv_id_3, serv_data_3,                  \
    594                                    serv_id_4, serv_data_4,                  \
    595                                    serv_id_5, serv_data_5,                  \
    596                                    serv_id_6, serv_data_6,                  \
    597                                    serv_id_7, serv_data_7 )                 \
    598   void                                                                      \
    599   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
    600                                FT_ServiceDescRec*  clazz )                  \
    601   {                                                                         \
    602     FT_Memory  memory = library->memory;                                    \
    603                                                                             \
    604                                                                             \
    605     if ( clazz )                                                            \
    606       FT_FREE( clazz );                                                     \
    607   }                                                                         \
    608                                                                             \
    609   FT_Error                                                                  \
    610   FT_Create_Class_ ## class_( FT_Library           library,                 \
    611                               FT_ServiceDescRec**  output_class)            \
    612   {                                                                         \
    613     FT_ServiceDescRec*  clazz  = NULL;                                      \
    614     FT_Error            error;                                              \
    615     FT_Memory           memory = library->memory;                           \
    616                                                                             \
    617                                                                             \
    618     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 8 ) )                         \
    619       return error;                                                         \
    620                                                                             \
    621     clazz[0].serv_id   = serv_id_1;                                         \
    622     clazz[0].serv_data = serv_data_1;                                       \
    623     clazz[1].serv_id   = serv_id_2;                                         \
    624     clazz[1].serv_data = serv_data_2;                                       \
    625     clazz[2].serv_id   = serv_id_3;                                         \
    626     clazz[2].serv_data = serv_data_3;                                       \
    627     clazz[3].serv_id   = serv_id_4;                                         \
    628     clazz[3].serv_data = serv_data_4;                                       \
    629     clazz[4].serv_id   = serv_id_5;                                         \
    630     clazz[4].serv_data = serv_data_5;                                       \
    631     clazz[5].serv_id   = serv_id_6;                                         \
    632     clazz[5].serv_data = serv_data_6;                                       \
    633     clazz[6].serv_id   = serv_id_7;                                         \
    634     clazz[6].serv_data = serv_data_7;                                       \
    635     clazz[7].serv_id   = NULL;                                              \
    636     clazz[7].serv_data = NULL;                                              \
    637                                                                             \
    638     *output_class = clazz;                                                  \
    639                                                                             \
    640     return FT_Err_Ok;                                                       \
    641   }
    642 
    643 #define FT_DEFINE_SERVICEDESCREC8( class_,                                  \
    644                                    serv_id_1, serv_data_1,                  \
    645                                    serv_id_2, serv_data_2,                  \
    646                                    serv_id_3, serv_data_3,                  \
    647                                    serv_id_4, serv_data_4,                  \
    648                                    serv_id_5, serv_data_5,                  \
    649                                    serv_id_6, serv_data_6,                  \
    650                                    serv_id_7, serv_data_7,                  \
    651                                    serv_id_8, serv_data_8 )                 \
    652   void                                                                      \
    653   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
    654                                FT_ServiceDescRec*  clazz )                  \
    655   {                                                                         \
    656     FT_Memory  memory = library->memory;                                    \
    657                                                                             \
    658                                                                             \
    659     if ( clazz )                                                            \
    660       FT_FREE( clazz );                                                     \
    661   }                                                                         \
    662                                                                             \
    663   FT_Error                                                                  \
    664   FT_Create_Class_ ## class_( FT_Library           library,                 \
    665                               FT_ServiceDescRec**  output_class)            \
    666   {                                                                         \
    667     FT_ServiceDescRec*  clazz  = NULL;                                      \
    668     FT_Error            error;                                              \
    669     FT_Memory           memory = library->memory;                           \
    670                                                                             \
    671                                                                             \
    672     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 9 ) )                         \
    673       return error;                                                         \
    674                                                                             \
    675     clazz[0].serv_id   = serv_id_1;                                         \
    676     clazz[0].serv_data = serv_data_1;                                       \
    677     clazz[1].serv_id   = serv_id_2;                                         \
    678     clazz[1].serv_data = serv_data_2;                                       \
    679     clazz[2].serv_id   = serv_id_3;                                         \
    680     clazz[2].serv_data = serv_data_3;                                       \
    681     clazz[3].serv_id   = serv_id_4;                                         \
    682     clazz[3].serv_data = serv_data_4;                                       \
    683     clazz[4].serv_id   = serv_id_5;                                         \
    684     clazz[4].serv_data = serv_data_5;                                       \
    685     clazz[5].serv_id   = serv_id_6;                                         \
    686     clazz[5].serv_data = serv_data_6;                                       \
    687     clazz[6].serv_id   = serv_id_7;                                         \
    688     clazz[6].serv_data = serv_data_7;                                       \
    689     clazz[7].serv_id   = serv_id_8;                                         \
    690     clazz[7].serv_data = serv_data_8;                                       \
    691     clazz[8].serv_id   = NULL;                                              \
    692     clazz[8].serv_data = NULL;                                              \
    693                                                                             \
    694     *output_class = clazz;                                                  \
    695                                                                             \
    696     return FT_Err_Ok;                                                       \
    697   }
    698 
    699 #define FT_DEFINE_SERVICEDESCREC9( class_,                                  \
    700                                    serv_id_1, serv_data_1,                  \
    701                                    serv_id_2, serv_data_2,                  \
    702                                    serv_id_3, serv_data_3,                  \
    703                                    serv_id_4, serv_data_4,                  \
    704                                    serv_id_5, serv_data_5,                  \
    705                                    serv_id_6, serv_data_6,                  \
    706                                    serv_id_7, serv_data_7,                  \
    707                                    serv_id_8, serv_data_8,                  \
    708                                    serv_id_9, serv_data_9 )                 \
    709   void                                                                      \
    710   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
    711                                FT_ServiceDescRec*  clazz )                  \
    712   {                                                                         \
    713     FT_Memory  memory = library->memory;                                    \
    714                                                                             \
    715                                                                             \
    716     if ( clazz )                                                            \
    717       FT_FREE( clazz );                                                     \
    718   }                                                                         \
    719                                                                             \
    720   FT_Error                                                                  \
    721   FT_Create_Class_ ## class_( FT_Library           library,                 \
    722                               FT_ServiceDescRec**  output_class)            \
    723   {                                                                         \
    724     FT_ServiceDescRec*  clazz  = NULL;                                      \
    725     FT_Error            error;                                              \
    726     FT_Memory           memory = library->memory;                           \
    727                                                                             \
    728                                                                             \
    729     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 10 ) )                        \
    730       return error;                                                         \
    731                                                                             \
    732     clazz[0].serv_id   = serv_id_1;                                         \
    733     clazz[0].serv_data = serv_data_1;                                       \
    734     clazz[1].serv_id   = serv_id_2;                                         \
    735     clazz[1].serv_data = serv_data_2;                                       \
    736     clazz[2].serv_id   = serv_id_3;                                         \
    737     clazz[2].serv_data = serv_data_3;                                       \
    738     clazz[3].serv_id   = serv_id_4;                                         \
    739     clazz[3].serv_data = serv_data_4;                                       \
    740     clazz[4].serv_id   = serv_id_5;                                         \
    741     clazz[4].serv_data = serv_data_5;                                       \
    742     clazz[5].serv_id   = serv_id_6;                                         \
    743     clazz[5].serv_data = serv_data_6;                                       \
    744     clazz[6].serv_id   = serv_id_7;                                         \
    745     clazz[6].serv_data = serv_data_7;                                       \
    746     clazz[7].serv_id   = serv_id_8;                                         \
    747     clazz[7].serv_data = serv_data_8;                                       \
    748     clazz[8].serv_id   = serv_id_9;                                         \
    749     clazz[8].serv_data = serv_data_9;                                       \
    750     clazz[9].serv_id   = NULL;                                              \
    751     clazz[9].serv_data = NULL;                                              \
    752                                                                             \
    753     *output_class = clazz;                                                  \
    754                                                                             \
    755     return FT_Err_Ok;                                                       \
    756   }
    757 
    758 #endif /* FT_CONFIG_OPTION_PIC */
    759 
    760 
    761   /*
    762    *  Parse a list of FT_ServiceDescRec descriptors and look for
    763    *  a specific service by ID.  Note that the last element in the
    764    *  array must be { NULL, NULL }, and that the function should
    765    *  return NULL if the service isn't available.
    766    *
    767    *  This function can be used by modules to implement their
    768    *  `get_service' method.
    769    */
    770   FT_BASE( FT_Pointer )
    771   ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
    772                           const char*     service_id );
    773 
    774 
    775   /*************************************************************************/
    776   /*************************************************************************/
    777   /*****                                                               *****/
    778   /*****             S E R V I C E S   C A C H E                       *****/
    779   /*****                                                               *****/
    780   /*************************************************************************/
    781   /*************************************************************************/
    782 
    783   /*
    784    *  This structure is used to store a cache for several frequently used
    785    *  services.  It is the type of `face->internal->services'.  You
    786    *  should only use FT_FACE_LOOKUP_SERVICE to access it.
    787    *
    788    *  All fields should have the type FT_Pointer to relax compilation
    789    *  dependencies.  We assume the developer isn't completely stupid.
    790    *
    791    *  Each field must be named `service_XXXX' where `XXX' corresponds to
    792    *  the correct FT_SERVICE_ID_XXXX macro.  See the definition of
    793    *  FT_FACE_LOOKUP_SERVICE below how this is implemented.
    794    *
    795    */
    796   typedef struct  FT_ServiceCacheRec_
    797   {
    798     FT_Pointer  service_POSTSCRIPT_FONT_NAME;
    799     FT_Pointer  service_MULTI_MASTERS;
    800     FT_Pointer  service_METRICS_VARIATIONS;
    801     FT_Pointer  service_GLYPH_DICT;
    802     FT_Pointer  service_PFR_METRICS;
    803     FT_Pointer  service_WINFNT;
    804 
    805   } FT_ServiceCacheRec, *FT_ServiceCache;
    806 
    807 
    808   /*
    809    *  A magic number used within the services cache.
    810    */
    811 
    812   /* ensure that value `1' has the same width as a pointer */
    813 #define FT_SERVICE_UNAVAILABLE  ((FT_Pointer)~(FT_PtrDist)1)
    814 
    815 
    816   /*
    817    * @macro:
    818    *   FT_FACE_LOOKUP_SERVICE
    819    *
    820    * @description:
    821    *   This macro is used to look up a service from a face's driver module
    822    *   using its cache.
    823    *
    824    * @input:
    825    *   face::
    826    *     The source face handle containing the cache.
    827    *
    828    *   field ::
    829    *     The field name in the cache.
    830    *
    831    *   id ::
    832    *     The service ID.
    833    *
    834    * @output:
    835    *   ptr ::
    836    *     A variable receiving the service data.  NULL if not available.
    837    */
    838 #ifdef __cplusplus
    839 
    840 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
    841   FT_BEGIN_STMNT                                               \
    842     FT_Pointer   svc;                                          \
    843     FT_Pointer*  Pptr = (FT_Pointer*)&(ptr);                   \
    844                                                                \
    845                                                                \
    846     svc = FT_FACE( face )->internal->services. service_ ## id; \
    847     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
    848       svc = NULL;                                              \
    849     else if ( svc == NULL )                                    \
    850     {                                                          \
    851       FT_FACE_FIND_SERVICE( face, svc, id );                   \
    852                                                                \
    853       FT_FACE( face )->internal->services. service_ ## id =    \
    854         (FT_Pointer)( svc != NULL ? svc                        \
    855                                   : FT_SERVICE_UNAVAILABLE );  \
    856     }                                                          \
    857     *Pptr = svc;                                               \
    858   FT_END_STMNT
    859 
    860 #else /* !C++ */
    861 
    862 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
    863   FT_BEGIN_STMNT                                               \
    864     FT_Pointer  svc;                                           \
    865                                                                \
    866                                                                \
    867     svc = FT_FACE( face )->internal->services. service_ ## id; \
    868     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
    869       svc = NULL;                                              \
    870     else if ( svc == NULL )                                    \
    871     {                                                          \
    872       FT_FACE_FIND_SERVICE( face, svc, id );                   \
    873                                                                \
    874       FT_FACE( face )->internal->services. service_ ## id =    \
    875         (FT_Pointer)( svc != NULL ? svc                        \
    876                                   : FT_SERVICE_UNAVAILABLE );  \
    877     }                                                          \
    878     ptr = svc;                                                 \
    879   FT_END_STMNT
    880 
    881 #endif /* !C++ */
    882 
    883   /*
    884    *  A macro used to define new service structure types.
    885    */
    886 
    887 #define FT_DEFINE_SERVICE( name )            \
    888   typedef struct FT_Service_ ## name ## Rec_ \
    889     FT_Service_ ## name ## Rec ;             \
    890   typedef struct FT_Service_ ## name ## Rec_ \
    891     const * FT_Service_ ## name ;            \
    892   struct FT_Service_ ## name ## Rec_
    893 
    894   /* */
    895 
    896   /*
    897    *  The header files containing the services.
    898    */
    899 
    900 #define FT_SERVICE_BDF_H                <freetype/internal/services/svbdf.h>
    901 #define FT_SERVICE_CID_H                <freetype/internal/services/svcid.h>
    902 #define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
    903 #define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
    904 #define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
    905 #define FT_SERVICE_METRICS_VARIATIONS_H <freetype/internal/services/svmetric.h>
    906 #define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
    907 #define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
    908 #define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
    909 #define FT_SERVICE_POSTSCRIPT_CMAPS_H   <freetype/internal/services/svpscmap.h>
    910 #define FT_SERVICE_POSTSCRIPT_INFO_H    <freetype/internal/services/svpsinfo.h>
    911 #define FT_SERVICE_POSTSCRIPT_NAME_H    <freetype/internal/services/svpostnm.h>
    912 #define FT_SERVICE_PROPERTIES_H         <freetype/internal/services/svprop.h>
    913 #define FT_SERVICE_SFNT_H               <freetype/internal/services/svsfnt.h>
    914 #define FT_SERVICE_TRUETYPE_ENGINE_H    <freetype/internal/services/svtteng.h>
    915 #define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>
    916 #define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>
    917 #define FT_SERVICE_FONT_FORMAT_H        <freetype/internal/services/svfntfmt.h>
    918 #define FT_SERVICE_TRUETYPE_GLYF_H      <freetype/internal/services/svttglyf.h>
    919 
    920  /* */
    921 
    922 FT_END_HEADER
    923 
    924 #endif /* FTSERV_H_ */
    925 
    926 
    927 /* END */
    928