source: trunk/poppler/freetype-2.1.10/src/cache/ftccmap.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

File size: 9.6 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  ftccmap.c                                                              */
4/*                                                                         */
5/*    FreeType CharMap cache (body)                                        */
6/*                                                                         */
7/*  Copyright 2000-2001, 2002, 2003, 2004, 2005 by                         */
8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9/*                                                                         */
10/*  This file is part of the FreeType project, and may only be used,       */
11/*  modified, and distributed under the terms of the FreeType project      */
12/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13/*  this file you indicate that you have read the license and              */
14/*  understand and accept it fully.                                        */
15/*                                                                         */
16/***************************************************************************/
17
18
19#include <ft2build.h>
20#include FT_FREETYPE_H
21#include FT_CACHE_H
22#include FT_CACHE_INTERNAL_MANAGER_H
23#include FT_INTERNAL_MEMORY_H
24#include FT_INTERNAL_DEBUG_H
25#include FT_TRUETYPE_IDS_H
26
27#include "ftccback.h"
28#include "ftcerror.h"
29
30#undef  FT_COMPONENT
31#define FT_COMPONENT  trace_cache
32
33
34  /*************************************************************************/
35  /*                                                                       */
36  /* Each FTC_CMapNode contains a simple array to map a range of character */
37  /* codes to equivalent glyph indices.                                    */
38  /*                                                                       */
39  /* For now, the implementation is very basic: Each node maps a range of  */
40  /* 128 consecutive character codes to their corresponding glyph indices. */
41  /*                                                                       */
42  /* We could do more complex things, but I don't think it is really very  */
43  /* useful.                                                               */
44  /*                                                                       */
45  /*************************************************************************/
46
47
48  /* number of glyph indices / character code per node */
49#define FTC_CMAP_INDICES_MAX  128
50
51  /* compute a query/node hash */
52#define FTC_CMAP_HASH( faceid, index, charcode )           \
53          ( FTC_FACE_ID_HASH( faceid ) + 211 * ( index ) + \
54            ( (char_code) / FTC_CMAP_INDICES_MAX )       )
55
56  /* the charmap query */
57  typedef struct  FTC_CMapQueryRec_
58  {
59    FTC_FaceID  face_id;
60    FT_UInt     cmap_index;
61    FT_UInt32   char_code;
62
63  } FTC_CMapQueryRec, *FTC_CMapQuery;
64
65#define FTC_CMAP_QUERY( x )  ((FTC_CMapQuery)(x))
66#define FTC_CMAP_QUERY_HASH( x )                                         \
67          FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code )
68
69  /* the cmap cache node */
70  typedef struct  FTC_CMapNodeRec_
71  {
72    FTC_NodeRec  node;
73    FTC_FaceID   face_id;
74    FT_UInt      cmap_index;
75    FT_UInt32    first;                         /* first character in node */
76    FT_UInt16    indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices  */
77
78  } FTC_CMapNodeRec, *FTC_CMapNode;
79
80#define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
81#define FTC_CMAP_NODE_HASH( x )                                      \
82          FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first )
83
84  /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
85  /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet   */
86#define FTC_CMAP_UNKNOWN  ( (FT_UInt16)-1 )
87
88
89  /*************************************************************************/
90  /*************************************************************************/
91  /*****                                                               *****/
92  /*****                        CHARMAP NODES                          *****/
93  /*****                                                               *****/
94  /*************************************************************************/
95  /*************************************************************************/
96
97
98  /* no need for specific finalizer; we use `ftc_node_done' directly */
99
100  FT_CALLBACK_DEF( void )
101  ftc_cmap_node_free( FTC_Node   ftcnode,
102                      FTC_Cache  cache )
103  {
104    FTC_CMapNode  node   = (FTC_CMapNode)ftcnode;
105    FT_Memory     memory = cache->memory;
106
107
108    FT_FREE( node );
109  }
110
111
112  /* initialize a new cmap node */
113  FT_CALLBACK_DEF( FT_Error )
114  ftc_cmap_node_new( FTC_Node   *ftcanode,
115                     FT_Pointer  ftcquery,
116                     FTC_Cache   cache )
117  {
118    FTC_CMapNode  *anode  = (FTC_CMapNode*)ftcanode;
119    FTC_CMapQuery  query  = (FTC_CMapQuery)ftcquery;
120    FT_Error       error;
121    FT_Memory      memory = cache->memory;
122    FTC_CMapNode   node;
123    FT_UInt        nn;
124
125
126    if ( !FT_NEW( node ) )
127    {
128      node->face_id    = query->face_id;
129      node->cmap_index = query->cmap_index;
130      node->first      = (query->char_code / FTC_CMAP_INDICES_MAX) *
131                         FTC_CMAP_INDICES_MAX;
132
133      for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
134        node->indices[nn] = FTC_CMAP_UNKNOWN;
135    }
136
137    *anode = node;
138    return error;
139  }
140
141
142  /* compute the weight of a given cmap node */
143  FT_CALLBACK_DEF( FT_ULong )
144  ftc_cmap_node_weight( FTC_Node   cnode,
145                        FTC_Cache  cache )
146  {
147    FT_UNUSED( cnode );
148    FT_UNUSED( cache );
149
150    return sizeof ( *cnode );
151  }
152
153
154  /* compare a cmap node to a given query */
155  FT_CALLBACK_DEF( FT_Bool )
156  ftc_cmap_node_compare( FTC_Node    ftcnode,
157                         FT_Pointer  ftcquery,
158                         FTC_Cache   cache )
159  {
160    FTC_CMapNode   node  = (FTC_CMapNode)ftcnode;
161    FTC_CMapQuery  query = (FTC_CMapQuery)ftcquery;
162    FT_UNUSED( cache );
163
164
165    if ( node->face_id    == query->face_id    &&
166         node->cmap_index == query->cmap_index )
167    {
168      FT_UInt32  offset = (FT_UInt32)( query->char_code - node->first );
169
170
171      return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
172    }
173
174    return 0;
175  }
176
177
178  FT_CALLBACK_DEF( FT_Bool )
179  ftc_cmap_node_remove_faceid( FTC_Node    ftcnode,
180                               FT_Pointer  ftcface_id,
181                               FTC_Cache   cache )
182  {
183    FTC_CMapNode  node    = (FTC_CMapNode)ftcnode;
184    FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;
185    FT_UNUSED( cache );
186
187    return FT_BOOL( node->face_id == face_id );
188  }
189
190
191  /*************************************************************************/
192  /*************************************************************************/
193  /*****                                                               *****/
194  /*****                    GLYPH IMAGE CACHE                          *****/
195  /*****                                                               *****/
196  /*************************************************************************/
197  /*************************************************************************/
198
199
200  FT_CALLBACK_TABLE_DEF
201  const FTC_CacheClassRec  ftc_cmap_cache_class =
202  {
203    ftc_cmap_node_new,
204    ftc_cmap_node_weight,
205    ftc_cmap_node_compare,
206    ftc_cmap_node_remove_faceid,
207    ftc_cmap_node_free,
208
209    sizeof ( FTC_CacheRec ),
210    ftc_cache_init,
211    ftc_cache_done,
212  };
213
214
215  /* documentation is in ftcache.h */
216
217  FT_EXPORT_DEF( FT_Error )
218  FTC_CMapCache_New( FTC_Manager     manager,
219                     FTC_CMapCache  *acache )
220  {
221    return FTC_Manager_RegisterCache( manager,
222                                      &ftc_cmap_cache_class,
223                                      FTC_CACHE_P( acache ) );
224  }
225
226
227  /* documentation is in ftcache.h */
228
229  FT_EXPORT_DEF( FT_UInt )
230  FTC_CMapCache_Lookup( FTC_CMapCache  cmap_cache,
231                        FTC_FaceID     face_id,
232                        FT_Int         cmap_index,
233                        FT_UInt32      char_code )
234  {
235    FTC_Cache         cache = FTC_CACHE( cmap_cache );
236    FTC_CMapQueryRec  query;
237    FTC_CMapNode      node;
238    FT_Error          error;
239    FT_UInt           gindex = 0;
240    FT_UInt32         hash;
241
242
243    if ( !cache )
244    {
245      FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" ));
246      return 0;
247    }
248
249    query.face_id    = face_id;
250    query.cmap_index = (FT_UInt)cmap_index;
251    query.char_code  = char_code;
252
253    hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );
254
255#if 1
256    FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
257                          node, error );
258#else
259    error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node );
260#endif
261    if ( error )
262      goto Exit;
263
264    FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX );
265
266    gindex = node->indices[char_code - node->first];
267    if ( gindex == FTC_CMAP_UNKNOWN )
268    {
269      FT_Face  face;
270
271
272      gindex = 0;
273
274      error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face );
275      if ( error )
276        goto Exit;
277
278      if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
279      {
280        FT_CharMap  old, cmap  = NULL;
281
282
283        old  = face->charmap;
284        cmap = face->charmaps[cmap_index];
285
286        if ( old != cmap )
287          FT_Set_Charmap( face, cmap );
288
289        gindex = FT_Get_Char_Index( face, char_code );
290
291        if ( old != cmap )
292          FT_Set_Charmap( face, old );
293      }
294
295      node->indices[char_code - node->first] = (FT_UShort)gindex;
296    }
297
298  Exit:
299    return gindex;
300  }
301
302
303/* END */
Note: See TracBrowser for help on using the repository browser.