30#define FT_COMPONENT cache
48#define FTC_CMAP_INDICES_MAX 128
51#define FTC_CMAP_HASH( faceid, index, charcode ) \
52 ( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \
53 ( (charcode) / FTC_CMAP_INDICES_MAX ) )
62 } FTC_CMapQueryRec, *FTC_CMapQuery;
64#define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x))
73 FT_UInt16 indices[FTC_CMAP_INDICES_MAX];
75 } FTC_CMapNodeRec, *FTC_CMapNode;
77#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
81#define FTC_CMAP_UNKNOWN (FT_UInt16)~0
93 FT_CALLBACK_DEF(
void )
94 ftc_cmap_node_free( FTC_Node ftcnode,
97 FTC_CMapNode node = (FTC_CMapNode)ftcnode;
98 FT_Memory memory = cache->memory;
106 FT_CALLBACK_DEF( FT_Error )
107 ftc_cmap_node_new( FTC_Node *ftcanode,
111 FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode;
112 FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
114 FT_Memory memory = cache->memory;
115 FTC_CMapNode node = NULL;
119 if ( !FT_QNEW( node ) )
121 node->face_id = query->face_id;
122 node->cmap_index = query->cmap_index;
123 node->first = (query->char_code / FTC_CMAP_INDICES_MAX) *
124 FTC_CMAP_INDICES_MAX;
126 for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
127 node->indices[nn] = FTC_CMAP_UNKNOWN;
136 FT_CALLBACK_DEF( FT_Offset )
137 ftc_cmap_node_weight( FTC_Node cnode,
143 return sizeof ( *cnode );
148 FT_CALLBACK_DEF( FT_Bool )
149 ftc_cmap_node_compare( FTC_Node ftcnode,
152 FT_Bool* list_changed )
154 FTC_CMapNode node = (FTC_CMapNode)ftcnode;
155 FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
160 *list_changed = FALSE;
161 if ( node->face_id == query->face_id &&
162 node->cmap_index == query->cmap_index )
164 FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first );
167 return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
174 FT_CALLBACK_DEF( FT_Bool )
175 ftc_cmap_node_remove_faceid( FTC_Node ftcnode,
176 FT_Pointer ftcface_id,
178 FT_Bool* list_changed )
180 FTC_CMapNode node = (FTC_CMapNode)ftcnode;
181 FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
186 *list_changed = FALSE;
187 return FT_BOOL( node->face_id == face_id );
201 const FTC_CacheClassRec ftc_cmap_cache_class =
204 ftc_cmap_node_weight,
205 ftc_cmap_node_compare,
206 ftc_cmap_node_remove_faceid,
209 sizeof ( FTC_CacheRec ),
217 FT_EXPORT_DEF( FT_Error )
218 FTC_CMapCache_New( FTC_Manager manager,
219 FTC_CMapCache *acache )
221 return FTC_Manager_RegisterCache( manager,
222 &ftc_cmap_cache_class,
223 FTC_CACHE_P( acache ) );
229 FT_EXPORT_DEF( FT_UInt )
230 FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache,
233 FT_UInt32 char_code )
235 FTC_Cache cache = FTC_CACHE( cmap_cache );
236 FTC_CMapQueryRec query;
241 FT_Int no_cmap_change = 0;
244 if ( cmap_index < 0 )
257 FT_TRACE0((
"FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));
261 query.face_id = face_id;
262 query.cmap_index = (FT_UInt)cmap_index;
263 query.char_code = char_code;
265 hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code );
268 FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
271 error = FTC_Cache_Lookup( cache, hash, &query, &node );
276 FT_ASSERT( char_code - FTC_CMAP_NODE( node )->first <
277 FTC_CMAP_INDICES_MAX );
280 if ( char_code - FTC_CMAP_NODE( node )->first >= FTC_CMAP_INDICES_MAX )
283 gindex = FTC_CMAP_NODE( node )->indices[char_code -
284 FTC_CMAP_NODE( node )->first];
285 if ( gindex == FTC_CMAP_UNKNOWN )
292 error = FTC_Manager_LookupFace( cache->manager,
293 FTC_CMAP_NODE( node )->face_id,
298 if ( cmap_index < face->num_charmaps )
300 FT_CharMap old = face->charmap;
301 FT_CharMap cmap = face->charmaps[cmap_index];
304 if ( !no_cmap_change )
305 face->charmap = cmap;
307 gindex = FT_Get_Char_Index( face, char_code );
309 if ( !no_cmap_change )
313 FTC_CMAP_NODE( node )->indices[char_code -
314 FTC_CMAP_NODE( node )->first]