1
0

ftserv.h 44 KB

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