diff --git a/include/freetype/internal/ftexcept.h b/include/freetype/internal/ftexcept.h index 36f1713aa..f3c770e5e 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 000000000..96391b6b2 --- /dev/null +++ b/src/base/ftexcept.c @@ -0,0 +1,168 @@ +#include +#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 000000000..344ee516d --- /dev/null +++ b/src/base/ftsysio.c @@ -0,0 +1,131 @@ +#include +#include FT_SYSTEM_STREAM_H + +#include + + /* 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 000000000..6a34f693f --- /dev/null +++ b/src/base/ftsysmem.c @@ -0,0 +1,30 @@ +#include +#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;