ReactOS 0.4.16-dev-2358-g0df3463
ftserv.h
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * ftserv.h
4 *
5 * The FreeType services (specification only).
6 *
7 * Copyright (C) 2003-2020 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 in
25 * C it is possible that function pointers might be implemented differently
26 * than data pointers (e.g. 48 bits instead of 32).
27 *
28 */
29
30
31#ifndef FTSERV_H_
32#define FTSERV_H_
33
34#include "compiler-macros.h"
35
37
38 /**************************************************************************
39 *
40 * @macro:
41 * FT_FACE_FIND_SERVICE
42 *
43 * @description:
44 * This macro is used to look up a service from a face's driver module.
45 *
46 * @input:
47 * face ::
48 * The source face handle.
49 *
50 * id ::
51 * A string describing the service as defined in the service's header
52 * files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
53 * 'multi-masters'). It is automatically prefixed with
54 * `FT_SERVICE_ID_`.
55 *
56 * @output:
57 * ptr ::
58 * A variable that receives the service pointer. Will be `NULL` if not
59 * found.
60 */
61#ifdef __cplusplus
62
63#define FT_FACE_FIND_SERVICE( face, ptr, id ) \
64 FT_BEGIN_STMNT \
65 FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
66 FT_Pointer _tmp_ = NULL; \
67 FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \
68 \
69 \
70 if ( module->clazz->get_interface ) \
71 _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
72 *_pptr_ = _tmp_; \
73 FT_END_STMNT
74
75#else /* !C++ */
76
77#define FT_FACE_FIND_SERVICE( face, ptr, id ) \
78 FT_BEGIN_STMNT \
79 FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
80 FT_Pointer _tmp_ = NULL; \
81 \
82 if ( module->clazz->get_interface ) \
83 _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
84 ptr = _tmp_; \
85 FT_END_STMNT
86
87#endif /* !C++ */
88
89
90 /**************************************************************************
91 *
92 * @macro:
93 * FT_FACE_FIND_GLOBAL_SERVICE
94 *
95 * @description:
96 * This macro is used to look up a service from all modules.
97 *
98 * @input:
99 * face ::
100 * The source face handle.
101 *
102 * id ::
103 * A string describing the service as defined in the service's header
104 * files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to
105 * 'multi-masters'). It is automatically prefixed with
106 * `FT_SERVICE_ID_`.
107 *
108 * @output:
109 * ptr ::
110 * A variable that receives the service pointer. Will be `NULL` if not
111 * found.
112 */
113#ifdef __cplusplus
114
115#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \
116 FT_BEGIN_STMNT \
117 FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
118 FT_Pointer _tmp_; \
119 FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \
120 \
121 \
122 _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
123 *_pptr_ = _tmp_; \
124 FT_END_STMNT
125
126#else /* !C++ */
127
128#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \
129 FT_BEGIN_STMNT \
130 FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
131 FT_Pointer _tmp_; \
132 \
133 \
134 _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
135 ptr = _tmp_; \
136 FT_END_STMNT
137
138#endif /* !C++ */
139
140
141 /*************************************************************************/
142 /*************************************************************************/
143 /***** *****/
144 /***** S E R V I C E D E S C R I P T O R S *****/
145 /***** *****/
146 /*************************************************************************/
147 /*************************************************************************/
148
149 /*
150 * The following structure is used to _describe_ a given service to the
151 * library. This is useful to build simple static service lists.
152 */
153 typedef struct FT_ServiceDescRec_
154 {
155 const char* serv_id; /* service name */
156 const void* serv_data; /* service pointer/data */
157
159
161
162
163 /**************************************************************************
164 *
165 * @macro:
166 * FT_DEFINE_SERVICEDESCREC1
167 * FT_DEFINE_SERVICEDESCREC2
168 * FT_DEFINE_SERVICEDESCREC3
169 * FT_DEFINE_SERVICEDESCREC4
170 * FT_DEFINE_SERVICEDESCREC5
171 * FT_DEFINE_SERVICEDESCREC6
172 * FT_DEFINE_SERVICEDESCREC7
173 * FT_DEFINE_SERVICEDESCREC8
174 * FT_DEFINE_SERVICEDESCREC9
175 * FT_DEFINE_SERVICEDESCREC10
176 *
177 * @description:
178 * Used to initialize an array of FT_ServiceDescRec structures.
179 *
180 * The array will be allocated in the global scope (or the scope where
181 * the macro is used).
182 */
183#define FT_DEFINE_SERVICEDESCREC1( class_, \
184 serv_id_1, serv_data_1 ) \
185 static const FT_ServiceDescRec class_[] = \
186 { \
187 { serv_id_1, serv_data_1 }, \
188 { NULL, NULL } \
189 };
190
191#define FT_DEFINE_SERVICEDESCREC2( class_, \
192 serv_id_1, serv_data_1, \
193 serv_id_2, serv_data_2 ) \
194 static const FT_ServiceDescRec class_[] = \
195 { \
196 { serv_id_1, serv_data_1 }, \
197 { serv_id_2, serv_data_2 }, \
198 { NULL, NULL } \
199 };
200
201#define FT_DEFINE_SERVICEDESCREC3( class_, \
202 serv_id_1, serv_data_1, \
203 serv_id_2, serv_data_2, \
204 serv_id_3, serv_data_3 ) \
205 static const FT_ServiceDescRec class_[] = \
206 { \
207 { serv_id_1, serv_data_1 }, \
208 { serv_id_2, serv_data_2 }, \
209 { serv_id_3, serv_data_3 }, \
210 { NULL, NULL } \
211 };
212
213#define FT_DEFINE_SERVICEDESCREC4( class_, \
214 serv_id_1, serv_data_1, \
215 serv_id_2, serv_data_2, \
216 serv_id_3, serv_data_3, \
217 serv_id_4, serv_data_4 ) \
218 static const FT_ServiceDescRec class_[] = \
219 { \
220 { serv_id_1, serv_data_1 }, \
221 { serv_id_2, serv_data_2 }, \
222 { serv_id_3, serv_data_3 }, \
223 { serv_id_4, serv_data_4 }, \
224 { NULL, NULL } \
225 };
226
227#define FT_DEFINE_SERVICEDESCREC5( class_, \
228 serv_id_1, serv_data_1, \
229 serv_id_2, serv_data_2, \
230 serv_id_3, serv_data_3, \
231 serv_id_4, serv_data_4, \
232 serv_id_5, serv_data_5 ) \
233 static const FT_ServiceDescRec class_[] = \
234 { \
235 { serv_id_1, serv_data_1 }, \
236 { serv_id_2, serv_data_2 }, \
237 { serv_id_3, serv_data_3 }, \
238 { serv_id_4, serv_data_4 }, \
239 { serv_id_5, serv_data_5 }, \
240 { NULL, NULL } \
241 };
242
243#define FT_DEFINE_SERVICEDESCREC6( class_, \
244 serv_id_1, serv_data_1, \
245 serv_id_2, serv_data_2, \
246 serv_id_3, serv_data_3, \
247 serv_id_4, serv_data_4, \
248 serv_id_5, serv_data_5, \
249 serv_id_6, serv_data_6 ) \
250 static const FT_ServiceDescRec class_[] = \
251 { \
252 { serv_id_1, serv_data_1 }, \
253 { serv_id_2, serv_data_2 }, \
254 { serv_id_3, serv_data_3 }, \
255 { serv_id_4, serv_data_4 }, \
256 { serv_id_5, serv_data_5 }, \
257 { serv_id_6, serv_data_6 }, \
258 { NULL, NULL } \
259 };
260
261#define FT_DEFINE_SERVICEDESCREC7( class_, \
262 serv_id_1, serv_data_1, \
263 serv_id_2, serv_data_2, \
264 serv_id_3, serv_data_3, \
265 serv_id_4, serv_data_4, \
266 serv_id_5, serv_data_5, \
267 serv_id_6, serv_data_6, \
268 serv_id_7, serv_data_7 ) \
269 static const FT_ServiceDescRec class_[] = \
270 { \
271 { serv_id_1, serv_data_1 }, \
272 { serv_id_2, serv_data_2 }, \
273 { serv_id_3, serv_data_3 }, \
274 { serv_id_4, serv_data_4 }, \
275 { serv_id_5, serv_data_5 }, \
276 { serv_id_6, serv_data_6 }, \
277 { serv_id_7, serv_data_7 }, \
278 { NULL, NULL } \
279 };
280
281#define FT_DEFINE_SERVICEDESCREC8( class_, \
282 serv_id_1, serv_data_1, \
283 serv_id_2, serv_data_2, \
284 serv_id_3, serv_data_3, \
285 serv_id_4, serv_data_4, \
286 serv_id_5, serv_data_5, \
287 serv_id_6, serv_data_6, \
288 serv_id_7, serv_data_7, \
289 serv_id_8, serv_data_8 ) \
290 static const FT_ServiceDescRec class_[] = \
291 { \
292 { serv_id_1, serv_data_1 }, \
293 { serv_id_2, serv_data_2 }, \
294 { serv_id_3, serv_data_3 }, \
295 { serv_id_4, serv_data_4 }, \
296 { serv_id_5, serv_data_5 }, \
297 { serv_id_6, serv_data_6 }, \
298 { serv_id_7, serv_data_7 }, \
299 { serv_id_8, serv_data_8 }, \
300 { NULL, NULL } \
301 };
302
303#define FT_DEFINE_SERVICEDESCREC9( class_, \
304 serv_id_1, serv_data_1, \
305 serv_id_2, serv_data_2, \
306 serv_id_3, serv_data_3, \
307 serv_id_4, serv_data_4, \
308 serv_id_5, serv_data_5, \
309 serv_id_6, serv_data_6, \
310 serv_id_7, serv_data_7, \
311 serv_id_8, serv_data_8, \
312 serv_id_9, serv_data_9 ) \
313 static const FT_ServiceDescRec class_[] = \
314 { \
315 { serv_id_1, serv_data_1 }, \
316 { serv_id_2, serv_data_2 }, \
317 { serv_id_3, serv_data_3 }, \
318 { serv_id_4, serv_data_4 }, \
319 { serv_id_5, serv_data_5 }, \
320 { serv_id_6, serv_data_6 }, \
321 { serv_id_7, serv_data_7 }, \
322 { serv_id_8, serv_data_8 }, \
323 { serv_id_9, serv_data_9 }, \
324 { NULL, NULL } \
325 };
326
327#define FT_DEFINE_SERVICEDESCREC10( class_, \
328 serv_id_1, serv_data_1, \
329 serv_id_2, serv_data_2, \
330 serv_id_3, serv_data_3, \
331 serv_id_4, serv_data_4, \
332 serv_id_5, serv_data_5, \
333 serv_id_6, serv_data_6, \
334 serv_id_7, serv_data_7, \
335 serv_id_8, serv_data_8, \
336 serv_id_9, serv_data_9, \
337 serv_id_10, serv_data_10 ) \
338 static const FT_ServiceDescRec class_[] = \
339 { \
340 { serv_id_1, serv_data_1 }, \
341 { serv_id_2, serv_data_2 }, \
342 { serv_id_3, serv_data_3 }, \
343 { serv_id_4, serv_data_4 }, \
344 { serv_id_5, serv_data_5 }, \
345 { serv_id_6, serv_data_6 }, \
346 { serv_id_7, serv_data_7 }, \
347 { serv_id_8, serv_data_8 }, \
348 { serv_id_9, serv_data_9 }, \
349 { serv_id_10, serv_data_10 }, \
350 { NULL, NULL } \
351 };
352
353
354 /*
355 * Parse a list of FT_ServiceDescRec descriptors and look for a specific
356 * service by ID. Note that the last element in the array must be { NULL,
357 * NULL }, and that the function should return NULL if the service isn't
358 * available.
359 *
360 * This function can be used by modules to implement their `get_service'
361 * method.
362 */
364 ft_service_list_lookup( FT_ServiceDesc service_descriptors,
365 const char* service_id );
366
367
368 /*************************************************************************/
369 /*************************************************************************/
370 /***** *****/
371 /***** S E R V I C E S C A C H E *****/
372 /***** *****/
373 /*************************************************************************/
374 /*************************************************************************/
375
376 /*
377 * This structure is used to store a cache for several frequently used
378 * services. It is the type of `face->internal->services'. You should
379 * only use FT_FACE_LOOKUP_SERVICE to access it.
380 *
381 * All fields should have the type FT_Pointer to relax compilation
382 * dependencies. We assume the developer isn't completely stupid.
383 *
384 * Each field must be named `service_XXXX' where `XXX' corresponds to the
385 * correct FT_SERVICE_ID_XXXX macro. See the definition of
386 * FT_FACE_LOOKUP_SERVICE below how this is implemented.
387 *
388 */
389 typedef struct FT_ServiceCacheRec_
390 {
397
399
400
401 /*
402 * A magic number used within the services cache.
403 */
404
405 /* ensure that value `1' has the same width as a pointer */
406#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)~(FT_PtrDist)1)
407
408
409 /**************************************************************************
410 *
411 * @macro:
412 * FT_FACE_LOOKUP_SERVICE
413 *
414 * @description:
415 * This macro is used to look up a service from a face's driver module
416 * using its cache.
417 *
418 * @input:
419 * face ::
420 * The source face handle containing the cache.
421 *
422 * field ::
423 * The field name in the cache.
424 *
425 * id ::
426 * The service ID.
427 *
428 * @output:
429 * ptr ::
430 * A variable receiving the service data. `NULL` if not available.
431 */
432#ifdef __cplusplus
433
434#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \
435 FT_BEGIN_STMNT \
436 FT_Pointer svc; \
437 FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \
438 \
439 \
440 svc = FT_FACE( face )->internal->services. service_ ## id; \
441 if ( svc == FT_SERVICE_UNAVAILABLE ) \
442 svc = NULL; \
443 else if ( svc == NULL ) \
444 { \
445 FT_FACE_FIND_SERVICE( face, svc, id ); \
446 \
447 FT_FACE( face )->internal->services. service_ ## id = \
448 (FT_Pointer)( svc != NULL ? svc \
449 : FT_SERVICE_UNAVAILABLE ); \
450 } \
451 *Pptr = svc; \
452 FT_END_STMNT
453
454#else /* !C++ */
455
456#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \
457 FT_BEGIN_STMNT \
458 FT_Pointer svc; \
459 \
460 \
461 svc = FT_FACE( face )->internal->services. service_ ## id; \
462 if ( svc == FT_SERVICE_UNAVAILABLE ) \
463 svc = NULL; \
464 else if ( svc == NULL ) \
465 { \
466 FT_FACE_FIND_SERVICE( face, svc, id ); \
467 \
468 FT_FACE( face )->internal->services. service_ ## id = \
469 (FT_Pointer)( svc != NULL ? svc \
470 : FT_SERVICE_UNAVAILABLE ); \
471 } \
472 ptr = svc; \
473 FT_END_STMNT
474
475#endif /* !C++ */
476
477 /*
478 * A macro used to define new service structure types.
479 */
480
481#define FT_DEFINE_SERVICE( name ) \
482 typedef struct FT_Service_ ## name ## Rec_ \
483 FT_Service_ ## name ## Rec ; \
484 typedef struct FT_Service_ ## name ## Rec_ \
485 const * FT_Service_ ## name ; \
486 struct FT_Service_ ## name ## Rec_
487
488 /* */
489
491
492#endif /* FTSERV_H_ */
493
494
495/* END */
#define FT_BASE(x)
#define FT_END_HEADER
Definition: ftheader.h:57
#define FT_BEGIN_HEADER
Definition: ftheader.h:37
struct FT_ServiceCacheRec_ FT_ServiceCacheRec
struct FT_ServiceDescRec_ FT_ServiceDescRec
struct FT_ServiceCacheRec_ * FT_ServiceCache
const FT_ServiceDescRec * FT_ServiceDesc
Definition: ftserv.h:160
ft_service_list_lookup(FT_ServiceDesc service_descriptors, const char *service_id)
Definition: ftobjs.c:109
FT_Pointer service_POSTSCRIPT_FONT_NAME
Definition: ftserv.h:391
FT_Pointer service_METRICS_VARIATIONS
Definition: ftserv.h:393
FT_Pointer service_WINFNT
Definition: ftserv.h:396
FT_Pointer service_MULTI_MASTERS
Definition: ftserv.h:392
FT_Pointer service_PFR_METRICS
Definition: ftserv.h:395
FT_Pointer service_GLYPH_DICT
Definition: ftserv.h:394
const void * serv_data
Definition: ftserv.h:156
const char * serv_id
Definition: ftserv.h:155