2000-01-09 18:54:56 +01:00
|
|
|
/***************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* 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. */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
2000-05-11 20:23:52 +02:00
|
|
|
#include <freetype/internal/ftextend.h>
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
/* required by the tracing mode */
|
|
|
|
#undef FT_COMPONENT
|
2000-01-09 18:54:56 +01:00
|
|
|
#define FT_COMPONENT trace_extend
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
typedef struct FT_Extension_Registry_
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Int num_extensions;
|
|
|
|
FT_Long cur_offset;
|
|
|
|
FT_Extension_Class classes[FT_MAX_EXTENSIONS];
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
} FT_Extension_Registry;
|
|
|
|
|
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* FT_Init_Extensions */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Initializes the extension component. */
|
|
|
|
/* */
|
|
|
|
/* <InOut> */
|
|
|
|
/* driver :: A handle to the driver object. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
|
|
|
FT_Error FT_Init_Extensions( FT_Driver driver )
|
|
|
|
{
|
2000-01-09 18:54:56 +01:00
|
|
|
FT_Error error;
|
1999-12-17 00:11:37 +01:00
|
|
|
FT_Memory memory;
|
|
|
|
FT_Extension_Registry* registry;
|
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
memory = driver->library->memory;
|
2000-01-09 18:54:56 +01:00
|
|
|
if ( ALLOC( registry, sizeof ( *registry ) ) )
|
1999-12-17 00:11:37 +01:00
|
|
|
return error;
|
|
|
|
|
|
|
|
registry->num_extensions = 0;
|
|
|
|
registry->cur_offset = 0;
|
|
|
|
driver->extensions = registry;
|
|
|
|
|
|
|
|
return FT_Err_Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* FT_Done_Extensions */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Finalizes the extension component. */
|
|
|
|
/* */
|
|
|
|
/* <InOut> */
|
|
|
|
/* driver :: A handle to the driver object. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
|
|
|
FT_Error FT_Done_Extensions( FT_Driver driver )
|
|
|
|
{
|
|
|
|
FT_Memory memory = driver->memory;
|
2000-01-09 18:54:56 +01:00
|
|
|
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
FREE( driver->extensions );
|
|
|
|
return FT_Err_Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <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. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
EXPORT_FUNC
|
|
|
|
FT_Error FT_Register_Extension( FT_Driver driver,
|
2000-01-09 18:54:56 +01:00
|
|
|
FT_Extension_Class* class )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Extension_Registry* registry;
|
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
registry = (FT_Extension_Registry*)driver->extensions;
|
2000-01-09 18:54:56 +01:00
|
|
|
if ( registry )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Int n = registry->num_extensions;
|
|
|
|
FT_Extension_Class* cur = registry->classes + n;
|
2000-01-09 18:54:56 +01:00
|
|
|
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
if ( n >= FT_MAX_EXTENSIONS )
|
|
|
|
return FT_Err_Too_Many_Extensions;
|
|
|
|
|
2000-01-10 18:19:45 +01:00
|
|
|
*cur = *class;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
cur->offset = registry->cur_offset;
|
|
|
|
|
|
|
|
registry->num_extensions++;
|
|
|
|
registry->cur_offset += ( cur->size + FT_ALIGNMENT-1 ) & -FT_ALIGNMENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FT_Err_Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <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 pointer to the extension block. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
EXPORT_FUNC
|
|
|
|
void* FT_Get_Extension( FT_Face face,
|
|
|
|
const char* extension_id,
|
2000-01-10 18:19:45 +01:00
|
|
|
void* *extension_interface )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Extension_Registry* registry;
|
2000-01-09 18:54:56 +01:00
|
|
|
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
registry = (FT_Extension_Registry*)face->driver->extensions;
|
2000-01-09 18:54:56 +01:00
|
|
|
if ( registry && face->extensions )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Extension_Class* cur = registry->classes;
|
|
|
|
FT_Extension_Class* limit = cur + registry->num_extensions;
|
2000-01-09 18:54:56 +01:00
|
|
|
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
for ( ; cur < limit; cur++ )
|
|
|
|
if ( strcmp( cur->id, extension_id ) == 0 )
|
|
|
|
{
|
|
|
|
*extension_interface = cur->interface;
|
|
|
|
return (void*)((char*)face->extensions + cur->offset);
|
|
|
|
}
|
|
|
|
}
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* could not find the extension id */
|
2000-01-09 18:54:56 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
*extension_interface = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <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. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
|
|
|
FT_Error FT_Destroy_Extensions( FT_Face face )
|
|
|
|
{
|
|
|
|
FT_Extension_Registry* registry;
|
|
|
|
FT_Memory memory;
|
2000-01-09 18:54:56 +01:00
|
|
|
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
registry = (FT_Extension_Registry*)face->driver->extensions;
|
2000-01-09 18:54:56 +01:00
|
|
|
if ( registry && face->extensions )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Extension_Class* cur = registry->classes;
|
|
|
|
FT_Extension_Class* limit = cur + registry->num_extensions;
|
2000-01-09 18:54:56 +01:00
|
|
|
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
for ( ; cur < limit; cur++ )
|
|
|
|
{
|
|
|
|
char* ext = (char*)face->extensions + cur->offset;
|
2000-01-10 18:19:45 +01:00
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
if ( cur->finalize )
|
1999-12-17 00:11:37 +01:00
|
|
|
cur->finalize( ext, face );
|
|
|
|
}
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
memory = face->driver->memory;
|
|
|
|
FREE( face->extensions );
|
|
|
|
}
|
2000-01-09 18:54:56 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
return FT_Err_Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <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. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
|
|
|
FT_Error FT_Create_Extensions( FT_Face face )
|
|
|
|
{
|
|
|
|
FT_Extension_Registry* registry;
|
|
|
|
FT_Memory memory;
|
|
|
|
FT_Error error;
|
2000-01-09 18:54:56 +01:00
|
|
|
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
face->extensions = 0;
|
2000-01-10 18:19:45 +01:00
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
/* load extensions registry, exit successfully if none is there */
|
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
registry = (FT_Extension_Registry*)face->driver->extensions;
|
2000-01-09 18:54:56 +01:00
|
|
|
if ( !registry )
|
|
|
|
return FT_Err_Ok;
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
memory = face->driver->memory;
|
|
|
|
if ( ALLOC( face->extensions, registry->cur_offset ) )
|
|
|
|
return error;
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Extension_Class* cur = registry->classes;
|
|
|
|
FT_Extension_Class* limit = cur + registry->num_extensions;
|
2000-01-09 18:54:56 +01:00
|
|
|
|
2000-01-10 18:19:45 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
for ( ; cur < limit; cur++ )
|
|
|
|
{
|
|
|
|
char* ext = (char*)face->extensions + cur->offset;
|
2000-01-10 18:19:45 +01:00
|
|
|
|
2000-01-09 18:54:56 +01:00
|
|
|
if ( cur->init )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
error = cur->init( ext, face );
|
2000-01-09 18:54:56 +01:00
|
|
|
if ( error )
|
|
|
|
break;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-01-09 18:54:56 +01:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* END */
|