summaryrefslogtreecommitdiff
path: root/src/cache/ftcbasic.c
diff options
context:
space:
mode:
authorDavid Turner <david@freetype.org>2003-12-23 23:54:00 +0000
committerDavid Turner <david@freetype.org>2003-12-23 23:54:00 +0000
commit023612221e75e7240316d67a01d80cad069023f6 (patch)
treea3600aad67e35ff7b2206132b708d9a33eb19419 /src/cache/ftcbasic.c
parent48b6ddb8a86d54f73b4b2d3387d4625f064f5a63 (diff)
downloadfreetype2-023612221e75e7240316d67a01d80cad069023f6.tar.gz
* include/freetype/cache/ftccache.h,
include/freetype/cache/ftcmru.h, include/freetype/cache/ftcglyph.h, src/cache/ftcbasic.c, src/cache/ftccache.c, src/cache/ftccmap.c, src/cache/ftcmanag.c: additional speed optimization to the cache sub-system. It is now up to 70% faster than the one in the previous table release (i.e. 2.1.7). Note that the API did slightly change though.
Diffstat (limited to 'src/cache/ftcbasic.c')
-rw-r--r--src/cache/ftcbasic.c766
1 files changed, 393 insertions, 373 deletions
diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c
index b1f825ed7..3f8954830 100644
--- a/src/cache/ftcbasic.c
+++ b/src/cache/ftcbasic.c
@@ -1,373 +1,393 @@
-#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_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;
- }
-
-
- 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;
- }
-
-
-
- /*
- *
- * 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) NULL,
- (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;
-
- 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) NULL,
- (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;
- }
-
+#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_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;
+ }
+
+
+ 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;
+ }
+
+
+
+ /*
+ *
+ * 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) NULL,
+ (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;
+
+#if 1 /* inlining is about 50% faster !! */
+ FTC_GCACHE_LOOKUP_CMP( cache,
+ ftc_basic_family_compare,
+ FTC_GNode_Compare,
+ hash, gindex,
+ &query,
+ node,
+ error );
+#else
+ error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
+ hash, gindex,
+ FTC_GQUERY( &query ),
+ (FTC_Node*) &node );
+#endif
+ 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) NULL,
+ (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);
+
+#if 1 /* inlining is about 50% faster !! */
+ FTC_GCACHE_LOOKUP_CMP( cache,
+ ftc_basic_family_compare,
+ FTC_SNode_Compare,
+ hash, gindex,
+ &query,
+ node,
+ error );
+#else
+ error = FTC_GCache_Lookup( FTC_GCACHE( cache ),
+ hash,
+ gindex,
+ FTC_GQUERY( &query ),
+ (FTC_Node*) &node );
+#endif
+ 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;
+ }
+