FreeType 1.31.1
This commit is contained in:
212
lib/ttextend.c
Normal file
212
lib/ttextend.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/*******************************************************************
|
||||
*
|
||||
* ttextend.h 2.0
|
||||
*
|
||||
* Extensions Interface
|
||||
*
|
||||
* Copyright 1996-1999 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 "ttextend.h"
|
||||
#include "ttengine.h"
|
||||
#include "ttmemory.h"
|
||||
|
||||
/* required by the tracing mode */
|
||||
#undef TT_COMPONENT
|
||||
#define TT_COMPONENT trace_extend
|
||||
|
||||
|
||||
struct TExtension_Registry_
|
||||
{
|
||||
Int num_extensions;
|
||||
Long cur_offset;
|
||||
TExtension_Class classes[TT_MAX_EXTENSIONS];
|
||||
};
|
||||
|
||||
typedef struct TExtension_Registry_ TExtension_Registry;
|
||||
typedef TExtension_Registry* PExtension_Registry;
|
||||
|
||||
|
||||
|
||||
/* Initialize the extension component */
|
||||
|
||||
LOCAL_FUNC
|
||||
TT_Error TTExtend_Init( PEngine_Instance engine )
|
||||
{
|
||||
TT_Error error;
|
||||
PExtension_Registry exts;
|
||||
|
||||
|
||||
if ( ALLOC( exts, sizeof ( TExtension_Registry ) ) )
|
||||
return error;
|
||||
|
||||
exts->num_extensions = 0;
|
||||
exts->cur_offset = 0;
|
||||
engine->extension_component = (void*)exts;
|
||||
|
||||
return TT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* Finalize the extension component */
|
||||
|
||||
LOCAL_FUNC
|
||||
TT_Error TTExtend_Done( PEngine_Instance engine )
|
||||
{
|
||||
FREE( engine->extension_component );
|
||||
return TT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* Register a new extension */
|
||||
|
||||
EXPORT_FUNC
|
||||
TT_Error TT_Register_Extension( PEngine_Instance engine,
|
||||
Long id,
|
||||
Long size,
|
||||
PExt_Constructor create,
|
||||
PExt_Destructor destroy )
|
||||
{
|
||||
PExtension_Registry exts;
|
||||
PExtension_Class clazz;
|
||||
Int p;
|
||||
|
||||
|
||||
exts = (PExtension_Registry)engine->extension_component;
|
||||
if ( !exts )
|
||||
return TT_Err_Ok;
|
||||
|
||||
p = exts->num_extensions;
|
||||
|
||||
if ( p >= TT_MAX_EXTENSIONS )
|
||||
return TT_Err_Too_Many_Extensions;
|
||||
|
||||
clazz = exts->classes + p;
|
||||
clazz->id = id;
|
||||
clazz->size = size;
|
||||
clazz->build = create;
|
||||
clazz->destroy = destroy;
|
||||
|
||||
clazz->offset = exts->cur_offset;
|
||||
|
||||
exts->num_extensions++;
|
||||
exts->cur_offset += ( size + ALIGNMENT-1 ) & -ALIGNMENT;
|
||||
|
||||
return TT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* Query an extension block by extension_ID */
|
||||
|
||||
EXPORT_FUNC
|
||||
TT_Error TT_Extension_Get( PFace face,
|
||||
Long extension_id,
|
||||
void** extension_block )
|
||||
{
|
||||
PExtension_Registry registry;
|
||||
PExtension_Class clazz;
|
||||
Int n;
|
||||
|
||||
|
||||
if ( !face->extension )
|
||||
return TT_Err_Extensions_Unsupported;
|
||||
|
||||
registry = (PExtension_Registry)face->engine->extension_component;
|
||||
|
||||
for ( n = 0; n < face->n_extensions; n++ )
|
||||
{
|
||||
clazz = registry->classes + n;
|
||||
if ( clazz->id == extension_id )
|
||||
{
|
||||
*extension_block = (PByte)face->extension + clazz->offset;
|
||||
return TT_Err_Ok;
|
||||
}
|
||||
}
|
||||
|
||||
return TT_Err_Invalid_Extension_Id;
|
||||
}
|
||||
|
||||
|
||||
/* Destroy all extensions within a face object. Called by the */
|
||||
/* face object destructor. */
|
||||
|
||||
LOCAL_FUNC
|
||||
TT_Error Extension_Destroy( PFace face )
|
||||
{
|
||||
PEngine_Instance engine = face->engine;
|
||||
PExtension_Registry registry;
|
||||
PExtension_Class clazz;
|
||||
Int n;
|
||||
PByte ext;
|
||||
|
||||
|
||||
registry = (PExtension_Registry)engine->extension_component;
|
||||
|
||||
for ( n = 0; n < face->n_extensions; n++ )
|
||||
{
|
||||
clazz = registry->classes + n;
|
||||
ext = (PByte)face->extension + clazz->offset;
|
||||
|
||||
/* the destructor is optional */
|
||||
if ( clazz->destroy )
|
||||
clazz->destroy( (void*)ext, face );
|
||||
}
|
||||
|
||||
/* destroy the face's extension block too */
|
||||
FREE( face->extension );
|
||||
face->n_extensions = 0;
|
||||
|
||||
return TT_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
/* Create an extension within a face object. Called by the */
|
||||
/* face object constructor. */
|
||||
|
||||
LOCAL_FUNC
|
||||
TT_Error Extension_Create( PFace face )
|
||||
{
|
||||
PEngine_Instance engine = face->engine;
|
||||
PExtension_Registry registry;
|
||||
PExtension_Class clazz;
|
||||
TT_Error error;
|
||||
Int n;
|
||||
PByte ext;
|
||||
|
||||
|
||||
registry = (PExtension_Registry)engine->extension_component;
|
||||
|
||||
face->n_extensions = registry->num_extensions;
|
||||
if ( ALLOC( face->extension, registry->cur_offset ) )
|
||||
return error;
|
||||
|
||||
for ( n = 0; n < face->n_extensions; n++ )
|
||||
{
|
||||
clazz = registry->classes + n;
|
||||
ext = (PByte)face->extension + clazz->offset;
|
||||
error = clazz->build( (void*)ext, face );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
}
|
||||
return TT_Err_Ok;
|
||||
|
||||
Fail:
|
||||
Extension_Destroy( face );
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
Reference in New Issue
Block a user