• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftserv.h                                                               */
4 /*                                                                         */
5 /*    The FreeType services (specification only).                          */
6 /*                                                                         */
7 /*  Copyright 2003-2007, 2009, 2012 by                                     */
8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 /*                                                                         */
10 /*  This file is part of the FreeType project, and may only be used,       */
11 /*  modified, and distributed under the terms of the FreeType project      */
12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13 /*  this file you indicate that you have read the license and              */
14 /*  understand and accept it fully.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17 
18   /*************************************************************************/
19   /*                                                                       */
20   /*  Each module can export one or more `services'.  Each service is      */
21   /*  identified by a constant string and modeled by a pointer; the latter */
22   /*  generally corresponds to a structure containing function pointers.   */
23   /*                                                                       */
24   /*  Note that a service's data cannot be a mere function pointer because */
25   /*  in C it is possible that function pointers might be implemented      */
26   /*  differently than data pointers (e.g. 48 bits instead of 32).         */
27   /*                                                                       */
28   /*************************************************************************/
29 
30 
31 #ifndef __FTSERV_H__
32 #define __FTSERV_H__
33 
34 
35 FT_BEGIN_HEADER
36 
37 #if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
38 
39   /* we disable the warning `conditional expression is constant' here */
40   /* in order to compile cleanly with the maximum level of warnings   */
41 #pragma warning( disable : 4127 )
42 
43 #endif /* _MSC_VER */
44 
45   /*
46    * @macro:
47    *   FT_FACE_FIND_SERVICE
48    *
49    * @description:
50    *   This macro is used to look up a service from a face's driver module.
51    *
52    * @input:
53    *   face ::
54    *     The source face handle.
55    *
56    *   id ::
57    *     A string describing the service as defined in the service's
58    *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
59    *     `multi-masters').  It is automatically prefixed with
60    *     `FT_SERVICE_ID_'.
61    *
62    * @output:
63    *   ptr ::
64    *     A variable that receives the service pointer.  Will be NULL
65    *     if not found.
66    */
67 #ifdef __cplusplus
68 
69 #define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
70   FT_BEGIN_STMNT                                                            \
71     FT_Module    module = FT_MODULE( FT_FACE( face )->driver );             \
72     FT_Pointer   _tmp_  = NULL;                                             \
73     FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                              \
74                                                                             \
75                                                                             \
76     if ( module->clazz->get_interface )                                     \
77       _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
78     *_pptr_ = _tmp_;                                                        \
79   FT_END_STMNT
80 
81 #else /* !C++ */
82 
83 #define FT_FACE_FIND_SERVICE( face, ptr, id )                               \
84   FT_BEGIN_STMNT                                                            \
85     FT_Module   module = FT_MODULE( FT_FACE( face )->driver );              \
86     FT_Pointer  _tmp_  = NULL;                                              \
87                                                                             \
88     if ( module->clazz->get_interface )                                     \
89       _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
90     ptr = _tmp_;                                                            \
91   FT_END_STMNT
92 
93 #endif /* !C++ */
94 
95   /*
96    * @macro:
97    *   FT_FACE_FIND_GLOBAL_SERVICE
98    *
99    * @description:
100    *   This macro is used to look up a service from all modules.
101    *
102    * @input:
103    *   face ::
104    *     The source face handle.
105    *
106    *   id ::
107    *     A string describing the service as defined in the service's
108    *     header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
109    *     `multi-masters').  It is automatically prefixed with
110    *     `FT_SERVICE_ID_'.
111    *
112    * @output:
113    *   ptr ::
114    *     A variable that receives the service pointer.  Will be NULL
115    *     if not found.
116    */
117 #ifdef __cplusplus
118 
119 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
120   FT_BEGIN_STMNT                                                   \
121     FT_Module    module = FT_MODULE( FT_FACE( face )->driver );    \
122     FT_Pointer   _tmp_;                                            \
123     FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                     \
124                                                                    \
125                                                                    \
126     _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
127     *_pptr_ = _tmp_;                                               \
128   FT_END_STMNT
129 
130 #else /* !C++ */
131 
132 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
133   FT_BEGIN_STMNT                                                   \
134     FT_Module   module = FT_MODULE( FT_FACE( face )->driver );     \
135     FT_Pointer  _tmp_;                                             \
136                                                                    \
137                                                                    \
138     _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
139     ptr   = _tmp_;                                                 \
140   FT_END_STMNT
141 
142 #endif /* !C++ */
143 
144 
145   /*************************************************************************/
146   /*************************************************************************/
147   /*****                                                               *****/
148   /*****         S E R V I C E   D E S C R I P T O R S                 *****/
149   /*****                                                               *****/
150   /*************************************************************************/
151   /*************************************************************************/
152 
153   /*
154    *  The following structure is used to _describe_ a given service
155    *  to the library.  This is useful to build simple static service lists.
156    */
157   typedef struct  FT_ServiceDescRec_
158   {
159     const char*  serv_id;     /* service name         */
160     const void*  serv_data;   /* service pointer/data */
161 
162   } FT_ServiceDescRec;
163 
164   typedef const FT_ServiceDescRec*  FT_ServiceDesc;
165 
166 
167   /*************************************************************************/
168   /*                                                                       */
169   /* <Macro>                                                               */
170   /*    FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6             */
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 #else /* FT_CONFIG_OPTION_PIC */
268 
269 #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
270                                    serv_id_1, serv_data_1 )                 \
271   void                                                                      \
272   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
273                                FT_ServiceDescRec*  clazz )                  \
274   {                                                                         \
275     FT_Memory  memory = library->memory;                                    \
276                                                                             \
277                                                                             \
278     if ( clazz )                                                            \
279       FT_FREE( clazz );                                                     \
280   }                                                                         \
281                                                                             \
282   FT_Error                                                                  \
283   FT_Create_Class_ ## class_( FT_Library           library,                 \
284                               FT_ServiceDescRec**  output_class )           \
285   {                                                                         \
286     FT_ServiceDescRec*  clazz;                                              \
287     FT_Error            error;                                              \
288     FT_Memory           memory = library->memory;                           \
289                                                                             \
290                                                                             \
291     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 2 ) )                         \
292       return error;                                                         \
293                                                                             \
294     clazz[0].serv_id   = serv_id_1;                                         \
295     clazz[0].serv_data = serv_data_1;                                       \
296     clazz[1].serv_id   = NULL;                                              \
297     clazz[1].serv_data = NULL;                                              \
298                                                                             \
299     *output_class = clazz;                                                  \
300                                                                             \
301     return FT_Err_Ok;                                                       \
302   }
303 
304 #define FT_DEFINE_SERVICEDESCREC2( class_,                                  \
305                                    serv_id_1, serv_data_1,                  \
306                                    serv_id_2, serv_data_2 )                 \
307   void                                                                      \
308   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
309                                FT_ServiceDescRec*  clazz )                  \
310   {                                                                         \
311     FT_Memory  memory = library->memory;                                    \
312                                                                             \
313                                                                             \
314     if ( clazz )                                                            \
315       FT_FREE( clazz );                                                     \
316   }                                                                         \
317                                                                             \
318   FT_Error                                                                  \
319   FT_Create_Class_ ## class_( FT_Library           library,                 \
320                               FT_ServiceDescRec**  output_class )           \
321   {                                                                         \
322     FT_ServiceDescRec*  clazz;                                              \
323     FT_Error            error;                                              \
324     FT_Memory           memory = library->memory;                           \
325                                                                             \
326                                                                             \
327     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 3 ) )                         \
328       return error;                                                         \
329                                                                             \
330     clazz[0].serv_id   = serv_id_1;                                         \
331     clazz[0].serv_data = serv_data_1;                                       \
332     clazz[1].serv_id   = serv_id_2;                                         \
333     clazz[1].serv_data = serv_data_2;                                       \
334     clazz[2].serv_id   = NULL;                                              \
335     clazz[2].serv_data = NULL;                                              \
336                                                                             \
337     *output_class = clazz;                                                  \
338                                                                             \
339     return FT_Err_Ok;                                                       \
340   }
341 
342 #define FT_DEFINE_SERVICEDESCREC3( class_,                                  \
343                                    serv_id_1, serv_data_1,                  \
344                                    serv_id_2, serv_data_2,                  \
345                                    serv_id_3, serv_data_3 )                 \
346   void                                                                      \
347   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
348                                FT_ServiceDescRec*  clazz )                  \
349   {                                                                         \
350     FT_Memory  memory = library->memory;                                    \
351                                                                             \
352                                                                             \
353     if ( clazz )                                                            \
354       FT_FREE( clazz );                                                     \
355   }                                                                         \
356                                                                             \
357   FT_Error                                                                  \
358   FT_Create_Class_ ## class_( FT_Library           library,                 \
359                               FT_ServiceDescRec**  output_class )           \
360   {                                                                         \
361     FT_ServiceDescRec*  clazz;                                              \
362     FT_Error            error;                                              \
363     FT_Memory           memory = library->memory;                           \
364                                                                             \
365                                                                             \
366     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 4 ) )                         \
367       return error;                                                         \
368                                                                             \
369     clazz[0].serv_id   = serv_id_1;                                         \
370     clazz[0].serv_data = serv_data_1;                                       \
371     clazz[1].serv_id   = serv_id_2;                                         \
372     clazz[1].serv_data = serv_data_2;                                       \
373     clazz[2].serv_id   = serv_id_3;                                         \
374     clazz[2].serv_data = serv_data_3;                                       \
375     clazz[3].serv_id   = NULL;                                              \
376     clazz[3].serv_data = NULL;                                              \
377                                                                             \
378     *output_class = clazz;                                                  \
379                                                                             \
380     return FT_Err_Ok;                                                       \
381   }
382 
383 #define FT_DEFINE_SERVICEDESCREC4( class_,                                  \
384                                    serv_id_1, serv_data_1,                  \
385                                    serv_id_2, serv_data_2,                  \
386                                    serv_id_3, serv_data_3,                  \
387                                    serv_id_4, serv_data_4 )                 \
388   void                                                                      \
389   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
390                                FT_ServiceDescRec*  clazz )                  \
391   {                                                                         \
392     FT_Memory  memory = library->memory;                                    \
393                                                                             \
394                                                                             \
395     if ( clazz )                                                            \
396       FT_FREE( clazz );                                                     \
397   }                                                                         \
398                                                                             \
399   FT_Error                                                                  \
400   FT_Create_Class_ ## class_( FT_Library           library,                 \
401                               FT_ServiceDescRec**  output_class )           \
402   {                                                                         \
403     FT_ServiceDescRec*  clazz;                                              \
404     FT_Error            error;                                              \
405     FT_Memory           memory = library->memory;                           \
406                                                                             \
407                                                                             \
408     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 5 ) )                         \
409       return error;                                                         \
410                                                                             \
411     clazz[0].serv_id   = serv_id_1;                                         \
412     clazz[0].serv_data = serv_data_1;                                       \
413     clazz[1].serv_id   = serv_id_2;                                         \
414     clazz[1].serv_data = serv_data_2;                                       \
415     clazz[2].serv_id   = serv_id_3;                                         \
416     clazz[2].serv_data = serv_data_3;                                       \
417     clazz[3].serv_id   = serv_id_4;                                         \
418     clazz[3].serv_data = serv_data_4;                                       \
419     clazz[4].serv_id   = NULL;                                              \
420     clazz[4].serv_data = NULL;                                              \
421                                                                             \
422     *output_class = clazz;                                                  \
423                                                                             \
424     return FT_Err_Ok;                                                       \
425   }
426 
427 #define FT_DEFINE_SERVICEDESCREC5( class_,                                  \
428                                    serv_id_1, serv_data_1,                  \
429                                    serv_id_2, serv_data_2,                  \
430                                    serv_id_3, serv_data_3,                  \
431                                    serv_id_4, serv_data_4,                  \
432                                    serv_id_5, serv_data_5 )                 \
433   void                                                                      \
434   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
435                                FT_ServiceDescRec*  clazz )                  \
436   {                                                                         \
437     FT_Memory  memory = library->memory;                                    \
438                                                                             \
439                                                                             \
440     if ( clazz )                                                            \
441       FT_FREE( clazz );                                                     \
442   }                                                                         \
443                                                                             \
444   FT_Error                                                                  \
445   FT_Create_Class_ ## class_( FT_Library           library,                 \
446                               FT_ServiceDescRec**  output_class )           \
447   {                                                                         \
448     FT_ServiceDescRec*  clazz;                                              \
449     FT_Error            error;                                              \
450     FT_Memory           memory = library->memory;                           \
451                                                                             \
452                                                                             \
453     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 6 ) )                         \
454       return error;                                                         \
455                                                                             \
456     clazz[0].serv_id   = serv_id_1;                                         \
457     clazz[0].serv_data = serv_data_1;                                       \
458     clazz[1].serv_id   = serv_id_2;                                         \
459     clazz[1].serv_data = serv_data_2;                                       \
460     clazz[2].serv_id   = serv_id_3;                                         \
461     clazz[2].serv_data = serv_data_3;                                       \
462     clazz[3].serv_id   = serv_id_4;                                         \
463     clazz[3].serv_data = serv_data_4;                                       \
464     clazz[4].serv_id   = serv_id_5;                                         \
465     clazz[4].serv_data = serv_data_5;                                       \
466     clazz[5].serv_id   = NULL;                                              \
467     clazz[5].serv_data = NULL;                                              \
468                                                                             \
469     *output_class = clazz;                                                  \
470                                                                             \
471     return FT_Err_Ok;                                                       \
472   }
473 
474 #define FT_DEFINE_SERVICEDESCREC6( class_,                                  \
475                                    serv_id_1, serv_data_1,                  \
476                                    serv_id_2, serv_data_2,                  \
477                                    serv_id_3, serv_data_3,                  \
478                                    serv_id_4, serv_data_4,                  \
479                                    serv_id_5, serv_data_5,                  \
480                                    serv_id_6, serv_data_6 )                 \
481   void                                                                      \
482   FT_Destroy_Class_ ## class_( FT_Library          library,                 \
483                                FT_ServiceDescRec*  clazz )                  \
484   {                                                                         \
485     FT_Memory  memory = library->memory;                                    \
486                                                                             \
487                                                                             \
488     if ( clazz )                                                            \
489       FT_FREE( clazz );                                                     \
490   }                                                                         \
491                                                                             \
492   FT_Error                                                                  \
493   FT_Create_Class_ ## class_( FT_Library           library,                 \
494                               FT_ServiceDescRec**  output_class)            \
495   {                                                                         \
496     FT_ServiceDescRec*  clazz;                                              \
497     FT_Error            error;                                              \
498     FT_Memory           memory = library->memory;                           \
499                                                                             \
500                                                                             \
501     if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 7 ) )                         \
502       return error;                                                         \
503                                                                             \
504     clazz[0].serv_id   = serv_id_1;                                         \
505     clazz[0].serv_data = serv_data_1;                                       \
506     clazz[1].serv_id   = serv_id_2;                                         \
507     clazz[1].serv_data = serv_data_2;                                       \
508     clazz[2].serv_id   = serv_id_3;                                         \
509     clazz[2].serv_data = serv_data_3;                                       \
510     clazz[3].serv_id   = serv_id_4;                                         \
511     clazz[3].serv_data = serv_data_4;                                       \
512     clazz[4].serv_id   = serv_id_5;                                         \
513     clazz[4].serv_data = serv_data_5;                                       \
514     clazz[5].serv_id   = serv_id_6;                                         \
515     clazz[5].serv_data = serv_data_6;                                       \
516     clazz[6].serv_id   = NULL;                                              \
517     clazz[6].serv_data = NULL;                                              \
518                                                                             \
519     *output_class = clazz;                                                  \
520                                                                             \
521     return FT_Err_Ok;                                                       \
522   }
523 
524 #endif /* FT_CONFIG_OPTION_PIC */
525 
526 
527   /*
528    *  Parse a list of FT_ServiceDescRec descriptors and look for
529    *  a specific service by ID.  Note that the last element in the
530    *  array must be { NULL, NULL }, and that the function should
531    *  return NULL if the service isn't available.
532    *
533    *  This function can be used by modules to implement their
534    *  `get_service' method.
535    */
536   FT_BASE( FT_Pointer )
537   ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
538                           const char*     service_id );
539 
540 
541   /*************************************************************************/
542   /*************************************************************************/
543   /*****                                                               *****/
544   /*****             S E R V I C E S   C A C H E                       *****/
545   /*****                                                               *****/
546   /*************************************************************************/
547   /*************************************************************************/
548 
549   /*
550    *  This structure is used to store a cache for several frequently used
551    *  services.  It is the type of `face->internal->services'.  You
552    *  should only use FT_FACE_LOOKUP_SERVICE to access it.
553    *
554    *  All fields should have the type FT_Pointer to relax compilation
555    *  dependencies.  We assume the developer isn't completely stupid.
556    *
557    *  Each field must be named `service_XXXX' where `XXX' corresponds to
558    *  the correct FT_SERVICE_ID_XXXX macro.  See the definition of
559    *  FT_FACE_LOOKUP_SERVICE below how this is implemented.
560    *
561    */
562   typedef struct  FT_ServiceCacheRec_
563   {
564     FT_Pointer  service_POSTSCRIPT_FONT_NAME;
565     FT_Pointer  service_MULTI_MASTERS;
566     FT_Pointer  service_GLYPH_DICT;
567     FT_Pointer  service_PFR_METRICS;
568     FT_Pointer  service_WINFNT;
569 
570   } FT_ServiceCacheRec, *FT_ServiceCache;
571 
572 
573   /*
574    *  A magic number used within the services cache.
575    */
576 #define FT_SERVICE_UNAVAILABLE  ((FT_Pointer)-2)  /* magic number */
577 
578 
579   /*
580    * @macro:
581    *   FT_FACE_LOOKUP_SERVICE
582    *
583    * @description:
584    *   This macro is used to lookup a service from a face's driver module
585    *   using its cache.
586    *
587    * @input:
588    *   face::
589    *     The source face handle containing the cache.
590    *
591    *   field ::
592    *     The field name in the cache.
593    *
594    *   id ::
595    *     The service ID.
596    *
597    * @output:
598    *   ptr ::
599    *     A variable receiving the service data.  NULL if not available.
600    */
601 #ifdef __cplusplus
602 
603 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
604   FT_BEGIN_STMNT                                               \
605     FT_Pointer   svc;                                          \
606     FT_Pointer*  Pptr = (FT_Pointer*)&(ptr);                   \
607                                                                \
608                                                                \
609     svc = FT_FACE( face )->internal->services. service_ ## id; \
610     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
611       svc = NULL;                                              \
612     else if ( svc == NULL )                                    \
613     {                                                          \
614       FT_FACE_FIND_SERVICE( face, svc, id );                   \
615                                                                \
616       FT_FACE( face )->internal->services. service_ ## id =    \
617         (FT_Pointer)( svc != NULL ? svc                        \
618                                   : FT_SERVICE_UNAVAILABLE );  \
619     }                                                          \
620     *Pptr = svc;                                               \
621   FT_END_STMNT
622 
623 #else /* !C++ */
624 
625 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id )                \
626   FT_BEGIN_STMNT                                               \
627     FT_Pointer  svc;                                           \
628                                                                \
629                                                                \
630     svc = FT_FACE( face )->internal->services. service_ ## id; \
631     if ( svc == FT_SERVICE_UNAVAILABLE )                       \
632       svc = NULL;                                              \
633     else if ( svc == NULL )                                    \
634     {                                                          \
635       FT_FACE_FIND_SERVICE( face, svc, id );                   \
636                                                                \
637       FT_FACE( face )->internal->services. service_ ## id =    \
638         (FT_Pointer)( svc != NULL ? svc                        \
639                                   : FT_SERVICE_UNAVAILABLE );  \
640     }                                                          \
641     ptr = svc;                                                 \
642   FT_END_STMNT
643 
644 #endif /* !C++ */
645 
646   /*
647    *  A macro used to define new service structure types.
648    */
649 
650 #define FT_DEFINE_SERVICE( name )            \
651   typedef struct FT_Service_ ## name ## Rec_ \
652     FT_Service_ ## name ## Rec ;             \
653   typedef struct FT_Service_ ## name ## Rec_ \
654     const * FT_Service_ ## name ;            \
655   struct FT_Service_ ## name ## Rec_
656 
657   /* */
658 
659   /*
660    *  The header files containing the services.
661    */
662 
663 #define FT_SERVICE_BDF_H                <freetype/internal/services/svbdf.h>
664 #define FT_SERVICE_CID_H                <freetype/internal/services/svcid.h>
665 #define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
666 #define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
667 #define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
668 #define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
669 #define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
670 #define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
671 #define FT_SERVICE_POSTSCRIPT_CMAPS_H   <freetype/internal/services/svpscmap.h>
672 #define FT_SERVICE_POSTSCRIPT_INFO_H    <freetype/internal/services/svpsinfo.h>
673 #define FT_SERVICE_POSTSCRIPT_NAME_H    <freetype/internal/services/svpostnm.h>
674 #define FT_SERVICE_SFNT_H               <freetype/internal/services/svsfnt.h>
675 #define FT_SERVICE_TRUETYPE_ENGINE_H    <freetype/internal/services/svtteng.h>
676 #define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>
677 #define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>
678 #define FT_SERVICE_XFREE86_NAME_H       <freetype/internal/services/svxf86nm.h>
679 #define FT_SERVICE_TRUETYPE_GLYF_H      <freetype/internal/services/svttglyf.h>
680 
681  /* */
682 
683 FT_END_HEADER
684 
685 #endif /* __FTSERV_H__ */
686 
687 
688 /* END */
689