Commit e7880499312da5f83c237c49023441e9aa62d959

David Turner 2002-04-25T21:42:59

adding experimental (alpha) exception support code + system code

diff --git a/include/freetype/internal/ftexcept.h b/include/freetype/internal/ftexcept.h
index 36f1713..f3c770e 100644
--- a/include/freetype/internal/ftexcept.h
+++ b/include/freetype/internal/ftexcept.h
@@ -51,33 +51,40 @@ FT_BEGIN_HEADER
 
   typedef struct FT_CleanupStackRec_
   {
-    FT_CleanupItem   top;
-    FT_CleanupChunk  chunk;
-    FT_Memory        memory;
+    FT_CleanupItem     top;
+    FT_CleanupItem     limit;
+    FT_CleanupChunk    chunk;
+    FT_CleanupChunkRec chunk_0;  /* avoids stupid dynamic allocation */
+    FT_Memory          memory;
 
   } FT_CleanupStackRec, *FT_CleanupStack;
 
 
-  FT_BASE_DEF( void )
+  FT_BASE( void )
   ft_cleanup_stack_push( FT_CleanupStack  stack,
                          FT_Pointer       item,
                          FT_CleanupFunc   item_func,
                          FT_Pointer       item_data );
 
-  FT_BASE_DEF( void )
+  FT_BASE( void )
   ft_cleanup_stack_pop( FT_CleanupStack   stack,
                         FT_Int            destroy );
 
-  FT_BASE_DEF( FT_Pointer )
+  FT_BASE( FT_CleanupItem )
   ft_cleanup_stack_peek( FT_CleanupStack  stack );
 
-  FT_BASE_DEF( void )
+  FT_BASE( void )
   ft_xhandler_enter( FT_XHandler  xhandler,
                      FT_Memory    memory );                         
 
-  FT_BASE_DEF( void )
+  FT_BASE( void )
   ft_xhandler_exit( FT_XHandler  xhandler );
 
+
+  FT_BASE( void )
+  ft_cleanup_throw( FT_CleanupStack  stack,
+                    FT_Error         error );
+
 FT_END_HEADER
 
 #endif /* __FT_EXCEPT_H__ */
