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