~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/freetype/src/cache/ftccmap.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  ftccmap.c                                                              */
 
4
/*                                                                         */
 
5
/*    FreeType CharMap cache (body)                                        */
 
6
/*                                                                         */
 
7
/*  Copyright 2000-2001, 2002, 2003, 2004 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] = gindex;
 
296
    }
 
297
 
 
298
  Exit:
 
299
    return gindex;
 
300
  }
 
301
 
 
302
 
 
303
/* END */