ReactOS 0.4.15-dev-7788-g1ad9096
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 */
#define FT_BASE(x)
Definition: ftconfig.h:408
#define FT_END_HEADER
Definition: ftheader.h:54
#define FT_BEGIN_HEADER
Definition: ftheader.h:36
struct FT_ServiceCacheRec_ FT_ServiceCacheRec
struct FT_ServiceDescRec_ FT_ServiceDescRec
struct FT_ServiceCacheRec_ * FT_ServiceCache
const FT_ServiceDescRec * FT_ServiceDesc
Definition: ftserv.h:157
ft_service_list_lookup(FT_ServiceDesc service_descriptors, const char *service_id)
Definition: ftobjs.c:98
FT_Pointer service_POSTSCRIPT_FONT_NAME
Definition: ftserv.h:886
FT_Pointer service_METRICS_VARIATIONS
Definition: ftserv.h:888
FT_Pointer service_WINFNT
Definition: ftserv.h:891
FT_Pointer service_MULTI_MASTERS
Definition: ftserv.h:887
FT_Pointer service_PFR_METRICS
Definition: ftserv.h:890
FT_Pointer service_GLYPH_DICT
Definition: ftserv.h:889
const void * serv_data
Definition: ftserv.h:153
const char * serv_id
Definition: ftserv.h:152