ftobjs.c 99.7 KB
Newer Older
David Turner's avatar
David Turner committed
1
2
3
4
/***************************************************************************/
/*                                                                         */
/*  ftobjs.c                                                               */
/*                                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
5
/*    The FreeType private base classes (base).                            */
David Turner's avatar
David Turner committed
6
/*                                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
7
/*  Copyright 1996-2000 by                                                 */
Werner Lemberg's avatar
   
Werner Lemberg committed
8
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
David Turner's avatar
David Turner committed
9
/*                                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
10
11
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
David Turner's avatar
David Turner committed
12
13
14
15
16
17
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/***************************************************************************/

Werner Lemberg's avatar
   
Werner Lemberg committed
18

19
20
21
22
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/ftlist.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
David Turner's avatar
David Turner committed
23

24
#include <freetype/tttables.h>
Werner Lemberg's avatar
   
Werner Lemberg committed
25

Werner Lemberg's avatar
   
Werner Lemberg committed
26

David Turner's avatar
David Turner committed
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  /*************************************************************************/
  /*************************************************************************/
  /*************************************************************************/
  /****                                                                 ****/
  /****                                                                 ****/
  /****                           M E M O R Y                           ****/
  /****                                                                 ****/
  /****                                                                 ****/
  /*************************************************************************/
  /*************************************************************************/
  /*************************************************************************/

  /*************************************************************************/
  /*                                                                       */
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
Werner Lemberg's avatar
   
Werner Lemberg committed
42
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
David Turner's avatar
David Turner committed
43
44
45
46
47
48
49
50
51
52
53
54
55
  /* messages during execution.                                            */
  /*                                                                       */
#undef  FT_COMPONENT
#define FT_COMPONENT  trace_memory


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_Alloc                                                           */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Allocates a new block of memory.  The returned area is always      */
Werner Lemberg's avatar
   
Werner Lemberg committed
56
  /*    zero-filled; this is a strong convention in many FreeType parts.   */
David Turner's avatar
David Turner committed
57
58
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
59
60
  /*    memory :: A handle to a given `memory object' which handles        */
  /*              allocation.                                              */
David Turner's avatar
David Turner committed
61
62
63
64
65
66
67
68
69
70
  /*                                                                       */
  /*    size   :: The size in bytes of the block to allocate.              */
  /*                                                                       */
  /* <Output>                                                              */
  /*    P      :: A pointer to the fresh new block.  It should be set to   */
  /*              NULL if `size' is 0, or in case of error.                */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
71
72
73
  BASE_FUNC( FT_Error )  FT_Alloc( FT_Memory  memory,
                                   FT_Long    size,
                                   void**     P )
David Turner's avatar
David Turner committed
74
75
76
  {
    FT_Assert( P != 0 );

Werner Lemberg's avatar
   
Werner Lemberg committed
77
    if ( size > 0 )
David Turner's avatar
David Turner committed
78
79
    {
      *P = memory->alloc( memory, size );
Werner Lemberg's avatar
   
Werner Lemberg committed
80
      if ( !*P )
David Turner's avatar
David Turner committed
81
      {
Werner Lemberg's avatar
   
Werner Lemberg committed
82
        FT_ERROR(( "FT_Alloc:" ));
Werner Lemberg's avatar
   
Werner Lemberg committed
83
        FT_ERROR(( " Out of memory? (%ld requested)\n",
David Turner's avatar
David Turner committed
84
85
86
87
88
89
90
91
92
                   size ));

        return FT_Err_Out_Of_Memory;
      }
      MEM_Set( *P, 0, size );
    }
    else
      *P = NULL;

Werner Lemberg's avatar
   
Werner Lemberg committed
93
94
    FT_TRACE7(( "FT_Alloc:" ));
    FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n",
95
                size, *P, P ));
David Turner's avatar
David Turner committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

    return FT_Err_Ok;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_Realloc                                                         */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Reallocates a block of memory pointed to by `*P' to `Size' bytes   */
  /*    from the heap, possibly changing `*P'.                             */
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
111
112
  /*    memory  :: A handle to a given `memory object' which handles       */
  /*               reallocation.                                           */
David Turner's avatar
David Turner committed
113
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
114
  /*    current :: The current block size in bytes.                        */
Werner Lemberg's avatar
   
Werner Lemberg committed
115
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
116
  /*    size    :: The new block size in bytes.                            */
David Turner's avatar
David Turner committed
117
118
  /*                                                                       */
  /* <InOut>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
119
120
  /*    P       :: A pointer to the fresh new block.  It should be set to  */
  /*               NULL if `size' is 0, or in case of error.               */
David Turner's avatar
David Turner committed
121
122
123
124
125
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  /* <Note>                                                                */
Werner Lemberg's avatar
   
Werner Lemberg committed
126
  /*    All callers of FT_Realloc() _must_ provide the current block size  */
David Turner's avatar
David Turner committed
127
128
  /*    as well as the new one.                                            */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
129
130
131
132
  BASE_FUNC( FT_Error )  FT_Realloc( FT_Memory  memory,
                                     FT_Long    current,
                                     FT_Long    size,
                                     void**     P )
