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