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