David Turner's avatar
David Turner committed
133
134
135
  {
    void*  Q;

Werner Lemberg's avatar
   
Werner Lemberg committed
136

David Turner's avatar
David Turner committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150
    FT_Assert( P != 0 );

    /* if the original pointer is NULL, call FT_Alloc() */
    if ( !*P )
      return FT_Alloc( memory, size, P );

    /* if the new block if zero-sized, clear the current one */
    if ( size <= 0 )
    {
      FT_Free( memory, P );
      return FT_Err_Ok;
    }

    Q = memory->realloc( memory, current, size, *P );
Werner Lemberg's avatar
   
Werner Lemberg committed
151
152
    if ( !Q )
      goto Fail;
David Turner's avatar
David Turner committed
153
154
155
156
157

    *P = Q;
    return FT_Err_Ok;

  Fail:
Werner Lemberg's avatar
   
Werner Lemberg committed
158
    FT_ERROR(( "FT_Realloc:" ));
Werner Lemberg's avatar
   
Werner Lemberg committed
159
    FT_ERROR(( " Failed (current %ld, requested %ld)\n",
David Turner's avatar
David Turner committed
160
161
162
163
164
165
166
167
168
169
170
171
172
173
               current, size ));
    return FT_Err_Out_Of_Memory;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_Free                                                            */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Releases a given block of memory allocated through FT_Alloc().     */
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
174
175
  /*    memory :: A handle to a given `memory object' which handles        */
  /*              memory deallocation                                      */
David Turner's avatar
David Turner committed
176
177
178
179
180
181
182
183
184
185
186
187
  /*                                                                       */
  /*    P      :: This is the _address_ of a _pointer_ which points to the */
  /*              allocated block.  It is always set to NULL on exit.      */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  /* <Note>                                                                */
  /*    If P or *P are NULL, this function should return successfully.     */
  /*    This is a strong convention within all of FreeType and its         */
  /*    drivers.                                                           */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
188
189
  BASE_FUNC( void )  FT_Free( FT_Memory  memory,
                              void**     P )
David Turner's avatar
David Turner committed
190
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
191
192
    FT_TRACE7(( "FT_Free:" ));
    FT_TRACE7(( " Freeing block 0x%08p, ref 0x%08p\n",
Werner Lemberg's avatar
   
Werner Lemberg committed
193
                P, P ? *P : (void*)0 ));
David Turner's avatar
David Turner committed
194
195

    FT_Assert( P != 0 );
Werner Lemberg's avatar
   
Werner Lemberg committed
196

David Turner's avatar
David Turner committed
197
198
199
200
201
202
203
    if ( *P )
    {
      memory->free( memory, *P );
      *P = 0;
    }
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
204

Werner Lemberg's avatar
   
Werner Lemberg committed
205
206
207
208
209
210
211
212
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    ft_new_input_stream                                                */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Creates a new input stream object from an FT_Open_Args structure.  */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
213
214
  /* <Note>                                                                */
  /*    The function expects a valid `astream' parameter.                  */
215
  static
Werner Lemberg's avatar
   
Werner Lemberg committed
216
217
  FT_Error  ft_new_input_stream( FT_Library     library,
                                 FT_Open_Args*  args,
Werner Lemberg's avatar
   
Werner Lemberg committed
218
                                 FT_Stream*     astream )
219
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
220
221
222
223
    FT_Error   error;
    FT_Memory  memory;
    FT_Stream  stream;

Werner Lemberg's avatar
   
Werner Lemberg committed
224

Werner Lemberg's avatar
   
Werner Lemberg committed
225
226
227
228
229
230
    if ( !library )
      return FT_Err_Invalid_Library_Handle;

    if ( !args )
      return FT_Err_Invalid_Argument;

David Turner's avatar
David Turner committed
231
232
    *astream = 0;
    memory   = library->memory;
Werner Lemberg's avatar
   
Werner Lemberg committed
233
    if ( ALLOC( stream, sizeof ( *stream ) ) )
David Turner's avatar
David Turner committed
234
      goto Exit;
235

236
    stream->memory = memory;
237

238
239
    /* now, look at the stream flags */
    if ( args->flags & ft_open_memory )
240
    {
241
242
243
244
245
246
      error = 0;
      FT_New_Memory_Stream( library,
                            args->memory_base,
                            args->memory_size,
                            stream );
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
247
    else if ( args->flags & ft_open_pathname )
248
249
250
251
    {
      error = FT_New_Stream( args->pathname, stream );
      stream->pathname.pointer = args->pathname;
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
252
    else if ( args->flags & ft_open_stream && args->stream )
253
254
255
256
257
258
    {
      *stream        = *(args->stream);
      stream->memory = memory;
    }
    else
      error = FT_Err_Invalid_Argument;
259

Werner Lemberg's avatar
   
Werner Lemberg committed
260
261
    if ( error )
      FREE( stream );
262

263
    *astream = stream;
Werner Lemberg's avatar
   
Werner Lemberg committed
264

David Turner's avatar
David Turner committed
265
  Exit:
266
267
268
269
    return error;
  }


Werner Lemberg's avatar
   
Werner Lemberg committed
270
271
272
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
David Turner's avatar
David Turner committed
273
  /*    FT_Done_Stream                                                     */
Werner Lemberg's avatar
   
Werner Lemberg committed
274
275
276
277
  /*                                                                       */
  /* <Description>                                                         */
  /*    Closes and destroys a stream object.                               */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
278
279
280
281
  /* <Input>                                                               */
  /*    stream :: The stream to be closed and destroyed.                   */
  /*                                                                       */
  FT_EXPORT_FUNC( void )  FT_Done_Stream( FT_Stream  stream )
David Turner's avatar
David Turner committed
282
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
283
    if ( stream && stream->close )
David Turner's avatar
David Turner committed
284
285
286
287
      stream->close( stream );
  }


288
  static
Werner Lemberg's avatar
   
Werner Lemberg committed
289
  void  ft_done_stream( FT_Stream*  astream )
290
291
292
  {
    FT_Stream  stream = *astream;
    FT_Memory  memory = stream->memory;
Werner Lemberg's avatar
   
Werner Lemberg committed
293

Werner Lemberg's avatar
   
Werner Lemberg committed
294

Werner Lemberg's avatar
   
Werner Lemberg committed
295
    if ( stream->close )
296
      stream->close( stream );
297

298
299
300
301
    FREE( stream );
    *astream = 0;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
302

David Turner's avatar
David Turner committed
303
304
305
306
307
  /*************************************************************************/
  /*************************************************************************/
  /*************************************************************************/
  /****                                                                 ****/
  /****                                                                 ****/
Werner Lemberg's avatar
   
Werner Lemberg committed
308
  /****               O B J E C T   M A N A G E M E N T                 ****/
David Turner's avatar
David Turner committed
309
310
311
312
313
314
  /****                                                                 ****/
  /****                                                                 ****/
  /*************************************************************************/
  /*************************************************************************/
  /*************************************************************************/

Werner Lemberg's avatar
   
Werner Lemberg committed
315
316
317
318
319

#undef  FT_COMPONENT
#define FT_COMPONENT  trace_objs


Werner Lemberg's avatar
   
Werner Lemberg committed
320
321
322
323
324
325
326
327
328
329
  /* destructor for sizes list */
  static
  void  destroy_size( FT_Memory  memory,
                      FT_Size    size,
                      FT_Driver  driver )
  {
    /* finalize format-specific stuff */
    driver->interface.done_size( size );
    FREE( size );
  }
David Turner's avatar
David Turner committed
330
331


Werner Lemberg's avatar
   
Werner Lemberg committed
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
  /* destructor for faces list */
  static
  void  destroy_face( FT_Memory  memory,
                      FT_Face    face,
                      FT_Driver  driver )
  {
    /* Discard glyph slots for this face                                */
    /* XXX: Beware!  FT_Done_GlyphSlot() changes the field `face->slot' */
    while ( face->glyph )
      FT_Done_GlyphSlot( face->glyph );

    /* Discard all sizes for this face */
    FT_List_Finalize( &face->sizes_list,
                     (FT_List_Destructor)destroy_size,
                     memory,
                     driver );
    face->size = 0;

    /* finalize format-specific stuff */
    driver->interface.done_face( face );

    /* Now discard client data */
    if ( face->generic.finalizer )
      face->generic.finalizer( face );

357
    /* close the stream for this face */
358
    ft_done_stream( &face->stream );
359

Werner Lemberg's avatar
   
Werner Lemberg committed
360
361
362
    /* get rid of it */
    FREE( face );
  }
David Turner's avatar
David Turner committed
363
364
365
366
367


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
Werner Lemberg's avatar
   
Werner Lemberg committed
368
  /*    Destroy_Driver                                                     */
David Turner's avatar
David Turner committed
369
370
371
372
373
  /*                                                                       */
  /* <Description>                                                         */
  /*    Destroys a given driver object.  This also destroys all child      */
  /*    faces.                                                             */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
374
  /* <InOut>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
375
  /*     driver :: A handle to the target driver object.                   */
David Turner's avatar
David Turner committed
376
377
  /*                                                                       */
  /* <Note>                                                                */
Werner Lemberg's avatar
   
Werner Lemberg committed
378
  /*     The driver _must_ be LOCKED!                                      */
David Turner's avatar
David Turner committed
379
380
  /*                                                                       */
  static
Werner Lemberg's avatar
   
Werner Lemberg committed
381
  void  Destroy_Driver( FT_Driver  driver )
David Turner's avatar
David Turner committed
382
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
383
384
    FT_Memory  memory = driver->memory;

David Turner's avatar
David Turner committed
385
386
387
388
389
390
391
392

    /* now, finalize all faces in the driver list */
    FT_List_Finalize( &driver->faces_list,
                      (FT_List_Destructor)destroy_face,
                      memory,
                      driver );

    /* finalize the driver object */
Werner Lemberg's avatar
   
Werner Lemberg committed
393
394
    if ( driver->interface.done_driver )
      driver->interface.done_driver( driver );
David Turner's avatar
David Turner committed
395
396

    /* finalize client-data */
Werner Lemberg's avatar
   
Werner Lemberg committed
397
398
    if ( driver->generic.finalizer )
      driver->generic.finalizer( driver );
David Turner's avatar
David Turner committed
399
400
401
402
403
404

    /* discard it */
    FREE( driver );
  }


Werner Lemberg's avatar
   
Werner Lemberg committed
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*   FT_Get_Raster                                                       */
  /*                                                                       */
  /* <Description>                                                         */
  /*   Returns the raster interface corresponding to a given glyph format  */
  /*   tag.                                                                */
  /*                                                                       */
  /* <Input>                                                               */
  /*   library      :: A handle to the source library object.              */
  /*                                                                       */
  /*   glyph_format :: The glyph format tag.                               */
  /*                                                                       */
  /* <Output>                                                              */
  /*   raster_funcs :: If this field is not 0, the raster's interface      */
  /*                   functions are returned.                             */
  /*                                                                       */
  /* <Return>                                                              */
  /*   A pointer to the corresponding raster object.                       */
  /*                                                                       */
  FT_EXPORT_FUNC( FT_Raster )  FT_Get_Raster(
                                 FT_Library        library,
                                 FT_Glyph_Format   glyph_format,
                                 FT_Raster_Funcs*  raster_funcs )
David Turner's avatar
David Turner committed
430
431
  {
    FT_Int  n;
432

Werner Lemberg's avatar
   
Werner Lemberg committed
433

Werner Lemberg's avatar
   
Werner Lemberg committed
434
435
436
    if ( !library )
      return 0;

David Turner's avatar
David Turner committed
437
438
439
    for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ )
    {
      FT_Raster_Funcs*  funcs = &library->raster_funcs[n];
Werner Lemberg's avatar
   
Werner Lemberg committed
440
441
442


      if ( funcs->glyph_format == glyph_format )
David Turner's avatar
David Turner committed
443
      {
Werner Lemberg's avatar
   
Werner Lemberg committed
444
        if ( raster_funcs )
David Turner's avatar
David Turner committed
445
446
447
448
449
450
451
          *raster_funcs = *funcs;
        return library->rasters[n];
      }
    }
    return 0;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
452

Werner Lemberg's avatar
   
Werner Lemberg committed
453
454
455
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
David Turner's avatar
David Turner committed
456
  /*    FT_Set_Raster                                                      */
Werner Lemberg's avatar
   
Werner Lemberg committed
457
458
  /*                                                                       */
  /* <Description>                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
459
  /*    Registers a given raster to the library.                           */
Werner Lemberg's avatar
   
Werner Lemberg committed
460
461
  /*                                                                       */
  /* <Input>                                                               */
David Turner's avatar
David Turner committed
462
  /*    library      :: A handle to a target library object.               */
Werner Lemberg's avatar
   
Werner Lemberg committed
463
464
  /*                                                                       */
  /*    raster_funcs :: A pointer to the raster's interface functions.     */
Werner Lemberg's avatar
   
Werner Lemberg committed
465
466
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
467
  /*    FreeType error code.  0 means success.                             */
Werner Lemberg's avatar
   
Werner Lemberg committed
468
  /*                                                                       */
David Turner's avatar
David Turner committed
469
470
471
  /* <Note>                                                                */
  /*    This function will do the following:                               */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
472
473
  /*    - A new raster object is created through `raster_func.raster_new'. */
  /*      If this fails, the function returns.                             */
David Turner's avatar
David Turner committed
474
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
475
476
  /*    - If a raster is already registered for the glyph format           */
  /*      specified in raster_funcs, it will be destroyed.                 */
David Turner's avatar
David Turner committed
477
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
478
  /*    - The new raster is registered for the glyph format.               */
David Turner's avatar
David Turner committed
479
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
480
481
  FT_EXPORT_FUNC( FT_Error )  FT_Set_Raster( FT_Library        library,
                                             FT_Raster_Funcs*  raster_funcs )
David Turner's avatar
David Turner committed
482
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
483
    FT_Glyph_Format  glyph_format;
David Turner's avatar
David Turner committed
484
485
486
487
    FT_Raster_Funcs* funcs;
    FT_Raster        raster;
    FT_Error         error;
    FT_Int           n, index;
488

Werner Lemberg's avatar
   
Werner Lemberg committed
489

Werner Lemberg's avatar
   
Werner Lemberg committed
490
491
492
493
494
495
496
497
    if ( !library )
      return FT_Err_Invalid_Library_Handle;

    if ( !raster_funcs )
      return FT_Err_Invalid_Argument;

    glyph_format = raster_funcs->glyph_format;

Werner Lemberg's avatar
   
Werner Lemberg committed
498
    if ( glyph_format == ft_glyph_format_none )
David Turner's avatar
David Turner committed
499
      return FT_Err_Invalid_Argument;
500

David Turner's avatar
David Turner committed
501
502
    /* create a new raster object */
    error = raster_funcs->raster_new( library->memory, &raster );
Werner Lemberg's avatar
   
Werner Lemberg committed
503
504
    if ( error )
      goto Exit;
505

David Turner's avatar
David Turner committed
506
507
508
    raster_funcs->raster_reset( raster,
                                library->raster_pool,
                                library->raster_pool_size );
509

David Turner's avatar
David Turner committed
510
    index = -1;
Werner Lemberg's avatar
   
Werner Lemberg committed
511
    for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ )
