X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1e1af41e4b811fa4e927b61234c6fd90e254ec09..cabec8729e0b28f790d4a7f068a25697b9aa9dab:/src/freetype/base/ftextend.c diff --git a/src/freetype/base/ftextend.c b/src/freetype/base/ftextend.c new file mode 100644 index 0000000000..f298b19a8a --- /dev/null +++ b/src/freetype/base/ftextend.c @@ -0,0 +1,332 @@ +/***************************************************************************/ +/* */ +/* ftextend.h */ +/* */ +/* FreeType extensions implementation (body). */ +/* */ +/* Copyright 1996-2000 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* 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. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* This is an updated version of the extension component, now located */ + /* in the main library's source directory. It allows the dynamic */ + /* registration/use of various face object extensions through a simple */ + /* API. */ + /* */ + /*************************************************************************/ + + +#include +#include + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_extend + + + typedef struct FT_Extension_Registry_ + { + FT_Int num_extensions; + FT_Long cur_offset; + FT_Extension_Class classes[FT_MAX_EXTENSIONS]; + + } FT_Extension_Registry; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Init_Extensions */ + /* */ + /* */ + /* Initializes the extension component. */ + /* */ + /* */ + /* driver :: A handle to the driver object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + LOCAL_FUNC + FT_Error FT_Init_Extensions( FT_Driver driver ) + { + FT_Error error; + FT_Memory memory; + FT_Extension_Registry* registry; + + + memory = driver->root.library->memory; + if ( ALLOC( registry, sizeof ( *registry ) ) ) + return error; + + registry->num_extensions = 0; + registry->cur_offset = 0; + driver->extensions = registry; + + FT_TRACE2(( "FT_Init_Extensions: success\n" )); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Done_Extensions */ + /* */ + /* */ + /* Finalizes the extension component. */ + /* */ + /* */ + /* driver :: A handle to the driver object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + LOCAL_FUNC + FT_Error FT_Done_Extensions( FT_Driver driver ) + { + FT_Memory memory = driver->root.memory; + + + FREE( driver->extensions ); + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Register_Extension */ + /* */ + /* */ + /* Registers a new extension. */ + /* */ + /* */ + /* driver :: A handle to the driver object. */ + /* class :: A pointer to a class describing the extension. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + FT_EXPORT_FUNC( FT_Error ) FT_Register_Extension( + FT_Driver driver, + FT_Extension_Class* clazz ) + { + FT_Extension_Registry* registry; + + + if ( !driver ) + return FT_Err_Invalid_Driver_Handle; + + if ( !clazz ) + return FT_Err_Invalid_Argument; + + registry = (FT_Extension_Registry*)driver->extensions; + if ( registry ) + { + FT_Int n = registry->num_extensions; + FT_Extension_Class* cur = registry->classes + n; + + + if ( n >= FT_MAX_EXTENSIONS ) + return FT_Err_Too_Many_Extensions; + + *cur = *clazz; + + cur->offset = registry->cur_offset; + + registry->num_extensions++; + registry->cur_offset += + ( cur->size + FT_ALIGNMENT - 1 ) & -FT_ALIGNMENT; + + FT_TRACE1(( "FT_Register_Extension: `%s' successfully registered\n", + cur->id )); + } + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Get_Extension */ + /* */ + /* */ + /* Queries an extension block by an extension ID string. */ + /* */ + /* */ + /* face :: A handle to the face object. */ + /* extension_id :: An ID string identifying the extension. */ + /* */ + /* */ + /* extension_interface :: A generic pointer, usually pointing to a */ + /* table of functions implementing the */ + /* extension interface. */ + /* */ + /* */ + /* A generic pointer to the extension block. */ + /* */ + FT_EXPORT_FUNC( void* ) FT_Get_Extension( + FT_Face face, + const char* extension_id, + void** extension_interface ) + { + FT_Extension_Registry* registry; + + + if ( !face || !extension_id || !extension_interface ) + return 0; + + registry = (FT_Extension_Registry*)face->driver->extensions; + if ( registry && face->extensions ) + { + FT_Extension_Class* cur = registry->classes; + FT_Extension_Class* limit = cur + registry->num_extensions; + + + for ( ; cur < limit; cur++ ) + if ( strcmp( cur->id, extension_id ) == 0 ) + { + *extension_interface = cur->interface; + + FT_TRACE1(( "FT_Get_Extension: got `%s'\n", extension_id )); + + return (void*)((char*)face->extensions + cur->offset); + } + } + + /* could not find the extension id */ + + FT_ERROR(( "FT_Get_Extension: couldn't find `%s'\n", extension_id )); + + *extension_interface = 0; + + return 0; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Destroy_Extensions */ + /* */ + /* */ + /* Destroys all extensions within a face object. */ + /* */ + /* */ + /* face :: A handle to the face object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Called by the face object destructor. */ + /* */ + LOCAL_FUNC + FT_Error FT_Destroy_Extensions( FT_Face face ) + { + FT_Extension_Registry* registry; + FT_Memory memory; + + + registry = (FT_Extension_Registry*)face->driver->extensions; + if ( registry && face->extensions ) + { + FT_Extension_Class* cur = registry->classes; + FT_Extension_Class* limit = cur + registry->num_extensions; + + + for ( ; cur < limit; cur++ ) + { + char* ext = (char*)face->extensions + cur->offset; + + if ( cur->finalize ) + cur->finalize( ext, face ); + } + + memory = face->driver->root.memory; + FREE( face->extensions ); + } + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Create_Extensions */ + /* */ + /* */ + /* Creates an extension object within a face object for all */ + /* registered extensions. */ + /* */ + /* */ + /* face :: A handle to the face object. */ + /* */ + /* */ + /* FreeType error code. 0 means success. */ + /* */ + /* */ + /* Called by the face object constructor. */ + /* */ + LOCAL_FUNC + FT_Error FT_Create_Extensions( FT_Face face ) + { + FT_Extension_Registry* registry; + FT_Memory memory; + FT_Error error; + + + face->extensions = 0; + + /* load extensions registry; exit successfully if none is there */ + + registry = (FT_Extension_Registry*)face->driver->extensions; + if ( !registry ) + return FT_Err_Ok; + + memory = face->driver->root.memory; + if ( ALLOC( face->extensions, registry->cur_offset ) ) + return error; + + { + FT_Extension_Class* cur = registry->classes; + FT_Extension_Class* limit = cur + registry->num_extensions; + + + for ( ; cur < limit; cur++ ) + { + char* ext = (char*)face->extensions + cur->offset; + + if ( cur->init ) + { + error = cur->init( ext, face ); + if ( error ) + break; + } + } + } + + return error; + } + + +/* END */