00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020 #include FT_FREETYPE_H
00021 #include FT_CACHE_H
00022 #include "ftcmanag.h"
00023 #include FT_INTERNAL_MEMORY_H
00024 #include FT_INTERNAL_DEBUG_H
00025
00026 #include "ftccback.h"
00027 #include "ftcerror.h"
00028
00029 #undef FT_COMPONENT
00030 #define FT_COMPONENT trace_cache
00031
00032
00033 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
00034
00035 typedef enum FTC_OldCMapType_
00036 {
00037 FTC_OLD_CMAP_BY_INDEX = 0,
00038 FTC_OLD_CMAP_BY_ENCODING = 1,
00039 FTC_OLD_CMAP_BY_ID = 2
00040
00041 } FTC_OldCMapType;
00042
00043
00044 typedef struct FTC_OldCMapIdRec_
00045 {
00046 FT_UInt platform;
00047 FT_UInt encoding;
00048
00049 } FTC_OldCMapIdRec, *FTC_OldCMapId;
00050
00051
00052 typedef struct FTC_OldCMapDescRec_
00053 {
00054 FTC_FaceID face_id;
00055 FTC_OldCMapType type;
00056
00057 union
00058 {
00059 FT_UInt index;
00060 FT_Encoding encoding;
00061 FTC_OldCMapIdRec id;
00062
00063 } u;
00064
00065 } FTC_OldCMapDescRec, *FTC_OldCMapDesc;
00066
00067 #endif
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 #define FTC_CMAP_INDICES_MAX 128
00086
00087
00088 #define FTC_CMAP_HASH( faceid, index, charcode ) \
00089 ( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \
00090 ( (charcode) / FTC_CMAP_INDICES_MAX ) )
00091
00092
00093 typedef struct FTC_CMapQueryRec_
00094 {
00095 FTC_FaceID face_id;
00096 FT_UInt cmap_index;
00097 FT_UInt32 char_code;
00098
00099 } FTC_CMapQueryRec, *FTC_CMapQuery;
00100
00101 #define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x))
00102 #define FTC_CMAP_QUERY_HASH( x ) \
00103 FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code )
00104
00105
00106 typedef struct FTC_CMapNodeRec_
00107 {
00108 FTC_NodeRec node;
00109 FTC_FaceID face_id;
00110 FT_UInt cmap_index;
00111 FT_UInt32 first;
00112 FT_UInt16 indices[FTC_CMAP_INDICES_MAX];
00113
00114 } FTC_CMapNodeRec, *FTC_CMapNode;
00115
00116 #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
00117 #define FTC_CMAP_NODE_HASH( x ) \
00118 FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first )
00119
00120
00121
00122 #define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 )
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 FT_CALLBACK_DEF( void )
00135 ftc_cmap_node_free( FTC_Node ftcnode,
00136 FTC_Cache cache )
00137 {
00138 FTC_CMapNode node = (FTC_CMapNode)ftcnode;
00139 FT_Memory memory = cache->memory;
00140
00141
00142 FT_FREE( node );
00143 }
00144
00145
00146
00147 FT_CALLBACK_DEF( FT_Error )
00148 ftc_cmap_node_new( FTC_Node *ftcanode,
00149 FT_Pointer ftcquery,
00150 FTC_Cache cache )
00151 {
00152 FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode;
00153 FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
00154 FT_Error error;
00155 FT_Memory memory = cache->memory;
00156 FTC_CMapNode node;
00157 FT_UInt nn;
00158
00159
00160 if ( !FT_NEW( node ) )
00161 {
00162 node->face_id = query->face_id;
00163 node->cmap_index = query->cmap_index;
00164 node->first = (query->char_code / FTC_CMAP_INDICES_MAX) *
00165 FTC_CMAP_INDICES_MAX;
00166
00167 for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
00168 node->indices[nn] = FTC_CMAP_UNKNOWN;
00169 }
00170
00171 *anode = node;
00172 return error;
00173 }
00174
00175
00176
00177 FT_CALLBACK_DEF( FT_Offset )
00178 ftc_cmap_node_weight( FTC_Node cnode,
00179 FTC_Cache cache )
00180 {
00181 FT_UNUSED( cnode );
00182 FT_UNUSED( cache );
00183
00184 return sizeof ( *cnode );
00185 }
00186
00187
00188
00189 FT_CALLBACK_DEF( FT_Bool )
00190 ftc_cmap_node_compare( FTC_Node ftcnode,
00191 FT_Pointer ftcquery,
00192 FTC_Cache cache )
00193 {
00194 FTC_CMapNode node = (FTC_CMapNode)ftcnode;
00195 FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
00196 FT_UNUSED( cache );
00197
00198
00199 if ( node->face_id == query->face_id &&
00200 node->cmap_index == query->cmap_index )
00201 {
00202 FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first );
00203
00204
00205 return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
00206 }
00207
00208 return 0;
00209 }
00210
00211
00212 FT_CALLBACK_DEF( FT_Bool )
00213 ftc_cmap_node_remove_faceid( FTC_Node ftcnode,
00214 FT_Pointer ftcface_id,
00215 FTC_Cache cache )
00216 {
00217 FTC_CMapNode node = (FTC_CMapNode)ftcnode;
00218 FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
00219 FT_UNUSED( cache );
00220
00221 return FT_BOOL( node->face_id == face_id );
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 FT_CALLBACK_TABLE_DEF
00235 const FTC_CacheClassRec ftc_cmap_cache_class =
00236 {
00237 ftc_cmap_node_new,
00238 ftc_cmap_node_weight,
00239 ftc_cmap_node_compare,
00240 ftc_cmap_node_remove_faceid,
00241 ftc_cmap_node_free,
00242
00243 sizeof ( FTC_CacheRec ),
00244 ftc_cache_init,
00245 ftc_cache_done,
00246 };
00247
00248
00249
00250
00251 FT_EXPORT_DEF( FT_Error )
00252 FTC_CMapCache_New( FTC_Manager manager,
00253 FTC_CMapCache *acache )
00254 {
00255 return FTC_Manager_RegisterCache( manager,
00256 &ftc_cmap_cache_class,
00257 FTC_CACHE_P( acache ) );
00258 }
00259
00260
00261 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 #endif
00274
00275
00276
00277
00278 FT_EXPORT_DEF( FT_UInt )
00279 FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache,
00280 FTC_FaceID face_id,
00281 FT_Int cmap_index,
00282 FT_UInt32 char_code )
00283 {
00284 FTC_Cache cache = FTC_CACHE( cmap_cache );
00285 FTC_CMapQueryRec query;
00286 FTC_Node node;
00287 FT_Error error;
00288 FT_UInt gindex = 0;
00289 FT_UInt32 hash;
00290 FT_Int no_cmap_change = 0;
00291
00292
00293 if ( cmap_index < 0 )
00294 {
00295
00296
00297
00298
00299
00300 no_cmap_change = 1;
00301 cmap_index = 0;
00302 }
00303
00304 if ( !cache )
00305 {
00306 FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));
00307 return 0;
00308 }
00309
00310 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 if ( cmap_index >= 16 && !no_cmap_change )
00326 {
00327 FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id;
00328
00329
00330 char_code = (FT_UInt32)cmap_index;
00331 query.face_id = desc->face_id;
00332
00333
00334 switch ( desc->type )
00335 {
00336 case FTC_OLD_CMAP_BY_INDEX:
00337 query.cmap_index = desc->u.index;
00338 query.char_code = (FT_UInt32)cmap_index;
00339 break;
00340
00341 case FTC_OLD_CMAP_BY_ENCODING:
00342 {
00343 FT_Face face;
00344
00345
00346 error = FTC_Manager_LookupFace( cache->manager, desc->face_id,
00347 &face );
00348 if ( error )
00349 return 0;
00350
00351 FT_Select_Charmap( face, desc->u.encoding );
00352
00353 return FT_Get_Char_Index( face, char_code );
00354 }
00355
00356 default:
00357 return 0;
00358 }
00359 }
00360 else
00361
00362 #endif
00363
00364 {
00365 query.face_id = face_id;
00366 query.cmap_index = (FT_UInt)cmap_index;
00367 query.char_code = char_code;
00368 }
00369
00370 hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );
00371
00372 #if 1
00373 FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
00374 node, error );
00375 #else
00376 error = FTC_Cache_Lookup( cache, hash, &query, &node );
00377 #endif
00378 if ( error )
00379 goto Exit;
00380
00381 FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) <
00382 FTC_CMAP_INDICES_MAX );
00383
00384
00385 if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=
00386 FTC_CMAP_INDICES_MAX ) )
00387 return 0;
00388
00389 gindex = FTC_CMAP_NODE( node )->indices[char_code -
00390 FTC_CMAP_NODE( node )->first];
00391 if ( gindex == FTC_CMAP_UNKNOWN )
00392 {
00393 FT_Face face;
00394
00395
00396 gindex = 0;
00397
00398 error = FTC_Manager_LookupFace( cache->manager,
00399 FTC_CMAP_NODE( node )->face_id,
00400 &face );
00401 if ( error )
00402 goto Exit;
00403
00404 if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
00405 {
00406 FT_CharMap old, cmap = NULL;
00407
00408
00409 old = face->charmap;
00410 cmap = face->charmaps[cmap_index];
00411
00412 if ( old != cmap && !no_cmap_change )
00413 FT_Set_Charmap( face, cmap );
00414
00415 gindex = FT_Get_Char_Index( face, char_code );
00416
00417 if ( old != cmap && !no_cmap_change )
00418 FT_Set_Charmap( face, old );
00419 }
00420
00421 FTC_CMAP_NODE( node )->indices[char_code -
00422 FTC_CMAP_NODE( node )->first]
00423 = (FT_UShort)gindex;
00424 }
00425
00426 Exit:
00427 return gindex;
00428 }
00429
00430
00431