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