Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ftserv.h                                                               */
  4. /*                                                                         */
  5. /*    The FreeType services (specification only).                          */
  6. /*                                                                         */
  7. /*  Copyright 2003-2007, 2009, 2012, 2013 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 ); \
  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 ); \
  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.   /*                                                                       */
  171.   /* <Description>                                                         */
  172.   /*    Used to initialize an array of FT_ServiceDescRec structures.       */
  173.   /*                                                                       */
  174.   /*    When FT_CONFIG_OPTION_PIC is defined a `create' function needs to  */
  175.   /*    be called with a pointer to return an allocated array.  As soon as */
  176.   /*    it is no longer needed, a `destroy' function needs to be called to */
  177.   /*    release that allocation.                                           */
  178.   /*                                                                       */
  179.   /*    These functions should be manually called from the `pic_init' and  */
  180.   /*    `pic_free' functions of your module (see FT_DEFINE_MODULE).        */
  181.   /*                                                                       */
  182.   /*    When FT_CONFIG_OPTION_PIC is not defined the array will be         */
  183.   /*    allocated in the global scope (or the scope where the macro is     */
  184.   /*    used).                                                             */
  185.   /*                                                                       */
  186. #ifndef FT_CONFIG_OPTION_PIC
  187.  
  188. #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
  189.                                    serv_id_1, serv_data_1 )                 \
  190.   static const FT_ServiceDescRec  class_[] =                                \
  191.   {                                                                         \
  192.     { serv_id_1, serv_data_1 },                                             \
  193.     { NULL, NULL }                                                          \
  194.   };
  195.  
  196. #define FT_DEFINE_SERVICEDESCREC2( class_,                                  \
  197.                                    serv_id_1, serv_data_1,                  \
  198.                                    serv_id_2, serv_data_2 )                 \
  199.   static const FT_ServiceDescRec  class_[] =                                \
  200.   {                                                                         \
  201.     { serv_id_1, serv_data_1 },                                             \
  202.     { serv_id_2, serv_data_2 },                                             \
  203.     { NULL, NULL }                                                          \
  204.   };
  205.  
  206. #define FT_DEFINE_SERVICEDESCREC3( class_,                                  \
  207.                                    serv_id_1, serv_data_1,                  \
  208.                                    serv_id_2, serv_data_2,                  \
  209.                                    serv_id_3, serv_data_3 )                 \
  210.   static const FT_ServiceDescRec  class_[] =                                \
  211.   {                                                                         \
  212.     { serv_id_1, serv_data_1 },                                             \
  213.     { serv_id_2, serv_data_2 },                                             \
  214.     { serv_id_3, serv_data_3 },                                             \
  215.     { NULL, NULL }                                                          \
  216.   };
  217.  
  218. #define FT_DEFINE_SERVICEDESCREC4( class_,                                  \
  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.   static const FT_ServiceDescRec  class_[] =                                \
  224.   {                                                                         \
  225.     { serv_id_1, serv_data_1 },                                             \
  226.     { serv_id_2, serv_data_2 },                                             \
  227.     { serv_id_3, serv_data_3 },                                             \
  228.     { serv_id_4, serv_data_4 },                                             \
  229.     { NULL, NULL }                                                          \
  230.   };
  231.  
  232. #define FT_DEFINE_SERVICEDESCREC5( class_,                                  \
  233.                                    serv_id_1, serv_data_1,                  \
  234.                                    serv_id_2, serv_data_2,                  \
  235.                                    serv_id_3, serv_data_3,                  \
  236.                                    serv_id_4, serv_data_4,                  \
  237.                                    serv_id_5, serv_data_5 )                 \
  238.   static const FT_ServiceDescRec  class_[] =                                \
  239.   {                                                                         \
  240.     { serv_id_1, serv_data_1 },                                             \
  241.     { serv_id_2, serv_data_2 },                                             \
  242.     { serv_id_3, serv_data_3 },                                             \
  243.     { serv_id_4, serv_data_4 },                                             \
  244.     { serv_id_5, serv_data_5 },                                             \
  245.     { NULL, NULL }                                                          \
  246.   };
  247.  
  248. #define FT_DEFINE_SERVICEDESCREC6( class_,                                  \
  249.                                    serv_id_1, serv_data_1,                  \
  250.                                    serv_id_2, serv_data_2,                  \
  251.                                    serv_id_3, serv_data_3,                  \
  252.                                    serv_id_4, serv_data_4,                  \
  253.                                    serv_id_5, serv_data_5,                  \
  254.                                    serv_id_6, serv_data_6 )                 \
  255.   static const FT_ServiceDescRec  class_[] =                                \
  256.   {                                                                         \
  257.     { serv_id_1, serv_data_1 },                                             \
  258.     { serv_id_2, serv_data_2 },                                             \
  259.     { serv_id_3, serv_data_3 },                                             \
  260.     { serv_id_4, serv_data_4 },                                             \
  261.     { serv_id_5, serv_data_5 },                                             \
  262.     { serv_id_6, serv_data_6 },                                             \
  263.     { NULL, NULL }                                                          \
  264.   };
  265.  
  266. #define FT_DEFINE_SERVICEDESCREC7( class_,                                  \
  267.                                    serv_id_1, serv_data_1,                  \
  268.                                    serv_id_2, serv_data_2,                  \
  269.                                    serv_id_3, serv_data_3,                  \
  270.                                    serv_id_4, serv_data_4,                  \
  271.                                    serv_id_5, serv_data_5,                  \
  272.                                    serv_id_6, serv_data_6,                  \
  273.                                    serv_id_7, serv_data_7 )                 \
  274.   static const FT_ServiceDescRec  class_[] =                                \
  275.   {                                                                         \
  276.     { serv_id_1, serv_data_1 },                                             \
  277.     { serv_id_2, serv_data_2 },                                             \
  278.     { serv_id_3, serv_data_3 },                                             \
  279.     { serv_id_4, serv_data_4 },                                             \
  280.     { serv_id_5, serv_data_5 },                                             \
  281.     { serv_id_6, serv_data_6 },                                             \
  282.     { serv_id_7, serv_data_7 },                                             \
  283.     { NULL, NULL }                                                          \
  284.   };
  285.  
  286. #else /* FT_CONFIG_OPTION_PIC */
  287.  
  288. #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
  289.                                    serv_id_1, serv_data_1 )                 \
  290.   void                                                                      \
  291.   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
  292.                                FT_ServiceDescRec*  clazz )                  \
  293.   {                                                                         \
  294.     FT_Memory  memory = library->memory;                                    \
  295.                                                                             \
  296.                                                                             \
  297.     if ( clazz )                                                            \
  298.       FT_FREE( clazz );                                                     \
  299.   }                                                                         \
  300.                                                                             \
  301.   FT_Error                                                                  \
  302.   FT_Create_Class_ ## class_( FT_Library           library,                 \
  303.                               FT_ServiceDescRec**  output_class )           \
  304.   {                                                                         \
  305.     FT_ServiceDescRec*  clazz  = NULL;                                      \
  306.     FT_Error            error;                                              \
  307.     FT_Memory           memory = library->memory;                           \
  308.                                                                             \
  309.                                                                             \
  310.     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 2 ) )                         \
  311.       return error;                                                         \
  312.                                                                             \
  313.     clazz[0].serv_id   = serv_id_1;                                         \
  314.     clazz[0].serv_data = serv_data_1;                                       \
  315.     clazz[1].serv_id   = NULL;                                              \
  316.     clazz[1].serv_data = NULL;                                              \
  317.                                                                             \
  318.     *output_class = clazz;                                                  \
  319.                                                                             \
  320.     return FT_Err_Ok;                                                       \
  321.   }
  322.  
  323. #define FT_DEFINE_SERVICEDESCREC2( class_,                                  \
  324.                                    serv_id_1, serv_data_1,                  \
  325.                                    serv_id_2, serv_data_2 )                 \
  326.   void                                                                      \
  327.   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
  328.                                FT_ServiceDescRec*  clazz )                  \
  329.   {                                                                         \
  330.     FT_Memory  memory = library->memory;                                    \
  331.                                                                             \
  332.                                                                             \
  333.     if ( clazz )                                                            \
  334.       FT_FREE( clazz );                                                     \
  335.   }                                                                         \
  336.                                                                             \
  337.   FT_Error                                                                  \
  338.   FT_Create_Class_ ## class_( FT_Library           library,                 \
  339.                               FT_ServiceDescRec**  output_class )           \
  340.   {                                                                         \
  341.     FT_ServiceDescRec*  clazz  = NULL;                                      \
  342.     FT_Error            error;                                              \
  343.     FT_Memory           memory = library->memory;                           \
  344.                                                                             \
  345.                                                                             \
  346.     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 3 ) )                         \
  347.       return error;                                                         \
  348.                                                                             \
  349.     clazz[0].serv_id   = serv_id_1;                                         \
  350.     clazz[0].serv_data = serv_data_1;                                       \
  351.     clazz[1].serv_id   = serv_id_2;                                         \
  352.     clazz[1].serv_data = serv_data_2;                                       \
  353.     clazz[2].serv_id   = NULL;                                              \
  354.     clazz[2].serv_data = NULL;                                              \
  355.                                                                             \
  356.     *output_class = clazz;                                                  \
  357.                                                                             \
  358.     return FT_Err_Ok;                                                       \
  359.   }
  360.  
  361. #define FT_DEFINE_SERVICEDESCREC3( class_,                                  \
  362.                                    serv_id_1, serv_data_1,                  \
  363.                                    serv_id_2, serv_data_2,                  \
  364.                                    serv_id_3, serv_data_3 )                 \
  365.   void                                                                      \
  366.   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
  367.                                FT_ServiceDescRec*  clazz )                  \
  368.   {                                                                         \
  369.     FT_Memory  memory = library->memory;                                    \
  370.                                                                             \
  371.                                                                             \
  372.     if ( clazz )                                                            \
  373.       FT_FREE( clazz );                                                     \
  374.   }                                                                         \
  375.                                                                             \
  376.   FT_Error                                                                  \
  377.   FT_Create_Class_ ## class_( FT_Library           library,                 \
  378.                               FT_ServiceDescRec**  output_class )           \
  379.   {                                                                         \
  380.     FT_ServiceDescRec*  clazz  = NULL;                                      \
  381.     FT_Error            error;                                              \
  382.     FT_Memory           memory = library->memory;                           \
  383.                                                                             \
  384.                                                                             \
  385.     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 4 ) )                         \
  386.       return error;                                                         \
  387.                                                                             \
  388.     clazz[0].serv_id   = serv_id_1;                                         \
  389.     clazz[0].serv_data = serv_data_1;                                       \
  390.     clazz[1].serv_id   = serv_id_2;                                         \
  391.     clazz[1].serv_data = serv_data_2;                                       \
  392.     clazz[2].serv_id   = serv_id_3;                                         \
  393.     clazz[2].serv_data = serv_data_3;                                       \
  394.     clazz[3].serv_id   = NULL;                                              \
  395.     clazz[3].serv_data = NULL;                                              \
  396.                                                                             \
  397.     *output_class = clazz;                                                  \
  398.                                                                             \
  399.     return FT_Err_Ok;                                                       \
  400.   }
  401.  
  402. #define FT_DEFINE_SERVICEDESCREC4( class_,                                  \
  403.                                    serv_id_1, serv_data_1,                  \
  404.                                    serv_id_2, serv_data_2,                  \
  405.                                    serv_id_3, serv_data_3,                  \
  406.                                    serv_id_4, serv_data_4 )                 \
  407.   void                                                                      \
  408.   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
  409.                                FT_ServiceDescRec*  clazz )                  \
  410.   {                                                                         \
  411.     FT_Memory  memory = library->memory;                                    \
  412.                                                                             \
  413.                                                                             \
  414.     if ( clazz )                                                            \
  415.       FT_FREE( clazz );                                                     \
  416.   }                                                                         \
  417.                                                                             \
  418.   FT_Error                                                                  \
  419.   FT_Create_Class_ ## class_( FT_Library           library,                 \
  420.                               FT_ServiceDescRec**  output_class )           \
  421.   {                                                                         \
  422.     FT_ServiceDescRec*  clazz  = NULL;                                      \
  423.     FT_Error            error;                                              \
  424.     FT_Memory           memory = library->memory;                           \
  425.                                                                             \
  426.                                                                             \
  427.     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 5 ) )                         \
  428.       return error;                                                         \
  429.                                                                             \
  430.     clazz[0].serv_id   = serv_id_1;                                         \
  431.     clazz[0].serv_data = serv_data_1;                                       \
  432.     clazz[1].serv_id   = serv_id_2;                                         \
  433.     clazz[1].serv_data = serv_data_2;                                       \
  434.     clazz[2].serv_id   = serv_id_3;                                         \
  435.     clazz[2].serv_data = serv_data_3;                                       \
  436.     clazz[3].serv_id   = serv_id_4;                                         \
  437.     clazz[3].serv_data = serv_data_4;                                       \
  438.     clazz[4].serv_id   = NULL;                                              \
  439.     clazz[4].serv_data = NULL;                                              \
  440.                                                                             \
  441.     *output_class = clazz;                                                  \
  442.                                                                             \
  443.     return FT_Err_Ok;                                                       \
  444.   }
  445.  
  446. #define FT_DEFINE_SERVICEDESCREC5( class_,                                  \
  447.                                    serv_id_1, serv_data_1,                  \
  448.                                    serv_id_2, serv_data_2,                  \
  449.                                    serv_id_3, serv_data_3,                  \
  450.                                    serv_id_4, serv_data_4,                  \
  451.                                    serv_id_5, serv_data_5 )                 \
  452.   void                                                                      \
  453.   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
  454.                                FT_ServiceDescRec*  clazz )                  \
  455.   {                                                                         \
  456.     FT_Memory  memory = library->memory;                                    \
  457.                                                                             \
  458.                                                                             \
  459.     if ( clazz )                                                            \
  460.       FT_FREE( clazz );                                                     \
  461.   }                                                                         \
  462.                                                                             \
  463.   FT_Error                                                                  \
  464.   FT_Create_Class_ ## class_( FT_Library           library,                 \
  465.                               FT_ServiceDescRec**  output_class )           \
  466.   {                                                                         \
  467.     FT_ServiceDescRec*  clazz  = NULL;                                      \
  468.     FT_Error            error;                                              \
  469.     FT_Memory           memory = library->memory;                           \
  470.                                                                             \
  471.                                                                             \
  472.     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 6 ) )                         \
  473.       return error;                                                         \
  474.                                                                             \
  475.     clazz[0].serv_id   = serv_id_1;                                         \
  476.     clazz[0].serv_data = serv_data_1;                                       \
  477.     clazz[1].serv_id   = serv_id_2;                                         \
  478.     clazz[1].serv_data = serv_data_2;                                       \
  479.     clazz[2].serv_id   = serv_id_3;                                         \
  480.     clazz[2].serv_data = serv_data_3;                                       \
  481.     clazz[3].serv_id   = serv_id_4;                                         \
  482.     clazz[3].serv_data = serv_data_4;                                       \
  483.     clazz[4].serv_id   = serv_id_5;                                         \
  484.     clazz[4].serv_data = serv_data_5;                                       \
  485.     clazz[5].serv_id   = NULL;                                              \
  486.     clazz[5].serv_data = NULL;                                              \
  487.                                                                             \
  488.     *output_class = clazz;                                                  \
  489.                                                                             \
  490.     return FT_Err_Ok;                                                       \
  491.   }
  492.  
  493. #define FT_DEFINE_SERVICEDESCREC6( 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.                                    serv_id_6, serv_data_6 )                 \
  500.   void                                                                      \
  501.   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
  502.                                FT_ServiceDescRec*  clazz )                  \
  503.   {                                                                         \
  504.     FT_Memory  memory = library->memory;                                    \
  505.                                                                             \
  506.                                                                             \
  507.     if ( clazz )                                                            \
  508.       FT_FREE( clazz );                                                     \
  509.   }                                                                         \
  510.                                                                             \
  511.   FT_Error                                                                  \
  512.   FT_Create_Class_ ## class_( FT_Library           library,                 \
  513.                               FT_ServiceDescRec**  output_class)            \
  514.   {                                                                         \
  515.     FT_ServiceDescRec*  clazz  = NULL;                                      \
  516.     FT_Error            error;                                              \
  517.     FT_Memory           memory = library->memory;                           \
  518.                                                                             \
  519.                                                                             \
  520.     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 7 ) )                         \
  521.       return error;                                                         \
  522.                                                                             \
  523.     clazz[0].serv_id   = serv_id_1;                                         \
  524.     clazz[0].serv_data = serv_data_1;                                       \
  525.     clazz[1].serv_id   = serv_id_2;                                         \
  526.     clazz[1].serv_data = serv_data_2;                                       \
  527.     clazz[2].serv_id   = serv_id_3;                                         \
  528.     clazz[2].serv_data = serv_data_3;                                       \
  529.     clazz[3].serv_id   = serv_id_4;                                         \
  530.     clazz[3].serv_data = serv_data_4;                                       \
  531.     clazz[4].serv_id   = serv_id_5;                                         \
  532.     clazz[4].serv_data = serv_data_5;                                       \
  533.     clazz[5].serv_id   = serv_id_6;                                         \
  534.     clazz[5].serv_data = serv_data_6;                                       \
  535.     clazz[6].serv_id   = NULL;                                              \
  536.     clazz[6].serv_data = NULL;                                              \
  537.                                                                             \
  538.     *output_class = clazz;                                                  \
  539.                                                                             \
  540.     return FT_Err_Ok;                                                       \
  541.   }
  542.  
  543. #define FT_DEFINE_SERVICEDESCREC7( class_,                                  \
  544.                                    serv_id_1, serv_data_1,                  \
  545.                                    serv_id_2, serv_data_2,                  \
  546.                                    serv_id_3, serv_data_3,                  \
  547.                                    serv_id_4, serv_data_4,                  \
  548.                                    serv_id_5, serv_data_5,                  \
  549.                                    serv_id_6, serv_data_6,                  \
  550.                                    serv_id_7, serv_data_7 )                 \
  551.   void                                                                      \
  552.   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
  553.                                FT_ServiceDescRec*  clazz )                  \
  554.   {                                                                         \
  555.     FT_Memory  memory = library->memory;                                    \
  556.                                                                             \
  557.                                                                             \
  558.     if ( clazz )                                                            \
  559.       FT_FREE( clazz );                                                     \
  560.   }                                                                         \
  561.                                                                             \
  562.   FT_Error                                                                  \
  563.   FT_Create_Class_ ## class_( FT_Library           library,                 \
  564.                               FT_ServiceDescRec**  output_class)            \
  565.   {                                                                         \
  566.     FT_ServiceDescRec*  clazz  = NULL;                                      \
  567.     FT_Error            error;                                              \
  568.     FT_Memory           memory = library->memory;                           \
  569.                                                                             \
  570.                                                                             \
  571.     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 8 ) )                         \
  572.       return error;                                                         \
  573.                                                                             \
  574.     clazz[0].serv_id   = serv_id_1;                                         \
  575.     clazz[0].serv_data = serv_data_1;                                       \
  576.     clazz[1].serv_id   = serv_id_2;                                         \
  577.     clazz[1].serv_data = serv_data_2;                                       \
  578.     clazz[2].serv_id   = serv_id_3;                                         \
  579.     clazz[2].serv_data = serv_data_3;                                       \
  580.     clazz[3].serv_id   = serv_id_4;                                         \
  581.     clazz[3].serv_data = serv_data_4;                                       \
  582.     clazz[4].serv_id   = serv_id_5;                                         \
  583.     clazz[4].serv_data = serv_data_5;                                       \
  584.     clazz[5].serv_id   = serv_id_6;                                         \
  585.     clazz[5].serv_data = serv_data_6;                                       \
  586.     clazz[6].serv_id   = serv_id_7;                                         \
  587.     clazz[6].serv_data = serv_data_7;                                       \
  588.     clazz[7].serv_id   = NULL;                                              \
  589.     clazz[7].serv_data = NULL;                                              \
  590.                                                                             \
  591.     *output_class = clazz;                                                  \
  592.                                                                             \
  593.     return FT_Err_Ok;                                                       \
  594.   }
  595.  
  596. #endif /* FT_CONFIG_OPTION_PIC */
  597.  
  598.  
  599.   /*
  600.    *  Parse a list of FT_ServiceDescRec descriptors and look for
  601.    *  a specific service by ID.  Note that the last element in the
  602.    *  array must be { NULL, NULL }, and that the function should
  603.    *  return NULL if the service isn't available.
  604.    *
  605.    *  This function can be used by modules to implement their
  606.    *  `get_service' method.
  607.    */
  608.   FT_BASE( FT_Pointer )
  609.   ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
  610.                           const char*     service_id );
  611.  
  612.  
  613.   /*************************************************************************/
  614.   /*************************************************************************/
  615.   /*****                                                               *****/
  616.   /*****             S E R V I C E S   C A C H E                       *****/
  617.   /*****                                                               *****/
  618.   /*************************************************************************/
  619.   /*************************************************************************/
  620.  
  621.   /*
  622.    *  This structure is used to store a cache for several frequently used
  623.    *  services.  It is the type of `face->internal->services'.  You
  624.    *  should only use FT_FACE_LOOKUP_SERVICE to access it.
  625.    *
  626.    *  All fields should have the type FT_Pointer to relax compilation
  627.    *  dependencies.  We assume the developer isn't completely stupid.
  628.    *
  629.    *  Each field must be named `service_XXXX' where `XXX' corresponds to
  630.    *  the correct FT_SERVICE_ID_XXXX macro.  See the definition of
  631.    *  FT_FACE_LOOKUP_SERVICE below how this is implemented.
  632.    *
  633.    */
  634.   typedef struct  FT_ServiceCacheRec_
  635.   {
  636.     FT_Pointer  service_POSTSCRIPT_FONT_NAME;
  637.     FT_Pointer  service_MULTI_MASTERS;
  638.     FT_Pointer  service_GLYPH_DICT;
  639.     FT_Pointer  service_PFR_METRICS;
  640.     FT_Pointer  service_WINFNT;
  641.  
  642.   } FT_ServiceCacheRec, *FT_ServiceCache;
  643.  
  644.  
  645.   /*
  646.    *  A magic number used within the services cache.
  647.    */
  648.  
  649.   /* ensure that value `1' has the same width as a pointer */
  650. #define FT_SERVICE_UNAVAILABLE  ((FT_Pointer)~(FT_PtrDist)1)
  651.  
  652.  
  653.   /*
  654.    * @macro:
  655.    *   FT_FACE_LOOKUP_SERVICE
  656.    *
  657.    * @description:
  658.    *   This macro is used to lookup a service from a face's driver module
  659.    *   using its cache.
  660.    *
  661.    * @input:
  662.    *   face::
  663.    *     The source face handle containing the cache.
  664.    *
  665.    *   field ::
  666.    *     The field name in the cache.
  667.    *
  668.    *   id ::
  669.    *     The service ID.
  670.    *
  671.    * @output:
  672.    *   ptr ::
  673.    *     A variable receiving the service data.  NULL if not available.
  674.    */
  675. #ifdef __cplusplus
  676.  
  677. #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
  678.   FT_BEGIN_STMNT                                               \
  679.     FT_Pointer   svc;                                          \
  680.     FT_Pointer*  Pptr = (FT_Pointer*)&(ptr);                   \
  681.                                                                \
  682.                                                                \
  683.     svc = FT_FACE( face )->internal->services. service_ ## id; \
  684.     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
  685.       svc = NULL;                                              \
  686.     else if ( svc == NULL )                                    \
  687.     {                                                          \
  688.       FT_FACE_FIND_SERVICE( face, svc, id );                   \
  689.                                                                \
  690.       FT_FACE( face )->internal->services. service_ ## id =    \
  691.         (FT_Pointer)( svc != NULL ? svc                        \
  692.                                   : FT_SERVICE_UNAVAILABLE );  \
  693.     }                                                          \
  694.     *Pptr = svc;                                               \
  695.   FT_END_STMNT
  696.  
  697. #else /* !C++ */
  698.  
  699. #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
  700.   FT_BEGIN_STMNT                                               \
  701.     FT_Pointer  svc;                                           \
  702.                                                                \
  703.                                                                \
  704.     svc = FT_FACE( face )->internal->services. service_ ## id; \
  705.     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
  706.       svc = NULL;                                              \
  707.     else if ( svc == NULL )                                    \
  708.     {                                                          \
  709.       FT_FACE_FIND_SERVICE( face, svc, id );                   \
  710.                                                                \
  711.       FT_FACE( face )->internal->services. service_ ## id =    \
  712.         (FT_Pointer)( svc != NULL ? svc                        \
  713.                                   : FT_SERVICE_UNAVAILABLE );  \
  714.     }                                                          \
  715.     ptr = svc;                                                 \
  716.   FT_END_STMNT
  717.  
  718. #endif /* !C++ */
  719.  
  720.   /*
  721.    *  A macro used to define new service structure types.
  722.    */
  723.  
  724. #define FT_DEFINE_SERVICE( name )            \
  725.   typedef struct FT_Service_ ## name ## Rec_ \
  726.     FT_Service_ ## name ## Rec ;             \
  727.   typedef struct FT_Service_ ## name ## Rec_ \
  728.     const * FT_Service_ ## name ;            \
  729.   struct FT_Service_ ## name ## Rec_
  730.  
  731.   /* */
  732.  
  733.   /*
  734.    *  The header files containing the services.
  735.    */
  736.  
  737. #define FT_SERVICE_BDF_H                <freetype/internal/services/svbdf.h>
  738. #define FT_SERVICE_CID_H                <freetype/internal/services/svcid.h>
  739. #define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
  740. #define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
  741. #define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
  742. #define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
  743. #define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
  744. #define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
  745. #define FT_SERVICE_POSTSCRIPT_CMAPS_H   <freetype/internal/services/svpscmap.h>
  746. #define FT_SERVICE_POSTSCRIPT_INFO_H    <freetype/internal/services/svpsinfo.h>
  747. #define FT_SERVICE_POSTSCRIPT_NAME_H    <freetype/internal/services/svpostnm.h>
  748. #define FT_SERVICE_PROPERTIES_H         <freetype/internal/services/svprop.h>
  749. #define FT_SERVICE_SFNT_H               <freetype/internal/services/svsfnt.h>
  750. #define FT_SERVICE_TRUETYPE_ENGINE_H    <freetype/internal/services/svtteng.h>
  751. #define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>
  752. #define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>
  753. #define FT_SERVICE_XFREE86_NAME_H       <freetype/internal/services/svxf86nm.h>
  754. #define FT_SERVICE_TRUETYPE_GLYF_H      <freetype/internal/services/svttglyf.h>
  755.  
  756.  /* */
  757.  
  758. FT_END_HEADER
  759.  
  760. #endif /* __FTSERV_H__ */
  761.  
  762.  
  763. /* END */
  764.