David Turner's avatar
David Turner committed
512
513
    {
      FT_Raster_Funcs*  funcs = library->raster_funcs + n;
Werner Lemberg's avatar
   
Werner Lemberg committed
514

Werner Lemberg's avatar
   
Werner Lemberg committed
515
516
517

      /* record the first vacant entry in `index' */
      if ( index < 0 && funcs->glyph_format == ft_glyph_format_none )
David Turner's avatar
David Turner committed
518
        index = n;
519

David Turner's avatar
David Turner committed
520
      /* compare this entry's glyph format with the one we need */
Werner Lemberg's avatar
   
Werner Lemberg committed
521
      if ( funcs->glyph_format == glyph_format )
David Turner's avatar
David Turner committed
522
      {
Werner Lemberg's avatar
   
Werner Lemberg committed
523
524
        /* A raster already exists for this glyph format.  We will */
        /* destroy it before updating its entry in the table.      */
David Turner's avatar
David Turner committed
525
526
527
528
529
        funcs->raster_done( library->rasters[n] );
        index = n;
        break;
      }
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
530

Werner Lemberg's avatar
   
Werner Lemberg committed
531
    if ( index < 0 )
David Turner's avatar
David Turner committed
532
    {
David Turner's avatar
David Turner committed
533
534
535
      /* the table is full and has no vacant entries */
      error = FT_Err_Too_Many_Glyph_Formats;
      goto Fail;
David Turner's avatar
David Turner committed
536
    }
Werner Lemberg's avatar
   
Werner Lemberg committed
537

David Turner's avatar
David Turner committed
538
539
540
541
542
543
    funcs  = library->raster_funcs + index;
    *funcs = *raster_funcs;
    library->rasters[index] = raster;

  Exit:
    return error;
David Turner's avatar
David Turner committed
544

David Turner's avatar
David Turner committed
545
546
547
  Fail:
    raster_funcs->raster_done( raster );
    goto Exit;
548
  }
