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