Home | History | Annotate | Download | only in internal
      1 /****************************************************************************
      2  *
      3  * ftserv.h
      4  *
      5  *   The FreeType services (specification only).
      6  *
      7  * Copyright 2003-2018 by
      8  * David Turner, Robert Wilhelm, and Werner Lemberg.
      9  *
     10  * This file is part of the FreeType project, and may only be used,
     11  * modified, and distributed under the terms of the FreeType project
     12  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     13  * this file you indicate that you have read the license and
     14  * understand and accept it fully.
     15  *
     16  */
     17 
     18   /**************************************************************************
     19    *
     20    * 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    *
     39    * @macro:
     40    *   FT_FACE_FIND_SERVICE
     41    *
     42    * @description:
     43    *   This macro is used to look up a service from a face's driver module.
     44    *
     45    * @input:
     46    *   face ::
     47    *     The source face handle.
     48    *
     49    *   id ::
     50    *     A string describing the service as defined in the service's
     51    *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
     52    *     `multi-masters').  It is automatically prefixed with
     53    *     `FT_SERVICE_ID_'.
     54    *
     55    * @output:
     56    *   ptr ::
     57    *     A variable that receives the service pointer.  Will be NULL
     58    *     if not found.
     59    */
     60 #ifdef __cplusplus
     61 
     62 #define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
     63   FT_BEGIN_STMNT                                                            \
     64     FT_Module    module = FT_MODULE( FT_FACE( face )->driver );             \
     65     FT_Pointer   _tmp_  = NULL;                                             \
     66     FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                              \
     67                                                                             \
     68                                                                             \
     69     if ( module->clazz->get_interface )                                     \
     70       _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
     71     *_pptr_ = _tmp_;                                                        \
     72   FT_END_STMNT
     73 
     74 #else /* !C++ */
     75 
     76 #define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
     77   FT_BEGIN_STMNT                                                            \
     78     FT_Module   module = FT_MODULE( FT_FACE( face )->driver );              \
     79     FT_Pointer  _tmp_  = NULL;                                              \
     80                                                                             \
     81     if ( module->clazz->get_interface )                                     \
     82       _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
     83     ptr = _tmp_;                                                            \
     84   FT_END_STMNT
     85 
     86 #endif /* !C++ */
     87 
     88 
     89   /**************************************************************************
     90    *
     91    * @macro:
     92    *   FT_FACE_FIND_GLOBAL_SERVICE
     93    *
     94    * @description:
     95    *   This macro is used to look up a service from all modules.
     96    *
     97    * @input:
     98    *   face ::
     99    *     The source face handle.
    100    *
    101    *   id ::
    102    *     A string describing the service as defined in the service's
    103    *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
    104    *     `multi-masters').  It is automatically prefixed with
    105    *     `FT_SERVICE_ID_'.
    106    *
    107    * @output:
    108    *   ptr ::
    109    *     A variable that receives the service pointer.  Will be NULL
    110    *     if not found.
    111    */
    112 #ifdef __cplusplus
    113 
    114 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )                  \
    115   FT_BEGIN_STMNT                                                      \
    116     FT_Module    module = FT_MODULE( FT_FACE( face )->driver );       \
    117     FT_Pointer   _tmp_;                                               \
    118     FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                        \
    119                                                                       \
    120                                                                       \
    121     _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
    122     *_pptr_ = _tmp_;                                                  \
    123   FT_END_STMNT
    124 
    125 #else /* !C++ */
    126 
    127 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )                  \
    128   FT_BEGIN_STMNT                                                      \
    129     FT_Module   module = FT_MODULE( FT_FACE( face )->driver );        \
    130     FT_Pointer  _tmp_;                                                \
    131                                                                       \
    132                                                                       \
    133     _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
    134     ptr   = _tmp_;                                                    \
    135   FT_END_STMNT
    136 
    137 #endif /* !C++ */
    138 
    139 
    140   /*************************************************************************/
    141   /*************************************************************************/
    142   /*****                                                               *****/
    143   /*****         S E R V I C E   D E S C R I P T O R S                 *****/
    144   /*****                                                               *****/
    145   /*************************************************************************/
    146   /*************************************************************************/
    147 
    148   /*
    149    * The following structure is used to _describe_ a given service
    150    * to the library.  This is useful to build simple static service lists.
    151    */
    152   typedef struct  FT_ServiceDescRec_
    153   {
    154     const char*  serv_id;     /* service name         */
    155     const void*  serv_data;   /* service pointer/data */
    156 
    157   } FT_ServiceDescRec;
    158 
    159   typedef const FT_ServiceDescRec*  FT_ServiceDesc;
    160 
    161 
    162   /**************************************************************************
    163    *
    164    * @macro:
    165    *   FT_DEFINE_SERVICEDESCREC1
    166    *   FT_DEFINE_SERVICEDESCREC2
    167    *   FT_DEFINE_SERVICEDESCREC3
    168    *   FT_DEFINE_SERVICEDESCREC4
    169    *   FT_DEFINE_SERVICEDESCREC5
    170    *   FT_DEFINE_SERVICEDESCREC6
    171    *   FT_DEFINE_SERVICEDESCREC7
    172    *   FT_DEFINE_SERVICEDESCREC8
    173    *   FT_DEFINE_SERVICEDESCREC9
    174    *   FT_DEFINE_SERVICEDESCREC10
    175    *
    176    * @description:
    177    *   Used to initialize an array of FT_ServiceDescRec structures.
    178    *
    179    *   The array will be allocated in the global scope (or the scope
    180    *   where the macro is used).
    181    */
    182 #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
    183                                    serv_id_1, serv_data_1 )                 \
    184   static const FT_ServiceDescRec  class_[] =                                \
    185   {                                                                         \
    186     { serv_id_1, serv_data_1 },                                             \
    187     { NULL, NULL }                                                          \
    188   };
    189 
    190 #define FT_DEFINE_SERVICEDESCREC2( class_,                                  \
    191                                    serv_id_1, serv_data_1,                  \
    192                                    serv_id_2, serv_data_2 )                 \
    193   static const FT_ServiceDescRec  class_[] =                                \
    194   {                                                                         \
    195     { serv_id_1, serv_data_1 },                                             \
    196     { serv_id_2, serv_data_2 },                                             \
    197     { NULL, NULL }                                                          \
    198   };
    199 
    200 #define FT_DEFINE_SERVICEDESCREC3( class_,                                  \
    201                                    serv_id_1, serv_data_1,                  \
    202                                    serv_id_2, serv_data_2,                  \
    203                                    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 
    212 #define FT_DEFINE_SERVICEDESCREC4( class_,                                  \
    213                                    serv_id_1, serv_data_1,                  \
    214                                    serv_id_2, serv_data_2,                  \
    215                                    serv_id_3, serv_data_3,                  \
    216                                    serv_id_4, serv_data_4 )                 \
    217   static const FT_ServiceDescRec  class_[] =                                \
    218   {                                                                         \
    219     { serv_id_1, serv_data_1 },                                             \
    220     { serv_id_2, serv_data_2 },                                             \
    221     { serv_id_3, serv_data_3 },                                             \
    222     { serv_id_4, serv_data_4 },                                             \
    223     { NULL, NULL }                                                          \
    224   };
    225 
    226 #define FT_DEFINE_SERVICEDESCREC5( class_,                                  \
    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   static const FT_ServiceDescRec  class_[] =                                \
    233   {                                                                         \
    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     { NULL, NULL }                                                          \
    240   };
    241 
    242 #define FT_DEFINE_SERVICEDESCREC6( class_,                                  \
    243                                    serv_id_1, serv_data_1,                  \
    244                                    serv_id_2, serv_data_2,                  \
    245                                    serv_id_3, serv_data_3,                  \
    246                                    serv_id_4, serv_data_4,                  \
    247                                    serv_id_5, serv_data_5,                  \
    248                                    serv_id_6, serv_data_6 )                 \
    249   static const FT_ServiceDescRec  class_[] =                                \
    250   {                                                                         \
    251     { serv_id_1, serv_data_1 },                                             \
    252     { serv_id_2, serv_data_2 },                                             \
    253     { serv_id_3, serv_data_3 },                                             \
    254     { serv_id_4, serv_data_4 },                                             \
    255     { serv_id_5, serv_data_5 },                                             \
    256     { serv_id_6, serv_data_6 },                                             \
    257     { NULL, NULL }                                                          \
    258   };
    259 
    260 #define FT_DEFINE_SERVICEDESCREC7( class_,                                  \
    261                                    serv_id_1, serv_data_1,                  \
    262                                    serv_id_2, serv_data_2,                  \
    263                                    serv_id_3, serv_data_3,                  \
    264                                    serv_id_4, serv_data_4,                  \
    265                                    serv_id_5, serv_data_5,                  \
    266                                    serv_id_6, serv_data_6,                  \
    267                                    serv_id_7, serv_data_7 )                 \
    268   static const FT_ServiceDescRec  class_[] =                                \
    269   {                                                                         \
    270     { serv_id_1, serv_data_1 },                                             \
    271     { serv_id_2, serv_data_2 },                                             \
    272     { serv_id_3, serv_data_3 },                                             \
    273     { serv_id_4, serv_data_4 },                                             \
    274     { serv_id_5, serv_data_5 },                                             \
    275     { serv_id_6, serv_data_6 },                                             \
    276     { serv_id_7, serv_data_7 },                                             \
    277     { NULL, NULL }                                                          \
    278   };
    279 
    280 #define FT_DEFINE_SERVICEDESCREC8( class_,                                  \
    281                                    serv_id_1, serv_data_1,                  \
    282                                    serv_id_2, serv_data_2,                  \
    283                                    serv_id_3, serv_data_3,                  \
    284                                    serv_id_4, serv_data_4,                  \
    285                                    serv_id_5, serv_data_5,                  \
    286                                    serv_id_6, serv_data_6,                  \
    287                                    serv_id_7, serv_data_7,                  \
    288                                    serv_id_8, serv_data_8 )                 \
    289   static const FT_ServiceDescRec  class_[] =                                \
    290   {                                                                         \
    291     { serv_id_1, serv_data_1 },                                             \
    292     { serv_id_2, serv_data_2 },                                             \
    293     { serv_id_3, serv_data_3 },                                             \
    294     { serv_id_4, serv_data_4 },                                             \
    295     { serv_id_5, serv_data_5 },                                             \
    296     { serv_id_6, serv_data_6 },                                             \
    297     { serv_id_7, serv_data_7 },                                             \
    298     { serv_id_8, serv_data_8 },                                             \
    299     { NULL, NULL }                                                          \
    300   };
    301 
    302 #define FT_DEFINE_SERVICEDESCREC9( class_,                                  \
    303                                    serv_id_1, serv_data_1,                  \
    304                                    serv_id_2, serv_data_2,                  \
    305                                    serv_id_3, serv_data_3,                  \
    306                                    serv_id_4, serv_data_4,                  \
    307                                    serv_id_5, serv_data_5,                  \
    308                                    serv_id_6, serv_data_6,                  \
    309                                    serv_id_7, serv_data_7,                  \
    310                                    serv_id_8, serv_data_8,                  \
    311                                    serv_id_9, serv_data_9 )                 \
    312   static const FT_ServiceDescRec  class_[] =                                \
    313   {                                                                         \
    314     { serv_id_1, serv_data_1 },                                             \
    315     { serv_id_2, serv_data_2 },                                             \
    316     { serv_id_3, serv_data_3 },                                             \
    317     { serv_id_4, serv_data_4 },                                             \
    318     { serv_id_5, serv_data_5 },                                             \
    319     { serv_id_6, serv_data_6 },                                             \
    320     { serv_id_7, serv_data_7 },                                             \
    321     { serv_id_8, serv_data_8 },                                             \
    322     { serv_id_9, serv_data_9 },                                             \
    323     { NULL, NULL }                                                          \
    324   };
    325 
    326 #define FT_DEFINE_SERVICEDESCREC10( class_,                                 \
    327                                     serv_id_1, serv_data_1,                 \
    328                                     serv_id_2, serv_data_2,                 \
    329                                     serv_id_3, serv_data_3,                 \
    330                                     serv_id_4, serv_data_4,                 \
    331                                     serv_id_5, serv_data_5,                 \
    332                                     serv_id_6, serv_data_6,                 \
    333                                     serv_id_7, serv_data_7,                 \
    334                                     serv_id_8, serv_data_8,                 \
    335                                     serv_id_9, serv_data_9,                 \
    336                                     serv_id_10, serv_data_10 )              \
    337   static const FT_ServiceDescRec  class_[] =                                \
    338   {                                                                         \
    339     { serv_id_1, serv_data_1 },                                             \
    340     { serv_id_2, serv_data_2 },                                             \
    341     { serv_id_3, serv_data_3 },                                             \
    342     { serv_id_4, serv_data_4 },                                             \
    343     { serv_id_5, serv_data_5 },                                             \
    344     { serv_id_6, serv_data_6 },                                             \
    345     { serv_id_7, serv_data_7 },                                             \
    346     { serv_id_8, serv_data_8 },                                             \
    347     { serv_id_9, serv_data_9 },                                             \
    348     { serv_id_10, serv_data_10 },                                           \
    349     { NULL, NULL }                                                          \
    350   };
    351 
    352 
    353   /*
    354    * Parse a list of FT_ServiceDescRec descriptors and look for
    355    * a specific service by ID.  Note that the last element in the
    356    * array must be { NULL, NULL }, and that the function should
    357    * return NULL if the service isn't available.
    358    *
    359    * This function can be used by modules to implement their
    360    * `get_service' method.
    361    */
    362   FT_BASE( FT_Pointer )
    363   ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
    364                           const char*     service_id );
    365 
    366 
    367   /*************************************************************************/
    368   /*************************************************************************/
    369   /*****                                                               *****/
    370   /*****             S E R V I C E S   C A C H E                       *****/
    371   /*****                                                               *****/
    372   /*************************************************************************/
    373   /*************************************************************************/
    374 
    375   /*
    376    * This structure is used to store a cache for several frequently used
    377    * services.  It is the type of `face->internal->services'.  You
    378    * should only use FT_FACE_LOOKUP_SERVICE to access it.
    379    *
    380    * All fields should have the type FT_Pointer to relax compilation
    381    * dependencies.  We assume the developer isn't completely stupid.
    382    *
    383    * Each field must be named `service_XXXX' where `XXX' corresponds to
    384    * the correct FT_SERVICE_ID_XXXX macro.  See the definition of
    385    * FT_FACE_LOOKUP_SERVICE below how this is implemented.
    386    *
    387    */
    388   typedef struct  FT_ServiceCacheRec_
    389   {
    390     FT_Pointer  service_POSTSCRIPT_FONT_NAME;
    391     FT_Pointer  service_MULTI_MASTERS;
    392     FT_Pointer  service_METRICS_VARIATIONS;
    393     FT_Pointer  service_GLYPH_DICT;
    394     FT_Pointer  service_PFR_METRICS;
    395     FT_Pointer  service_WINFNT;
    396 
    397   } FT_ServiceCacheRec, *FT_ServiceCache;
    398 
    399 
    400   /*
    401    * A magic number used within the services cache.
    402    */
    403 
    404   /* ensure that value `1' has the same width as a pointer */
    405 #define FT_SERVICE_UNAVAILABLE  ((FT_Pointer)~(FT_PtrDist)1)
    406 
    407 
    408   /**************************************************************************
    409    *
    410    * @macro:
    411    *   FT_FACE_LOOKUP_SERVICE
    412    *
    413    * @description:
    414    *   This macro is used to look up a service from a face's driver module
    415    *   using its cache.
    416    *
    417    * @input:
    418    *   face ::
    419    *     The source face handle containing the cache.
    420    *
    421    *   field ::
    422    *     The field name in the cache.
    423    *
    424    *   id ::
    425    *     The service ID.
    426    *
    427    * @output:
    428    *   ptr ::
    429    *     A variable receiving the service data.  NULL if not available.
    430    */
    431 #ifdef __cplusplus
    432 
    433 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
    434   FT_BEGIN_STMNT                                               \
    435     FT_Pointer   svc;                                          \
    436     FT_Pointer*  Pptr = (FT_Pointer*)&(ptr);                   \
    437                                                                \
    438                                                                \
    439     svc = FT_FACE( face )->internal->services. service_ ## id; \
    440     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
    441       svc = NULL;                                              \
    442     else if ( svc == NULL )                                    \
    443     {                                                          \
    444       FT_FACE_FIND_SERVICE( face, svc, id );                   \
    445                                                                \
    446       FT_FACE( face )->internal->services. service_ ## id =    \
    447         (FT_Pointer)( svc != NULL ? svc                        \
    448                                   : FT_SERVICE_UNAVAILABLE );  \
    449     }                                                          \
    450     *Pptr = svc;                                               \
    451   FT_END_STMNT
    452 
    453 #else /* !C++ */
    454 
    455 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
    456   FT_BEGIN_STMNT                                               \
    457     FT_Pointer  svc;                                           \
    458                                                                \
    459                                                                \
    460     svc = FT_FACE( face )->internal->services. service_ ## id; \
    461     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
    462       svc = NULL;                                              \
    463     else if ( svc == NULL )                                    \
    464     {                                                          \
    465       FT_FACE_FIND_SERVICE( face, svc, id );                   \
    466                                                                \
    467       FT_FACE( face )->internal->services. service_ ## id =    \
    468         (FT_Pointer)( svc != NULL ? svc                        \
    469                                   : FT_SERVICE_UNAVAILABLE );  \
    470     }                                                          \
    471     ptr = svc;                                                 \
    472   FT_END_STMNT
    473 
    474 #endif /* !C++ */
    475 
    476   /*
    477    * A macro used to define new service structure types.
    478    */
    479 
    480 #define FT_DEFINE_SERVICE( name )            \
    481   typedef struct FT_Service_ ## name ## Rec_ \
    482     FT_Service_ ## name ## Rec ;             \
    483   typedef struct FT_Service_ ## name ## Rec_ \
    484     const * FT_Service_ ## name ;            \
    485   struct FT_Service_ ## name ## Rec_
    486 
    487   /* */
    488 
    489   /*
    490    * The header files containing the services.
    491    */
    492 
    493 #define FT_SERVICE_BDF_H                <freetype/internal/services/svbdf.h>
    494 #define FT_SERVICE_CFF_TABLE_LOAD_H     <freetype/internal/services/svcfftl.h>
    495 #define FT_SERVICE_CID_H                <freetype/internal/services/svcid.h>
    496 #define FT_SERVICE_FONT_FORMAT_H        <freetype/internal/services/svfntfmt.h>
    497 #define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
    498 #define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
    499 #define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
    500 #define FT_SERVICE_METRICS_VARIATIONS_H <freetype/internal/services/svmetric.h>
    501 #define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
    502 #define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
    503 #define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
    504 #define FT_SERVICE_POSTSCRIPT_CMAPS_H   <freetype/internal/services/svpscmap.h>
    505 #define FT_SERVICE_POSTSCRIPT_INFO_H    <freetype/internal/services/svpsinfo.h>
    506 #define FT_SERVICE_POSTSCRIPT_NAME_H    <freetype/internal/services/svpostnm.h>
    507 #define FT_SERVICE_PROPERTIES_H         <freetype/internal/services/svprop.h>
    508 #define FT_SERVICE_SFNT_H               <freetype/internal/services/svsfnt.h>
    509 #define FT_SERVICE_TRUETYPE_ENGINE_H    <freetype/internal/services/svtteng.h>
    510 #define FT_SERVICE_TRUETYPE_GLYF_H      <freetype/internal/services/svttglyf.h>
    511 #define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>
    512 #define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>
    513 
    514  /* */
    515 
    516 FT_END_HEADER
    517 
    518 #endif /* FTSERV_H_ */
    519 
    520 
    521 /* END */
    522