David Turner's avatar
David Turner committed
549

Werner Lemberg's avatar
   
Werner Lemberg committed
550

David Turner's avatar
David Turner committed
551
552
553
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
David Turner's avatar
David Turner committed
554
  /*    FT_Unset_Raster                                                    */
David Turner's avatar
David Turner committed
555
556
  /*                                                                       */
  /* <Description>                                                         */
David Turner's avatar
David Turner committed
557
  /*    Removes a given raster from the library.                           */
David Turner's avatar
David Turner committed
558
559
  /*                                                                       */
  /* <Input>                                                               */
David Turner's avatar
David Turner committed
560
  /*    library      :: A handle to a target library object.               */
Werner Lemberg's avatar
   
Werner Lemberg committed
561
562
  /*                                                                       */
  /*    raster_funcs :: A pointer to the raster's interface functions.     */
David Turner's avatar
David Turner committed
563
564
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
565
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
566
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
567
568
569
  FT_EXPORT_DEF( FT_Error )  FT_Unset_Raster(
                               FT_Library        library,
                               FT_Raster_Funcs*  raster_funcs )
David Turner's avatar
David Turner committed
570
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
571
    FT_Glyph_Format  glyph_format;
David Turner's avatar
David Turner committed
572
573
    FT_Error         error;
    FT_Int           n;
