Edit

kc3-lang/freetype/src/cache/ftcbasic.c

Branch :

  • Show log

    Commit

  • Author : David Turner
    Date : 2003-12-19 21:23:58
    Hash : 57ecae22
    Message : new version of the cache sub-system - still under debugging

  • src/cache/ftcbasic.c
  • #include <ft2build.h>
    #include FT_CACHE_H
    #include FT_CACHE_INTERNAL_GLYPH_H
    #include FT_CACHE_INTERNAL_IMAGE_H
    #include FT_CACHE_INTERNAL_SBITS_H
    #include FT_INTERNAL_MEMORY_H
    
    #include "ftcerror.h"
    
    
     /*
      *  Basic Families
      *
      *
      */
      typedef struct FTC_BasicAttrRec_
      {
        FTC_ScalerRec  scaler;
        FT_UInt        load_flags;
    
      } FTC_BasicAttrRec, *FTC_BasicAttrs;
    
    #define  FTC_BASIC_ATTR_COMPARE(a,b)                           \
           ( FTC_SCALER_COMPARE( &(a)->scaler, &(b)->scaler ) &&   \
             (a)->load_flags == (b)->load_flags                )
    
    #define  FTC_BASIC_ATTR_HASH(a)   \
           ( FTC_SCALER_HASH(&(a)->scaler) + 31*(a)->load_flags )
    
    
      typedef struct FTC_BasicQueryRec_
      {
        FTC_GQueryRec      gquery;
        FTC_BasicAttrRec   attrs;
    
      } FTC_BasicQueryRec, *FTC_BasicQuery;
    
    
    
      typedef struct FTC_BasicFamilyRec_
      {
        FTC_FamilyRec      family;
        FTC_BasicAttrRec   attrs;
    
      } FTC_BasicFamilyRec, *FTC_BasicFamily;
    
    
      static FT_Bool
      ftc_basic_family_compare( FTC_BasicFamily   family,
                                FTC_BasicQuery    query )
      {
        return FT_BOOL( FTC_BASIC_ATTR_COMPARE( &family->attrs, &query->attrs ) );
      }
    
      static FT_Error
      ftc_basic_family_init( FTC_BasicFamily   family,
                             FTC_BasicQuery    query,
                             FTC_Cache         cache )
      {
        ftc_family_init( FTC_FAMILY( family ), cache );
        family->attrs = query->attrs;
        return 0;
      }
    
      static FT_Error
      ftc_basic_family_reset( FTC_BasicFamily  family,
                              FTC_BasicQuery   query )
      {
        family->attrs = query->attrs;
        return 0;
      }
    
    
      static FT_Bool
      ftc_basic_gnode_compare_faceid( FTC_GNode   gnode,
                                      FTC_FaceID  face_id,
                                      FTC_Cache   cache )
      {
        FTC_BasicFamily  family = (FTC_BasicFamily) gnode->family;
        FT_Bool          result;
    
        result = FT_BOOL( family->attrs.scaler.face_id == face_id );
        if ( result )
        {
         /* we must call this function to avoid this node from appearing
          * in later lookups with the same face_id !!
          */
          FTC_GNode_UnselectFamily( gnode, cache );
        }
        return result;
      }
    
    
      static FT_UInt
      ftc_basic_family_get_count( FTC_BasicFamily  family,
                                  FTC_Manager      manager )
      {
        FT_Error  error;
        FT_Face   face;
        FT_UInt   result = 0;
    
        error = FTC_Manager_LookupFace( manager, &family->attrs.scaler.face_id,
                                        &face );
        if ( !error )
          result = face->num_glyphs;
    
        return result;
      }
    
    
      static FT_Error
      ftc_basic_family_load_bitmap( FTC_BasicFamily  family,
                                    FT_UInt          gindex,
                                    FTC_Manager      manager,
                                    FT_Face         *aface )
      {
        FT_Error  error;
        FT_Size   size;
    
        error = FTC_Manager_LookupSize( manager, &family->attrs.scaler, &size );
        if ( !error )
        {
          FT_Face   face = size->face;
    
          error = FT_Load_Glyph( face, gindex, family->attrs.load_flags |
                                               FT_LOAD_RENDER );
          if ( !error )
            *aface = face;
        }
        return error;
      }
    
    
      static FT_Error
      ftc_basic_family_load_glyph( FTC_BasicFamily  family,
                                   FT_UInt          gindex,
                                   FTC_Cache        cache,
                                   FT_Glyph        *aglyph )
      {
        FT_Error       error;
        FTC_Scaler     scaler = &family->attrs.scaler;
        FT_Face        face;
        FT_Size        size;
    
        /* we will now load the glyph image */
        error = FTC_Manager_LookupSize( cache->manager,
                                        scaler,
                                        &size );
        if ( !error )
        {
          face = size->face;
    
          error = FT_Load_Glyph( face, gindex, family->attrs.load_flags );
          if ( !error )
          {
            if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP  ||
                 face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
            {
              /* ok, copy it */
              FT_Glyph  glyph;
    
    
              error = FT_Get_Glyph( face->glyph, &glyph );
              if ( !error )
              {
                *aglyph = glyph;
                goto Exit;
              }
            }
            else
              error = FTC_Err_Invalid_Argument;
          }
        }
      Exit:
        return error;
      }
    
    
     /*
      *
      * basic image cache
      *
      */
    
      static const FTC_IFamilyClassRec  ftc_basic_image_family_class =
      {
        {
          sizeof( FTC_BasicFamilyRec ),
          (FTC_MruNode_CompareFunc)  ftc_basic_family_compare,
          (FTC_MruNode_InitFunc)     ftc_basic_family_init,
          (FTC_MruNode_ResetFunc)    ftc_basic_family_reset,
          (FTC_MruNode_DoneFunc)     NULL
        },
        (FTC_IFamily_LoadGlyphFunc)  ftc_basic_family_load_glyph
      };
    
    
    
      static const FTC_GCacheClassRec  ftc_basic_image_cache_class =
      {
        {
          (FTC_Node_NewFunc)      FTC_INode_New,
          (FTC_Node_WeightFunc)   FTC_INode_Weight,
          (FTC_Node_CompareFunc)  FTC_GNode_Compare,
          (FTC_Node_CompareFunc)  ftc_basic_gnode_compare_faceid,
          (FTC_Node_FreeFunc)     FTC_INode_Free,
    
          sizeof( FTC_GCacheRec ),
          (FTC_Cache_InitFunc)    FTC_GCache_Init,
          (FTC_Cache_DoneFunc)    FTC_GCache_Done
        },
        (FTC_MruListClass) & ftc_basic_image_family_class
      };
    
    
      FT_EXPORT_DEF( FT_Error )
      FTC_ImageCache_New( FTC_Manager      manager,
                          FTC_ImageCache  *acache )
      {
        return FTC_GCache_New( manager, & ftc_basic_image_cache_class,
                               (FTC_GCache*) acache );
      }
    
    
      /* documentation is in ftcimage.h */
    
      FT_EXPORT_DEF( FT_Error )
      FTC_ImageCache_Lookup( FTC_ImageCache  cache,
                             FTC_ImageType   type,
                             FT_UInt         gindex,
                             FT_Glyph       *aglyph,
                             FTC_Node       *anode )
      {
        FTC_BasicQueryRec  query;
        FTC_INode          node;
        FT_Error           error;
        FT_UInt32          hash;
    
    
        /* some argument checks are delayed to FTC_Cache_Lookup */
        if ( !aglyph )
        {
          error = FTC_Err_Invalid_Argument;
          goto Exit;
        }
    
        *aglyph = NULL;
        if ( anode )
          *anode  = NULL;
    
        query.attrs.scaler.face_id = type->face_id;
        query.attrs.scaler.width   = type->width;
        query.attrs.scaler.height  = type->height;
        query.attrs.scaler.pixel   = 1;
        query.attrs.load_flags     = type->flags;
    
        hash = FTC_BASIC_ATTR_HASH( &query.attrs ) ^ (gindex << 8);
    
        error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
                                   hash, gindex,
                                   FTC_GQUERY( &query ),
                                   (FTC_Node*) &node );
        if ( !error )
        {
          *aglyph = FTC_INODE(node)->glyph;
    
          if ( anode )
          {
            *anode = FTC_NODE(node);
            FTC_NODE(node)->ref_count++;
          }
        }
    
      Exit:
        return error;
      }
    
    
    
     /*
      *
      * basic small bitmap cache
      *
      */
    
    
      static const FTC_SFamilyClassRec  ftc_basic_sbit_family_class =
      {
        {
          sizeof( FTC_BasicFamilyRec ),
          (FTC_MruNode_CompareFunc)  ftc_basic_family_compare,
          (FTC_MruNode_InitFunc)     ftc_basic_family_init,
          (FTC_MruNode_ResetFunc)    ftc_basic_family_reset,
          (FTC_MruNode_DoneFunc)     NULL
        },
        (FTC_SFamily_GetCountFunc)   ftc_basic_family_get_count,
        (FTC_SFamily_LoadGlyphFunc)  ftc_basic_family_load_bitmap
      };
    
    
      static const FTC_GCacheClassRec  ftc_basic_sbit_cache_class =
      {
        {
          (FTC_Node_NewFunc)      FTC_SNode_New,
          (FTC_Node_WeightFunc)   FTC_SNode_Weight,
          (FTC_Node_CompareFunc)  FTC_SNode_Compare,
          (FTC_Node_CompareFunc)  ftc_basic_gnode_compare_faceid,
          (FTC_Node_FreeFunc)     FTC_SNode_Free,
    
          sizeof( FTC_GCacheRec ),
          (FTC_Cache_InitFunc)    FTC_GCache_Init,
          (FTC_Cache_DoneFunc)    FTC_GCache_Done
        },
        (FTC_MruListClass) & ftc_basic_sbit_family_class
      };
    
    
    
    
      FT_EXPORT_DEF( FT_Error )
      FTC_SBitCache_New( FTC_Manager     manager,
                         FTC_SBitCache  *acache )
      {
        return FTC_GCache_New( manager, & ftc_basic_sbit_cache_class,
                               (FTC_GCache*) acache );
      }
    
    
      FT_EXPORT_DEF( FT_Error )
      FTC_SBitCache_Lookup( FTC_SBitCache   cache,
                            FTC_ImageType   type,
                            FT_UInt         gindex,
                            FTC_SBit       *ansbit,
                            FTC_Node       *anode )
      {
        FT_Error           error;
        FTC_BasicQueryRec  query;
        FTC_SNode          node;
        FT_UInt32          hash;
    
        if ( anode )
          *anode = NULL;
    
        /* other argument checks delayed to FTC_Cache_Lookup */
        if ( !ansbit )
          return FTC_Err_Invalid_Argument;
    
        *ansbit = NULL;
    
        query.attrs.scaler.face_id = type->face_id;
        query.attrs.scaler.width   = type->width;
        query.attrs.scaler.height  = type->height;
        query.attrs.scaler.pixel   = 1;
        query.attrs.load_flags     = type->flags;
    
       /* beware, the hash must be the same for all glyph ranges !!
        */
        hash = FTC_BASIC_ATTR_HASH( &query.attrs ) ^
               (gindex/FTC_SBIT_ITEMS_PER_NODE);
    
        error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
                                   hash,
                                   gindex,
                                   FTC_GQUERY( &query ),
                                   (FTC_Node*) &node );
        if ( error )
          goto Exit;
    
        *ansbit = node->sbits + ( gindex - FTC_GNODE(node)->gindex );
    
        if ( anode )
        {
          *anode = FTC_NODE( node );
          FTC_NODE( node )->ref_count++;
        }
    
      Exit:
        return error;
      }