From 7b52cc13af4e85f1ca2deb6b6c77de9c95ea0dcf Mon Sep 17 00:00:00 2001 From: scuri Date: Fri, 17 Oct 2008 06:10:33 +0000 Subject: First commit - moving from LuaForge to SourceForge --- src/freetype2/cache/ftccmap.c | 413 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 413 insertions(+) create mode 100644 src/freetype2/cache/ftccmap.c (limited to 'src/freetype2/cache/ftccmap.c') diff --git a/src/freetype2/cache/ftccmap.c b/src/freetype2/cache/ftccmap.c new file mode 100644 index 0000000..aa59307 --- /dev/null +++ b/src/freetype2/cache/ftccmap.c @@ -0,0 +1,413 @@ +/***************************************************************************/ +/* */ +/* ftccmap.c */ +/* */ +/* FreeType CharMap cache (body) */ +/* */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include +#include FT_FREETYPE_H +#include FT_CACHE_H +#include "ftcmanag.h" +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_DEBUG_H +#include FT_TRUETYPE_IDS_H + +#include "ftccback.h" +#include "ftcerror.h" + +#undef FT_COMPONENT +#define FT_COMPONENT trace_cache + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + typedef enum FTC_OldCMapType_ + { + FTC_OLD_CMAP_BY_INDEX = 0, + FTC_OLD_CMAP_BY_ENCODING = 1, + FTC_OLD_CMAP_BY_ID = 2 + + } FTC_OldCMapType; + + + typedef struct FTC_OldCMapIdRec_ + { + FT_UInt platform; + FT_UInt encoding; + + } FTC_OldCMapIdRec, *FTC_OldCMapId; + + + typedef struct FTC_OldCMapDescRec_ + { + FTC_FaceID face_id; + FTC_OldCMapType type; + + union + { + FT_UInt index; + FT_Encoding encoding; + FTC_OldCMapIdRec id; + + } u; + + } FTC_OldCMapDescRec, *FTC_OldCMapDesc; + +#endif /* FT_CONFIG_OLD_INTERNALS */ + + + /*************************************************************************/ + /* */ + /* Each FTC_CMapNode contains a simple array to map a range of character */ + /* codes to equivalent glyph indices. */ + /* */ + /* For now, the implementation is very basic: Each node maps a range of */ + /* 128 consecutive character codes to their corresponding glyph indices. */ + /* */ + /* We could do more complex things, but I don't think it is really very */ + /* useful. */ + /* */ + /*************************************************************************/ + + + /* number of glyph indices / character code per node */ +#define FTC_CMAP_INDICES_MAX 128 + + /* compute a query/node hash */ +#define FTC_CMAP_HASH( faceid, index, charcode ) \ + ( FTC_FACE_ID_HASH( faceid ) + 211 * ( index ) + \ + ( (char_code) / FTC_CMAP_INDICES_MAX ) ) + + /* the charmap query */ + typedef struct FTC_CMapQueryRec_ + { + FTC_FaceID face_id; + FT_UInt cmap_index; + FT_UInt32 char_code; + + } FTC_CMapQueryRec, *FTC_CMapQuery; + +#define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x)) +#define FTC_CMAP_QUERY_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) + + /* the cmap cache node */ + typedef struct FTC_CMapNodeRec_ + { + FTC_NodeRec node; + FTC_FaceID face_id; + FT_UInt cmap_index; + FT_UInt32 first; /* first character in node */ + FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ + + } FTC_CMapNodeRec, *FTC_CMapNode; + +#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) +#define FTC_CMAP_NODE_HASH( x ) \ + FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) + + /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ + /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ +#define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CHARMAP NODES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_DEF( void ) + ftc_cmap_node_free( FTC_Node ftcnode, + FTC_Cache cache ) + { + FTC_CMapNode node = (FTC_CMapNode)ftcnode; + FT_Memory memory = cache->memory; + + + FT_FREE( node ); + } + + + /* initialize a new cmap node */ + FT_CALLBACK_DEF( FT_Error ) + ftc_cmap_node_new( FTC_Node *ftcanode, + FT_Pointer ftcquery, + FTC_Cache cache ) + { + FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode; + FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; + FT_Error error; + FT_Memory memory = cache->memory; + FTC_CMapNode node; + FT_UInt nn; + + + if ( !FT_NEW( node ) ) + { + node->face_id = query->face_id; + node->cmap_index = query->cmap_index; + node->first = (query->char_code / FTC_CMAP_INDICES_MAX) * + FTC_CMAP_INDICES_MAX; + + for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ ) + node->indices[nn] = FTC_CMAP_UNKNOWN; + } + + *anode = node; + return error; + } + + + /* compute the weight of a given cmap node */ + FT_CALLBACK_DEF( FT_ULong ) + ftc_cmap_node_weight( FTC_Node cnode, + FTC_Cache cache ) + { + FT_UNUSED( cnode ); + FT_UNUSED( cache ); + + return sizeof ( *cnode ); + } + + + /* compare a cmap node to a given query */ + FT_CALLBACK_DEF( FT_Bool ) + ftc_cmap_node_compare( FTC_Node ftcnode, + FT_Pointer ftcquery, + FTC_Cache cache ) + { + FTC_CMapNode node = (FTC_CMapNode)ftcnode; + FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; + FT_UNUSED( cache ); + + + if ( node->face_id == query->face_id && + node->cmap_index == query->cmap_index ) + { + FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first ); + + + return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); + } + + return 0; + } + + + FT_CALLBACK_DEF( FT_Bool ) + ftc_cmap_node_remove_faceid( FTC_Node ftcnode, + FT_Pointer ftcface_id, + FTC_Cache cache ) + { + FTC_CMapNode node = (FTC_CMapNode)ftcnode; + FTC_FaceID face_id = (FTC_FaceID)ftcface_id; + FT_UNUSED( cache ); + + return FT_BOOL( node->face_id == face_id ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** GLYPH IMAGE CACHE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + FT_CALLBACK_TABLE_DEF + const FTC_CacheClassRec ftc_cmap_cache_class = + { + ftc_cmap_node_new, + ftc_cmap_node_weight, + ftc_cmap_node_compare, + ftc_cmap_node_remove_faceid, + ftc_cmap_node_free, + + sizeof ( FTC_CacheRec ), + ftc_cache_init, + ftc_cache_done, + }; + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ) + { + return FTC_Manager_RegisterCache( manager, + &ftc_cmap_cache_class, + FTC_CACHE_P( acache ) ); + } + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /* + * Unfortunately, it is not possible to support binary backwards + * compatibility in the cmap cache. The FTC_CMapCache_Lookup signature + * changes were too deep, and there is no clever hackish way to detect + * what kind of structure we are being passed. + * + * On the other hand it seems that no production code is using this + * function on Unix distributions. + */ + +#endif + + + /* documentation is in ftcache.h */ + + FT_EXPORT_DEF( FT_UInt ) + 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_CMapNode node; + FT_Error error; + FT_UInt gindex = 0; + FT_UInt32 hash; + + + if ( !cache ) + { + FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); + return 0; + } + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /* + * Detect a call from a rogue client that thinks it is linking + * to FreeType 2.1.7. This is possible because the third parameter + * is then a character code, and we have never seen any font with + * more than a few charmaps, so if the index is very large... + * + * It is also very unlikely that a rogue client is interested + * in Unicode values 0 to 15. + * + * NOTE: The original threshold was 4, but we found a font from the + * Adobe Acrobat Reader Pack, named `KozMinProVI-Regular.otf', + * which contains more than 5 charmaps. + */ + if ( cmap_index >= 16 ) + { + 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, (FTC_Node*) &node ); +#endif + if ( error ) + goto Exit; + + FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX ); + + /* something rotten can happen with rogue clients */ + if ( (FT_UInt)( char_code - node->first >= FTC_CMAP_INDICES_MAX ) ) + return 0; + + gindex = node->indices[char_code - node->first]; + if ( gindex == FTC_CMAP_UNKNOWN ) + { + FT_Face face; + + + gindex = 0; + + error = FTC_Manager_LookupFace( cache->manager, 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 ) + FT_Set_Charmap( face, cmap ); + + gindex = FT_Get_Char_Index( face, char_code ); + + if ( old != cmap ) + FT_Set_Charmap( face, old ); + } + + node->indices[char_code - node->first] = (FT_UShort)gindex; + } + + Exit: + return gindex; + } + + +/* END */ -- cgit v1.2.3