574

Werner Lemberg's avatar
   
Werner Lemberg committed
575

Werner Lemberg's avatar
   
Werner Lemberg committed
576
577
578
    if ( !library )
      return FT_Err_Invalid_Library_Handle;

579
    error = FT_Err_Invalid_Argument;
Werner Lemberg's avatar
   
Werner Lemberg committed
580

Werner Lemberg's avatar
   
Werner Lemberg committed
581
582
583
584
585
    if ( !raster_funcs )
      goto Exit;

    glyph_format = raster_funcs->glyph_format;

Werner Lemberg's avatar
   
Werner Lemberg committed
586
    if ( glyph_format == ft_glyph_format_none )
David Turner's avatar
David Turner committed
587
      goto Exit;
Werner Lemberg's avatar
   
Werner Lemberg committed
588

Werner Lemberg's avatar
   
Werner Lemberg committed
589
    for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ )
David Turner's avatar
David Turner committed
590
    {
David Turner's avatar
David Turner committed
591
      FT_Raster_Funcs*  funcs = library->raster_funcs + n;
Werner Lemberg's avatar
   
Werner Lemberg committed
592

Werner Lemberg's avatar
   
Werner Lemberg committed
593
594

      if ( funcs->glyph_format == glyph_format )
David Turner's avatar
David Turner committed
595
      {
David Turner's avatar
David Turner committed
596
597
598
599
600
        funcs->raster_done( library->rasters[n] );
        library->rasters[n]                   = 0;
        library->raster_funcs[n].glyph_format = ft_glyph_format_none;
        error = FT_Err_Ok;
        break;
David Turner's avatar
David Turner committed
601
602
603
604
605
606
607
      }
    }

  Exit:
    return error;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
608

David Turner's avatar
David Turner committed
609
610
611
612
613
614
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_Set_Raster_Mode                                                 */
  /*                                                                       */
  /* <Description>                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
615
  /*    Sets a raster-specific mode.                                       */
David Turner's avatar
David Turner committed
616
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
617
  /* <InOut>                                                               */
David Turner's avatar
David Turner committed
618
  /*    library :: A handle to a target library object.                    */
