2002-04-25 23:42:59 +02:00
|
|
|
#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;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
stack->memory = memory;
|
2002-05-01 10:46:56 +02:00
|
|
|
}
|
2002-04-25 23:42:59 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_BASE_DEF( void )
|
|
|
|
ft_cleanup_stack_done( FT_CleanupStack stack )
|
|
|
|
{
|
|
|
|
FT_Memory memory = stack->memory;
|
|
|
|
FT_CleanupChunk chunk, next;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
chunk = stack->chunk;
|
|
|
|
if ( chunk == &stack->chunk_0 )
|
|
|
|
break;
|
|
|
|
|
|
|
|
stack->chunk = chunk->link;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
|
|
|
FT_Free( chunk, memory );
|
2002-04-25 23:42:59 +02:00
|
|
|
}
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
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 );
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
top = stack->top;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
top->item = item;
|
|
|
|
top->item_func = item_func;
|
|
|
|
top->item_data = item_data;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
top ++;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
if ( top == stack->limit )
|
|
|
|
{
|
|
|
|
FT_CleanupChunk chunk;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
|
|
|
chunk = FT_QAlloc( sizeof(*chunk), stack->memory );
|
2002-04-25 23:42:59 +02:00
|
|
|
|
|
|
|
chunk->link = stack->chunk;
|
|
|
|
stack->chunk = chunk;
|
|
|
|
stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE;
|
|
|
|
top = chunk->items;
|
|
|
|
}
|
|
|
|
|
|
|
|
stack->top = top;
|
2002-05-01 10:46:56 +02:00
|
|
|
}
|
2002-04-25 23:42:59 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_BASE_DEF( void )
|
|
|
|
ft_cleanup_stack_pop( FT_CleanupStack stack,
|
|
|
|
FT_Int destroy )
|
|
|
|
{
|
|
|
|
FT_CleanupItem top;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
FT_ASSERT( stack && stack->chunk && stack->top );
|
|
|
|
top = stack->top;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
if ( top == stack->chunk->items )
|
|
|
|
{
|
|
|
|
FT_CleanupChunk chunk;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
chunk = stack->chunk;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
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 );
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
stack->chunk = chunk;
|
|
|
|
stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE;
|
|
|
|
top = stack->limit;
|
|
|
|
}
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
top --;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
if ( destroy )
|
|
|
|
top->item_func( top->item, top->item_data );
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
top->item = NULL;
|
|
|
|
top->item_func = NULL;
|
|
|
|
top->item_data = NULL;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
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 );
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
top = stack->top;
|
|
|
|
chunk = stack->chunk;
|
2002-05-01 10:46:56 +02:00
|
|
|
|
2002-04-25 23:42:59 +02:00
|
|
|
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_xhandler_enter( FT_XHandler xhandler,
|
|
|
|
FT_Memory memory )
|
|
|
|
{
|
2002-05-01 10:46:56 +02:00
|
|
|
FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory);
|
|
|
|
|
|
|
|
xhandler->previous = stack->xhandler;
|
|
|
|
xhandler->cleanup = stack->top;
|
|
|
|
xhandler->error = 0;
|
|
|
|
stack->xhandler = xhandler;
|
2002-04-25 23:42:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_BASE_DEF( void )
|
|
|
|
ft_xhandler_exit( FT_XHandler xhandler )
|
|
|
|
{
|
2002-05-01 10:46:56 +02:00
|
|
|
FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory);
|
|
|
|
|
|
|
|
stack->xhandler = xhandler->previous;
|
|
|
|
xhandler->previous = NULL;
|
|
|
|
xhandler->error = error;
|
|
|
|
xhandler->cleanup = NULL;
|
2002-04-25 23:42:59 +02:00
|
|
|
}
|
|
|
|
|
2002-05-01 10:46:56 +02:00
|
|
|
|
|
|
|
|
|
|
|
FT_BASE_DEF( void )
|
|
|
|
ft_cleanup_throw( FT_CleanupStack stack,
|
|
|
|
FT_Error error )
|
|
|
|
{
|
|
|
|
FT_XHandler xhandler = stack->xhandler;
|
|
|
|
|
|
|
|
if ( xhandler == NULL )
|
|
|
|
{
|
|
|
|
/* no exception handler was registered. this */
|
|
|
|
/* means that we have an un-handled exception */
|
|
|
|
/* the only thing we can do is _PANIC_ and */
|
|
|
|
/* halt the current program.. */
|
|
|
|
/* */
|
|
|
|
FT_ERROR(( "FREETYPE PANIC: An un-handled exception occured. Program aborted" ));
|
|
|
|
ft_exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup the stack until we reach the handler's */
|
|
|
|
/* starting stack location.. */
|
|
|
|
|
|
|
|
xhandler->error = error;
|
|
|
|
longmp( xhandler->jump_buffer, 1 );
|
|
|
|
}
|