The BIG graph update
[rrdtool.git] / libraries / freetype-2.0.5 / ftextend.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftextend.c                                                             */
4 /*                                                                         */
5 /*    FreeType extensions implementation (body).                           */
6 /*                                                                         */
7 /*  Copyright 1996-2001 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   /*  This is an updated version of the extension component, now located   */
21   /*  in the main library's source directory.  It allows the dynamic       */
22   /*  registration/use of various face object extensions through a simple  */
23   /*  API.                                                                 */
24   /*                                                                       */
25   /*************************************************************************/
26
27
28 #include <ft2build.h>
29 #include FT_INTERNAL_EXTEND_H
30 #include FT_INTERNAL_DEBUG_H
31
32
33   /*************************************************************************/
34   /*                                                                       */
35   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
36   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
37   /* messages during execution.                                            */
38   /*                                                                       */
39 #undef  FT_COMPONENT
40 #define FT_COMPONENT  trace_extend
41
42
43   typedef struct  FT_Extension_Registry_
44   {
45     FT_Int              num_extensions;
46     FT_Long             cur_offset;
47     FT_Extension_Class  classes[FT_MAX_EXTENSIONS];
48
49   } FT_Extension_Registry;
50
51
52   /*************************************************************************/
53   /*                                                                       */
54   /* <Function>                                                            */
55   /*    FT_Init_Extensions                                                 */
56   /*                                                                       */
57   /* <Description>                                                         */
58   /*    Initializes the extension component.                               */
59   /*                                                                       */
60   /* <InOut>                                                               */
61   /*    driver :: A handle to the driver object.                           */
62   /*                                                                       */
63   /* <Return>                                                              */
64   /*    FreeType error code.  0 means success.                             */
65   /*                                                                       */
66   FT_LOCAL_DEF FT_Error
67   FT_Init_Extensions( FT_Driver  driver )
68   {
69     FT_Error                error;
70     FT_Memory               memory;
71     FT_Extension_Registry*  registry;
72
73
74     memory = driver->root.library->memory;
75     if ( ALLOC( registry, sizeof ( *registry ) ) )
76       return error;
77
78     registry->num_extensions = 0;
79     registry->cur_offset     = 0;
80     driver->extensions       = registry;
81
82     FT_TRACE2(( "FT_Init_Extensions: success\n" ));
83
84     return FT_Err_Ok;
85   }
86
87
88   /*************************************************************************/
89   /*                                                                       */
90   /* <Function>                                                            */
91   /*    FT_Done_Extensions                                                 */
92   /*                                                                       */
93   /* <Description>                                                         */
94   /*    Finalizes the extension component.                                 */
95   /*                                                                       */
96   /* <InOut>                                                               */
97   /*    driver :: A handle to the driver object.                           */
98   /*                                                                       */
99   /* <Return>                                                              */
100   /*    FreeType error code.  0 means success.                             */
101   /*                                                                       */
102   FT_LOCAL_DEF FT_Error
103   FT_Done_Extensions( FT_Driver  driver )
104   {
105     FT_Memory  memory = driver->root.memory;
106
107
108     FREE( driver->extensions );
109     return FT_Err_Ok;
110   }
111
112
113   /* documentation is in ftextend.h */
114
115   FT_EXPORT_DEF( FT_Error )
116   FT_Register_Extension( FT_Driver            driver,
117                          FT_Extension_Class*  clazz )
118   {
119     FT_Extension_Registry*  registry;
120
121
122     if ( !driver )
123       return FT_Err_Invalid_Driver_Handle;
124
125     if ( !clazz )
126       return FT_Err_Invalid_Argument;
127
128     registry = (FT_Extension_Registry*)driver->extensions;
129     if ( registry )
130     {
131       FT_Int               n   = registry->num_extensions;
132       FT_Extension_Class*  cur = registry->classes + n;
133
134
135       if ( n >= FT_MAX_EXTENSIONS )
136         return FT_Err_Too_Many_Extensions;
137
138       *cur = *clazz;
139
140       cur->offset  = registry->cur_offset;
141
142       registry->num_extensions++;
143       registry->cur_offset +=
144         ( cur->size + FT_ALIGNMENT - 1 ) & -FT_ALIGNMENT;
145
146       FT_TRACE1(( "FT_Register_Extension: `%s' successfully registered\n",
147                   cur->id ));
148     }
149
150     return FT_Err_Ok;
151   }
152
153
154   /* documentation is in ftextend.h */
155
156   FT_EXPORT_DEF( void* )
157   FT_Get_Extension( FT_Face      face,
158                     const char*  extension_id,
159                     void**       extension_interface )
160   {
161     FT_Extension_Registry*  registry;
162
163
164     if ( !face || !extension_id || !extension_interface )
165       return 0;
166
167     registry = (FT_Extension_Registry*)face->driver->extensions;
168     if ( registry && face->extensions )
169     {
170       FT_Extension_Class*  cur   = registry->classes;
171       FT_Extension_Class*  limit = cur + registry->num_extensions;
172
173
174       for ( ; cur < limit; cur++ )
175         if ( strcmp( cur->id, extension_id ) == 0 )
176         {
177           *extension_interface = cur->interface;
178
179           FT_TRACE1(( "FT_Get_Extension: got `%s'\n", extension_id ));
180
181           return (void*)((char*)face->extensions + cur->offset);
182         }
183     }
184
185     /* could not find the extension id */
186
187     FT_ERROR(( "FT_Get_Extension: couldn't find `%s'\n", extension_id ));
188
189     *extension_interface = 0;
190
191     return 0;
192   }
193
194
195   /*************************************************************************/
196   /*                                                                       */
197   /* <Function>                                                            */
198   /*    FT_Destroy_Extensions                                              */
199   /*                                                                       */
200   /* <Description>                                                         */
201   /*    Destroys all extensions within a face object.                      */
202   /*                                                                       */
203   /* <InOut>                                                               */
204   /*    face :: A handle to the face object.                               */
205   /*                                                                       */
206   /* <Return>                                                              */
207   /*    FreeType error code.  0 means success.                             */
208   /*                                                                       */
209   /* <Note>                                                                */
210   /*    Called by the face object destructor.                              */
211   /*                                                                       */
212   FT_LOCAL_DEF FT_Error
213   FT_Destroy_Extensions( FT_Face  face )
214   {
215     FT_Extension_Registry*  registry;
216     FT_Memory               memory;
217
218
219     registry = (FT_Extension_Registry*)face->driver->extensions;
220     if ( registry && face->extensions )
221     {
222       FT_Extension_Class*  cur   = registry->classes;
223       FT_Extension_Class*  limit = cur + registry->num_extensions;
224
225
226       for ( ; cur < limit; cur++ )
227       {
228         char*  ext = (char*)face->extensions + cur->offset;
229
230         if ( cur->finalize )
231           cur->finalize( ext, face );
232       }
233
234       memory = face->driver->root.memory;
235       FREE( face->extensions );
236     }
237
238     return FT_Err_Ok;
239   }
240
241
242   /*************************************************************************/
243   /*                                                                       */
244   /* <Function>                                                            */
245   /*    FT_Create_Extensions                                               */
246   /*                                                                       */
247   /* <Description>                                                         */
248   /*    Creates an extension object within a face object for all           */
249   /*    registered extensions.                                             */
250   /*                                                                       */
251   /* <InOut>                                                               */
252   /*    face :: A handle to the face object.                               */
253   /*                                                                       */
254   /* <Return>                                                              */
255   /*    FreeType error code.  0 means success.                             */
256   /*                                                                       */
257   /* <Note>                                                                */
258   /*    Called by the face object constructor.                             */
259   /*                                                                       */
260   FT_LOCAL_DEF FT_Error
261   FT_Create_Extensions( FT_Face  face )
262   {
263     FT_Extension_Registry*  registry;
264     FT_Memory               memory;
265     FT_Error                error;
266
267
268     face->extensions = 0;
269
270     /* load extensions registry; exit successfully if none is there */
271
272     registry = (FT_Extension_Registry*)face->driver->extensions;
273     if ( !registry )
274       return FT_Err_Ok;
275
276     memory = face->driver->root.memory;
277     if ( ALLOC( face->extensions, registry->cur_offset ) )
278       return error;
279
280     {
281       FT_Extension_Class*  cur   = registry->classes;
282       FT_Extension_Class*  limit = cur + registry->num_extensions;
283
284
285       for ( ; cur < limit; cur++ )
286       {
287         char*  ext = (char*)face->extensions + cur->offset;
288
289         if ( cur->init )
290         {
291           error = cur->init( ext, face );
292           if ( error )
293             break;
294         }
295       }
296     }
297
298     return error;
299   }
300
301
302 /* END */