ref: 660138753b036ea5fe14c55c1ee2a57ea7615431
parent: 8db6a0702147a56a5c26fb66e6caf7de9869953e
author: David Turner <[email protected]>
date: Thu Jul 11 12:27:16 EDT 2002
updatinf the object sub-system and dynamic hash table implementations
--- a/include/freetype/fttypes.h
+++ b/include/freetype/fttypes.h
@@ -21,6 +21,7 @@
#include <ft2build.h>
+#include FT_CONFIG_CONFIG_H
#include FT_SYSTEM_H
#include FT_IMAGE_H
--- a/include/freetype/internal/fthash.h
+++ b/include/freetype/internal/fthash.h
@@ -125,7 +125,7 @@
FT_Hash_EqualFunc node_equal;
FT_Memory memory;
- } FT_HashRec, *FT_Hash;
+ } FT_HashRec;
/***********************************************************
@@ -270,7 +270,7 @@
*/
FT_BASE_DEF( FT_HashLookup )
ft_hash_lookup( FT_Hash table,
- FT_HashNode keynode )
+ FT_HashNode keynode );
/****************************************************************
@@ -380,7 +380,7 @@
*/
FT_BASE( FT_Error )
ft_hash_remove( FT_Hash table,
- FT_HashLookup lookup )
+ FT_HashLookup lookup );
--- a/include/freetype/internal/ftobject.h
+++ b/include/freetype/internal/ftobject.h
@@ -288,14 +288,17 @@
*
* @note:
* if 'obj_init' is NULL, the class will use it's parent
- * constructor.
+ * constructor, if any
*
* if 'obj_done' is NULL, the class will use it's parent
- * finalizer.
+ * finalizer, if any
*
* the object sub-system allocates a new class, copies
* the content of its super-class into the new structure,
* _then_ calls 'clazz_init'.
+ *
+ * 'class_init' and 'class_done' can be NULL, in which case
+ * the parent's class constructor and destructor wil be used
*/
typedef struct FT_TypeRec_
{
@@ -337,7 +340,7 @@
* @return:
* 1 iff the handle points to a valid object. 0 otherwise
*/
- FT_BASE_DEF( FT_Int )
+ FT_BASE( FT_Int )
ft_object_check( FT_Pointer obj );
@@ -357,7 +360,7 @@
* 1 iff the handle points to a valid 'clazz' instance. 0
* otherwise.
*/
- FT_BASE_DEF( FT_Int )
+ FT_BASE( FT_Int )
ft_object_is_a( FT_Pointer obj,
FT_Class clazz );
@@ -379,7 +382,7 @@
* @return:
* error code. 0 means success
*/
- FT_BASE_DEF( FT_Error )
+ FT_BASE( FT_Error )
ft_object_create( FT_Object *aobject,
FT_Class clazz,
FT_Pointer init_data );
@@ -408,7 +411,7 @@
* this is equivalent to calling @ft_class_from_type followed by
* @ft_object_create
*/
- FT_BASE_DEF( FT_Error )
+ FT_BASE( FT_Error )
ft_object_create_from_type( FT_Object *aobject,
FT_Type type,
FT_Pointer init_data,
@@ -438,7 +441,7 @@
* code returned by the object constructor.
*/
#define FT_CREATE( _obj, _clazz, _init ) \
- FT_MEM_SET( FT_OBJ_CREATE( _obj, _clazz, _init ) )
+ FT_SET_ERROR( FT_OBJ_CREATE( _obj, _clazz, _init ) )
/**************************************************************
*
@@ -462,7 +465,7 @@
* code returned by the object constructor.
*/
#define FT_CREATE_FROM_TYPE( _obj, _type, _init, _lib ) \
- FT_MEM_SET( FT_OBJ_CREATE( _obj, _type, _init, _lib ) )
+ FT_SET_ERROR( FT_OBJ_CREATE_FROM_TYPE( _obj, _type, _init, _lib ) )
/* */
@@ -486,39 +489,12 @@
* @return:
* error code. 0 means success
*/
- FT_BASE_DEF( FT_Error )
+ FT_BASE( FT_Error )
ft_class_from_type( FT_Class *aclass,
FT_Type type,
FT_Library library );
- /**************************************************************
- *
- * @function: ft_class_from_name
- *
- * @description:
- * retrieves the class object corresponding to a given type
- * name. The class is created when needed
- *
- * @output:
- * aclass :: handle to corresponding class object. NULL
- * in case of error
- *
- * @input:
- * name :: class name
- * library :: library handle
- *
- * @return:
- * error code. 0 means success
- *
- * @note:
- * this function is _very_ slow. You should only use it for
- * debugging purposes..
- */
- FT_BASE_DEF( FT_Error )
- ft_class_from_name( FT_Class *aclass,
- FT_CString class_name,
- FT_Library library );
/* */
#include FT_INTERNAL_HASH_H
@@ -542,12 +518,12 @@
/* initialize meta class */
- FT_BASE_DEF( FT_Error )
+ FT_BASE( FT_Error )
ft_metaclass_init( FT_MetaClass meta,
FT_Library library );
/* finalize meta class - destroy all registered class objects */
- FT_BASE_DEF( void )
+ FT_BASE( void )
ft_metaclass_done( FT_MetaClass meta );
/* */
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -34,8 +34,8 @@
#include FT_INTERNAL_GLYPH_LOADER_H
#include FT_INTERNAL_DRIVER_H
#include FT_INTERNAL_AUTOHINT_H
+#include FT_INTERNAL_OBJECT_H
-
FT_BEGIN_HEADER
@@ -694,6 +694,8 @@
FT_ULong raster_pool_size; /* size of render pool in bytes */
FT_DebugHook_Func debug_hooks[4];
+
+ FT_MetaClassRec meta_class;
} FT_LibraryRec;
--- a/include/freetype/internal/internal.h
+++ b/include/freetype/internal/internal.h
@@ -35,6 +35,8 @@
#define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h>
#define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h>
#define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h>
+#define FT_INTERNAL_HASH_H <freetype/internal/fthash.h>
+#define FT_INTERNAL_OBJECT_H <freetype/internal/ftobject.h>
#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h>
#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h>
--- a/src/base/Jamfile
+++ b/src/base/Jamfile
@@ -25,7 +25,7 @@
#
Library $(FT2_LIB) : ftsystem.c ftinit.c ftglyph.c ftmm.c ftbdf.c
ftbbox.c ftdebug.c ftxf86.c fttype1.c ftstroker.c
- ftsynth.c ;
+ ftsynth.c ftobject.c fthash.c ;
# Add Macintosh-specific file to the library when necessary.
#
--- a/src/base/fthash.c
+++ b/src/base/fthash.c
@@ -1,4 +1,6 @@
-#include "fthash.h"
+#include <ft2build.h>
+#include FT_TYPES_H
+#include FT_INTERNAL_HASH_H
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_DEBUG_H
@@ -27,7 +29,7 @@
table->mask = 0;
table->slack = 0;
- table->compare = NULL;
+ table->node_equal = NULL;
}
}
@@ -46,17 +48,21 @@
FT_BASE_DEF( FT_Error )
- ft_hash_init( FT_Hash table,
- FT_Hash_CompareFunc compare,
- FT_Memory memory )
+ ft_hash_init( FT_Hash table,
+ FT_Hash_EqualFunc equal,
+ FT_Memory memory )
{
- hash->memory = memory;
- hash->compare = node_compare;
- hash->p = 0;
- hash->mask = FT_HASH_INITIAL_SIZE-1;
- hash->slack = FT_HASH_INITIAL_SIZE*FT_HASH_MAX_LOAD;
+ FT_Error error;
- FT_NEW_ARRAY( hash->buckets, FT_HASH_INITIAL_SIZE*2 );
+ table->memory = memory;
+ table->p = 0;
+ table->mask = FT_HASH_INITIAL_SIZE-1;
+ table->slack = FT_HASH_INITIAL_SIZE*FT_HASH_MAX_LOAD;
+ table->node_equal = equal;
+
+ (void)FT_NEW_ARRAY( table->buckets, FT_HASH_INITIAL_SIZE*2 );
+
+ return error;
}
@@ -84,12 +90,13 @@
- FT_BASE_DEF( FT_HashNode* )
+ FT_BASE_DEF( FT_HashLookup )
ft_hash_lookup( FT_Hash table,
FT_HashNode keynode )
{
- FT_UInt index;
- FT_UInt23 hash = keynode->hash;
+ FT_UInt index;
+ FT_UInt32 hash = keynode->hash;
+ FT_HashNode node, *pnode;
index = (FT_UInt)(hash & table->mask);
if ( index < table->p )
@@ -102,7 +109,7 @@
if ( node == NULL )
break;
- if ( node->hash == hash && table->compare( node, keynode ) )
+ if ( node->hash == hash && table->node_equal( node, keynode ) )
break;
pnode = &node->link;
@@ -114,20 +121,22 @@
- FT_BASE_DEF( void )
- ft_hash_add( FT_Hash table,
- FT_HashNode* pnode,
- FT_HashNode new_node )
+ FT_BASE_DEF( FT_Error )
+ ft_hash_add( FT_Hash table,
+ FT_HashLookup lookup,
+ FT_HashNode new_node )
{
+ FT_Error error = 0;
+
/* add it to the hash table */
- new_node->link = *pnode;
- *pnode = new_node;
+ new_node->link = *lookup;
+ *lookup = new_node;
if ( --table->slack < 0 )
{
FT_UInt p = table->p;
FT_UInt mask = table->mask;
- FT_HashNode new_list;
+ FT_HashNode new_list, node, *pnode;
/* split a single bucket */
new_list = NULL;
@@ -154,7 +163,12 @@
if ( p >= mask )
{
- FT_RENEW_ARRAY( hash->buckets, (mask+1)*2, (mask+1)*4 );
+ FT_Memory memory = table->memory;
+
+
+ if (FT_RENEW_ARRAY( table->buckets, (mask+1)*2, (mask+1)*4 ))
+ goto Exit;
+
table->mask = 2*mask + 1;
table->p = 0;
}
@@ -161,22 +175,25 @@
else
table->p = p + 1;
}
+ Exit:
+ return error;
}
- FT_BASE_DEF( FT_Int )
- ft_hash_remove( FT_Hash table,
- FT_HashNode* pnode )
+ FT_BASE_DEF( FT_Error )
+ ft_hash_remove( FT_Hash table,
+ FT_HashLookup lookup )
{
FT_HashNode node;
FT_UInt num_buckets;
+ FT_Error error = 0;
FT_ASSERT( pnode != NULL && node != NULL );
- node = *pnode;
- *pnode->link = node->link;
- node->link = NULL;
+ node = *lookup;
+ *lookup = node->link;
+ node->link = NULL;
num_buckets = ( table->p + table->mask + 1) ;
@@ -189,14 +206,26 @@
FT_HashNode* pold;
if ( old_index < FT_HASH_INITIAL_SIZE )
- return;
+ goto Exit;
if ( p == 0 )
{
+ FT_Memory memory = table->memory;
+
table->mask >>= 1;
p = table->mask;
- FT_RENEW_ARRAY( hash->buckets, (mask+1)*2, (mask+1) );
+ if ( FT_RENEW_ARRAY( table->buckets, (mask+1)*2, (mask+1) ) )
+ {
+ /* this should never happen normally, but who knows :-) */
+ /* we need to re-inject the node in the hash table before */
+ /* returning there, since it's safer */
+ pnode = table->buckets;
+ node->link = *pnode;
+ *pnode = node;
+
+ goto Exit;
+ }
}
else
p--;
@@ -212,4 +241,6 @@
table->slack -= FT_HASH_MAX_LOAD;
table->p = p;
}
+ Exit:
+ return error;
}
--- a/src/base/ftobject.c
+++ b/src/base/ftobject.c
@@ -1,13 +1,16 @@
-#include "ftobject.h"
-#include "fthash.h"
+#include <ft2build.h>
+#include FT_INTERNAL_OBJECT_H
+#include FT_INTERNAL_OBJECTS_H
#define FT_MAGIC_DEATH 0xDEADdead
#define FT_MAGIC_CLASS 0x12345678
+#define FT_TYPE_HASH(x) (( (FT_UInt32)(x) >> 2 )^( (FT_UInt32)(x) >> 10 ))
+
#define FT_OBJECT_CHECK(o) \
- ( FT_OBJECT(o) != NULL && \
- FT_OBJECT(o)->clazz != NULL && \
- FT_OBJECT(o)->ref_count >= 1 && \
+ ( FT_OBJECT(o) != NULL && \
+ FT_OBJECT(o)->clazz != NULL && \
+ FT_OBJECT(o)->ref_count >= 1 && \
FT_OBJECT(o)->clazz->magic == FT_MAGIC_CLASS )
@@ -21,28 +24,6 @@
/*******************************************************************/
/*******************************************************************/
- /* we use a dynamic hash table to map types to classes */
- /* this structure defines the layout of each node of */
- /* this table */
- typedef struct FT_ClassHNodeRec_
- {
- FT_HashNodeRec hnode;
- FT_Type ctype;
- FT_Class clazz;
-
- } FT_ClassHNodeRec, *FT_ClassHNode;
-
-
- /* the meta class contains a type -> class mapping */
- /* and owns all class objects.. */
- /* */
- typedef struct FT_MetaClassRec_
- {
- FT_ClassRec clazz;
- FT_HashRec type_to_class;
-
- } FT_MetaClassRec, *FT_MetaClass;
-
/* forward declaration */
static const FT_TypeRec ft_meta_class_type;
@@ -51,12 +32,12 @@
static void
ft_class_hnode_destroy( FT_ClassHNode node )
{
- FT_Clazz clazz = node->clazz;
+ FT_Class clazz = node->clazz;
FT_Memory memory = clazz->memory;
FT_Type ctype = clazz->type;
- if ( ctype->class_done )
- ctype->class_done( clazz );
+ if ( clazz->class_done )
+ clazz->class_done( (FT_Object) clazz );
FT_FREE( clazz );
@@ -68,32 +49,81 @@
static FT_Int
- ft_class_hnode_compare( const FT_ClassHNode node1,
- const FT_ClassHNode node2 )
+ ft_type_equal( FT_Type type1,
+ FT_Type type2 )
{
- return ( node1->type == node2->type );
+ if ( type1 == type2 )
+ goto Ok;
+
+ if ( type1 == NULL || type2 == NULL )
+ goto Fail;
+
+ /* compare parent types */
+ if ( type1->super != type2->super )
+ {
+ if ( type1->super == NULL ||
+ type2->super == NULL ||
+ !ft_type_compare( type1, type2 ) )
+ goto Fail;
+ }
+
+ /* compare type names */
+ if ( type1->name != type2->name )
+ {
+ if ( type1->name == NULL ||
+ type2->name == NULL ||
+ ft_strcmp( type1->name, type2->name ) != 0 )
+ goto Fail;
+ }
+
+ /* compare the other type fields */
+ if ( type1->class_size != type2->class_size ||
+ type1->class_init != type2->class_init ||
+ type1->class_done != type2->class_done ||
+ type1->obj_size != type2->obj_size ||
+ type1->obj_init != type2->obj_init ||
+ type1->obj_done != type2->obj_done )
+ goto Fail;
+
+ Ok:
+ return 1;
+
+ Fail:
+ return 0;
}
- static void
+ static FT_Int
+ ft_class_hnode_equal( const FT_ClassHNode node1,
+ const FT_ClassHNode node2 )
+ {
+ FT_Type type1 = node1->type;
+ FT_Type type2 = node2->type;
+
+ /* comparing the pointers should work in 99% of cases */
+ return ( type1 == type2 ) ? 1 : ft_type_equal( type1, type2 );
+ }
+
+
+ FT_BASE_DEF( void )
ft_metaclass_done( FT_MetaClass meta )
{
- /* clear all objects */
+ /* clear all classes */
ft_hash_done( &meta->type_to_class,
- (FT_Hash_ForeachFunc) ft_class_destroy,
+ (FT_Hash_ForeachFunc) ft_class_hnode_destroy,
NULL );
- meta->clazz->object.clazz = NULL;
- meta->clazz->object.ref_count = 0;
- meta->clazz->magic = FT_MAGIC_DEATH;
+ meta->clazz.object.clazz = NULL;
+ meta->clazz.object.ref_count = 0;
+ meta->clazz.magic = FT_MAGIC_DEATH;
}
- static void
+ FT_BASE_DEF( FT_Error )
ft_metaclass_init( FT_MetaClass meta,
FT_Library library )
{
- FT_ClassRec* clazz = meta->clazz;
+ FT_ClassRec* clazz = (FT_ClassRec*) &meta->clazz;
/* the meta-class is its OWN class !! */
clazz->object.clazz = (FT_Class) clazz;
@@ -101,20 +131,25 @@
clazz->magic = FT_MAGIC_CLASS;
clazz->library = library;
clazz->memory = library->memory;
- clazz->type = &ft_metaclass_type;
+ clazz->type = &ft_meta_class_type;
clazz->info = NULL;
+ clazz->class_done = (FT_Object_DoneFunc) ft_metaclass_done;
+
clazz->obj_size = sizeof( FT_ClassRec );
clazz->obj_init = NULL;
clazz->obj_done = NULL;
- ft_hash_init( &meta->type_to_class,
- (FT_Hash_CompareFunc) ft_class_hnode_compare,
- library->memory );
+ return ft_hash_init( &meta->type_to_class,
+ (FT_Hash_EqualFunc) ft_class_hnode_equal,
+ library->memory );
}
/* find or create the class corresponding to a given type */
+ /* note that this function will retunr NULL in case of */
+ /* memory overflow */
+ /* */
static FT_Class
ft_metaclass_get_class( FT_MetaClass meta,
FT_Type ctype )
@@ -121,29 +156,105 @@
{
FT_ClassHNodeRec keynode, *node, **pnode;
FT_Memory memory;
+ FT_ClassRec* clazz;
+ FT_Class parent;
+ FT_Error error;
- keynode.hnode.hash = (FT_UInt32)( ctype >> 2 );
- keynode.type = type;
+ keynode.hnode.hash = FT_TYPE_HASH( ctype );
+ keynode.type = ctype;
- pnode = (FT_ClassHNode) ft_hash_lookup( &meta->type_to_class,
- &noderec );
+ pnode = (FT_ClassHNode*) ft_hash_lookup( &meta->type_to_class,
+ (FT_HashNode) &keynode );
node = *pnode;
if ( node != NULL )
- return node->clazz;
+ {
+ clazz = (FT_ClassRec*) node->clazz;
+ goto Exit;
+ }
memory = FT_CLASS__MEMORY(meta);
- node = FT_MEM_SAFE_ALLOC( sizeof(*node) );
- if ( node != NULL )
+ clazz = NULL;
+ parent = NULL;
+ if ( ctype->super != NULL )
{
- FT_ClassRec* clazz;
+ FT_ASSERT( ctype->super->class_size <= ctype->class_size );
+ FT_ASSERT( ctype->super->obj_size <= ctype->obj_size );
- clazz = FT_MEM_SAFE_ALLOC( ctype->class_size );
- if ( clazz == NULL )
+ parent = ft_metaclass_get_class( meta, ctype->super );
+ }
+
+ if ( !FT_NEW( node ) )
+ {
+ if ( !FT_ALLOC( clazz, ctype->class_size ) )
{
+ if ( parent )
+ FT_MEM_COPY( (FT_ClassRec*)clazz, parent, parent->type->class_size );
+
+ clazz->object.clazz = (FT_Class) meta;
+ clazz->object.ref_count = 1;
+
+ clazz->memory = memory;
+ clazz->library = FT_CLASS__LIBRARY(meta);
+ clazz->super = parent;
+ clazz->type = ctype;
+ clazz->info = NULL;
+ clazz->magic = FT_MAGIC_CLASS;
+
+ clazz->class_done = ctype->class_done;
+ clazz->obj_size = ctype->obj_size;
+ clazz->obj_init = ctype->obj_init;
+ clazz->obj_done = ctype->obj_done;
+
+ if ( parent )
+ {
+ if ( clazz->class_done == NULL )
+ clazz->class_done = parent->class_done;
+
+ if ( clazz->obj_init == NULL )
+ clazz->obj_init = parent->obj_init;
+
+ if ( clazz->obj_done == NULL )
+ clazz->obj_done = parent->obj_done;
+ }
+
+ /* find class initializer, if any */
+ {
+ FT_Type ztype = ctype;
+ FT_Object_InitFunc cinit = NULL;
+
+ do
+ {
+ cinit = ztype->class_init;
+ if ( cinit != NULL )
+ break;
+
+ ztype = ztype->super;
+ }
+ while ( ztype != NULL );
+
+ /* then call it when needed */
+ if ( cinit != NULL )
+ error = cinit( (FT_Object) clazz, NULL );
+ }
+ }
+
+ if (error)
+ {
+ if ( clazz )
+ {
+ /* we always call the class destructor when */
+ /* an error was detected in the constructor !! */
+ if ( clazz->class_done )
+ clazz->class_done( (FT_Object) clazz );
+
+ FT_FREE( clazz );
+ }
FT_FREE( node );
- FT_XTHROW( FT_Err_Out_Of_Memory );
}
}
+
+ Exit:
+ return (FT_Class) clazz;
}
@@ -157,8 +268,8 @@
(FT_Object_DoneFunc) ft_metaclass_done,
sizeof( FT_ClassRec ),
- (FT_Object_InitFunc) ft_class_init,
- (FT_Object_DoneFunc) ft_class_done
+ (FT_Object_InitFunc) NULL,
+ (FT_Object_DoneFunc) NULL
};
@@ -204,90 +315,69 @@
}
- /* the cleanup routine for all objects */
- static void
- ft_object_cleanup( FT_Object object )
+ FT_BASE_DEF( FT_Error )
+ ft_object_create( FT_Object *pobject,
+ FT_Class clazz,
+ FT_Pointer init_data )
{
- FT_Memory memory = FT_OBJECT__MEMORY(object);
- FT_Class clazz = FT_OBJECT__CLASS(object);
-
- if ( clazz->obj_done )
- clazz->obj_done( object );
-
- FT_FREE( object );
- }
-
-
- FT_BASE_DEF( FT_Object )
- ft_object_new( FT_Class clazz,
- FT_Pointer init_data )
- {
FT_Memory memory;
+ FT_Error error;
FT_Object obj;
-
FT_ASSERT_IS_CLASS(clazz);
- memory = FT_CLASS__MEMORY(clazz);
- obj = ft_mem_alloc( clazz->obj_size, memory );
- obj->clazz = clazz;
- obj->ref_count = 1;
-
- if ( clazz->obj_init )
+ memory = FT_CLASS__MEMORY(memory);
+ if ( !FT_ALLOC( obj, clazz->obj_size ) )
{
- FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory);
+ obj->clazz = clazz;
+ obj->ref_count = 1;
+ if ( clazz->obj_init )
+ {
+ error = clazz->obj_init( obj, init_data );
+ if ( error )
+ {
+ /* IMPORTANT: call the destructor when an error */
+ /* was detected in the constructor !! */
+ if ( clazz->obj_done )
+ clazz->obj_done( obj );
- ft_cleanup_push( stack, obj, (FT_CleanupFunc) ft_object_cleanup, NULL );
-
- clazz->obj_init( obj, init_data );
-
- ft_cleanup_pop( stack, obj, 0 );
+ FT_FREE( obj );
+ }
+ }
}
- return obj;
+ *pobject = obj;
+ return error;
}
-
- FT_BASE_DEF( void )
- ft_object_create( FT_Object *pobject,
- FT_Class clazz,
- FT_Pointer init_data )
+ FT_BASE_DEF( FT_Class )
+ ft_class_find_by_type( FT_Type type,
+ FT_Library library )
{
- FT_Memory memory;
- FT_Object obj;
+ FT_MetaClass meta = &library->meta_class;
- FT_ASSERT_IS_CLASS(clazz);
-
- memory = FT_CLASS__MEMORY(memory);
- obj = ft_mem_alloc( clazz->obj_size, memory );
- obj->clazz = clazz;
- obj->ref_count = 1;
- *pobject = obj;
-
- if ( clazz->obj_init )
- clazz->obj_init( obj, init_data );
+ return ft_metaclass_get_class( meta, type );
}
- FT_BASE_DEF( FT_Class )
- ft_class_find_by_type( FT_Type type,
- FT_Memory memory )
- {
- }
-
-
- FT_BASE_DEF( FT_Class )
- ft_class_find_by_name( FT_CString class_name,
- FT_Memory memory );
-
- FT_BASE_DEF( FT_Object )
- ft_object_new_from_type( FT_Type type,
- FT_Pointer data,
- FT_Memory memory );
-
- FT_BASE_DEF( void )
+ FT_BASE_DEF( FT_Error )
ft_object_create_from_type( FT_Object *pobject,
FT_Type type,
FT_Pointer init_data,
- FT_Memory memory );
+ FT_Library library )
+ {
+ FT_Class clazz;
+ FT_Error error;
+
+ clazz = ft_class_find_by_type( type, library );
+ if ( clazz )
+ error = ft_object_create( pobject, clazz, init_data );
+ else
+ {
+ *pobject = NULL;
+ error = FT_Err_Out_Of_Memory;
+ }
+
+ return error;
+ }