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