Werner Lemberg's avatar
   
Werner Lemberg committed
619
620
621
622
623
624
625
626
  /*                                                                       */
  /* <Input>                                                               */
  /*    format  :: The glyph format used to select the raster.             */
  /*                                                                       */
  /*    mode    :: The raster-specific mode descriptor.                    */
  /*                                                                       */
  /*    args    :: The mode arguments.                                     */
  /*                                                                       */
David Turner's avatar
David Turner committed
627
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
628
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
629
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
630
631
632
633
  FT_EXPORT_FUNC( FT_Error )  FT_Set_Raster_Mode( FT_Library       library,
                                                  FT_Glyph_Format  format,
                                                  unsigned long    mode,
                                                  void*            args )
David Turner's avatar
David Turner committed
634
635
636
  {
    FT_Raster_Funcs  funcs;
    FT_Raster        raster;
637

Werner Lemberg's avatar
   
Werner Lemberg committed
638

Werner Lemberg's avatar
   
Werner Lemberg committed
639
640
641
    if ( !library )
      return FT_Err_Invalid_Library_Handle;

David Turner's avatar
David Turner committed
642
    raster = FT_Get_Raster( library, format, &funcs );
Werner Lemberg's avatar
   
Werner Lemberg committed
643
    if ( raster && args && funcs.raster_set_mode )
David Turner's avatar
David Turner committed
644
645
646
647
648
      return funcs.raster_set_mode( raster, mode, args );
    else
      return FT_Err_Invalid_Argument;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
649

Werner Lemberg's avatar
   
Werner Lemberg committed
650
651
652
653
654
655
656
657
658
659
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_Set_Debug_Hook                                                  */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Sets a debug hook function for debugging the interpreter of a      */
  /*    font format.                                                       */
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
660
  /*    library    :: A handle to the library object.                      */
Werner Lemberg's avatar
   
Werner Lemberg committed
661
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
662
663
664
  /*    hook_index :: The index of the debug hook.  You should use the     */
  /*                  values defined in ftobjs.h, e.g.                     */
  /*                  FT_DEBUG_HOOK_TRUETYPE                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
665
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
666
  /*    debug_hook :: The function used to debug the interpreter.          */
Werner Lemberg's avatar
   
Werner Lemberg committed
667
668
669
670
671
  /*                                                                       */
  /* <Note>                                                                */
  /*    Currently, four debug hook slots are available, but only two (for  */
  /*    the TrueType and the Type 1 interpreter) are defined.              */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
672
673
674
  FT_EXPORT_FUNC( void )  FT_Set_Debug_Hook( FT_Library         library,
                                             FT_UInt            hook_index,
                                             FT_DebugHook_Func  debug_hook )
David Turner's avatar
David Turner committed
675
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
676
677
    if ( library && debug_hook &&
         hook_index <
Werner Lemberg's avatar
   
Werner Lemberg committed
678
           ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )
David Turner's avatar
David Turner committed
679
680
      library->debug_hooks[hook_index] = debug_hook;
  }
Werner Lemberg's avatar
   
Werner Lemberg committed
681
682


David Turner's avatar
David Turner committed
683
684
685
686
687
688
689
690
691
692
693
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_New_Library                                                     */
  /*                                                                       */
  /* <Description>                                                         */
  /*    This function is used to create a new FreeType library instance    */
  /*    from a given memory object.  It is thus possible to use libraries  */
  /*    with distinct memory allocators within the same program.           */
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
694
  /*    memory   :: A handle to the original memory object.                */
David Turner's avatar
David Turner committed
695
696
  /*                                                                       */
  /* <Output>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
697
  /*    alibrary :: A pointer to handle of a new library object.           */
David Turner's avatar
David Turner committed
698
699
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
700
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
701
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
702
703
  FT_EXPORT_FUNC( FT_Error )  FT_New_Library( FT_Memory    memory,
                                              FT_Library*  alibrary )
