1
/***************************************************************************/
5
/* The FreeType services (specification only). */
7
/* Copyright 2003, 2004, 2005, 2006, 2007 by */
8
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16
/***************************************************************************/
18
/*************************************************************************/
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. */
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). */
28
/*************************************************************************/
37
#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
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 )
47
* FT_FACE_FIND_SERVICE
50
* This macro is used to look up a service from a face's driver module.
54
* The source face handle.
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
64
* A variable that receives the service pointer. Will be NULL
69
#define FT_FACE_FIND_SERVICE( face, ptr, id ) \
71
FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
72
FT_Pointer _tmp_ = NULL; \
73
FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \
76
if ( module->clazz->get_interface ) \
77
_tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
83
#define FT_FACE_FIND_SERVICE( face, ptr, id ) \
85
FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
86
FT_Pointer _tmp_ = NULL; \
88
if ( module->clazz->get_interface ) \
89
_tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \
97
* FT_FACE_FIND_GLOBAL_SERVICE
100
* This macro is used to look up a service from all modules.
104
* The source face handle.
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
114
* A variable that receives the service pointer. Will be NULL
119
#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \
121
FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
123
FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \
126
_tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
132
#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \
134
FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \
138
_tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
145
/*************************************************************************/
146
/*************************************************************************/
148
/***** S E R V I C E D E S C R I P T O R S *****/
150
/*************************************************************************/
151
/*************************************************************************/
154
* The following structure is used to _describe_ a given service
155
* to the library. This is useful to build simple static service lists.
157
typedef struct FT_ServiceDescRec_
159
const char* serv_id; /* service name */
160
const void* serv_data; /* service pointer/data */
164
typedef const FT_ServiceDescRec* FT_ServiceDesc;
166
/*************************************************************************/
169
/* FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6 */
172
/* Used to initialize an array of FT_ServiceDescRec structs. */
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. */
179
/* These functions should be manyally called from the pic_init and */
180
/* pic_free functions of your module (see FT_DEFINE_MODULE) */
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 */
186
#ifndef FT_CONFIG_OPTION_PIC
188
#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \
189
static const FT_ServiceDescRec class_[] = \
191
{serv_id_1, serv_data_1}, \
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_[] = \
198
{serv_id_1, serv_data_1}, \
199
{serv_id_2, serv_data_2}, \
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_[] = \
206
{serv_id_1, serv_data_1}, \
207
{serv_id_2, serv_data_2}, \
208
{serv_id_3, serv_data_3}, \
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_[] = \
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}, \
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_[] = \
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}, \
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_[] = \
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}, \
249
#else /* FT_CONFIG_OPTION_PIC */
251
#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1) \
253
FT_Destroy_Class_##class_( FT_Library library, \
254
FT_ServiceDescRec* clazz ) \
256
FT_Memory memory = library->memory; \
262
FT_Create_Class_##class_( FT_Library library, \
263
FT_ServiceDescRec** output_class) \
265
FT_ServiceDescRec* clazz; \
267
FT_Memory memory = library->memory; \
269
if ( FT_ALLOC( clazz, sizeof(*clazz)*2 ) ) \
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; \
279
#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1, \
280
serv_id_2, serv_data_2) \
282
FT_Destroy_Class_##class_( FT_Library library, \
283
FT_ServiceDescRec* clazz ) \
285
FT_Memory memory = library->memory; \
291
FT_Create_Class_##class_( FT_Library library, \
292
FT_ServiceDescRec** output_class) \
294
FT_ServiceDescRec* clazz; \
296
FT_Memory memory = library->memory; \
298
if ( FT_ALLOC( clazz, sizeof(*clazz)*3 ) ) \
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; \
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) \
313
FT_Destroy_Class_##class_( FT_Library library, \
314
FT_ServiceDescRec* clazz ) \
316
FT_Memory memory = library->memory; \
322
FT_Create_Class_##class_( FT_Library library, \
323
FT_ServiceDescRec** output_class) \
325
FT_ServiceDescRec* clazz; \
327
FT_Memory memory = library->memory; \
329
if ( FT_ALLOC( clazz, sizeof(*clazz)*4 ) ) \
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; \
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) \
347
FT_Destroy_Class_##class_( FT_Library library, \
348
FT_ServiceDescRec* clazz ) \
350
FT_Memory memory = library->memory; \
356
FT_Create_Class_##class_( FT_Library library, \
357
FT_ServiceDescRec** output_class) \
359
FT_ServiceDescRec* clazz; \
361
FT_Memory memory = library->memory; \
363
if ( FT_ALLOC( clazz, sizeof(*clazz)*5 ) ) \
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; \
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) \
383
FT_Destroy_Class_##class_( FT_Library library, \
384
FT_ServiceDescRec* clazz ) \
386
FT_Memory memory = library->memory; \
392
FT_Create_Class_##class_( FT_Library library, \
393
FT_ServiceDescRec** output_class) \
395
FT_ServiceDescRec* clazz; \
397
FT_Memory memory = library->memory; \
399
if ( FT_ALLOC( clazz, sizeof(*clazz)*6 ) ) \
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; \
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) \
422
FT_Destroy_Class_##class_( FT_Library library, \
423
FT_ServiceDescRec* clazz ) \
425
FT_Memory memory = library->memory; \
431
FT_Create_Class_##class_( FT_Library library, \
432
FT_ServiceDescRec** output_class) \
434
FT_ServiceDescRec* clazz; \
436
FT_Memory memory = library->memory; \
438
if ( FT_ALLOC( clazz, sizeof(*clazz)*7 ) ) \
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; \
457
#endif /* FT_CONFIG_OPTION_PIC */
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.
465
* This function can be used by modules to implement their
466
* `get_service' method.
468
FT_BASE( FT_Pointer )
469
ft_service_list_lookup( FT_ServiceDesc service_descriptors,
470
const char* service_id );
473
/*************************************************************************/
474
/*************************************************************************/
476
/***** S E R V I C E S C A C H E *****/
478
/*************************************************************************/
479
/*************************************************************************/
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.
486
* All fields should have the type FT_Pointer to relax compilation
487
* dependencies. We assume the developer isn't completely stupid.
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.
494
typedef struct FT_ServiceCacheRec_
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;
502
} FT_ServiceCacheRec, *FT_ServiceCache;
506
* A magic number used within the services cache.
508
#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)-2) /* magic number */
513
* FT_FACE_LOOKUP_SERVICE
516
* This macro is used to lookup a service from a face's driver module
521
* The source face handle containing the cache.
524
* The field name in the cache.
531
* A variable receiving the service data. NULL if not available.
535
#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \
538
FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \
541
svc = FT_FACE( face )->internal->services. service_ ## id; \
542
if ( svc == FT_SERVICE_UNAVAILABLE ) \
544
else if ( svc == NULL ) \
546
FT_FACE_FIND_SERVICE( face, svc, id ); \
548
FT_FACE( face )->internal->services. service_ ## id = \
549
(FT_Pointer)( svc != NULL ? svc \
550
: FT_SERVICE_UNAVAILABLE ); \
557
#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \
562
svc = FT_FACE( face )->internal->services. service_ ## id; \
563
if ( svc == FT_SERVICE_UNAVAILABLE ) \
565
else if ( svc == NULL ) \
567
FT_FACE_FIND_SERVICE( face, svc, id ); \
569
FT_FACE( face )->internal->services. service_ ## id = \
570
(FT_Pointer)( svc != NULL ? svc \
571
: FT_SERVICE_UNAVAILABLE ); \
579
* A macro used to define new service structure types.
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_
592
* The header files containing the services.
595
#define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h>
596
#define FT_SERVICE_CID_H <freetype/internal/services/svcid.h>
597
#define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h>
598
#define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h>
599
#define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h>
600
#define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h>
601
#define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h>
602
#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h>
603
#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h>
604
#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h>
605
#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h>
606
#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h>
607
#define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h>
608
#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h>
609
#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h>
610
#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h>
611
#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h>
617
#endif /* __FTSERV_H__ */