FTC_GCache_Lookup( FTC_GCache cache, FT_Offset hash, FT_UInt gindex, FTC_GQuery query, FTC_Node *anode ) { FT_Error error; query->gindex = gindex; FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); if ( !error ) { FTC_Family family = query->family; /* prevent the family from being destroyed too early when an */ /* out-of-memory condition occurs during glyph node initialization. */ family->num_nodes++; error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); if ( --family->num_nodes == 0 ) FTC_FAMILY_FREE( family, cache ); } return error; }
ftc_gcache_init( FTC_Cache ftccache ) { FTC_GCache cache = (FTC_GCache)ftccache; FT_Error error; error = FTC_Cache_Init( FTC_CACHE( cache ) ); if ( !error ) { FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; FTC_MruList_Init( &cache->families, clazz->family_class, 0, /* no maximum here! */ cache, FTC_CACHE( cache )->memory ); } return error; }
FTC_GCache_Lookup( FTC_GCache cache, FT_UInt32 hash, FT_UInt gindex, FTC_GQuery query, FTC_Node *anode ) { FT_Error error; query->gindex = gindex; FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); if ( !error ) error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); return error; }
FTC_ImageCache_Lookup( FTC_ImageCache cache, FTC_ImageType type, FT_UInt gindex, FT_Glyph *aglyph, FTC_Node *anode ) { FTC_ImageQueryRec iquery; FTC_ImageNode node; FT_Error error; /* some argument checks are delayed to ftc_cache_lookup */ if ( !aglyph ) return FTC_Err_Invalid_Argument; if ( anode ) *anode = NULL; iquery.gquery.gindex = gindex; iquery.type = *type; error = ftc_cache_lookup( FTC_CACHE( cache ), FTC_QUERY( &iquery ), (FTC_Node*)&node ); if ( !error ) { *aglyph = node->glyph; if ( anode ) { *anode = (FTC_Node)node; FTC_NODE( node )->ref_count++; } } return error; }
FTC_GCache_Done( FTC_GCache cache ) { ftc_gcache_done( FTC_CACHE( cache ) ); }
FTC_GCache_Init( FTC_GCache cache ) { return ftc_gcache_init( FTC_CACHE( cache ) ); }
FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, FTC_FaceID face_id, FT_Int cmap_index, FT_UInt32 char_code ) { FTC_Cache cache = FTC_CACHE( cmap_cache ); FTC_CMapQueryRec query; FTC_Node node; FT_Error error; FT_UInt gindex = 0; FT_Offset hash; FT_Int no_cmap_change = 0; if ( cmap_index < 0 ) { /* Treat a negative cmap index as a special value, meaning that you */ /* don't want to change the FT_Face's character map through this */ /* call. This can be useful if the face requester callback already */ /* sets the face's charmap to the appropriate value. */ no_cmap_change = 1; cmap_index = 0; } if ( !cache ) { FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" )); return 0; } query.face_id = face_id; query.cmap_index = (FT_UInt)cmap_index; query.char_code = char_code; hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code ); #if 1 FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, node, error ); #else error = FTC_Cache_Lookup( cache, hash, &query, &node ); #endif if ( error ) goto Exit; FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < FTC_CMAP_INDICES_MAX ); /* something rotten can happen with rogue clients */ if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= FTC_CMAP_INDICES_MAX ) ) return 0; /* XXX: should return appropriate error */ gindex = FTC_CMAP_NODE( node )->indices[char_code - FTC_CMAP_NODE( node )->first]; if ( gindex == FTC_CMAP_UNKNOWN ) { FT_Face face; gindex = 0; error = FTC_Manager_LookupFace( cache->manager, FTC_CMAP_NODE( node )->face_id, &face ); if ( error ) goto Exit; if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) { FT_CharMap old, cmap = NULL; old = face->charmap; cmap = face->charmaps[cmap_index]; if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, cmap ); gindex = FT_Get_Char_Index( face, char_code ); if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, old ); } FTC_CMAP_NODE( node )->indices[char_code - FTC_CMAP_NODE( node )->first] = (FT_UShort)gindex; } Exit: return gindex; }
FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, FTC_FaceID face_id, FT_Int cmap_index, FT_UInt32 char_code ) { FTC_Cache cache = FTC_CACHE( cmap_cache ); FTC_CMapQueryRec query; FTC_Node node; FT_Error error; FT_UInt gindex = 0; FT_PtrDist hash; FT_Int no_cmap_change = 0; if ( cmap_index < 0 ) { /* Treat a negative cmap index as a special value, meaning that you */ /* don't want to change the FT_Face's character map through this */ /* call. This can be useful if the face requester callback already */ /* sets the face's charmap to the appropriate value. */ no_cmap_change = 1; cmap_index = 0; } if ( !cache ) { FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" )); return 0; } #ifdef FT_CONFIG_OPTION_OLD_INTERNALS /* * If cmap_index is greater than the maximum number of cachable * charmaps, we assume the request is from a legacy rogue client * using old internal header. See include/config/ftoption.h. */ if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE && !no_cmap_change ) { FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id; char_code = (FT_UInt32)cmap_index; query.face_id = desc->face_id; switch ( desc->type ) { case FTC_OLD_CMAP_BY_INDEX: query.cmap_index = desc->u.index; query.char_code = (FT_UInt32)cmap_index; break; case FTC_OLD_CMAP_BY_ENCODING: { FT_Face face; error = FTC_Manager_LookupFace( cache->manager, desc->face_id, &face ); if ( error ) return 0; FT_Select_Charmap( face, desc->u.encoding ); return FT_Get_Char_Index( face, char_code ); } default: return 0; } } else #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ { query.face_id = face_id; query.cmap_index = (FT_UInt)cmap_index; query.char_code = char_code; } hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); #if 1 FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, node, error ); #else error = FTC_Cache_Lookup( cache, hash, &query, &node ); #endif if ( error ) goto Exit; FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < FTC_CMAP_INDICES_MAX ); /* something rotten can happen with rogue clients */ if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= FTC_CMAP_INDICES_MAX ) ) return 0; /* XXX: should return appropriate error */ gindex = FTC_CMAP_NODE( node )->indices[char_code - FTC_CMAP_NODE( node )->first]; if ( gindex == FTC_CMAP_UNKNOWN ) { FT_Face face; gindex = 0; error = FTC_Manager_LookupFace( cache->manager, FTC_CMAP_NODE( node )->face_id, &face ); if ( error ) goto Exit; #ifdef FT_MAX_CHARMAP_CACHEABLE /* something rotten can happen with rogue clients */ if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE ) return 0; /* XXX: should return appropriate error */ #endif if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) { FT_CharMap old, cmap = NULL; old = face->charmap; cmap = face->charmaps[cmap_index]; if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, cmap ); gindex = FT_Get_Char_Index( face, char_code ); if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, old ); } FTC_CMAP_NODE( node )->indices[char_code - FTC_CMAP_NODE( node )->first] = (FT_UShort)gindex; } Exit: return gindex; }
FTC_CMapCache_Lookup( FTC_CMapCache cache, FTC_CMapDesc desc, FT_UInt32 char_code ) { FTC_CMapQueryRec cquery; FTC_CMapNode node; FT_Error error; FT_UInt gindex = 0; if ( !cache || !desc ) { FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); return 0; } cquery.desc = desc; cquery.char_code = char_code; error = ftc_cmap_cache_lookup( FTC_CACHE( cache ), FTC_QUERY( &cquery ), (FTC_Node*)&node ); if ( !error ) { FT_UInt offset = (FT_UInt)( char_code - node->first ); FT_ASSERT( offset < FTC_CMAP_INDICES_MAX ); gindex = node->indices[offset]; if ( gindex == FTC_CMAP_UNKNOWN ) { FT_Face face; /* we need to use FT_Get_Char_Index */ gindex = 0; error = FTC_Manager_Lookup_Face( FTC_CACHE(cache)->manager, desc->face_id, &face ); if ( !error ) { FT_CharMap old, cmap = NULL; FT_UInt cmap_index; /* save old charmap, select new one */ old = face->charmap; cmap_index = FTC_CMAP_FAMILY( FTC_QUERY( &cquery )->family )->index; cmap = face->charmaps[cmap_index]; FT_Set_Charmap( face, cmap ); /* perform lookup */ gindex = FT_Get_Char_Index( face, char_code ); node->indices[offset] = (FT_UInt16)gindex; /* restore old charmap */ FT_Set_Charmap( face, old ); } } } return gindex; }