Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
tree: 70951bc71b
Fetching contributors…

Cannot retrieve contributors at this time

333 lines (264 sloc) 13.644 kb
/***************************************************************************/
/* */
/* 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 "ftextend.h"
#include "ftdebug.h"
/*************************************************************************/
/* */
/* 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;
/*************************************************************************/
/* */
/* <Function> */
/* FT_Init_Extensions */
/* */
/* <Description> */
/* Initializes the extension component. */
/* */
/* <InOut> */
/* driver :: A handle to the driver object. */
/* */
/* <Return> */
/* 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;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Done_Extensions */
/* */
/* <Description> */
/* Finalizes the extension component. */
/* */
/* <InOut> */
/* driver :: A handle to the driver object. */
/* */
/* <Return> */
/* 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;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Register_Extension */
/* */
/* <Description> */
/* Registers a new extension. */
/* */
/* <InOut> */
/* driver :: A handle to the driver object. */
/* class :: A pointer to a class describing the extension. */
/* */
/* <Return> */
/* 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;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Get_Extension */
/* */
/* <Description> */
/* Queries an extension block by an extension ID string. */
/* */
/* <Input> */
/* face :: A handle to the face object. */
/* extension_id :: An ID string identifying the extension. */
/* */
/* <Output> */
/* extension_interface :: A generic pointer, usually pointing to a */
/* table of functions implementing the */
/* extension interface. */
/* */
/* <Return> */
/* 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;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Destroy_Extensions */
/* */
/* <Description> */
/* Destroys all extensions within a face object. */
/* */
/* <InOut> */
/* face :: A handle to the face object. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* 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;
}
/*************************************************************************/
/* */
/* <Function> */
/* FT_Create_Extensions */
/* */
/* <Description> */
/* Creates an extension object within a face object for all */
/* registered extensions. */
/* */
/* <InOut> */
/* face :: A handle to the face object. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
/* <Note> */
/* 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 */
Jump to Line
Something went wrong with that request. Please try again.