Edit

kc3-lang/freetype/src/base/ftobject.c

Branch :

  • Show log

    Commit

  • Author : David Turner
    Date : 2002-08-22 20:35:36
    Hash : 5c0d3a4d
    Message : * src/base/ftobject.c, src/base/ftsynth.c, src/base/ftstroker.c, src/bdf/bdfdrivr.c: removed compiler warnings

  • src/base/ftobject.c
  • #include <ft2build.h>
    #include FT_INTERNAL_OBJECT_H
    #include FT_INTERNAL_DEBUG_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)->clazz->magic == FT_MAGIC_CLASS )
    
    #define  FT_CLASS_CHECK(c)  \
               ( FT_CLASS(c) != NULL && FT_CLASS(c)->magic == FT_MAGIC_CLASS )
    
    #define  FT_ASSERT_IS_CLASS(c)  FT_ASSERT( FT_CLASS_CHECK(c) )
    
     /*******************************************************************/
     /*******************************************************************/
     /*****                                                         *****/
     /*****                                                         *****/
     /*****                  M E T A - C L A S S                    *****/
     /*****                                                         *****/
     /*****                                                         *****/
     /*******************************************************************/
     /*******************************************************************/
    
     /* forward declaration */
      FT_BASE_DEF( FT_Error )
      ft_metaclass_init( FT_MetaClass  meta,
                         FT_Library    library );
    
      /* forward declaration */
      FT_BASE_DEF( void )
      ft_metaclass_done( FT_MetaClass  meta );
    
    
      /* class type for the meta-class itself */
      static const FT_TypeRec  ft_meta_class_type =
      {
        "FT2.MetaClass",
        NULL,
    
        sizeof( FT_MetaClassRec ),
        (FT_Object_InitFunc)  ft_metaclass_init,
        (FT_Object_DoneFunc)  ft_metaclass_done,
    
        sizeof( FT_ClassRec ),
        (FT_Object_InitFunc)  NULL,
        (FT_Object_DoneFunc)  NULL
      };
    
    
    
    
     /* destroy a given class */
      static void
      ft_class_hnode_destroy( FT_ClassHNode  node )
      {
        FT_Class   clazz  = node->clazz;
        FT_Memory  memory = clazz->memory;
    
        if ( clazz->class_done )
          clazz->class_done( (FT_Object) clazz );
    
        FT_FREE( clazz );
    
        node->clazz = NULL;
        node->type  = NULL;
    
        FT_FREE( node );
      }
    
    
      static FT_Int
      ft_type_equal( FT_Type  type1,
                     FT_Type  type2 )
      {
        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_equal( 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 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 classes */
        ft_hash_done( &meta->type_to_class,
                      (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;
      }
    
    
      FT_BASE_DEF( FT_Error )
      ft_metaclass_init( FT_MetaClass  meta,
                         FT_Library    library )
      {
        FT_ClassRec*  clazz = (FT_ClassRec*) &meta->clazz;
    
        /* the meta-class is its OWN class !! */
        clazz->object.clazz     = (FT_Class) clazz;
        clazz->object.ref_count = 1;
        clazz->magic            = FT_MAGIC_CLASS;
        clazz->library          = library;
        clazz->memory           = library->memory;
        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;
    
        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 )
      {
        FT_ClassHNodeRec   keynode, *node, **pnode;
        FT_Memory          memory;
        FT_ClassRec*       clazz;
        FT_Class           parent;
        FT_Error           error;
    
        keynode.hnode.hash = FT_TYPE_HASH( ctype );
        keynode.type       = ctype;
    
        pnode = (FT_ClassHNode*) ft_hash_lookup( &meta->type_to_class,
                                                 (FT_HashNode) &keynode );
        node  = *pnode;
        if ( node != NULL )
        {
          clazz = (FT_ClassRec*) node->clazz;
          goto Exit;
        }
    
        memory = FT_CLASS__MEMORY(meta);
        clazz  = NULL;
        parent = NULL;
        if ( ctype->super != NULL )
        {
          FT_ASSERT( ctype->super->class_size <= ctype->class_size );
          FT_ASSERT( ctype->super->obj_size   <= ctype->obj_size   );
    
          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 );
          }
        }
    
      Exit:
        return  (FT_Class) clazz;
      }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
      FT_BASE_DEF( FT_Int )
      ft_object_check( FT_Pointer  obj )
      {
        return FT_OBJECT_CHECK(obj);
      }
    
    
      FT_BASE_DEF( FT_Int )
      ft_object_is_a( FT_Pointer  obj,
                      FT_Class    clazz )
      {
        if ( FT_OBJECT_CHECK(obj) )
        {
          FT_Class   c = FT_OBJECT__CLASS(obj);
    
          do
          {
            if ( c == clazz )
              return 1;
    
            c = c->super;
          }
          while ( c == NULL );
    
          return (clazz == NULL);
        }
        return 0;
      }
    
    
      FT_BASE_DEF( FT_Error )
      ft_object_create( FT_Object  *pobject,
                        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);
        if ( !FT_ALLOC( obj, clazz->obj_size ) )
        {
          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_FREE( obj );
            }
          }
        }
        *pobject = obj;
        return error;
      }
    
    
      FT_BASE_DEF( FT_Class )
      ft_class_find_by_type( FT_Type     type,
                             FT_Library  library )
      {
        FT_MetaClass  meta = &library->meta_class;
    
        return ft_metaclass_get_class( meta, type );
      }
    
    
      FT_BASE_DEF( FT_Error )
      ft_object_create_from_type( FT_Object  *pobject,
                                  FT_Type     type,
                                  FT_Pointer  init_data,
                                  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;
      }