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 */ 764