zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ftccmap.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftccmap.c */
4 /* */
5 /* FreeType CharMap cache (body) */
6 /* */
7 /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */
8 /* 2010, 2011 by */
9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* */
11 /* This file is part of the FreeType project, and may only be used, */
12 /* modified, and distributed under the terms of the FreeType project */
13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
14 /* this file you indicate that you have read the license and */
15 /* understand and accept it fully. */
16 /* */
17 /***************************************************************************/
18 
19 
20 #include <ft2build.h>
21 #include FT_FREETYPE_H
22 #include FT_CACHE_H
23 #include "ftcmanag.h"
24 #include FT_INTERNAL_MEMORY_H
25 #include FT_INTERNAL_OBJECTS_H
26 #include FT_INTERNAL_DEBUG_H
27 
28 #include "ftccback.h"
29 #include "ftcerror.h"
30 
31 #undef FT_COMPONENT
32 #define FT_COMPONENT trace_cache
33 
34 
35 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
36 
37  typedef enum FTC_OldCMapType_
38  {
39  FTC_OLD_CMAP_BY_INDEX = 0,
40  FTC_OLD_CMAP_BY_ENCODING = 1,
41  FTC_OLD_CMAP_BY_ID = 2
42 
43  } FTC_OldCMapType;
44 
45 
46  typedef struct FTC_OldCMapIdRec_
47  {
48  FT_UInt platform;
49  FT_UInt encoding;
50 
51  } FTC_OldCMapIdRec, *FTC_OldCMapId;
52 
53 
54  typedef struct FTC_OldCMapDescRec_
55  {
56  FTC_FaceID face_id;
57  FTC_OldCMapType type;
58 
59  union
60  {
61  FT_UInt index;
62  FT_Encoding encoding;
63  FTC_OldCMapIdRec id;
64 
65  } u;
66 
67  } FTC_OldCMapDescRec, *FTC_OldCMapDesc;
68 
69 #endif /* FT_CONFIG_OLD_INTERNALS */
70 
71 
72  /*************************************************************************/
73  /* */
74  /* Each FTC_CMapNode contains a simple array to map a range of character */
75  /* codes to equivalent glyph indices. */
76  /* */
77  /* For now, the implementation is very basic: Each node maps a range of */
78  /* 128 consecutive character codes to their corresponding glyph indices. */
79  /* */
80  /* We could do more complex things, but I don't think it is really very */
81  /* useful. */
82  /* */
83  /*************************************************************************/
84 
85 
86  /* number of glyph indices / character code per node */
87 #define FTC_CMAP_INDICES_MAX 128
88 
89  /* compute a query/node hash */
90 #define FTC_CMAP_HASH( faceid, index, charcode ) \
91  ( _FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \
92  ( (charcode) / FTC_CMAP_INDICES_MAX ) )
93 
94  /* the charmap query */
95  typedef struct FTC_CMapQueryRec_
96  {
97  FTC_FaceID face_id;
98  FT_UInt cmap_index;
99  FT_UInt32 char_code;
100 
102 
103 #define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x))
104 #define FTC_CMAP_QUERY_HASH( x ) \
105  FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code )
106 
107  /* the cmap cache node */
108  typedef struct FTC_CMapNodeRec_
109  {
110  FTC_NodeRec node;
111  FTC_FaceID face_id;
112  FT_UInt cmap_index;
113  FT_UInt32 first; /* first character in node */
114  FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */
115 
117 
118 #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
119 #define FTC_CMAP_NODE_HASH( x ) \
120  FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first )
121 
122  /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
123  /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */
124 #define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 )
125 
126 
127  /*************************************************************************/
128  /*************************************************************************/
129  /***** *****/
130  /***** CHARMAP NODES *****/
131  /***** *****/
132  /*************************************************************************/
133  /*************************************************************************/
134 
135 
136  FT_CALLBACK_DEF( void )
138  FTC_Cache cache )
139  {
140  FTC_CMapNode node = (FTC_CMapNode)ftcnode;
141  FT_Memory memory = cache->memory;
142 
143 
144  FT_FREE( node );
145  }
146 
147 
148  /* initialize a new cmap node */
151  FT_Pointer ftcquery,
152  FTC_Cache cache )
153  {
154  FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode;
155  FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
156  FT_Error error;
157  FT_Memory memory = cache->memory;
158  FTC_CMapNode node = NULL;
159  FT_UInt nn;
160 
161 
162  if ( !FT_NEW( node ) )
163  {
164  node->face_id = query->face_id;
165  node->cmap_index = query->cmap_index;
166  node->first = (query->char_code / FTC_CMAP_INDICES_MAX) *
168 
169  for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
170  node->indices[nn] = FTC_CMAP_UNKNOWN;
171  }
172 
173  *anode = node;
174  return error;
175  }
176 
177 
178  /* compute the weight of a given cmap node */
181  FTC_Cache cache )
182  {
183  FT_UNUSED( cnode );
184  FT_UNUSED( cache );
185 
186  return sizeof ( *cnode );
187  }
188 
189 
190  /* compare a cmap node to a given query */
193  FT_Pointer ftcquery,
194  FTC_Cache cache,
195  FT_Bool* list_changed )
196  {
197  FTC_CMapNode node = (FTC_CMapNode)ftcnode;
198  FTC_CMapQuery query = (FTC_CMapQuery)ftcquery;
199  FT_UNUSED( cache );
200 
201 
202  if ( list_changed )
203  *list_changed = FALSE;
204  if ( node->face_id == query->face_id &&
205  node->cmap_index == query->cmap_index )
206  {
207  FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first );
208 
209 
210  return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
211  }
212 
213  return 0;
214  }
215 
216 
219  FT_Pointer ftcface_id,
220  FTC_Cache cache,
221  FT_Bool* list_changed )
222  {
223  FTC_CMapNode node = (FTC_CMapNode)ftcnode;
224  FTC_FaceID face_id = (FTC_FaceID)ftcface_id;
225  FT_UNUSED( cache );
226 
227 
228  if ( list_changed )
229  *list_changed = FALSE;
230  return FT_BOOL( node->face_id == face_id );
231  }
232 
233 
234  /*************************************************************************/
235  /*************************************************************************/
236  /***** *****/
237  /***** GLYPH IMAGE CACHE *****/
238  /***** *****/
239  /*************************************************************************/
240  /*************************************************************************/
241 
242 
245  {
251 
252  sizeof ( FTC_CacheRec ),
255  };
256 
257 
258  /* documentation is in ftcache.h */
259 
262  FTC_CMapCache *acache )
263  {
264  return FTC_Manager_RegisterCache( manager,
265  &ftc_cmap_cache_class,
266  FTC_CACHE_P( acache ) );
267  }
268 
269 
270 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
271 
272  /*
273  * Unfortunately, it is not possible to support binary backwards
274  * compatibility in the cmap cache. The FTC_CMapCache_Lookup signature
275  * changes were too deep, and there is no clever hackish way to detect
276  * what kind of structure we are being passed.
277  *
278  * On the other hand it seems that no production code is using this
279  * function on Unix distributions.
280  */
281 
282 #endif
283 
284 
285  /* documentation is in ftcache.h */
286 
289  FTC_FaceID face_id,
290  FT_Int cmap_index,
291  FT_UInt32 char_code )
292  {
293  FTC_Cache cache = FTC_CACHE( cmap_cache );
295  FTC_Node node;
296  FT_Error error;
297  FT_UInt gindex = 0;
298  FT_PtrDist hash;
299  FT_Int no_cmap_change = 0;
300 
301 
302  if ( cmap_index < 0 )
303  {
304  /* Treat a negative cmap index as a special value, meaning that you */
305  /* don't want to change the FT_Face's character map through this */
306  /* call. This can be useful if the face requester callback already */
307  /* sets the face's charmap to the appropriate value. */
308 
309  no_cmap_change = 1;
310  cmap_index = 0;
311  }
312 
313  if ( !cache )
314  {
315  FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));
316  return 0;
317  }
318 
319 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
320 
321  /*
322  * If cmap_index is greater than the maximum number of cachable
323  * charmaps, we assume the request is from a legacy rogue client
324  * using old internal header. See include/config/ftoption.h.
325  */
326  if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE && !no_cmap_change )
327  {
328  FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id;
329 
330 
331  char_code = (FT_UInt32)cmap_index;
332  query.face_id = desc->face_id;
333 
334 
335  switch ( desc->type )
336  {
337  case FTC_OLD_CMAP_BY_INDEX:
338  query.cmap_index = desc->u.index;
339  query.char_code = (FT_UInt32)cmap_index;
340  break;
341 
342  case FTC_OLD_CMAP_BY_ENCODING:
343  {
344  FT_Face face;
345 
346 
347  error = FTC_Manager_LookupFace( cache->manager, desc->face_id,
348  &face );
349  if ( error )
350  return 0;
351 
352  FT_Select_Charmap( face, desc->u.encoding );
353 
354  return FT_Get_Char_Index( face, char_code );
355  }
356 
357  default:
358  return 0;
359  }
360  }
361  else
362 
363 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
364 
365  {
366  query.face_id = face_id;
367  query.cmap_index = (FT_UInt)cmap_index;
368  query.char_code = char_code;
369  }
370 
371  hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );
372 
373 #if 1
374  FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
375  node, error );
376 #else
377  error = FTC_Cache_Lookup( cache, hash, &query, &node );
378 #endif
379  if ( error )
380  goto Exit;
381 
382  FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) <
384 
385  /* something rotten can happen with rogue clients */
386  if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=
388  return 0; /* XXX: should return appropriate error */
389 
390  gindex = FTC_CMAP_NODE( node )->indices[char_code -
391  FTC_CMAP_NODE( node )->first];
392  if ( gindex == FTC_CMAP_UNKNOWN )
393  {
394  FT_Face face;
395 
396 
397  gindex = 0;
398 
399  error = FTC_Manager_LookupFace( cache->manager,
400  FTC_CMAP_NODE( node )->face_id,
401  &face );
402  if ( error )
403  goto Exit;
404 
405 #ifdef FT_MAX_CHARMAP_CACHEABLE
406  /* something rotten can happen with rogue clients */
407  if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE )
408  return 0; /* XXX: should return appropriate error */
409 #endif
410 
411  if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
412  {
413  FT_CharMap old, cmap = NULL;
414 
415 
416  old = face->charmap;
417  cmap = face->charmaps[cmap_index];
418 
419  if ( old != cmap && !no_cmap_change )
420  FT_Set_Charmap( face, cmap );
421 
422  gindex = FT_Get_Char_Index( face, char_code );
423 
424  if ( old != cmap && !no_cmap_change )
425  FT_Set_Charmap( face, old );
426  }
427 
428  FTC_CMAP_NODE( node )->indices[char_code -
429  FTC_CMAP_NODE( node )->first]
430  = (FT_UShort)gindex;
431  }
432 
433  Exit:
434  return gindex;
435  }
436 
437 
438 /* END */
FTC_CMapCache_New(FTC_Manager manager, FTC_CMapCache *acache)
Definition: ftccmap.c:261
int FT_Error
Definition: fttypes.h:296
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:333
FTC_Manager manager
Definition: ftccache.h:159
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
unsigned short FT_UInt16
Definition: ftconfig.h:176
struct FTC_CMapCacheRec_ * FTC_CMapCache
Definition: ftcache.h:571
FT_CharMap charmap
Definition: freetype.h:951
ftc_cmap_node_new(FTC_Node *ftcanode, FT_Pointer ftcquery, FTC_Cache cache)
Definition: ftccmap.c:150
ftc_cmap_node_weight(FTC_Node cnode, FTC_Cache cache)
Definition: ftccmap.c:180
#define NULL
Definition: ftobjs.h:61
signed int FT_Int
Definition: fttypes.h:216
struct FTC_CMapQueryRec_ FTC_CMapQueryRec
#define FTC_CMAP_NODE(x)
Definition: ftccmap.c:118
FT_CALLBACK_TABLE_DEF const FTC_CacheClassRec ftc_cmap_cache_class
Definition: ftccmap.c:244
ftc_cmap_node_compare(FTC_Node ftcnode, FT_Pointer ftcquery, FTC_Cache cache, FT_Bool *list_changed)
Definition: ftccmap.c:192
struct FTC_CMapNodeRec_ * FTC_CMapNode
#define FT_MAX_CHARMAP_CACHEABLE
Definition: ftoption.h:784
#define FTC_CMAP_INDICES_MAX
Definition: ftccmap.c:87
ftc_cmap_node_free(FTC_Node ftcnode, FTC_Cache cache)
Definition: ftccmap.c:137
FT_BEGIN_HEADER typedef FT_Pointer FTC_FaceID
Definition: ftcache.h:171
ftc_cache_init(FTC_Cache cache)
Definition: ftccache.c:340
GLuint id
Definition: gl2ext.h:1142
struct FTC_CMapQueryRec_ * FTC_CMapQuery
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
#define FT_ASSERT(condition)
Definition: ftdebug.h:204
#define FTC_CMAP_UNKNOWN
Definition: ftccmap.c:124
FTC_CMapCache_Lookup(FTC_CMapCache cache, FTC_FaceID face_id, FT_Int cmap_index, FT_UInt32 char_code)
Definition: ftccmap.c:288
GLenum query
Definition: glew.h:5140
FT_Int num_charmaps
Definition: freetype.h:928
#define FT_FREE(ptr)
Definition: ftmemory.h:286
ALuint u
Definition: alMain.h:58
FTC_Manager_RegisterCache(FTC_Manager manager, FTC_CacheClass clazz, FTC_Cache *acache)
Definition: ftcmanag.c:574
GLint first
Definition: gl2ext.h:1011
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3290
FT_Error error
Definition: cffdrivr.c:407
Colormap cmap
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
void * FT_Pointer
Definition: fttypes.h:307
FT_Select_Charmap(FT_Face face, FT_Encoding encoding)
Definition: ftobjs.c:3054
GLenum face
Definition: gl2ext.h:1490
#define FTC_CACHE(x)
Definition: ftccache.h:168
#define FTC_CMAP_HASH(faceid, index, charcode)
Definition: ftccmap.c:90
GLuint index
Definition: glew.h:1800
#define FTC_CACHE_P(x)
Definition: ftccache.h:169
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:554
#define FALSE
Definition: ftobjs.h:57
FT_CharMap * charmaps
Definition: freetype.h:929
enum FT_Encoding_ FT_Encoding
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3105
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
#define FT_BOOL(x)
Definition: fttypes.h:581
struct FTC_CacheRec_ FTC_CacheRec
#define FTC_CACHE_LOOKUP_CMP(cache, nodecmp, hash, query, node, error)
Definition: ftccache.h:217
GLintptr offset
Definition: glew.h:1668
#define FT_EXPORT_DEF(x)
Definition: ftconfig.h:511
unsigned int FT_UInt
Definition: fttypes.h:227
struct FTC_CMapNodeRec_ FTC_CMapNodeRec
#define FT_NEW(ptr)
Definition: ftmemory.h:288
unsigned short FT_UShort
Definition: fttypes.h:205
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
ftc_cache_done(FTC_Cache cache)
Definition: ftccache.c:394
#define FT_CALLBACK_TABLE_DEF
Definition: ftconfig.h:564
FTC_Manager_LookupFace(FTC_Manager manager, FTC_FaceID face_id, FT_Face *aface)
Definition: ftcmanag.c:308
size_t FT_Offset
Definition: fttypes.h:320
GLsizei GLenum const GLvoid * indices
Definition: gl2ext.h:1012
ftc_cmap_node_remove_faceid(FTC_Node ftcnode, FT_Pointer ftcface_id, FTC_Cache cache, FT_Bool *list_changed)
Definition: ftccmap.c:218