David Turner's avatar
David Turner committed
704
  {
Werner Lemberg's avatar
   
Werner Lemberg committed
705
706
707
    FT_Library  library = 0;
    FT_Error    error;

David Turner's avatar
David Turner committed
708

Werner Lemberg's avatar
   
Werner Lemberg committed
709
710
    if ( !memory )
      return FT_Err_Invalid_Argument;
Werner Lemberg's avatar
   
Werner Lemberg committed
711

Werner Lemberg's avatar
   
Werner Lemberg committed
712
    /* first of all, allocate the library object */
David Turner's avatar
David Turner committed
713
714
715
716
717
    if ( ALLOC( library, sizeof ( *library ) ) )
      return error;

    library->memory = memory;

David Turner's avatar
David Turner committed
718
719
720
721
    /* allocate the render pool */
    library->raster_pool_size = FT_RENDER_POOL_SIZE;
    if ( ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
      goto Fail;
Werner Lemberg's avatar
   
Werner Lemberg committed
722

Werner Lemberg's avatar
   
Werner Lemberg committed
723
724
    /* now register the default raster for the `outline' glyph image */
    /* format for now, ignore the error...                           */
David Turner's avatar
David Turner committed
725
    error = FT_Set_Raster( library, &ft_default_raster );
726

David Turner's avatar
David Turner committed
727
728
729
730
    /* That's ok now */
    *alibrary = library;

    return FT_Err_Ok;
Werner Lemberg's avatar
   
Werner Lemberg committed
731

David Turner's avatar
David Turner committed
732
733
734
  Fail:
    FREE( library );
    return error;
David Turner's avatar
David Turner committed
735
736
737
738
739
740
741
742
743
744
745
746
747
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_Done_Library                                                    */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Discards a given library object.  This closes all drivers and      */
  /*    discards all resource objects.                                     */
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
748
  /*    library :: A handle to the target library.                         */
David Turner's avatar
David Turner committed
749
750
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
751
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
752
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
753
  FT_EXPORT_FUNC( FT_Error )  FT_Done_Library( FT_Library  library )
David Turner's avatar
David Turner committed
754
755
756
757
758
759
760
761
762
763
764
  {
    FT_Memory  memory;
    FT_Int     n;


    if ( !library )
      return FT_Err_Invalid_Library_Handle;

    memory = library->memory;

    /* Discard client-data */
Werner Lemberg's avatar
   
Werner Lemberg committed
765
    if ( library->generic.finalizer )
David Turner's avatar
David Turner committed
766
767
768
769
770
771
772
      library->generic.finalizer( library );

    /* Close all drivers in the library */
    for ( n = 0; n < library->num_drivers; n++ )
    {
      FT_Driver  driver = library->drivers[n];

Werner Lemberg's avatar
   
Werner Lemberg committed
773

David Turner's avatar
David Turner committed
774
775
776
777
778
779
780
      if ( driver )
      {
        Destroy_Driver( driver );
        library->drivers[n] = 0;
      }
    }

David Turner's avatar
David Turner committed
781
    /* Destroy raster objects */
Werner Lemberg's avatar
   
Werner Lemberg committed
782
    FREE( library->raster_pool );
David Turner's avatar
David Turner committed
783
    library->raster_pool_size = 0;
Werner Lemberg's avatar
   
Werner Lemberg committed
784

David Turner's avatar
David Turner committed
785
    {
Werner Lemberg's avatar
   
Werner Lemberg committed
786
787
      FT_Raster_Funcs*  cur    = library->raster_funcs;
      FT_Raster_Funcs*  limit  = cur + FT_MAX_GLYPH_FORMATS;
David Turner's avatar
David Turner committed
788
      FT_Raster*        raster = library->rasters;
Werner Lemberg's avatar
   
Werner Lemberg committed
789

David Turner's avatar
David Turner committed
790
      for ( ; cur < limit; cur++, raster++ )
David Turner's avatar
David Turner committed
791
      {
David Turner's avatar
David Turner committed
792
        if ( cur->glyph_format != ft_glyph_format_none )
David Turner's avatar
David Turner committed
793
        {
David Turner's avatar
David Turner committed
794
795
796
          cur->raster_done( *raster );
          *raster = 0;
          cur->glyph_format = ft_glyph_format_none;
David Turner's avatar
David Turner committed
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
        }
      }
    }

    FREE( library );

    return FT_Err_Ok;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_Add_Driver                                                      */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Registers a new driver in a given library object.  This function   */
Werner Lemberg's avatar
   
Werner Lemberg committed
814
  /*    takes only a pointer to a driver interface; it uses it to create   */
David Turner's avatar
David Turner committed
815
816
  /*    the new driver, then sets up some important fields.                */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
817
  /* <InOut>                                                               */
David Turner's avatar
David Turner committed
818
819
  /*    library          :: A handle to the target library object.         */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
820
  /* <Input>                                                               */
David Turner's avatar
David Turner committed
821
822
823
  /*    driver_interface :: A pointer to a driver interface table.         */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
824
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
825
826
827
828
829
  /*                                                                       */
  /* <Note>                                                                */
  /*    This function doesn't check whether the driver is already          */
  /*    installed!                                                         */
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
830
831
832
  FT_EXPORT_FUNC( FT_Error )  FT_Add_Driver(
                                FT_Library                 library,
                                const FT_DriverInterface*  driver_interface )
David Turner's avatar
David Turner committed
833
834
835
836
837
  {
    FT_Error   error;
    FT_Driver  driver;
    FT_Memory  memory;

Werner Lemberg's avatar
   
Werner Lemberg committed
838

Werner Lemberg's avatar
   
Werner Lemberg committed
839
    if ( !library )
David Turner's avatar
David Turner committed
840
841
      return FT_Err_Invalid_Library_Handle;

Werner Lemberg's avatar
   
Werner Lemberg committed
842
843
844
    if ( !driver_interface )
      return FT_Err_Invalid_Argument;

David Turner's avatar
David Turner committed
845
846
847
848
849
850
851
852
853
854
855
856
857
858
    memory = library->memory;
    error  = FT_Err_Ok;

    if ( library->num_drivers >= FT_MAX_DRIVERS )
      error = FT_Err_Too_Many_Drivers;
    else
    {
      if ( ALLOC( driver, driver_interface->driver_object_size ) )
        goto Exit;

      driver->library   = library;
      driver->memory    = memory;
      driver->interface = *driver_interface;

Werner Lemberg's avatar
   
Werner Lemberg committed
859
      if ( driver_interface->init_driver )
David Turner's avatar
David Turner committed
860
861
      {
        error = driver_interface->init_driver( driver );
Werner Lemberg's avatar
   
Werner Lemberg committed
862
863
        if ( error )
          goto Fail;
David Turner's avatar
David Turner committed
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
      }

      library->drivers[library->num_drivers++] = driver;
      goto Exit;

    Fail:
      FREE( driver );
    }

  Exit:
    return error;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_Remove_Driver                                                   */
  /*                                                                       */
  /* <Description>                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
884
  /*    Unregisters a given driver.  This closes the driver, which in turn */
David Turner's avatar
David Turner committed
885
886
887
888
889
890
891
892
  /*    destroys all faces, sizes, slots, etc. associated with it.         */
  /*                                                                       */
  /*    This function also DESTROYS the driver object.                     */
  /*                                                                       */
  /* <Input>                                                               */
  /*    driver :: A handle to target driver object.                        */
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
893
  /*    FreeType error code.  0 means success.                             */
David Turner's avatar
David Turner committed
894
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
895
  FT_EXPORT_FUNC( FT_Error )  FT_Remove_Driver( FT_Driver  driver )
David Turner's avatar
David Turner committed
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
  {
    FT_Library  library;
    FT_Memory   memory;
    FT_Driver   *cur, *last;
    FT_Error    error;


    if ( !driver )
      return FT_Err_Invalid_Driver_Handle;

    library = driver->library;
    memory  = driver->memory;

    if ( !library || !memory )
      return FT_Err_Invalid_Driver_Handle;

    /* look-up driver entry in library table */
    error = FT_Err_Invalid_Driver_Handle;
    cur   = library->drivers;
    last  = cur + library->num_drivers - 1;

    for ( ; cur <= last; cur++ )
    {
      if ( *cur == driver )
      {
Werner Lemberg's avatar
   
Werner Lemberg committed
921
        /* destroy the driver object */
David Turner's avatar
David Turner committed
922
923
924
        Destroy_Driver( driver );

        /* now move the last driver in the table to the vacant slot */
Werner Lemberg's avatar
   
Werner Lemberg committed
925
        if ( cur < last )
David Turner's avatar
David Turner committed
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
        {
          *cur  = *last;
          *last = 0;
        }
        library->num_drivers--;

        /* exit loop */
        error = FT_Err_Ok;
        break;
      }
    }

    return error;
  }

Werner Lemberg's avatar
   
Werner Lemberg committed
941

David Turner's avatar
David Turner committed
942
943
944
945
946
947
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_Get_Driver                                                      */
  /*                                                                       */
  /* <Description>                                                         */
Werner Lemberg's avatar
   
Werner Lemberg committed
948
  /*    Returns the handle of the driver responsible for a given format    */
David Turner's avatar
David Turner committed
949
950
951
  /*    (or service) according to its `name'.                              */
  /*                                                                       */
  /* <Input>                                                               */
Werner Lemberg's avatar
   
Werner Lemberg committed
952
953
  /*    library     :: A handle to the library object.                     */
  /*    driver_name :: The name of the driver to look up.                  */
David Turner's avatar
David Turner committed
954
955
  /*                                                                       */
  /* <Return>                                                              */
Werner Lemberg's avatar
   
Werner Lemberg committed
956
  /*    A handle to the driver object, 0 otherwise.                        */
David Turner's avatar
David Turner committed
957
  /*                                                                       */
Werner Lemberg's avatar
   
Werner Lemberg committed
958
959
  FT_EXPORT_FUNC( FT_Driver )  FT_Get_Driver( FT_Library  library,
                                              char*       driver_name )
David Turner's avatar
David Turner committed
960
961
  {
    FT_Driver  *cur, *limit;
Werner Lemberg's avatar
   
Werner Lemberg committed
962
963
964


    if ( !library || !driver_name )
David Turner's avatar
David Turner committed
965
      return 0;
Werner Lemberg's avatar
   
Werner Lemberg committed
966

David Turner's avatar
David Turner committed
967
968
969
970
971
972
973
974
975
976
977
    cur   = library->drivers;
    limit = cur + library->num_drivers;
    for ( ; cur < limit; cur++ )
    {
      if ( strcmp( (*cur)->interface.driver_name, driver_name ) == 0 )
        return *cur;
    }
    return 0;
  }


Werner Lemberg's avatar
   
Werner Lemberg committed
978
979
980
981
982
983
984
985
  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    open_face                                                          */
  /*                                                                       */
  /* <Description>                                                         */
  /*    This function does some work for FT_Open_Face().                   */
  /*                                                                       */
David Turner's avatar
David Turner committed
986
  static
987
988
989
990
991
992
  FT_Error  open_face( FT_Driver      driver,
                       FT_Stream      stream,
                       FT_Long        face_index,
                       FT_Int         num_params,
                       FT_Parameter*  params,
                       FT_Face*       aface )
David Turner's avatar
David Turner committed
993
994
995
996
997
998
999
1000
  {
    FT_Memory            memory;
    FT_DriverInterface*  interface;
    FT_Face              face = 0;
    FT_Error             error;


    interface = &driver->interface;
For faster browsing, not all history is shown. View entire blame