diff --git a/src/base/ftexcept.c b/src/base/ftexcept.c
new file mode 100644
index 0000000..96391b6
--- /dev/null
+++ b/src/base/ftexcept.c
@@ -0,0 +1,168 @@
+#include <ft2build.h>
+#include FT_EXCEPT_H
+
+
+  FT_BASE_DEF( void )
+  ft_cleanup_stack_init( FT_CleanupStack  stack,
+                         FT_Memory        memory )
+  {
+    stack->chunk = &stack->chunk_0;
+    stack->top   = stack->chunk->items;
+    stack->limit = stack->top + FT_CLEANUP_CHUNK_SIZE;
+    stack->chunk_0.link = NULL;
+    
+    stack->memory = memory;
+  }                         
+
+
+
+  FT_BASE_DEF( void )
+  ft_cleanup_stack_done( FT_CleanupStack  stack )
+  {
+    FT_Memory        memory = stack->memory;
+    FT_CleanupChunk  chunk, next;
+    
+    for (;;)
+    {
+      chunk = stack->chunk;
+      if ( chunk == &stack->chunk_0 )
+        break;
+
+      stack->chunk = chunk->link;
+      
+      FT_FREE( chunk );
+    }
+    
+    stack->memory = NULL;
+  }
+
+
+
+  FT_BASE_DEF( void )
+  ft_cleanup_stack_push( FT_CleanupStack  stack,
+                         FT_Pointer       item,
+                         FT_CleanupFunc   item_func,
+                         FT_Pointer       item_data )
+  {
+    FT_CleanupItem  top;
+
+
+    FT_ASSERT( stack && stack->chunk && stack->top );
+    FT_ASSERT( item  && item_func );
+    
+    top = stack->top;
+    
+    top->item      = item;
+    top->item_func = item_func;
+    top->item_data = item_data;
+    
+    top ++;
+    
+    if ( top == stack->limit )
+    {
+      FT_CleanupChunk  chunk;
+      FT_Error         error;
+      
+      if ( FT_ALLOC( chunk, stack->memory ) )
+        ft_cleanup_stack_throw( stack, error );
+
+      chunk->link  = stack->chunk;
+      stack->chunk = chunk;
+      stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE;
+      top          = chunk->items;
+    }
+
+    stack->top = top;
+  }                         
+
+
+
+  FT_BASE_DEF( void )
+  ft_cleanup_stack_pop( FT_CleanupStack   stack,
+                        FT_Int            destroy )
+  {
+    FT_CleanupItem  top;
+    
+    
+    FT_ASSERT( stack && stack->chunk && stack->top );
+    top = stack->top;
+    
+    if ( top == stack->chunk->items )
+    {
+      FT_CleanupChunk  chunk;
+      
+      chunk = stack->chunk;
+      
+      if ( chunk == &stack->chunk_0 )
+      {
+        FT_ERROR(( "cleanup.pop: empty cleanup stack !!\n" ));
+        ft_cleanup_throw( stack, FT_Err_EmptyCleanupStack );
+      }
+
+      chunk = chunk->link;
+      FT_QFree( stack->chunk, stack->memory );
+      
+      stack->chunk = chunk;
+      stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE;
+      top          = stack->limit;
+    }
+    
+    top --;
+    
+    if ( destroy )
+      top->item_func( top->item, top->item_data );
+    
+    top->item      = NULL;
+    top->item_func = NULL;
+    top->item_data = NULL;
+    
+    stack->top = top;
+  }
+
+
+
+  FT_BASE_DEF( FT_CleanupItem )
+  ft_cleanup_stack_peek( FT_CleanupStack  stack )
+  {
+    FT_CleanupItem   top;
+    FT_CleanupChunk  chunk;
+
+
+    FT_ASSERT( stack && stack->chunk && stack->top );
+    
+    top   = stack->top;
+    chunk = stack->chunk;
+    
+    if ( top > chunk->items )
+      top--;
+    else
+    {
+      chunk = chunk->link;
+      top   = NULL;
+      if ( chunk != NULL )
+        top = chunk->items + FT_CLEANUP_CHUNK_SIZE - 1;
+    }
+    return top;
+  }
+
+
+  FT_BASE_DEF( void )
+  ft_cleanup_stack_throw( FT_CleanupStack  stack, FT_Error  error )
+  {
+  }
+
+
+  FT_BASE_DEF( void )
+  ft_xhandler_enter( FT_XHandler  xhandler,
+                     FT_Memory    memory )
+  {
+    
+  }
+
+
+
+  FT_BASE_DEF( void )
+  ft_xhandler_exit( FT_XHandler  xhandler )
+  {
+  }
+
diff --git a/src/base/ftsysio.c b/src/base/ftsysio.c
new file mode 100644
index 0000000..344ee51
--- /dev/null
+++ b/src/base/ftsysio.c
@@ -0,0 +1,131 @@
+#include <ft2build.h>
+#include FT_SYSTEM_STREAM_H
+
+#include <stdio.h>
+
+ /* the ISO/ANSI standard stream object */
+  typedef struct FT_StdStreamRec_
+  {
+    FT_StreamRec  stream;
+    FILE*         file;
+    const char*   pathname;
+  
+  } FT_StdStreamRec, *FT_StdStream;
+
+
+
+ /* read bytes from a standard stream */
+  static FT_ULong
+  ft_std_stream_read( FT_StdStream   stream,
+                      FT_Byte*       buffer,
+                      FT_ULong       size )
+  {
+    long   read_bytes;
+    
+    read_bytes = fread( buffer, 1, size, stream->file );
+    if ( read_bytes < 0 )
+      read_bytes = 0;
+      
+    return (FT_ULong) read_bytes;
+  }
+
+
+ /* seek the standard stream to a new position */
+  static FT_Error
+  ft_std_stream_seek( FT_StdStream   stream,
+                      FT_ULong       pos )
+  {
+    return ( fseek( stream->file, pos, SEEK_SET ) < 0 )
+         ? FT_Err_Stream_Seek
+         : FT_Err_Ok;
+  }
+  
+  
+ /* close a standard stream */  
+  static void
+  ft_std_stream_done( FT_StdStream  stream )
+  {
+    fclose( stream->file );
+    stream->file     = NULL;
+    stream->pathname = NULL;
+  }
+
+
+ /* open a standard stream from a given pathname */
+  static void
+  ft_std_stream_init( FT_StdStream  stream,
+                      const char*   pathname )
+  {
+    FT_ASSERT( pathname != NULL );
+
+    stream->file = fopen( pathname, "rb" );
+    if ( stream->file == NULL )
+    {
+      FT_ERROR(( "iso.stream.init: could not open '%s'\n", pathname ));
+      FT_XTHROW( FT_Err_Stream_Open );
+    }
+    
+    /* compute total size in bytes */
+    fseek( file, 0, SEEK_END );
+    FT_STREAM__SIZE(stream) = ftell( file );
+    fseek( file, 0, SEEK_SET );
+    
+    stream->pathname = pathname;
+    stream->pos      = 0;
+    
+    FT_TRACE1(( "iso.stream.init: opened '%s' (%ld bytes) succesfully\n",
+                 pathname, FT_STREAM__SIZE(stream) ));
+  }                 
+
+
+  static void
+  ft_std_stream_class_init( FT_ClassRec*  _clazz )
+  {
+    FT_StreamClassRec*  clazz = FT_STREAM_CLASS(_clazz);
+    
+    clazz->stream_read = (FT_Stream_ReadFunc) ft_std_stream_read;
+    clazz->stream_seek = (FT_Stream_SeekFunc) ft_std_stream_seek;
+  }
+
+
+  static const FT_TypeRec  ft_std_stream_type;
+  {
+    "StreamClass",
+    NULL,
+    
+    sizeof( FT_ClassRec ),
+    ft_stream_class_init,
+    NULL,
+    
+    sizeof( FT_StdStreamRec ),
+    ft_std_stream_init,
+    ft_std_stream_done,
+    NULL,
+  };
+  
+
+
+  FT_EXPORT_DEF( FT_Stream )
+  ft_std_stream_new( FT_Memory    memory,
+                     const char*  pathname )
+  {
+    FT_Class  clazz;
+    
+    clazz = ft_class_from_type( memory, &ft_std_stream_type );
+    
+    return (FT_Stream) ft_object_new( clazz, pathname );
+  }                     
+
+
+  FT_EXPORT_DEF( void )
+  ft_std_stream_create( FT_Memory    memory,
+                        const char*  pathname,
+                        FT_Stream*   astream )
+  {
+    FT_Class  clazz;
+    
+    clazz = ft_class_from_type( memory, &ft_std_stream_type );
+    
+    ft_object_create( clazz, pathname, FT_OBJECT_P(astream) );
+  }                        
+
diff --git a/src/base/ftsysmem.c b/src/base/ftsysmem.c
new file mode 100644
index 0000000..6a34f69
--- /dev/null
+++ b/src/base/ftsysmem.c
@@ -0,0 +1,30 @@
+#include <ft2build.h>
+#include FT_SYSTEM_MEMORY_H
+
+  static FT_Memory
+  ft_memory_new_default( FT_ULong  size )
+  {
+    return (FT_Memory) ft_malloc( size );
+  }
+  
+  static void
+  ft_memory_destroy_default( FT_Memory  memory )
+  {
+    ft_free( memory );
+  }
+
+  
+ /* notice that in normal builds, we use the ISO C library functions */
+ /* 'malloc', 'free' and 'realloc' directly..                        */
+ /*                                                                  */
+  static const FT_Memory_FuncsRec  ft_memory_funcs_default_rec = 
+  {
+    (FT_Memory_CreateFunc)  ft_memory_new_iso,
+    (FT_Memory_DestroyFunc) ft_memory_destroy_iso,
+    (FT_Memory_AllocFunc)   ft_malloc,
+    (FT_Memory_FreeFunc)    ft_free,
+    (FT_Memory_ReallocFunc) ft_realloc
+  };
+  
+  FT_APIVAR_DEF( const FT_Memory_Funcs )
+  ft_memory_funcs_default = &ft_memory_funcs_defaults_rec;