ReactOS  0.4.13-dev-651-g5dbc677
ftserv.h
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftserv.h */
4 /* */
5 /* The FreeType services (specification only). */
6 /* */
7 /* Copyright 2003-2018 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17 
18  /*************************************************************************/
19  /* */
20  /* Each module can export one or more `services'. Each service is */
21  /* identified by a constant string and modeled by a pointer; the latter */
22  /* generally corresponds to a structure containing function pointers. */
23  /* */
24  /* Note that a service's data cannot be a mere function pointer because */
25  /* in C it is possible that function pointers might be implemented */
26  /* differently than data pointers (e.g. 48 bits instead of 32). */
27  /* */
28  /*************************************************************************/
29 
30 
31 #ifndef FTSERV_H_
32 #define FTSERV_H_
33 
34 
36 
37  /*
38  * @macro:
39  * FT_FACE_FIND_SERVICE
40  *
41  * @description:
42  * This macro is used to look up a service from a face's driver module.
43  *
44  * @input:
45  * face ::
46  * The source face handle.
47  *
48  * id ::
49  * A string describing the service as defined in the service's
50  * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
51  * `multi-masters'). It is automatically prefixed with
52  * `FT_SERVICE_ID_'.
53  *
54  * @output:
55  * ptr ::
56  * A variable that receives the service pointer. Will be NULL
57  * if not found.
58  */
59 #ifdef __cplusplus
60 
61 #define FT_FACE_FIND_SERVICE( face, ptr, id ) \
62  FT_BEGIN_STMNT \
63  FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
64  FT_Pointer _tmp_ = NULL; \
65  FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \
66  \
67  \
68  if ( module->clazz->get_interface ) \
69  _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
70  *_pptr_ = _tmp_; \
71  FT_END_STMNT
72 
73 #else /* !C++ */
74 
75 #define FT_FACE_FIND_SERVICE( face, ptr, id ) \
76  FT_BEGIN_STMNT \
77  FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
78  FT_Pointer _tmp_ = NULL; \
79  \
80  if ( module->clazz->get_interface ) \
81  _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
82  ptr = _tmp_; \
83  FT_END_STMNT
84 
85 #endif /* !C++ */
86 
87 
88  /*
89  * @macro:
90  * FT_FACE_FIND_GLOBAL_SERVICE
91  *
92  * @description:
93  * This macro is used to look up a service from all modules.
94  *
95  * @input:
96  * face ::
97  * The source face handle.
98  *
99  * id ::
100  * A string describing the service as defined in the service's
101  * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
102  * `multi-masters'). It is automatically prefixed with
103  * `FT_SERVICE_ID_'.
104  *
105  * @output:
106  * ptr ::
107  * A variable that receives the service pointer. Will be NULL
108  * if not found.
109  */
110 #ifdef __cplusplus
111 
112 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \
113  FT_BEGIN_STMNT \
114  FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
115  FT_Pointer _tmp_; \
116  FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \
117  \
118  \
119  _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
120  *_pptr_ = _tmp_; \
121  FT_END_STMNT
122 
123 #else /* !C++ */
124 
125 #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \
126  FT_BEGIN_STMNT \
127  FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
128  FT_Pointer _tmp_; \
129  \
130  \
131  _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
132  ptr = _tmp_; \
133  FT_END_STMNT
134 
135 #endif /* !C++ */
136 
137 
138  /*************************************************************************/
139  /*************************************************************************/
140  /***** *****/
141  /***** S E R V I C E D E S C R I P T O R S *****/
142  /***** *****/
143  /*************************************************************************/
144  /*************************************************************************/
145 
146  /*
147  * The following structure is used to _describe_ a given service
148  * to the library. This is useful to build simple static service lists.
149  */
150  typedef struct FT_ServiceDescRec_
151  {
152  const char* serv_id; /* service name */
153  const void* serv_data; /* service pointer/data */
154 
156 
158 
159 
160  /*************************************************************************/
161  /* */
162  /* <Macro> */
163  /* FT_DEFINE_SERVICEDESCREC1 */
164  /* FT_DEFINE_SERVICEDESCREC2 */
165  /* FT_DEFINE_SERVICEDESCREC3 */
166  /* FT_DEFINE_SERVICEDESCREC4 */
167  /* FT_DEFINE_SERVICEDESCREC5 */
168  /* FT_DEFINE_SERVICEDESCREC6 */
169  /* FT_DEFINE_SERVICEDESCREC7 */
170  /* FT_DEFINE_SERVICEDESCREC8 */
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 #define FT_DEFINE_SERVICEDESCREC7( class_, \
268  serv_id_1, serv_data_1, \
269  serv_id_2, serv_data_2, \
270  serv_id_3, serv_data_3, \
271  serv_id_4, serv_data_4, \
272  serv_id_5, serv_data_5, \
273  serv_id_6, serv_data_6, \
274  serv_id_7, serv_data_7 ) \
275  static const FT_ServiceDescRec class_[] = \
276  { \
277  { serv_id_1, serv_data_1 }, \
278  { serv_id_2, serv_data_2 }, \
279  { serv_id_3, serv_data_3 }, \
280  { serv_id_4, serv_data_4 }, \
281  { serv_id_5, serv_data_5 }, \
282  { serv_id_6, serv_data_6 }, \
283  { serv_id_7, serv_data_7 }, \
284  { NULL, NULL } \
285  };
286 
287 #define FT_DEFINE_SERVICEDESCREC8( class_, \
288  serv_id_1, serv_data_1, \
289  serv_id_2, serv_data_2, \
290  serv_id_3, serv_data_3, \
291  serv_id_4, serv_data_4, \
292  serv_id_5, serv_data_5, \
293  serv_id_6, serv_data_6, \
294  serv_id_7, serv_data_7, \
295  serv_id_8, serv_data_8 ) \
296  static const FT_ServiceDescRec class_[] = \
297  { \
298  { serv_id_1, serv_data_1 }, \
299  { serv_id_2, serv_data_2 }, \
300  { serv_id_3, serv_data_3 }, \
301  { serv_id_4, serv_data_4 }, \
302  { serv_id_5, serv_data_5 }, \
303  { serv_id_6, serv_data_6 }, \
304  { serv_id_7, serv_data_7 }, \
305  { serv_id_8, serv_data_8 }, \
306  { NULL, NULL } \
307  };
308 
309 #define FT_DEFINE_SERVICEDESCREC9( class_, \
310  serv_id_1, serv_data_1, \
311  serv_id_2, serv_data_2, \
312  serv_id_3, serv_data_3, \
313  serv_id_4, serv_data_4, \
314  serv_id_5, serv_data_5, \
315  serv_id_6, serv_data_6, \
316  serv_id_7, serv_data_7, \
317  serv_id_8, serv_data_8, \
318  serv_id_9, serv_data_9 ) \
319  static const FT_ServiceDescRec class_[] = \
320  { \
321  { serv_id_1, serv_data_1 }, \
322  { serv_id_2, serv_data_2 }, \
323  { serv_id_3, serv_data_3 }, \
324  { serv_id_4, serv_data_4 }, \
325  { serv_id_5, serv_data_5 }, \
326  { serv_id_6, serv_data_6 }, \
327  { serv_id_7, serv_data_7 }, \
328  { serv_id_8, serv_data_8 }, \
329  { serv_id_9, serv_data_9 }, \
330  { NULL, NULL } \
331  };
332 
333 #define FT_DEFINE_SERVICEDESCREC10( class_, \
334  serv_id_1, serv_data_1, \
335  serv_id_2, serv_data_2, \
336  serv_id_3, serv_data_3, \
337  serv_id_4, serv_data_4, \
338  serv_id_5, serv_data_5, \
339  serv_id_6, serv_data_6, \
340  serv_id_7, serv_data_7, \
341  serv_id_8, serv_data_8, \
342  serv_id_9, serv_data_9, \
343  serv_id_10, serv_data_10 ) \
344  static const FT_ServiceDescRec class_[] = \
345  { \
346  { serv_id_1, serv_data_1 }, \
347  { serv_id_2, serv_data_2 }, \
348  { serv_id_3, serv_data_3 }, \
349  { serv_id_4, serv_data_4 }, \
350  { serv_id_5, serv_data_5 }, \
351  { serv_id_6, serv_data_6 }, \
352  { serv_id_7, serv_data_7 }, \
353  { serv_id_8, serv_data_8 }, \
354  { serv_id_9, serv_data_9 }, \
355  { serv_id_10, serv_data_10 }, \
356  { NULL, NULL } \
357  };
358 
359 #else /* FT_CONFIG_OPTION_PIC */
360 
361 #define FT_DEFINE_SERVICEDESCREC1( class_, \
362  serv_id_1, serv_data_1 ) \
363  void \
364  FT_Destroy_Class_ ## class_( FT_Library library, \
365  FT_ServiceDescRec* clazz ) \
366  { \
367  FT_Memory memory = library->memory; \
368  \
369  \
370  if ( clazz ) \
371  FT_FREE( clazz ); \
372  } \
373  \
374  FT_Error \
375  FT_Create_Class_ ## class_( FT_Library library, \
376  FT_ServiceDescRec** output_class ) \
377  { \
378  FT_ServiceDescRec* clazz = NULL; \
379  FT_Error error; \
380  FT_Memory memory = library->memory; \
381  \
382  \
383  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 2 ) ) \
384  return error; \
385  \
386  clazz[0].serv_id = serv_id_1; \
387  clazz[0].serv_data = serv_data_1; \
388  clazz[1].serv_id = NULL; \
389  clazz[1].serv_data = NULL; \
390  \
391  *output_class = clazz; \
392  \
393  return FT_Err_Ok; \
394  }
395 
396 #define FT_DEFINE_SERVICEDESCREC2( class_, \
397  serv_id_1, serv_data_1, \
398  serv_id_2, serv_data_2 ) \
399  void \
400  FT_Destroy_Class_ ## class_( FT_Library library, \
401  FT_ServiceDescRec* clazz ) \
402  { \
403  FT_Memory memory = library->memory; \
404  \
405  \
406  if ( clazz ) \
407  FT_FREE( clazz ); \
408  } \
409  \
410  FT_Error \
411  FT_Create_Class_ ## class_( FT_Library library, \
412  FT_ServiceDescRec** output_class ) \
413  { \
414  FT_ServiceDescRec* clazz = NULL; \
415  FT_Error error; \
416  FT_Memory memory = library->memory; \
417  \
418  \
419  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 3 ) ) \
420  return error; \
421  \
422  clazz[0].serv_id = serv_id_1; \
423  clazz[0].serv_data = serv_data_1; \
424  clazz[1].serv_id = serv_id_2; \
425  clazz[1].serv_data = serv_data_2; \
426  clazz[2].serv_id = NULL; \
427  clazz[2].serv_data = NULL; \
428  \
429  *output_class = clazz; \
430  \
431  return FT_Err_Ok; \
432  }
433 
434 #define FT_DEFINE_SERVICEDESCREC3( class_, \
435  serv_id_1, serv_data_1, \
436  serv_id_2, serv_data_2, \
437  serv_id_3, serv_data_3 ) \
438  void \
439  FT_Destroy_Class_ ## class_( FT_Library library, \
440  FT_ServiceDescRec* clazz ) \
441  { \
442  FT_Memory memory = library->memory; \
443  \
444  \
445  if ( clazz ) \
446  FT_FREE( clazz ); \
447  } \
448  \
449  FT_Error \
450  FT_Create_Class_ ## class_( FT_Library library, \
451  FT_ServiceDescRec** output_class ) \
452  { \
453  FT_ServiceDescRec* clazz = NULL; \
454  FT_Error error; \
455  FT_Memory memory = library->memory; \
456  \
457  \
458  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 4 ) ) \
459  return error; \
460  \
461  clazz[0].serv_id = serv_id_1; \
462  clazz[0].serv_data = serv_data_1; \
463  clazz[1].serv_id = serv_id_2; \
464  clazz[1].serv_data = serv_data_2; \
465  clazz[2].serv_id = serv_id_3; \
466  clazz[2].serv_data = serv_data_3; \
467  clazz[3].serv_id = NULL; \
468  clazz[3].serv_data = NULL; \
469  \
470  *output_class = clazz; \
471  \
472  return FT_Err_Ok; \
473  }
474 
475 #define FT_DEFINE_SERVICEDESCREC4( class_, \
476  serv_id_1, serv_data_1, \
477  serv_id_2, serv_data_2, \
478  serv_id_3, serv_data_3, \
479  serv_id_4, serv_data_4 ) \
480  void \
481  FT_Destroy_Class_ ## class_( FT_Library library, \
482  FT_ServiceDescRec* clazz ) \
483  { \
484  FT_Memory memory = library->memory; \
485  \
486  \
487  if ( clazz ) \
488  FT_FREE( clazz ); \
489  } \
490  \
491  FT_Error \
492  FT_Create_Class_ ## class_( FT_Library library, \
493  FT_ServiceDescRec** output_class ) \
494  { \
495  FT_ServiceDescRec* clazz = NULL; \
496  FT_Error error; \
497  FT_Memory memory = library->memory; \
498  \
499  \
500  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 5 ) ) \
501  return error; \
502  \
503  clazz[0].serv_id = serv_id_1; \
504  clazz[0].serv_data = serv_data_1; \
505  clazz[1].serv_id = serv_id_2; \
506  clazz[1].serv_data = serv_data_2; \
507  clazz[2].serv_id = serv_id_3; \
508  clazz[2].serv_data = serv_data_3; \
509  clazz[3].serv_id = serv_id_4; \
510  clazz[3].serv_data = serv_data_4; \
511  clazz[4].serv_id = NULL; \
512  clazz[4].serv_data = NULL; \
513  \
514  *output_class = clazz; \
515  \
516  return FT_Err_Ok; \
517  }
518 
519 #define FT_DEFINE_SERVICEDESCREC5( class_, \
520  serv_id_1, serv_data_1, \
521  serv_id_2, serv_data_2, \
522  serv_id_3, serv_data_3, \
523  serv_id_4, serv_data_4, \
524  serv_id_5, serv_data_5 ) \
525  void \
526  FT_Destroy_Class_ ## class_( FT_Library library, \
527  FT_ServiceDescRec* clazz ) \
528  { \
529  FT_Memory memory = library->memory; \
530  \
531  \
532  if ( clazz ) \
533  FT_FREE( clazz ); \
534  } \
535  \
536  FT_Error \
537  FT_Create_Class_ ## class_( FT_Library library, \
538  FT_ServiceDescRec** output_class ) \
539  { \
540  FT_ServiceDescRec* clazz = NULL; \
541  FT_Error error; \
542  FT_Memory memory = library->memory; \
543  \
544  \
545  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 6 ) ) \
546  return error; \
547  \
548  clazz[0].serv_id = serv_id_1; \
549  clazz[0].serv_data = serv_data_1; \
550  clazz[1].serv_id = serv_id_2; \
551  clazz[1].serv_data = serv_data_2; \
552  clazz[2].serv_id = serv_id_3; \
553  clazz[2].serv_data = serv_data_3; \
554  clazz[3].serv_id = serv_id_4; \
555  clazz[3].serv_data = serv_data_4; \
556  clazz[4].serv_id = serv_id_5; \
557  clazz[4].serv_data = serv_data_5; \
558  clazz[5].serv_id = NULL; \
559  clazz[5].serv_data = NULL; \
560  \
561  *output_class = clazz; \
562  \
563  return FT_Err_Ok; \
564  }
565 
566 #define FT_DEFINE_SERVICEDESCREC6( class_, \
567  serv_id_1, serv_data_1, \
568  serv_id_2, serv_data_2, \
569  serv_id_3, serv_data_3, \
570  serv_id_4, serv_data_4, \
571  serv_id_5, serv_data_5, \
572  serv_id_6, serv_data_6 ) \
573  void \
574  FT_Destroy_Class_ ## class_( FT_Library library, \
575  FT_ServiceDescRec* clazz ) \
576  { \
577  FT_Memory memory = library->memory; \
578  \
579  \
580  if ( clazz ) \
581  FT_FREE( clazz ); \
582  } \
583  \
584  FT_Error \
585  FT_Create_Class_ ## class_( FT_Library library, \
586  FT_ServiceDescRec** output_class ) \
587  { \
588  FT_ServiceDescRec* clazz = NULL; \
589  FT_Error error; \
590  FT_Memory memory = library->memory; \
591  \
592  \
593  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 7 ) ) \
594  return error; \
595  \
596  clazz[0].serv_id = serv_id_1; \
597  clazz[0].serv_data = serv_data_1; \
598  clazz[1].serv_id = serv_id_2; \
599  clazz[1].serv_data = serv_data_2; \
600  clazz[2].serv_id = serv_id_3; \
601  clazz[2].serv_data = serv_data_3; \
602  clazz[3].serv_id = serv_id_4; \
603  clazz[3].serv_data = serv_data_4; \
604  clazz[4].serv_id = serv_id_5; \
605  clazz[4].serv_data = serv_data_5; \
606  clazz[5].serv_id = serv_id_6; \
607  clazz[5].serv_data = serv_data_6; \
608  clazz[6].serv_id = NULL; \
609  clazz[6].serv_data = NULL; \
610  \
611  *output_class = clazz; \
612  \
613  return FT_Err_Ok; \
614  }
615 
616 #define FT_DEFINE_SERVICEDESCREC7( class_, \
617  serv_id_1, serv_data_1, \
618  serv_id_2, serv_data_2, \
619  serv_id_3, serv_data_3, \
620  serv_id_4, serv_data_4, \
621  serv_id_5, serv_data_5, \
622  serv_id_6, serv_data_6, \
623  serv_id_7, serv_data_7 ) \
624  void \
625  FT_Destroy_Class_ ## class_( FT_Library library, \
626  FT_ServiceDescRec* clazz ) \
627  { \
628  FT_Memory memory = library->memory; \
629  \
630  \
631  if ( clazz ) \
632  FT_FREE( clazz ); \
633  } \
634  \
635  FT_Error \
636  FT_Create_Class_ ## class_( FT_Library library, \
637  FT_ServiceDescRec** output_class ) \
638  { \
639  FT_ServiceDescRec* clazz = NULL; \
640  FT_Error error; \
641  FT_Memory memory = library->memory; \
642  \
643  \
644  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 8 ) ) \
645  return error; \
646  \
647  clazz[0].serv_id = serv_id_1; \
648  clazz[0].serv_data = serv_data_1; \
649  clazz[1].serv_id = serv_id_2; \
650  clazz[1].serv_data = serv_data_2; \
651  clazz[2].serv_id = serv_id_3; \
652  clazz[2].serv_data = serv_data_3; \
653  clazz[3].serv_id = serv_id_4; \
654  clazz[3].serv_data = serv_data_4; \
655  clazz[4].serv_id = serv_id_5; \
656  clazz[4].serv_data = serv_data_5; \
657  clazz[5].serv_id = serv_id_6; \
658  clazz[5].serv_data = serv_data_6; \
659  clazz[6].serv_id = serv_id_7; \
660  clazz[6].serv_data = serv_data_7; \
661  clazz[7].serv_id = NULL; \
662  clazz[7].serv_data = NULL; \
663  \
664  *output_class = clazz; \
665  \
666  return FT_Err_Ok; \
667  }
668 
669 #define FT_DEFINE_SERVICEDESCREC8( class_, \
670  serv_id_1, serv_data_1, \
671  serv_id_2, serv_data_2, \
672  serv_id_3, serv_data_3, \
673  serv_id_4, serv_data_4, \
674  serv_id_5, serv_data_5, \
675  serv_id_6, serv_data_6, \
676  serv_id_7, serv_data_7, \
677  serv_id_8, serv_data_8 ) \
678  void \
679  FT_Destroy_Class_ ## class_( FT_Library library, \
680  FT_ServiceDescRec* clazz ) \
681  { \
682  FT_Memory memory = library->memory; \
683  \
684  \
685  if ( clazz ) \
686  FT_FREE( clazz ); \
687  } \
688  \
689  FT_Error \
690  FT_Create_Class_ ## class_( FT_Library library, \
691  FT_ServiceDescRec** output_class ) \
692  { \
693  FT_ServiceDescRec* clazz = NULL; \
694  FT_Error error; \
695  FT_Memory memory = library->memory; \
696  \
697  \
698  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 9 ) ) \
699  return error; \
700  \
701  clazz[0].serv_id = serv_id_1; \
702  clazz[0].serv_data = serv_data_1; \
703  clazz[1].serv_id = serv_id_2; \
704  clazz[1].serv_data = serv_data_2; \
705  clazz[2].serv_id = serv_id_3; \
706  clazz[2].serv_data = serv_data_3; \
707  clazz[3].serv_id = serv_id_4; \
708  clazz[3].serv_data = serv_data_4; \
709  clazz[4].serv_id = serv_id_5; \
710  clazz[4].serv_data = serv_data_5; \
711  clazz[5].serv_id = serv_id_6; \
712  clazz[5].serv_data = serv_data_6; \
713  clazz[6].serv_id = serv_id_7; \
714  clazz[6].serv_data = serv_data_7; \
715  clazz[7].serv_id = serv_id_8; \
716  clazz[7].serv_data = serv_data_8; \
717  clazz[8].serv_id = NULL; \
718  clazz[8].serv_data = NULL; \
719  \
720  *output_class = clazz; \
721  \
722  return FT_Err_Ok; \
723  }
724 
725 #define FT_DEFINE_SERVICEDESCREC9( class_, \
726  serv_id_1, serv_data_1, \
727  serv_id_2, serv_data_2, \
728  serv_id_3, serv_data_3, \
729  serv_id_4, serv_data_4, \
730  serv_id_5, serv_data_5, \
731  serv_id_6, serv_data_6, \
732  serv_id_7, serv_data_7, \
733  serv_id_8, serv_data_8, \
734  serv_id_9, serv_data_9 ) \
735  void \
736  FT_Destroy_Class_ ## class_( FT_Library library, \
737  FT_ServiceDescRec* clazz ) \
738  { \
739  FT_Memory memory = library->memory; \
740  \
741  \
742  if ( clazz ) \
743  FT_FREE( clazz ); \
744  } \
745  \
746  FT_Error \
747  FT_Create_Class_ ## class_( FT_Library library, \
748  FT_ServiceDescRec** output_class ) \
749  { \
750  FT_ServiceDescRec* clazz = NULL; \
751  FT_Error error; \
752  FT_Memory memory = library->memory; \
753  \
754  \
755  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 10 ) ) \
756  return error; \
757  \
758  clazz[0].serv_id = serv_id_1; \
759  clazz[0].serv_data = serv_data_1; \
760  clazz[1].serv_id = serv_id_2; \
761  clazz[1].serv_data = serv_data_2; \
762  clazz[2].serv_id = serv_id_3; \
763  clazz[2].serv_data = serv_data_3; \
764  clazz[3].serv_id = serv_id_4; \
765  clazz[3].serv_data = serv_data_4; \
766  clazz[4].serv_id = serv_id_5; \
767  clazz[4].serv_data = serv_data_5; \
768  clazz[5].serv_id = serv_id_6; \
769  clazz[5].serv_data = serv_data_6; \
770  clazz[6].serv_id = serv_id_7; \
771  clazz[6].serv_data = serv_data_7; \
772  clazz[7].serv_id = serv_id_8; \
773  clazz[7].serv_data = serv_data_8; \
774  clazz[8].serv_id = serv_id_9; \
775  clazz[8].serv_data = serv_data_9; \
776  clazz[9].serv_id = NULL; \
777  clazz[9].serv_data = NULL; \
778  \
779  *output_class = clazz; \
780  \
781  return FT_Err_Ok; \
782  }
783 
784 #define FT_DEFINE_SERVICEDESCREC10( class_, \
785  serv_id_1, serv_data_1, \
786  serv_id_2, serv_data_2, \
787  serv_id_3, serv_data_3, \
788  serv_id_4, serv_data_4, \
789  serv_id_5, serv_data_5, \
790  serv_id_6, serv_data_6, \
791  serv_id_7, serv_data_7, \
792  serv_id_8, serv_data_8, \
793  serv_id_9, serv_data_9, \
794  serv_id_10, serv_data_10 ) \
795  void \
796  FT_Destroy_Class_ ## class_( FT_Library library, \
797  FT_ServiceDescRec* clazz ) \
798  { \
799  FT_Memory memory = library->memory; \
800  \
801  \
802  if ( clazz ) \
803  FT_FREE( clazz ); \
804  } \
805  \
806  FT_Error \
807  FT_Create_Class_ ## class_( FT_Library library, \
808  FT_ServiceDescRec** output_class ) \
809  { \
810  FT_ServiceDescRec* clazz = NULL; \
811  FT_Error error; \
812  FT_Memory memory = library->memory; \
813  \
814  \
815  if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 11 ) ) \
816  return error; \
817  \
818  clazz[ 0].serv_id = serv_id_1; \
819  clazz[ 0].serv_data = serv_data_1; \
820  clazz[ 1].serv_id = serv_id_2; \
821  clazz[ 1].serv_data = serv_data_2; \
822  clazz[ 2].serv_id = serv_id_3; \
823  clazz[ 2].serv_data = serv_data_3; \
824  clazz[ 3].serv_id = serv_id_4; \
825  clazz[ 3].serv_data = serv_data_4; \
826  clazz[ 4].serv_id = serv_id_5; \
827  clazz[ 4].serv_data = serv_data_5; \
828  clazz[ 5].serv_id = serv_id_6; \
829  clazz[ 5].serv_data = serv_data_6; \
830  clazz[ 6].serv_id = serv_id_7; \
831  clazz[ 6].serv_data = serv_data_7; \
832  clazz[ 7].serv_id = serv_id_8; \
833  clazz[ 7].serv_data = serv_data_8; \
834  clazz[ 8].serv_id = serv_id_9; \
835  clazz[ 8].serv_data = serv_data_9; \
836  clazz[ 9].serv_id = serv_id_10; \
837  clazz[ 9].serv_data = serv_data_10; \
838  clazz[10].serv_id = NULL; \
839  clazz[10].serv_data = NULL; \
840  \
841  *output_class = clazz; \
842  \
843  return FT_Err_Ok; \
844  }
845 
846 #endif /* FT_CONFIG_OPTION_PIC */
847 
848 
849  /*
850  * Parse a list of FT_ServiceDescRec descriptors and look for
851  * a specific service by ID. Note that the last element in the
852  * array must be { NULL, NULL }, and that the function should
853  * return NULL if the service isn't available.
854  *
855  * This function can be used by modules to implement their
856  * `get_service' method.
857  */
859  ft_service_list_lookup( FT_ServiceDesc service_descriptors,
860  const char* service_id );
861 
862 
863  /*************************************************************************/
864  /*************************************************************************/
865  /***** *****/
866  /***** S E R V I C E S C A C H E *****/
867  /***** *****/
868  /*************************************************************************/
869  /*************************************************************************/
870 
871  /*
872  * This structure is used to store a cache for several frequently used
873  * services. It is the type of `face->internal->services'. You
874  * should only use FT_FACE_LOOKUP_SERVICE to access it.
875  *
876  * All fields should have the type FT_Pointer to relax compilation
877  * dependencies. We assume the developer isn't completely stupid.
878  *
879  * Each field must be named `service_XXXX' where `XXX' corresponds to
880  * the correct FT_SERVICE_ID_XXXX macro. See the definition of
881  * FT_FACE_LOOKUP_SERVICE below how this is implemented.
882  *
883  */
884  typedef struct FT_ServiceCacheRec_
885  {
892 
894 
895 
896  /*
897  * A magic number used within the services cache.
898  */
899 
900  /* ensure that value `1' has the same width as a pointer */
901 #define FT_SERVICE_UNAVAILABLE ((FT_Pointer)~(FT_PtrDist)1)
902 
903 
904  /*
905  * @macro:
906  * FT_FACE_LOOKUP_SERVICE
907  *
908  * @description:
909  * This macro is used to look up a service from a face's driver module
910  * using its cache.
911  *
912  * @input:
913  * face::
914  * The source face handle containing the cache.
915  *
916  * field ::
917  * The field name in the cache.
918  *
919  * id ::
920  * The service ID.
921  *
922  * @output:
923  * ptr ::
924  * A variable receiving the service data. NULL if not available.
925  */
926 #ifdef __cplusplus
927 
928 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \
929  FT_BEGIN_STMNT \
930  FT_Pointer svc; \
931  FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \
932  \
933  \
934  svc = FT_FACE( face )->internal->services. service_ ## id; \
935  if ( svc == FT_SERVICE_UNAVAILABLE ) \
936  svc = NULL; \
937  else if ( svc == NULL ) \
938  { \
939  FT_FACE_FIND_SERVICE( face, svc, id ); \
940  \
941  FT_FACE( face )->internal->services. service_ ## id = \
942  (FT_Pointer)( svc != NULL ? svc \
943  : FT_SERVICE_UNAVAILABLE ); \
944  } \
945  *Pptr = svc; \
946  FT_END_STMNT
947 
948 #else /* !C++ */
949 
950 #define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \
951  FT_BEGIN_STMNT \
952  FT_Pointer svc; \
953  \
954  \
955  svc = FT_FACE( face )->internal->services. service_ ## id; \
956  if ( svc == FT_SERVICE_UNAVAILABLE ) \
957  svc = NULL; \
958  else if ( svc == NULL ) \
959  { \
960  FT_FACE_FIND_SERVICE( face, svc, id ); \
961  \
962  FT_FACE( face )->internal->services. service_ ## id = \
963  (FT_Pointer)( svc != NULL ? svc \
964  : FT_SERVICE_UNAVAILABLE ); \
965  } \
966  ptr = svc; \
967  FT_END_STMNT
968 
969 #endif /* !C++ */
970 
971  /*
972  * A macro used to define new service structure types.
973  */
974 
975 #define FT_DEFINE_SERVICE( name ) \
976  typedef struct FT_Service_ ## name ## Rec_ \
977  FT_Service_ ## name ## Rec ; \
978  typedef struct FT_Service_ ## name ## Rec_ \
979  const * FT_Service_ ## name ; \
980  struct FT_Service_ ## name ## Rec_
981 
982  /* */
983 
984  /*
985  * The header files containing the services.
986  */
987 
988 #define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h>
989 #define FT_SERVICE_CFF_TABLE_LOAD_H <freetype/internal/services/svcfftl.h>
990 #define FT_SERVICE_CID_H <freetype/internal/services/svcid.h>
991 #define FT_SERVICE_FONT_FORMAT_H <freetype/internal/services/svfntfmt.h>
992 #define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h>
993 #define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h>
994 #define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h>
995 #define FT_SERVICE_METRICS_VARIATIONS_H <freetype/internal/services/svmetric.h>
996 #define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h>
997 #define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h>
998 #define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h>
999 #define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h>
1000 #define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h>
1001 #define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h>
1002 #define FT_SERVICE_PROPERTIES_H <freetype/internal/services/svprop.h>
1003 #define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h>
1004 #define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h>
1005 #define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h>
1006 #define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h>
1007 #define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h>
1008 
1009  /* */
1010 
1012 
1013 #endif /* FTSERV_H_ */
1014 
1015 
1016 /* END */
ft_service_list_lookup(FT_ServiceDesc service_descriptors, const char *service_id)
Definition: ftobjs.c:98
FT_Pointer service_PFR_METRICS
Definition: ftserv.h:890
struct FT_ServiceDescRec_ FT_ServiceDescRec
#define FT_END_HEADER
Definition: ftheader.h:54
const void * serv_data
Definition: ftserv.h:153
struct FT_ServiceCacheRec_ FT_ServiceCacheRec
FT_Pointer service_MULTI_MASTERS
Definition: ftserv.h:887
#define FT_BEGIN_HEADER
Definition: ftheader.h:36
FT_Pointer service_WINFNT
Definition: ftserv.h:891
struct FT_ServiceCacheRec_ * FT_ServiceCache
FT_Pointer service_GLYPH_DICT
Definition: ftserv.h:889
const char * serv_id
Definition: ftserv.h:152
FT_Pointer service_METRICS_VARIATIONS
Definition: ftserv.h:888
#define FT_BASE(x)
Definition: ftconfig.h:408
const FT_ServiceDescRec * FT_ServiceDesc
Definition: ftserv.h:157
FT_Pointer service_POSTSCRIPT_FONT_NAME
Definition: ftserv.h:886